NeuralAmpModelerPlugin

Plugin for Neural Amp Modeler
Log | Files | Refs | Submodules | README | LICENSE

duplicate.py (11838B)


      1 #!/usr/bin/python3
      2 
      3 # Python shell script for Duplicating IPlug Projects
      4 # Oli Larkin 2012-2019
      5 # License: WTFPL http://sam.zoy.org/wtfpl/COPYING
      6 # Modified from this script by Bibha Tripathi http://code.activestate.com/recipes/435904-sedawk-python-script-to-rename-subdirectories-of-a/
      7 # Author accepts no responsibilty for wiping your hd
      8 
      9 # NOTES:
     10 # should work with Python2 or Python3
     11 # not designed to be fool proof- think carefully about what you choose for a project name
     12 # best to stick to standard characters in your project names - avoid spaces, numbers and dots
     13 # windows users need to install python and set it up so you can run it from the command line
     14 # see http://www.voidspace.org.uk/python/articles/command_line.shtml
     15 # this involves adding the python folder e.g. C:\Python27\ to your %PATH% environment variable
     16 
     17 # USAGE:
     18 # duplicate.py [inputprojectname] [outputprojectname] [manufacturername] (outputpath)
     19 
     20 # TODO:
     21 # - indentation of directory structure
     22 # - variable manufacturer name
     23 
     24 
     25 from __future__ import generators
     26 
     27 import fileinput, glob, string, sys, os, re, uuid, pprint, random
     28 from shutil import copy, copytree, ignore_patterns, rmtree
     29 from os.path import join
     30 
     31 scriptpath = os.path.dirname(os.path.realpath(__file__))
     32 
     33 sys.path.insert(0, scriptpath + "/iPlug2/Scripts/")
     34 
     35 from parse_config import parse_config, parse_xcconfig, set_uniqueid
     36 
     37 VERSION = "0.95"
     38 
     39 # binary files that we don't want to do find and replace inside
     40 FILTERED_FILE_EXTENSIONS = [
     41     ".ico",
     42     ".icns",
     43     ".pdf",
     44     ".png",
     45     ".zip",
     46     ".exe",
     47     ".wav",
     48     ".aif",
     49     ".data",
     50     ".wasm",
     51     "mkcert",
     52 ]
     53 FILTERED_FILE_NAMES = [".DS_Store"]
     54 # files that we don't want to duplicate
     55 DONT_COPY = (
     56     ".vs",
     57     "*.exe",
     58     "*.dmg",
     59     "*.pkg",
     60     "*.mpkg",
     61     "*.svn",
     62     "*.ncb",
     63     "*.suo",
     64     "*sdf",
     65     "ipch",
     66     "*.layout",
     67     "*.depend",
     68     ".DS_Store",
     69     "xcuserdata",
     70     "*.aps",
     71 )
     72 
     73 SUBFOLDERS_TO_SEARCH = [
     74     "projects",
     75     "config",
     76     "resources",
     77     "installer",
     78     "scripts",
     79     "manual",
     80     "xcschemes",
     81     "xcshareddata",
     82     "xcuserdata",
     83     "en-osx.lproj",
     84     "project.xcworkspace",
     85     "Images.xcassets",
     86     "build-web",
     87 ]
     88 
     89 
     90 def randomFourChar(chars=string.ascii_letters + string.digits):
     91     return "".join(random.choice(chars) for _ in range(4))
     92 
     93 
     94 def checkdirname(name, searchproject):
     95     "check if directory name matches with the given pattern"
     96     print("")
     97     if name == searchproject:
     98         return True
     99     else:
    100         return False
    101 
    102 
    103 def replacestrs(filename, s, r):
    104     files = glob.glob(filename)
    105 
    106     for line in fileinput.input(files, inplace=1):
    107         line.find(s)
    108         line = line.replace(s, r)
    109         sys.stdout.write(line)
    110 
    111 
    112 def replacestrsChop(filename, s, r):
    113     files = glob.glob(filename)
    114 
    115     for line in fileinput.input(files, inplace=1):
    116         if line.startswith(s):
    117             line = r + "\n"
    118         sys.stdout.write(line)
    119 
    120 
    121 def dirwalk(
    122     dir, searchproject, replaceproject, searchman, replaceman, oldroot="", newroot=""
    123 ):
    124     for f in os.listdir(dir):
    125         fullpath = os.path.join(dir, f)
    126 
    127         if os.path.isdir(fullpath) and not os.path.islink(fullpath):
    128             if checkdirname(f, searchproject + "-macOS.xcodeproj"):
    129                 os.rename(
    130                     fullpath, os.path.join(dir, replaceproject + "-macOS.xcodeproj")
    131                 )
    132                 fullpath = os.path.join(dir, replaceproject + "-macOS.xcodeproj")
    133 
    134                 print("recursing in macOS xcode project directory: ")
    135                 for x in dirwalk(
    136                     fullpath,
    137                     searchproject,
    138                     replaceproject,
    139                     searchman,
    140                     replaceman,
    141                     oldroot,
    142                     newroot,
    143                 ):
    144                     yield x
    145             elif checkdirname(f, searchproject + "-iOS.xcodeproj"):
    146                 os.rename(
    147                     fullpath, os.path.join(dir, replaceproject + "-iOS.xcodeproj")
    148                 )
    149                 fullpath = os.path.join(dir, replaceproject + "-iOS.xcodeproj")
    150 
    151                 print("recursing in iOS xcode project directory: ")
    152                 for x in dirwalk(
    153                     fullpath,
    154                     searchproject,
    155                     replaceproject,
    156                     searchman,
    157                     replaceman,
    158                     oldroot,
    159                     newroot,
    160                 ):
    161                     yield x
    162             elif checkdirname(f, searchproject + ".xcworkspace"):
    163                 os.rename(fullpath, os.path.join(dir, replaceproject + ".xcworkspace"))
    164                 fullpath = os.path.join(dir, replaceproject + ".xcworkspace")
    165 
    166                 print("recursing in main xcode workspace directory: ")
    167                 for x in dirwalk(
    168                     fullpath,
    169                     searchproject,
    170                     replaceproject,
    171                     searchman,
    172                     replaceman,
    173                     oldroot,
    174                     newroot,
    175                 ):
    176                     yield x
    177             elif checkdirname(f, searchproject + "-iOS.appiconset"):
    178                 os.rename(
    179                     fullpath, os.path.join(dir, replaceproject + "-iOS.appiconset")
    180                 )
    181                 fullpath = os.path.join(dir, replaceproject + "-iOS.appiconset")
    182 
    183                 print("recursing in -iOS.appiconset directory: ")
    184             elif checkdirname(f, searchproject + "-macOS.appiconset"):
    185                 os.rename(
    186                     fullpath, os.path.join(dir, replaceproject + "-macOS.appiconset")
    187                 )
    188                 fullpath = os.path.join(dir, replaceproject + "-macOS.appiconset")
    189 
    190                 print("recursing in -macOS.appiconset directory: ")
    191                 for x in dirwalk(
    192                     fullpath,
    193                     searchproject,
    194                     replaceproject,
    195                     searchman,
    196                     replaceman,
    197                     oldroot,
    198                     newroot,
    199                 ):
    200                     yield x
    201             elif f in SUBFOLDERS_TO_SEARCH:
    202                 print("recursing in " + f + " directory: ")
    203                 for x in dirwalk(
    204                     fullpath,
    205                     searchproject,
    206                     replaceproject,
    207                     searchman,
    208                     replaceman,
    209                     oldroot,
    210                     newroot,
    211                 ):
    212                     yield x
    213 
    214         if os.path.isfile(fullpath):
    215             filename = os.path.basename(fullpath)
    216             newfilename = filename.replace(searchproject, replaceproject)
    217             base, extension = os.path.splitext(filename)
    218 
    219             if not (extension in FILTERED_FILE_EXTENSIONS) and not (
    220                 filename in FILTERED_FILE_NAMES
    221             ):
    222 
    223                 print("Replacing project name strings in file " + filename)
    224                 replacestrs(fullpath, searchproject, replaceproject)
    225 
    226                 print("Replacing captitalized project name strings in file " + filename)
    227                 replacestrs(fullpath, searchproject.upper(), replaceproject.upper())
    228 
    229                 print("Replacing manufacturer name strings in file " + filename)
    230                 replacestrs(fullpath, searchman, replaceman)
    231 
    232                 if oldroot and newroot:
    233                     print("Replacing iPlug2 root folder in file  " + filename)
    234                     replacestrs(fullpath, oldroot, newroot)
    235                     replacestrs(
    236                         fullpath, oldroot.replace("/", "\\"), newroot.replace("/", "\\")
    237                     )
    238 
    239             else:
    240                 print("NOT replacing name strings in file " + filename)
    241 
    242             if filename != newfilename:
    243                 print("Renaming file " + filename + " to " + newfilename)
    244                 os.rename(fullpath, os.path.join(dir, newfilename))
    245 
    246             yield f, fullpath
    247         else:
    248             yield f, fullpath
    249 
    250 
    251 def main():
    252     global VERSION
    253     print(
    254         "\nIPlug Project Duplicator v"
    255         + VERSION
    256         + " by Oli Larkin ------------------------------\n"
    257     )
    258 
    259     numargs = len(sys.argv) - 1
    260 
    261     if not (numargs == 3 or numargs == 4):
    262         print(
    263             "Usage: duplicate.py inputprojectname outputprojectname manufacturername (outputprojectpath)"
    264         )
    265         sys.exit(1)
    266     else:
    267         inputprojectname = sys.argv[1]
    268         outputprojectname = sys.argv[2]
    269         manufacturer = sys.argv[3]
    270 
    271     if numargs == 4:
    272         outputbasepath = os.path.abspath(sys.argv[4])
    273     else:
    274         outputbasepath = os.getcwd()
    275 
    276     if not (os.path.isdir(outputbasepath)):
    277         print("error: Output path does not exist")
    278         sys.exit(1)
    279 
    280     outputpath = os.path.join(outputbasepath, outputprojectname)
    281 
    282     if " " in inputprojectname:
    283         print("error: input project name has spaces")
    284         sys.exit(1)
    285 
    286     if inputprojectname not in os.listdir(os.curdir):
    287         print(
    288             "error: input project "
    289             + inputprojectname
    290             + " doesn't exist, check spelling/case?"
    291         )
    292         sys.exit(1)
    293 
    294     if " " in outputprojectname:
    295         print("error: output project name has spaces")
    296         sys.exit(1)
    297 
    298     if " " in manufacturer:
    299         print("error: manufacturer name has spaces")
    300         sys.exit(1)
    301 
    302     # remove a trailing slash if it exists
    303     if inputprojectname[-1:] == "/":
    304         inputprojectname = inputprojectname[0:-1]
    305 
    306     if outputprojectname[-1:] == "/":
    307         outputprojectname = outputprojectname[0:-1]
    308 
    309     # check that the folders are OK
    310     if os.path.isdir(inputprojectname) == False:
    311         print("error: input project not found")
    312         sys.exit(1)
    313 
    314     if os.path.isdir(outputpath):
    315         print("error: output project allready exists")
    316         sys.exit(1)
    317     # rmtree(output)
    318 
    319     print("copying " + inputprojectname + " folder to " + outputpath)
    320     copytree(inputprojectname, outputpath, ignore=ignore_patterns(*DONT_COPY))
    321 
    322     oldroot = ""
    323     newroot = ""
    324 
    325     if numargs == 4:
    326         configpath = os.path.join(inputprojectname, "config")
    327         xcconfig = parse_xcconfig(configpath + "/" + inputprojectname + "-mac.xcconfig")
    328         oldroot = xcconfig["IPLUG2_ROOT"]
    329         iplug2folder = os.path.abspath(os.path.join(configpath, oldroot))
    330         newroot = os.path.relpath(iplug2folder, os.path.join(outputpath, "config"))
    331     else:
    332         newroot = ""
    333 
    334     # replace manufacturer name strings
    335     for dir in dirwalk(
    336         outputpath,
    337         inputprojectname,
    338         outputprojectname,
    339         "AcmeInc",
    340         manufacturer,
    341         oldroot,
    342         newroot,
    343     ):
    344         pass
    345 
    346     # replace project name in root
    347     for dir in dirwalk(
    348         scriptpath,
    349         inputprojectname,
    350         outputprojectname,
    351         "AcmeInc",
    352         manufacturer,
    353         oldroot,
    354         newroot,
    355     ):
    356         pass
    357 
    358     # replace project name in github
    359     for dir in dirwalk(
    360         scriptpath + "/.github/workflows",
    361         inputprojectname,
    362         outputprojectname,
    363         "AcmeInc",
    364         manufacturer,
    365         oldroot,
    366         newroot,
    367     ):
    368         pass
    369 
    370     # replace project name in vscode
    371     for dir in dirwalk(
    372         scriptpath + "/.vscode",
    373         inputprojectname,
    374         outputprojectname,
    375         "AcmeInc",
    376         manufacturer,
    377         oldroot,
    378         newroot,
    379     ):
    380         pass
    381 
    382     # print("\ncopying gitignore template into project folder\n")
    383 
    384     # copy('gitignore_template', outputpath + "/.gitignore")
    385 
    386     config = parse_config(outputpath)
    387 
    388     config["PLUG_UNIQUE_ID"] = randomFourChar()
    389 
    390     set_uniqueid(outputpath, config["PLUG_UNIQUE_ID"])
    391 
    392     pp = pprint.PrettyPrinter(indent=4)
    393     pp.pprint(config)
    394 
    395     print("\ndone - don't forget to change PLUG_MFR_UID in config.h")
    396 
    397 
    398 if __name__ == "__main__":
    399     main()