From 219573eab0fb253c0dc3e02dde38330c2a236109 Mon Sep 17 00:00:00 2001 From: Norberto Lopez <106690103+nobes888@users.noreply.github.com> Date: Fri, 4 May 2018 20:05:59 +0000 Subject: [PATCH] Various code cleanups. --- script/appleUtils.py | 290 ++++++++++++++----------------------- script/buildDist.py | 23 +++ src/distMaker/DistApp.java | 2 +- tools/buildRelease | 90 ++++++------ 4 files changed, 178 insertions(+), 227 deletions(-) diff --git a/script/appleUtils.py b/script/appleUtils.py index 337d695..eb9ddbb 100644 --- a/script/appleUtils.py +++ b/script/appleUtils.py @@ -48,7 +48,7 @@ def buildRelease(args, buildPath): if jreTarGzFile == None: # Let the user know that a compatible JRE was not found - thus no static release will be made. print('[Warning] No compatible JRE ({0}) is available for the {1} platform. A static release will not be provided for the platform.'.format(jreVerSpec, platformStr.capitalize())) - # Let the user know that a compatible JRE was not found - and thus no Apple builds will be made +# # Let the user know that a compatible JRE was not found - and thus no Apple builds will be made print('Only static Apple distributions are supported - thus there will be no Apple distribution of the application: ' + appName + '\n') return else: @@ -144,124 +144,6 @@ def buildRelease(args, buildPath): # os.rmdir(tmpPath) -def buildDistTree(buildPath, rootPath, args, jreTarGzFile): - # Retrieve vars of interest - appInstallRoot = miscUtils.getInstallRoot() - appInstallRoot = os.path.dirname(appInstallRoot) - appTemplatePath = os.path.join(appInstallRoot, 'template') - appName = args.name - bgFile = args.bgFile - icnsFile = args.icnsFile - - # Form the symbolic link which points to /Applications - srcPath = '/Applications' - dstPath = os.path.join(rootPath, 'Applications'); - os.symlink(srcPath, dstPath) - - # Construct the app folder - appNodes = ['MacOS', 'Resources'] - if jreTarGzFile != None: - appNodes.append('PlugIns') - for aPath in appNodes: - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', aPath) - os.makedirs(dstPath) - - if jreTarGzFile != None: - # Copy over the executable launcher - srcPath = os.path.join(appTemplatePath, 'apple', 'JavaAppLauncher') - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'MacOS') - shutil.copy(srcPath, dstPath) - - # Unpack the JRE and set up the JRE tree - destPath = os.path.join(rootPath, appName + '.app', 'Contents', 'PlugIns') - jreUtils.unpackAndRenameToStandard(jreTarGzFile, destPath) - else: - # Copy over the executable launcher - srcPath = os.path.join(appTemplatePath, 'apple', 'JavaApplicationStub') - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'MacOS') - shutil.copy(srcPath, dstPath) - - # Write out the PkgInfo file - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', "PkgInfo") - f = open(dstPath, 'wb') - f.write('APPL????') - f.close() - - # Determine the payloadPath for where to store the appLauncher - payloadPath = os.path.join(rootPath, appName + '.app', 'Contents') - if jreTarGzFile == None: - payloadPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources') - - # Form the app contents folder - srcPath = os.path.join(buildPath, "delta") - dstPath = os.path.join(payloadPath, 'app') - shutil.copytree(srcPath, dstPath, symlinks=True) - - # Link dlls to the MacOS directory so they can be found at launch - jarDir = os.path.join(rootPath, appName + '.app', 'Contents', 'app', 'code', 'osx') - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'MacOS') - for jniPath in glob.iglob(os.path.join(jarDir, "*.jnilib")): - jniFileName = os.path.basename(jniPath) - srcPath = os.path.join('..', 'app', 'code', 'osx', jniFileName) - linkPath = os.path.join(dstPath, jniFileName) - os.symlink(srcPath, linkPath) - for dylPath in glob.iglob(os.path.join(jarDir, "*.dylib")): - dylFileName = os.path.basename(dylPath) - srcPath = os.path.join('..', 'app', 'code', 'osx', dylFileName) - linkPath = os.path.join(dstPath, dylFileName) - os.symlink(srcPath, linkPath) - - - # Setup the launcher contents - dstPath = os.path.join(payloadPath, "Java/" + deployJreDist.getAppLauncherFileName()) - srcPath = os.path.join(appInstallRoot, "template/appLauncher.jar") - os.makedirs(os.path.dirname(dstPath)) - shutil.copy(srcPath, dstPath); - - # Build the java component of the distribution - if args.javaCode != None: - # Form the Info.plist file - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Info.plist') - if jreTarGzFile != None: - buildPListInfoStatic(dstPath, args, jreTarGzFile) - else: - buildPListInfoShared(dstPath, args) - - # Copy over the icon file *.icns - if icnsFile != None and os.path.exists(icnsFile) == True: - srcPath = icnsFile - dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources') - shutil.copy(srcPath, dstPath) - - # Copy over the background file - srcPath = bgFile - if srcPath == None: - srcPath = os.path.join(appTemplatePath, 'background', 'background.png'); - dstPath = os.path.join(rootPath, '.background') - os.mkdir(dstPath) - dstPath = os.path.join(rootPath, '.background', 'background.png') - shutil.copy(srcPath, dstPath) - - # Copy over the .DS_Store - srcPath = os.path.join(appTemplatePath, '.DS_Store.template') - dstPath = os.path.join(rootPath, '.DS_Store') - shutil.copy(srcPath, dstPath) - - # Update the .DS_Store file to reflect the new volume name - srcPath = os.path.join(rootPath, '.DS_Store') - classPath = appInstallRoot + '/lib/glum.jar:' + appInstallRoot + '/lib/distMaker.jar:' + appInstallRoot + '/lib/guava-18.0.jar' - cmd = ['java', '-cp', classPath, 'dsstore.MainApp', srcPath, appName] - proc = miscUtils.executeAndLog(cmd, "\t\tdsstore.MainApp: ") - if proc.returncode != 0: - print('\tError: Failed to update .DS_Store. Return code: ' + str(proc.returncode)) - - - - - - - - def normGuid(mountPt): # Ensure we are running as root miscUtils.checkRoot() @@ -302,74 +184,119 @@ def umount(mountPt): subprocess.call(cmd, stderr=subprocess.STDOUT) -def buildPListInfoShared(destFile, args): + + + +def buildDistTree(buildPath, rootPath, args, jreTarGzFile): # Retrieve vars of interest - icnsStr = None - if args.icnsFile != None: - icnsStr = os.path.basename(args.icnsFile) + appInstallRoot = miscUtils.getInstallRoot() + appInstallRoot = os.path.dirname(appInstallRoot) + appTemplatePath = os.path.join(appInstallRoot, 'template') + appName = args.name + bgFile = args.bgFile + icnsFile = args.icnsFile - jvmArgsStr = '' - for aStr in args.jvmArgs: - jvmArgsStr += aStr + ' ' - jvmArgsStr += '-Djava.system.class.loader=appLauncher.RootClassLoader' + # Form the symbolic link which points to /Applications + srcPath = '/Applications' + dstPath = os.path.join(rootPath, 'Applications'); + os.symlink(srcPath, dstPath) - f = open(destFile, 'wb') - writeln(f, 0, '') -# writeln(f, 0, '') - writeln(f, 0, '') - writeln(f, 1, '') + # Construct the app folder + appNodes = ['MacOS', 'Resources'] + for aPath in appNodes: + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', aPath) + os.makedirs(dstPath) - tupList = [] - tupList.append(('CFBundleExecutable', 'JavaApplicationStub')) - tupList.append(('CFBundleGetInfoString', args.company)) - tupList.append(('CFBundleInfoDictionaryVersion', 6.0)) - tupList.append(('CFBundleIconFile', icnsStr)) - tupList.append(('CFBundleIdentifier', args.name.lower())) - tupList.append(('CFBundleName', args.name)) - tupList.append(('CFBundlePackageType', 'APPL')) - tupList.append(('CFBundleSignature', '????')) - tupList.append(('CFBundleVersion', args.version)) + # Copy over the executable launcher + srcPath = os.path.join(appTemplatePath, 'apple', 'JavaAppLauncher') + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'MacOS') + shutil.copy(srcPath, dstPath) - # Application configuration - for (key, val) in tupList: - writeln(f, 2, '' + key + '') - writeln(f, 2, '' + str(val) + '') - - # JVM configuration - writeln(f, 2, 'Java') - writeln(f, 2, '') - - classPathStr = '$JAVAROOT/' + deployJreDist.getAppLauncherFileName() - - tupList = [] - tupList.append(('JVMVersion', '1.7+')) - tupList.append(('MainClass', 'appLauncher.AppLauncher')) - tupList.append(('WorkingDirectory', '$APP_PACKAGE/Contents/Resources/app')) - tupList.append(('ClassPath', classPathStr)) - tupList.append(('VMOptions', jvmArgsStr)) - - for (key, val) in tupList: - writeln(f, 3, '' + key + '') - writeln(f, 3, '' + str(val) + '') - - writeln(f, 3, 'Arguments') - writeln(f, 3, '') -# for aStr in args.appArgs: -# writeln(f, 4, '' + aStr + '') - writeln(f, 3, '') - writeln(f, 2, '') - writeln(f, 1, '') - writeln(f, 0, '') + # Unpack the JRE and set up the JRE tree + if jreTarGzFile != None: + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'PlugIns') + os.makedirs(dstPath) + jreUtils.unpackAndRenameToStandard(jreTarGzFile, dstPath) + # Write out the PkgInfo file + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', "PkgInfo") + f = open(dstPath, 'wb') + f.write('APPL????') f.close() -def buildPListInfoStatic(destFile, args, jreTarGzFile): + # Define the payloadPath for where to store the appLauncher + payloadPath = os.path.join(rootPath, appName + '.app', 'Contents') + + # Form the app contents folder + srcPath = os.path.join(buildPath, "delta") + dstPath = os.path.join(payloadPath, 'app') + shutil.copytree(srcPath, dstPath, symlinks=True) + + # Link dlls to the MacOS directory so they can be found at launch + jarDir = os.path.join(rootPath, appName + '.app', 'Contents', 'app', 'code', 'osx') + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'MacOS') + for jniPath in glob.iglob(os.path.join(jarDir, "*.jnilib")): + jniFileName = os.path.basename(jniPath) + srcPath = os.path.join('..', 'app', 'code', 'osx', jniFileName) + linkPath = os.path.join(dstPath, jniFileName) + os.symlink(srcPath, linkPath) + for dylPath in glob.iglob(os.path.join(jarDir, "*.dylib")): + dylFileName = os.path.basename(dylPath) + srcPath = os.path.join('..', 'app', 'code', 'osx', dylFileName) + linkPath = os.path.join(dstPath, dylFileName) + os.symlink(srcPath, linkPath) + + # Setup the launcher contents + dstPath = os.path.join(payloadPath, "Java/" + deployJreDist.getAppLauncherFileName()) + srcPath = os.path.join(appInstallRoot, "template/appLauncher.jar") + os.makedirs(os.path.dirname(dstPath)) + shutil.copy(srcPath, dstPath); + + # Build the java component of the distribution + if args.javaCode != None: + # Form the Info.plist file + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Info.plist') + buildPListInfo(dstPath, args, jreTarGzFile) + + # Copy over the icon file *.icns + if icnsFile != None and os.path.exists(icnsFile) == True: + srcPath = icnsFile + dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources') + shutil.copy(srcPath, dstPath) + + # Copy over the background file + srcPath = bgFile + if srcPath == None: + srcPath = os.path.join(appTemplatePath, 'background', 'background.png'); + dstPath = os.path.join(rootPath, '.background') + os.mkdir(dstPath) + dstPath = os.path.join(rootPath, '.background', 'background.png') + shutil.copy(srcPath, dstPath) + + # Copy over the .DS_Store + srcPath = os.path.join(appTemplatePath, '.DS_Store.template') + dstPath = os.path.join(rootPath, '.DS_Store') + shutil.copy(srcPath, dstPath) + + # Update the .DS_Store file to reflect the new volume name + srcPath = os.path.join(rootPath, '.DS_Store') + classPath = appInstallRoot + '/lib/glum.jar:' + appInstallRoot + '/lib/distMaker.jar:' + appInstallRoot + '/lib/guava-18.0.jar' + cmd = ['java', '-cp', classPath, 'dsstore.MainApp', srcPath, appName] + proc = miscUtils.executeAndLog(cmd, "\t\tdsstore.MainApp: ") + if proc.returncode != 0: + print('\tError: Failed to update .DS_Store. Return code: ' + str(proc.returncode)) + + +def buildPListInfo(destFile, args, jreTarGzFile): + """Method that will construct and populate the Info.plist file. This file + defines the attributes associated with the (Apple) app.""" # Retrieve vars of interest icnsStr = None if args.icnsFile != None: icnsStr = os.path.basename(args.icnsFile) f = open(destFile, 'wb') +# writeln(f, 0, '') writeln(f, 0, '') writeln(f, 0, '') writeln(f, 1, '') @@ -389,12 +316,18 @@ def buildPListInfoStatic(destFile, args, jreTarGzFile): tupList.append(('NSHighResolutionCapable', 'true')) tupList.append(('NSHumanReadableCopyright', '')) - jrePath = jreUtils.getBasePathForJreTarGzFile(jreTarGzFile) - tupList.append(('JVMRuntime', jrePath)) + # Define the JVM that is to be uesd + if jreTarGzFile != None: + jrePath = jreUtils.getBasePathForJreTarGzFile(jreTarGzFile) + tupList.append(('JVMRuntime', jrePath)) + else: +# tupList.append(('JVMVersion', '1.7+')) + raise Exception('Support for utilizing the system JRE has not been added yet.') + # Define the main entry point (AppLauncher) and the working directory tupList.append(('JVMMainClassName', 'appLauncher.AppLauncher')) - cwdPath = os.path.join('/Applications', args.name + '.app', 'Contents', 'app') + cwdPath = os.path.join('$APP_ROOT', 'Contents', 'app') tupList.append(('WorkingDirectory', cwdPath)) # Application configuration @@ -443,8 +376,9 @@ def buildPListInfoStatic(destFile, args, jreTarGzFile): def checkSystemEnvironment(): - """Checks to ensure that all system application / environment variables needed to build a Apple distribution are installed - and properly configured. Returns False if the system environment is insufficient""" + """Checks to ensure that all system application / environment variables + needed to build a Apple distribution are installed and properly configured. + Returns False if the system environment is insufficient""" return True diff --git a/script/buildDist.py b/script/buildDist.py index 25aac07..c1edf52 100755 --- a/script/buildDist.py +++ b/script/buildDist.py @@ -214,6 +214,29 @@ if __name__ == "__main__": # Check to ensure all of the required applications are installed before proceeding checkForRequiredApplicationsAndExit() + # Check to ensure that the JRE path is a folder (or symbolic link to a folder) + installRoot = miscUtils.getInstallRoot() + installRoot = os.path.dirname(installRoot) + jrePath = os.path.join(installRoot, 'jre') + if os.path.islink(jrePath) == True and os.path.exists(jrePath) == False: + print('The specified JRE path refers to a broken symbol link. Please fix the JRE path to reflect a proper location.') + print(' The broken JRE symbolic link is at: {}'.format(jrePath)) + print() + exit() + if os.path.exists(jrePath) == False: + print('The JRE folder does not exist. Please create a JRE folder (or a symolic link to a proper JRE folder).') + print(' The JRE path should be at: {}'.format(jrePath)) + print(' Populate the folder with the JRE tar.gz release files for each platform of interest.') + print(' JRE tar.gz files may be acquired from: {}'.format('http://www.oracle.com/technetwork/java/javase/downloads')) + print() + exit() + if os.path.isdir(jrePath) == False: + print('The specified JRE path does not refer to a folder.') + print(' The JRE path should be a folder which contains the proper JRE tar.gz files.') + print(' The JRE folder should be located at: {}'.format(jrePath)) + print() + exit() + # Parse the args parser.formatter_class.max_help_position = 50 args = parser.parse_args() diff --git a/src/distMaker/DistApp.java b/src/distMaker/DistApp.java index 290441f..9d82643 100644 --- a/src/distMaker/DistApp.java +++ b/src/distMaker/DistApp.java @@ -12,7 +12,7 @@ import distMaker.utils.Version; public class DistApp { /** The DistMaker version is defined here. */ - public static final Version version = new PlainVersion(0, 49, 0); + public static final Version version = new PlainVersion(0, 50, 0); /** * Main entry point that will print out the version of DistMaker to stdout. diff --git a/tools/buildRelease b/tools/buildRelease index 46a9428..13ec5d6 100755 --- a/tools/buildRelease +++ b/tools/buildRelease @@ -8,48 +8,15 @@ import signal import subprocess import sys -def getDistMakerVersion(): - # Retrieve the install path - installPath = getInstallRoot() - installPath = os.path.dirname(installPath) - - # Check for distMaker.jar library prerequisite - testPath = os.path.join(installPath, 'lib', 'distMaker.jar') - if os.path.exists(testPath) == False: - errPrintln('Aborting DistMaker release build. The file ' + testPath + ' does not exist.', indent=1) - errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1) - exit(-1) - - try: - exeCmd = ['java', '-cp', 'lib/distMaker.jar', 'distMaker.DistApp', '--version'] - output = subprocess.check_output(exeCmd).decode('utf-8') - version = output.split()[1] - return version - except: - errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1) - exit(-1) - - -def errPrintln(message="", indent=0): - """Print the specified string with a trailing newline to stderr.""" - while indent > 0: - indent -= 1 - message = ' ' + message - sys.stderr.write(message + '\n') - - def buildRelease(version, doNotClean=False): + """Method that builds a release of DistMaker. Upon sucessful execution, a + tar.gz archive will be generated named: 'DistMaker-.tar.gz'. Note + that releases of DistMaker version 0.50 or later (2018May01+) will no longer + include static JREs.""" # Retrieve the install path installPath = getInstallRoot() installPath = os.path.dirname(installPath) - # Check for static jre prerequisites - isPass = os.path.exists(os.path.join(installPath, 'jre')) - if isPass == False: - errPrintln('Aborting DistMaker release build. The jre path is not properly configured.', indent=1) - errPrintln('Please setup the jre path properly. A quick fix is to copy the jre tree from a previous release of DistMaker.', indent=1) - exit(-1) - # Determine the workPath workPath = os.path.join(installPath, 'release', 'DistMaker-' + version) destFileGZ = os.path.join(installPath, 'release', 'DistMaker-' + version + '.tar.gz') @@ -82,19 +49,12 @@ def buildRelease(version, doNotClean=False): srcPath = os.path.join(installPath, 'script', aScript) shutil.copy2(srcPath, dstPath) - # Copy the (tar.gz) JREs - globPath = os.path.join(installPath, 'jre/jre-*.tar.gz') - dstPath = os.path.join(workPath, 'jre') - os.mkdir(dstPath) - for aFile in glob.glob(globPath): - shutil.copy2(aFile, dstPath) - # Setup the template tree dstPath = os.path.join(workPath, 'template') os.makedirs(dstPath + '/apple') os.makedirs(dstPath + '/background') os.makedirs(dstPath + '/launch4j') - for aFile in ['appLauncher.jar', '.DS_Store.template', 'apple/JavaAppLauncher', 'apple/JavaApplicationStub', 'background/background.png', 'launch4j/launch4j-3.8-linux.tgz', 'launch4j/launch4j-3.8-macosx-x86-10.8.tgz']: + for aFile in ['appLauncher.jar', '.DS_Store.template', 'apple/JavaAppLauncher', 'background/background.png', 'launch4j/launch4j-3.8-linux.tgz', 'launch4j/launch4j-3.8-macosx-x86-10.8.tgz']: srcPath = os.path.join(installPath, 'template', aFile) shutil.copy2(srcPath, dstPath + '/' + aFile) @@ -112,6 +72,40 @@ def buildRelease(version, doNotClean=False): print('DistMaker release ' + version + ' built.') +def errPrintln(message="", indent=0): + """Print the specified string with a trailing newline to stderr.""" + while indent > 0: + indent -= 1 + message = ' ' + message + sys.stderr.write(message + '\n') + + +def getDistMakerVersion(): + """Method that will return the version of the distMaker.jar file that resides + in the library path. The version of the DistMaker release is defined by the + value associated with the disMaker.jar file. Any failures will result in the + abrupt exit of this script.""" + # Retrieve the install path + installPath = getInstallRoot() + installPath = os.path.dirname(installPath) + + # Check for distMaker.jar library prerequisite + testPath = os.path.join(installPath, 'lib', 'distMaker.jar') + if os.path.exists(testPath) == False: + errPrintln('Aborting DistMaker release build. The file ' + testPath + ' does not exist.', indent=1) + errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1) + exit(-1) + + try: + exeCmd = ['java', '-cp', 'lib/distMaker.jar', 'distMaker.DistApp', '--version'] + output = subprocess.check_output(exeCmd).decode('utf-8') + version = output.split()[1] + return version + except: + errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1) + exit(-1) + + def getInstallRoot(): """Returns the root path where the running script is installed.""" argv = sys.argv; @@ -121,9 +115,9 @@ def getInstallRoot(): def handleSignal(signal, frame): - """Signal handler, typically used to capture ctrl-c.""" - print('User aborted processing!') - sys.exit(0) + """Signal handler, typically used to capture ctrl-c.""" + print('User aborted processing!') + sys.exit(0) if __name__ == "__main__":