#!/usr/bin/env python import sys, os, re """Utility for substituting parameters in files in a specific folder. Create an instance and invoke the process method targetDir = the directory to target parametersName = file name of the properties file to use (without extension) For example: targetDir = /home/myapp/ templateDir = /home/myapp_template/ Example file = /home/myapp_template/somedir/config.py Containing: config = {'someKey' : '@someKey@', 'abc' : '@hi@'} parametersDir = /home/myapp_params/ For local dev = /home/myapp_params/local.properties Containing: someKey=someValue For production = /home/myapp_params/production.properties Containing: someKey=someOtherValue hi=Bye! Invoking Pants with '/home/myapp/ local' will create a directory 'somedir' in /home/myapp/ (if it doesn't exist) and a file 'config.py' with all parameters (all alphanumeric characters and dots in between 2 '@') replaced by the corresponding values, supplied in local.properties. The resulting content of /home/myapp/somedir/config.py: config = {'someKey' : 'someValue', 'abc' : '@hi@'} The '@hi@' parameters isn't replaced, because there's no entry for 'hi' in the properties file. Doing the same thing afterwards for '/home/myapp/ production', results in the following content of /home/myapp/somedir/config.py: config = {'someKey' : 'someOtherValue', 'abc' : 'Bye!'} """ class Pants: def __init__(self): self.__parameters = {} self.__ignorePatterns = [r'\.svn.*'] self.__ignorePatterns = [re.compile(elem) for elem in self.__ignorePatterns] def process(self, targetDir, parametersName): targetDirFull = os.path.abspath(targetDir) 'Preparing ' + targetDirFull + ' for ' + parametersName self.__readParameters(targetDirFull, parametersName) (targetDirPath, targetDir) = os.path.split(targetDirFull) templateDirFull = os.path.join(targetDirPath, targetDir + '_template') listing = os.listdir(templateDirFull) for listed in listing: processListed = True for regex in self.__ignorePatterns: if (regex.match(listed)): processListed = False continue if processListed: self.__processTemplate(os.path.join(templateDirFull, listed), os.path.join(targetDirFull, listed)) def __processTemplate(self, src, target): if (os.path.isdir(src)): listing = os.listdir(src) for listed in listing: processListed = True for regex in self.__ignorePatterns: if (regex.match(listed)): processListed = False continue if processListed: self.__processTemplate(os.path.join(src, listed), os.path.join(target, listed)) else: print 'Processing ' + src f = open(src, 'r') template = f.read(); f.close(); (target_dir, target_file) = os.path.split(target) if not os.path.exists(target_dir): print 'Creating ' + target_dir os.makedirs(target_dir) f = open(target, 'w') f.write(re.sub(r'@([\w|\\.]*)@', self.__getParameter, template)) f.close() def __getParameter(self, matchobj): match = matchobj.group(1) if match in self.__parameters: return self.__parameters[match] return '@' + match + '@' def __readParameters(self, targetDirFull, parametersName): (targetDirPath, targetDir) = os.path.split(targetDirFull) parametersDirFull = os.path.join(targetDirPath, targetDir + '_params') f = open(os.path.join(parametersDirFull, parametersName + '.properties'), 'r') params = f.read().split('\n') self.__parameters = {} for param in params: (property, x, value) = param.partition('=') self.__parameters[property] = value if len(sys.argv) < 3: print 'Supply the path to the folder that should be targeted and the target environment' else: p = Pants() p.process(sys.argv[1], sys.argv[2])