1919import subprocess , sys , re , os , shutil , stat , os .path , time
2020from string import Template
2121from argparse import ArgumentParser
22+ from typing import List , Optional
2223
2324# This is ported from the original macdeployqt with modifications
2425
@@ -48,18 +49,18 @@ class FrameworkInfo(object):
4849 return False
4950
5051 def __str__ (self ):
51- return """ Framework name: %s
52- Framework directory: %s
53- Framework path: %s
54- Binary name: %s
55- Binary directory: %s
56- Binary path: %s
57- Version: %s
58- Install name: %s
59- Deployed install name: %s
60- Source file Path: %s
61- Deployed Directory (relative to bundle): %s
62- """ % (self .frameworkName ,
52+ return """ Framework name: {}
53+ Framework directory: {}
54+ Framework path: {}
55+ Binary name: {}
56+ Binary directory: {}
57+ Binary path: {}
58+ Version: {}
59+ Install name: {}
60+ Deployed install name: {}
61+ Source file Path: {}
62+ Deployed Directory (relative to bundle): {}
63+ """ . format (self .frameworkName ,
6364 self .frameworkDirectory ,
6465 self .frameworkPath ,
6566 self .binaryName ,
@@ -85,7 +86,7 @@ class FrameworkInfo(object):
8586 bundleBinaryDirectory = "Contents/MacOS"
8687
8788 @classmethod
88- def fromOtoolLibraryLine (cls , line ) :
89+ def fromOtoolLibraryLine (cls , line : str ) -> Optional [ 'FrameworkInfo' ] :
8990 # Note: line must be trimmed
9091 if line == "" :
9192 return None
@@ -146,13 +147,12 @@ class FrameworkInfo(object):
146147 info .sourceContentsDirectory = os .path .join (info .frameworkPath , "Contents" )
147148 info .sourceVersionContentsDirectory = os .path .join (info .frameworkPath , "Versions" , info .version , "Contents" )
148149 info .destinationResourcesDirectory = os .path .join (cls .bundleFrameworkDirectory , info .frameworkName , "Resources" )
149- info .destinationContentsDirectory = os .path .join (cls .bundleFrameworkDirectory , info .frameworkName , "Contents" )
150150 info .destinationVersionContentsDirectory = os .path .join (cls .bundleFrameworkDirectory , info .frameworkName , "Versions" , info .version , "Contents" )
151151
152152 return info
153153
154154class ApplicationBundleInfo (object ):
155- def __init__ (self , path ):
155+ def __init__ (self , path : str ):
156156 self .path = path
157157 appName = "Bitcoin-Qt"
158158 self .binaryPath = os .path .join (path , "Contents" , "MacOS" , appName )
@@ -167,7 +167,7 @@ class DeploymentInfo(object):
167167 self .pluginPath = None
168168 self .deployedFrameworks = []
169169
170- def detectQtPath (self , frameworkDirectory ):
170+ def detectQtPath (self , frameworkDirectory : str ):
171171 parentDir = os .path .dirname (frameworkDirectory )
172172 if os .path .exists (os .path .join (parentDir , "translations" )):
173173 # Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x"
@@ -180,9 +180,9 @@ class DeploymentInfo(object):
180180 if os .path .exists (pluginPath ):
181181 self .pluginPath = pluginPath
182182
183- def usesFramework (self , name ) :
184- nameDot = "%s." % name
185- libNameDot = "lib%s." % name
183+ def usesFramework (self , name : str ) -> bool :
184+ nameDot = "{}." . format ( name )
185+ libNameDot = "lib{}." . format ( name )
186186 for framework in self .deployedFrameworks :
187187 if framework .endswith (".framework" ):
188188 if framework .startswith (nameDot ):
@@ -192,7 +192,7 @@ class DeploymentInfo(object):
192192 return True
193193 return False
194194
195- def getFrameworks (binaryPath , verbose ) :
195+ def getFrameworks (binaryPath : str , verbose : int ) -> List [ FrameworkInfo ] :
196196 if verbose >= 3 :
197197 print ("Inspecting with otool: " + binaryPath )
198198 otoolbin = os .getenv ("OTOOL" , "otool" )
@@ -202,7 +202,7 @@ def getFrameworks(binaryPath, verbose):
202202 if verbose >= 1 :
203203 sys .stderr .write (o_stderr )
204204 sys .stderr .flush ()
205- raise RuntimeError ("otool failed with return code %d" % otool .returncode )
205+ raise RuntimeError ("otool failed with return code {}" . format ( otool .returncode ) )
206206
207207 otoolLines = o_stdout .split ("\n " )
208208 otoolLines .pop (0 ) # First line is the inspected binary
@@ -221,33 +221,33 @@ def getFrameworks(binaryPath, verbose):
221221
222222 return libraries
223223
224- def runInstallNameTool (action , * args ):
224+ def runInstallNameTool (action : str , * args ):
225225 installnametoolbin = os .getenv ("INSTALLNAMETOOL" , "install_name_tool" )
226226 subprocess .check_call ([installnametoolbin , "-" + action ] + list (args ))
227227
228- def changeInstallName (oldName , newName , binaryPath , verbose ):
228+ def changeInstallName (oldName : str , newName : str , binaryPath : str , verbose : int ):
229229 if verbose >= 3 :
230230 print ("Using install_name_tool:" )
231231 print (" in" , binaryPath )
232232 print (" change reference" , oldName )
233233 print (" to" , newName )
234234 runInstallNameTool ("change" , oldName , newName , binaryPath )
235235
236- def changeIdentification (id , binaryPath , verbose ):
236+ def changeIdentification (id : str , binaryPath : str , verbose : int ):
237237 if verbose >= 3 :
238238 print ("Using install_name_tool:" )
239239 print (" change identification in" , binaryPath )
240240 print (" to" , id )
241241 runInstallNameTool ("id" , id , binaryPath )
242242
243- def runStrip (binaryPath , verbose ):
243+ def runStrip (binaryPath : str , verbose : int ):
244244 stripbin = os .getenv ("STRIP" , "strip" )
245245 if verbose >= 3 :
246246 print ("Using strip:" )
247247 print (" stripped" , binaryPath )
248248 subprocess .check_call ([stripbin , "-x" , binaryPath ])
249249
250- def copyFramework (framework , path , verbose ) :
250+ def copyFramework (framework : FrameworkInfo , path : str , verbose : int ) -> Optional [ str ] :
251251 if framework .sourceFilePath .startswith ("Qt" ):
252252 #standard place for Nokia Qt installer's frameworks
253253 fromPath = "/Library/Frameworks/" + framework .sourceFilePath
@@ -309,7 +309,7 @@ def copyFramework(framework, path, verbose):
309309
310310 return toPath
311311
312- def deployFrameworks (frameworks , bundlePath , binaryPath , strip , verbose , deploymentInfo = None ):
312+ def deployFrameworks (frameworks : List [ FrameworkInfo ] , bundlePath : str , binaryPath : str , strip : bool , verbose : int , deploymentInfo : Optional [ DeploymentInfo ] = None ) -> DeploymentInfo :
313313 if deploymentInfo is None :
314314 deploymentInfo = DeploymentInfo ()
315315
@@ -355,15 +355,15 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym
355355
356356 return deploymentInfo
357357
358- def deployFrameworksForAppBundle (applicationBundle , strip , verbose ) :
358+ def deployFrameworksForAppBundle (applicationBundle : ApplicationBundleInfo , strip : bool , verbose : int ) -> DeploymentInfo :
359359 frameworks = getFrameworks (applicationBundle .binaryPath , verbose )
360360 if len (frameworks ) == 0 and verbose >= 1 :
361- print ("Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle .path ))
361+ print ("Warning: Could not find any external frameworks to deploy in {}." . format (applicationBundle .path ))
362362 return DeploymentInfo ()
363363 else :
364364 return deployFrameworks (frameworks , applicationBundle .path , applicationBundle .binaryPath , strip , verbose )
365365
366- def deployPlugins (appBundleInfo , deploymentInfo , strip , verbose ):
366+ def deployPlugins (appBundleInfo : ApplicationBundleInfo , deploymentInfo : DeploymentInfo , strip : bool , verbose : int ):
367367 # Lookup available plugins, exclude unneeded
368368 plugins = []
369369 if deploymentInfo .pluginPath is None :
@@ -373,10 +373,12 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
373373 if pluginDirectory == "designer" :
374374 # Skip designer plugins
375375 continue
376- elif pluginDirectory == "phonon" or pluginDirectory == "phonon_backend" :
377- # Deploy the phonon plugins only if phonon is in use
378- if not deploymentInfo .usesFramework ("phonon" ):
379- continue
376+ elif pluginDirectory == "printsupport" :
377+ # Skip printsupport plugins
378+ continue
379+ elif pluginDirectory == "imageformats" :
380+ # Skip imageformats plugins
381+ continue
380382 elif pluginDirectory == "sqldrivers" :
381383 # Deploy the sql plugins only if QtSql is in use
382384 if not deploymentInfo .usesFramework ("QtSql" ):
@@ -409,6 +411,42 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
409411 # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use
410412 if not deploymentInfo .usesFramework ("QtMultimediaWidgets" ):
411413 continue
414+ elif pluginDirectory == "canbus" :
415+ # Deploy the canbus plugins only if QtSerialBus is in use
416+ if not deploymentInfo .usesFramework ("QtSerialBus" ):
417+ continue
418+ elif pluginDirectory == "webview" :
419+ # Deploy the webview plugins only if QtWebView is in use
420+ if not deploymentInfo .usesFramework ("QtWebView" ):
421+ continue
422+ elif pluginDirectory == "gamepads" :
423+ # Deploy the webview plugins only if QtGamepad is in use
424+ if not deploymentInfo .usesFramework ("QtGamepad" ):
425+ continue
426+ elif pluginDirectory == "geoservices" :
427+ # Deploy the webview plugins only if QtLocation is in use
428+ if not deploymentInfo .usesFramework ("QtLocation" ):
429+ continue
430+ elif pluginDirectory == "texttospeech" :
431+ # Deploy the texttospeech plugins only if QtTextToSpeech is in use
432+ if not deploymentInfo .usesFramework ("QtTextToSpeech" ):
433+ continue
434+ elif pluginDirectory == "virtualkeyboard" :
435+ # Deploy the virtualkeyboard plugins only if QtVirtualKeyboard is in use
436+ if not deploymentInfo .usesFramework ("QtVirtualKeyboard" ):
437+ continue
438+ elif pluginDirectory == "sceneparsers" :
439+ # Deploy the virtualkeyboard plugins only if Qt3DCore is in use
440+ if not deploymentInfo .usesFramework ("Qt3DCore" ):
441+ continue
442+ elif pluginDirectory == "renderplugins" :
443+ # Deploy the renderplugins plugins only if Qt3DCore is in use
444+ if not deploymentInfo .usesFramework ("Qt3DCore" ):
445+ continue
446+ elif pluginDirectory == "geometryloaders" :
447+ # Deploy the geometryloaders plugins only if Qt3DCore is in use
448+ if not deploymentInfo .usesFramework ("Qt3DCore" ):
449+ continue
412450
413451 for pluginName in filenames :
414452 pluginPath = os .path .join (pluginDirectory , pluginName )
@@ -431,6 +469,10 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
431469 # Deploy the accessible qtquick plugin only if QtQuick is in use
432470 if not deploymentInfo .usesFramework ("QtQuick" ):
433471 continue
472+ elif pluginPath == "platforminputcontexts/libqtvirtualkeyboardplugin.dylib" :
473+ # Deploy the virtualkeyboardplugin plugin only if QtVirtualKeyboard is in use
474+ if not deploymentInfo .usesFramework ("QtVirtualKeyboard" ):
475+ continue
434476
435477 plugins .append ((pluginDirectory , pluginName ))
436478
@@ -499,7 +541,7 @@ app_bundle = config.app_bundle[0]
499541
500542if not os .path .exists (app_bundle ):
501543 if verbose >= 1 :
502- sys .stderr .write ("Error: Could not find app bundle \" %s \" \n " % (app_bundle ))
544+ sys .stderr .write ("Error: Could not find app bundle \" {} \" \n " . format (app_bundle ))
503545 sys .exit (1 )
504546
505547app_bundle_name = os .path .splitext (os .path .basename (app_bundle ))[0 ]
@@ -511,7 +553,7 @@ if config.translations_dir and config.translations_dir[0]:
511553 translations_dir = config .translations_dir [0 ]
512554 else :
513555 if verbose >= 1 :
514- sys .stderr .write ("Error: Could not find translation dir \" %s \" \n " % (translations_dir ))
556+ sys .stderr .write ("Error: Could not find translation dir \" {} \" \n " . format (translations_dir ))
515557 sys .exit (1 )
516558# ------------------------------------------------
517559
@@ -520,7 +562,7 @@ for p in config.add_resources:
520562 print ("Checking for \" %s\" ..." % p )
521563 if not os .path .exists (p ):
522564 if verbose >= 1 :
523- sys .stderr .write ("Error: Could not find additional resource file \" %s \" \n " % (p ))
565+ sys .stderr .write ("Error: Could not find additional resource file \" {} \" \n " . format (p ))
524566 sys .exit (1 )
525567
526568# ------------------------------------------------
@@ -537,17 +579,17 @@ if len(config.fancy) == 1:
537579
538580 p = config .fancy [0 ]
539581 if verbose >= 3 :
540- print ("Fancy: Loading \" %s \" ..." % p )
582+ print ("Fancy: Loading \" {} \" ..." . format ( p ) )
541583 if not os .path .exists (p ):
542584 if verbose >= 1 :
543- sys .stderr .write ("Error: Could not find fancy disk image plist at \" %s \" \n " % (p ))
585+ sys .stderr .write ("Error: Could not find fancy disk image plist at \" {} \" \n " . format (p ))
544586 sys .exit (1 )
545587
546588 try :
547589 fancy = plistlib .readPlist (p )
548590 except :
549591 if verbose >= 1 :
550- sys .stderr .write ("Error: Could not parse fancy disk image plist at \" %s \" \n " % (p ))
592+ sys .stderr .write ("Error: Could not parse fancy disk image plist at \" {} \" \n " . format (p ))
551593 sys .exit (1 )
552594
553595 try :
@@ -561,18 +603,18 @@ if len(config.fancy) == 1:
561603 assert isinstance (value , list ) and len (value ) == 2 and isinstance (value [0 ], int ) and isinstance (value [1 ], int )
562604 except :
563605 if verbose >= 1 :
564- sys .stderr .write ("Error: Bad format of fancy disk image plist at \" %s \" \n " % (p ))
606+ sys .stderr .write ("Error: Bad format of fancy disk image plist at \" {} \" \n " . format (p ))
565607 sys .exit (1 )
566608
567609 if "background_picture" in fancy :
568610 bp = fancy ["background_picture" ]
569611 if verbose >= 3 :
570- print ("Fancy: Resolving background picture \" %s \" ..." % bp )
612+ print ("Fancy: Resolving background picture \" {} \" ..." . format ( bp ) )
571613 if not os .path .exists (bp ):
572614 bp = os .path .join (os .path .dirname (p ), bp )
573615 if not os .path .exists (bp ):
574616 if verbose >= 1 :
575- sys .stderr .write ("Error: Could not find background picture at \" %s \" or \" %s \" \n " % (fancy ["background_picture" ], bp ))
617+ sys .stderr .write ("Error: Could not find background picture at \" {} \" or \" {} \" \n " . format (fancy ["background_picture" ], bp ))
576618 sys .exit (1 )
577619 else :
578620 fancy ["background_picture" ] = bp
623665 config .plugins = False
624666except RuntimeError as e :
625667 if verbose >= 1 :
626- sys .stderr .write ("Error: %s \n " % str (e ))
668+ sys .stderr .write ("Error: {} \n " . format ( str (e ) ))
627669 sys .exit (1 )
628670
629671# ------------------------------------------------
@@ -636,7 +678,7 @@ if config.plugins:
636678 deployPlugins (applicationBundle , deploymentInfo , config .strip , verbose )
637679 except RuntimeError as e :
638680 if verbose >= 1 :
639- sys .stderr .write ("Error: %s \n " % str (e ))
681+ sys .stderr .write ("Error: {} \n " . format ( str (e ) ))
640682 sys .exit (1 )
641683
642684# ------------------------------------------------
@@ -652,14 +694,14 @@ else:
652694 else :
653695 sys .stderr .write ("Error: Could not find Qt translation path\n " )
654696 sys .exit (1 )
655- add_qt_tr = ["qt_%s .qm" % lng for lng in config .add_qt_tr [0 ].split ("," )]
697+ add_qt_tr = ["qt_{} .qm" . format ( lng ) for lng in config .add_qt_tr [0 ].split ("," )]
656698 for lng_file in add_qt_tr :
657699 p = os .path .join (qt_tr_dir , lng_file )
658700 if verbose >= 3 :
659- print ("Checking for \" %s \" ..." % p )
701+ print ("Checking for \" {} \" ..." . format ( p ) )
660702 if not os .path .exists (p ):
661703 if verbose >= 1 :
662- sys .stderr .write ("Error: Could not find Qt translation file \" %s \" \n " % (lng_file ))
704+ sys .stderr .write ("Error: Could not find Qt translation file \" {} \" \n " . format (lng_file ))
663705 sys .exit (1 )
664706
665707# ------------------------------------------------
@@ -700,14 +742,14 @@ if config.sign and 'CODESIGNARGS' not in os.environ:
700742 print ("You must set the CODESIGNARGS environment variable. Skipping signing." )
701743elif config .sign :
702744 if verbose >= 1 :
703- print ("Code-signing app bundle %s" % (target , ))
704- subprocess .check_call ("codesign --force %s %s" % (os .environ ['CODESIGNARGS' ], target ), shell = True )
745+ print ("Code-signing app bundle {}" . format (target ))
746+ subprocess .check_call ("codesign --force {} {}" . format (os .environ ['CODESIGNARGS' ], target ), shell = True )
705747
706748# ------------------------------------------------
707749
708750if config .dmg is not None :
709751
710- def runHDIUtil (verb , image_basename , ** kwargs ):
752+ def runHDIUtil (verb : str , image_basename : str , ** kwargs ) -> int :
711753 hdiutil_args = ["hdiutil" , verb , image_basename + ".dmg" ]
712754 if "capture_stdout" in kwargs :
713755 del kwargs ["capture_stdout" ]
@@ -721,7 +763,7 @@ if config.dmg is not None:
721763
722764 for key , value in kwargs .items ():
723765 hdiutil_args .append ("-" + key )
724- if not value is True :
766+ if value is not True :
725767 hdiutil_args .append (str (value ))
726768
727769 return run (hdiutil_args , universal_newlines = True )
0 commit comments