From 97d1e2c520673f14dde8d2f6b7dd03d9cd1e43d9 Mon Sep 17 00:00:00 2001 From: Kazunari Sekigawa Date: Thu, 11 Jan 2018 21:46:56 +0900 Subject: [PATCH] Prepare Python script for making a DMG file from bundles. This refs #22. --- macbuild/makeDMG4mac.py | 161 +++++++++++++++++++++++++++++++++++----- 1 file changed, 142 insertions(+), 19 deletions(-) diff --git a/macbuild/makeDMG4mac.py b/macbuild/makeDMG4mac.py index f2c452650..42c897ee7 100755 --- a/macbuild/makeDMG4mac.py +++ b/macbuild/makeDMG4mac.py @@ -38,7 +38,12 @@ def SetGlobals(): global DMGSerialNum # the DMG serial number global QtIndification # Qt identification global Version # KLayout's version - global DMGFileName # name of the DMG file + global TargetDMG # name of the target DMG file + # Work directories and files + global TemplateDMG # unpacked template DMG file + global WorkDir # work directory created under PkgDir/ + global WorkDMG # work DMG file deployed under PkgDir/ + global RootApplications # reserved directory name for applications # auxiliary variables on platform global System # 6-tuple from platform.uname() global Node # - do - @@ -61,6 +66,7 @@ def SetGlobals(): Usage += " <-c|--clean> : clean the work directory | disabled \n" Usage += " <-m|--make> : make a DMG file | disabled \n" Usage += " : <-c|--clean> and <-m|--make> are mutually exclusive | \n" + Usage += " [-q|--qt ] : ID name of deployed Qt | Qt593mp \n" Usage += " [-s|--serial ] : DMG serial number | 1 \n" Usage += " [-?|--?] : print this usage and exit | disabled \n" Usage += "--------------------------------------------------------------------------------------------------------\n" @@ -100,10 +106,17 @@ def SetGlobals(): OpClean = False OpMake = False DMGSerialNum = 1 - QtIndification = "Qt593mp" # constant for the time being + QtIndification = "Qt593mp" CheckComOnly = False Version = GetKLayoutVersionFrom( "./version.sh" ) - DMGFileName = "" + TargetDMG = "" + + # Work directories and files + TemplateDMG = "klayout.dmg" # unpacked template DMG file + # initially stored as 'macbuild/Resouces/klayout.dmg.bz2' + WorkDir = "work" # work directory created under PkgDir/ + WorkDMG = "work.dmg" # work DMG file deployed under PkgDir/ + RootApplications = "/Applications" # reserved directory name for applications #------------------------------------------------------------------------------ ## To check the contents of the package directory @@ -111,9 +124,6 @@ def SetGlobals(): # @return True on success; False on failure #------------------------------------------------------------------------------ def CheckPkgDirectory(): - global ProjectDir - global Usage - global PkgDir if PkgDir == "": print( "! Package directory is not specified", file=sys.stderr ) @@ -167,7 +177,7 @@ def ParseCommandLineArguments(): global DMGSerialNum global QtIndification global Version - global DMGFileName + global TargetDMG p = optparse.OptionParser( usage=Usage ) p.add_option( '-p', '--pkg', @@ -186,6 +196,10 @@ def ParseCommandLineArguments(): default=False, help="make operation" ) + p.add_option( '-q', '--qt', + dest='qt_identification', + help="Qt's ID" ) + p.add_option( '-s', '--serial', dest='dmg_serial', help="DMG serial number" ) @@ -196,11 +210,12 @@ def ParseCommandLineArguments(): default=False, help='check usage' ) - p.set_defaults( pkg_dir = "", - operation_clean = False, - operation_make = False, - dmg_serial = "1", - checkusage = False ) + p.set_defaults( pkg_dir = "", + operation_clean = False, + operation_make = False, + qt_identification = "Qt593mp", + dmg_serial = "1", + checkusage = False ) opt, args = p.parse_args() if (opt.checkusage): @@ -210,9 +225,9 @@ def ParseCommandLineArguments(): PkgDir = opt.pkg_dir OpClean = opt.operation_clean OpMake = opt.operation_make + QtIndification = opt.qt_identification DMGSerialNum = int(opt.dmg_serial) - QtIndification = "Qt593mp" - DMGFileName = "klayout-%s-%s-%d-%s.dmg" % (Version, Platform, DMGSerialNum, QtIndification) + TargetDMG = "klayout-%s-%s-%d-%s.dmg" % (Version, Platform, DMGSerialNum, QtIndification) if not CheckPkgDirectory(): quit() @@ -222,20 +237,128 @@ def ParseCommandLineArguments(): print(Usage) quit() - print( "" ) - print( "### You are going to make <%s> from <%s>" % (DMGFileName, PkgDir) ) - print( "" ) +#------------------------------------------------------------------------------ +## Make the target DMG file +# +# @param[in] msg message to print +# +# @return True on success; False on failure +#------------------------------------------------------------------------------ +def MakeTargetDMGFile(msg=""): + + #---------------------------------------------------- + # [1] Print message + #---------------------------------------------------- + if not msg == "": + print(msg) + + #-------------------------------------------------------- + # [2] Deploy unpacked template DMG under PkgDir/ + #-------------------------------------------------------- + os.chdir(ProjectDir) + tmplDMGbz2 = "macbuild/Resources/%s.bz2" % TemplateDMG + srcDMG = "macbuild/Resources/%s" % TemplateDMG + destDMG = "%s/%s" % (PkgDir, WorkDMG) + os.system( "%s -k %s" % ("bunzip2", tmplDMGbz2)) + shutil.copy2( srcDMG, destDMG ) + os.remove( srcDMG ) + + #---------------------------------------------------- + # [3] Prepare empty work directory under PkgDir/ + #---------------------------------------------------- + os.chdir(PkgDir) + if os.path.exists(WorkDir): + shutil.rmtree(WorkDir) + os.mkdir(WorkDir) + + #-------------------------------------------------------- + # [4] Attach the work directory to the work DMG + #-------------------------------------------------------- + os.system( "hdiutil attach %s -noautoopen -quiet -mountpoint %s" % (WorkDMG, WorkDir) ) + + #-------------------------------------------------------- + # [5] Populate the work directory + #-------------------------------------------------------- + os.system( "%s %s %s" % ("cp -Rp", "klayout.app", WorkDir) ) + os.system( "%s %s %s" % ("cp -Rp", "klayout.scripts", WorkDir) ) + os.symlink( RootApplications, WorkDir + RootApplications ) + + #-------------------------------------------------------- + # [6] Detach the work directory + # + # wordDev = /dev/disk10s1 (for example) + #-------------------------------------------------------- + command = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % WorkDir + wordDev = os.popen( command ).read().strip('\n') + if wordDev == "": + print( "! Failed to identify the file system on which <%s> is mounted" % WorkDir ) + return False + else: + os.system( "hdiutil detach %s -quiet -force" % wordDev ) + + #-------------------------------------------------------- + # [7] Finish up + #-------------------------------------------------------- + os.system( "rm -Rf %s" % TargetDMG ) + os.system( "hdiutil convert -quiet -format UDRW -imagekey zlib-level=9 -o %s %s" % (TargetDMG, WorkDMG) ) + os.system( "rm -Rf %s" % WorkDir ) + os.system( "rm -Rf %s" % WorkDMG ) + os.system( "rm -Rf %s" % TemplateDMG ) + os.chdir(ProjectDir) + + return True + +#------------------------------------------------------------------------------ +## Clean up +# +# @param[in] msg message to print +# +#------------------------------------------------------------------------------ +def CleanUp(msg=""): + + #---------------------------------------------------- + # [1] Print message + #---------------------------------------------------- + if not msg == "": + print(msg) + + #---------------------------------------------------- + # [2] Clean up + #---------------------------------------------------- + os.chdir(ProjectDir) + os.chdir(PkgDir) + dmgs = glob.glob( "*.dmg" ) + for item in dmgs: + os.system( "rm -Rf %s" % item ) + os.system( "rm -Rf %s" % WorkDir ) + os.chdir(ProjectDir) #------------------------------------------------------------------------------ ## The main function #------------------------------------------------------------------------------ -def main(): +def Main(): SetGlobals() ParseCommandLineArguments() + if OpMake: + print( "" ) + print( " ### You are going to make <%s> from <%s>" % (TargetDMG, PkgDir) ) + ok = MakeTargetDMGFile() + if not ok: + print( " !!! Failed to make the target DMG <%s> ..." % TargetDMG, file=sys.stderr ) + print( "", file=sys.stderr ) + else: + print( " ### Done" ) + print( "" ) + else: + print( "" ) + print( " ### You are going to clean up <%s> directory" % PkgDir ) + CleanUp() + print( " ### Done" ) + print( "" ) #=================================================================================== if __name__ == "__main__": - main() + Main() #--------------- # End of file