-rw-r--r-- | scripts/builder/backendBuilder.py | 37 | ||||
-rw-r--r-- | scripts/builder/backends/devBuilder.py | 56 | ||||
-rw-r--r-- | scripts/builder/frontendBuilder.py | 44 | ||||
-rw-r--r-- | scripts/builder/frontends/betaBuilder.py | 14 | ||||
-rw-r--r-- | scripts/builder/frontends/gammaBuilder.py | 26 | ||||
-rw-r--r-- | scripts/builder/frontends/gamma_mobileBuilder.py | 9 | ||||
-rwxr-xr-x | scripts/builder/main.py | 26 | ||||
-rw-r--r-- | scripts/builder/repository.py | 11 |
8 files changed, 191 insertions, 32 deletions
diff --git a/scripts/builder/backendBuilder.py b/scripts/builder/backendBuilder.py index 5b91678..36b28ca 100644 --- a/scripts/builder/backendBuilder.py +++ b/scripts/builder/backendBuilder.py @@ -1,131 +1,134 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- import sys, os, json import shutil import hashlib import main #=================================================================== - class BackendBuilder(object): def __init__ (self, projectTargetDir, frontends, versions, settings): self.projectTargetDir = projectTargetDir self.frontends = frontends self.versions = versions self.settings = settings # -------------------------------------------------------------------------- def name (self): raise NotImplementedError() def relativePath (self): raise NotImplementedError() def compileCode (self): raise NotImplementedError() def createPackage (self): raise NotImplementedError() # -------------------------------------------------------------------------- def sourceFolder (self): return os.path.join(main.projectBaseDir() , 'backend', self.relativePath(), 'src') def tempFolder (self): return os.path.join(self.projectTargetDir, '.tmp', self.relativePath()) def frontEndTempFolder (self): return self.tempFolder() def developmentTargetFolder (self): - return os.path.join(self.projectTargetDir, 'development', self.relativePath()) + return os.path.join(self.projectTargetDir, 'development') + def targetFolder (self): return os.path.join(self.projectTargetDir, self.relativePath()) + # -------------------------------------------------------------------------- def writeToFolder (self, folder, filename, content): file = open(os.path.join(folder, filename), 'w') file.write(content.encode('utf-8')) file.close() def configureIndexContent (self, indexContent, requestPathPrefix = ".."): result = indexContent result = result.replace( '@request.path@', requestPathPrefix + '/' + self.settings['request.path'] ) result = result.replace( '@should.pay.toll@', self.settings['should.pay.toll'] ) return result def logChecksums (self, content, message): md5Digest = hashlib.md5(content.encode('utf-8')).hexdigest() shaDigest = hashlib.sha1(content.encode('utf-8')).hexdigest() sha256Digest = hashlib.sha256(content.encode('utf-8')).hexdigest() print message + ": " + md5Digest + " (md5)" print message + ": " + shaDigest + " (sha1)" print message + ": " + sha256Digest + " (sha256)" def shouldCompileCode (self): return ('debug' in self.versions) or ('install' in self.versions) def run (self): print self.name() + " - RUN" if self.shouldCompileCode(): self.compileCode() for frontend in self.frontends: if (frontend.module == frontend.submodule): submoduleExtension = '' else: submoduleExtension = '.' + frontend.submodule main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module)) if 'debug' in self.versions: frontend.copyResourcesToFolder(self.frontEndTempFolder()) index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG')) self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug' + submoduleExtension + '.html'), index) - + if 'install' in self.versions: index = self.configureIndexContent(frontend.assemble()) self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index) self.logChecksums(index, "[" + self.name() + " - " + frontend.module + "] index" + submoduleExtension + ".html checksum") self.createPackage() - if 'development' in self.versions: - for frontend in self.frontends: - if (frontend.module == frontend.submodule): - submoduleExtension = '' - else: - submoduleExtension = '.' + frontend.submodule - - print "FRONTEND module: " + frontend.module - print "FRONTEND submodule: " + frontend.submodule - - main.createFolder(os.path.join(self.developmentTargetFolder(), frontend.module)) - - index = self.configureIndexContent(frontend.assemble(assemblyMode='DEVELOPMENT', versionType='DEBUG'), self.settings['development.settings']['url']) - self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index) +# if 'development' in self.versions: +# for frontend in self.frontends: +# if (frontend.module == frontend.submodule): +# submoduleExtension = '' +# else: +# submoduleExtension = '.' + frontend.submodule +# +# print "FRONTEND module: " + frontend.module +# print "FRONTEND submodule: " + frontend.submodule +# +## main.createFolder(os.path.join(self.developmentTargetFolder(), frontend.module)) +# main.createFolder(self.developmentTargetFolder()) +# +# index = self.configureIndexContent(frontend.assemble(assemblyMode='DEVELOPMENT', versionType='DEBUG'), self.settings['development.settings']['url']) +## self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module, 'index_development' + submoduleExtension + '.html'), index) +# self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module + submoduleExtension + '.html'), index) #=================================================================== diff --git a/scripts/builder/backends/devBuilder.py b/scripts/builder/backends/devBuilder.py new file mode 100644 index 0000000..671765e --- a/dev/null +++ b/scripts/builder/backends/devBuilder.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +import os +import shutil +import subprocess +import main + +from backendBuilder import BackendBuilder + +class DevBuilder(BackendBuilder): + + def name(self): + return "Dev builder" + + + def relativePath(self): + return 'dev' + + +# def frontEndTempFolder (self): +# return os.path.join(self.tempFolder(), 'src', 'main', 'webapp') + + +# def targetFolder (self): +# return self.projectTargetDir + + + def compileCode (self): + pass + + + def createPackage (self): + src = self.tempFolder() + dst = self.targetFolder() + + shutil.copytree(src, dst) + + + def run (self): + print self.name() + " - RUN (dev)" + + for frontend in self.frontends: + if (frontend.module == frontend.submodule): + submoduleExtension = '' + else: + submoduleExtension = '.' + frontend.submodule + + main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module)) + + index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG')) + self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index' + submoduleExtension + '.html'), index) + + self.createPackage() + + diff --git a/scripts/builder/frontendBuilder.py b/scripts/builder/frontendBuilder.py index 1f0f92f..fc603c4 100644 --- a/scripts/builder/frontendBuilder.py +++ b/scripts/builder/frontendBuilder.py @@ -1,102 +1,131 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- import sys, os, re import cssmin import jsmin import codecs import shutil import StringIO import urllib import main +#=============================================================================== + class FrontendBuilder(object): def __init__ (self, frontend, settings, repositoryVersion): if '.' in frontend: moduleComponents = frontend.split('.') self.module = moduleComponents[0] self.submodule = moduleComponents[1] else: self.module = frontend self.submodule = frontend self.settings = settings self.projectDir = main.projectBaseDir() # self.repository = repository.repositoryWithPath(self.projectDir) self.repositoryVersion = repositoryVersion self.processedFiles = {} - + + #--------------------------------------------------------------------------- + + def name (self): + raise NotImplementedError() + + + def copyStaticResources (self, targetFolder): + raise NotImplementedError() + + #--------------------------------------------------------------------------- def log (self, message): - print "frontend [" + self.module + "]: " + message + module = self.module + if (self.module != self.submodule): + module = module + "." + self.submodule + print "frontend [" + module + "]: " + message def absolutePathForSources (self): return os.path.join(self.projectDir, 'frontend', self.module) def absolutePathForSourceFile (self, basePath, file): return os.path.join(self.absolutePathForSources(), basePath, file) def absolutePathForTargetFile (self, folder, basePath, file): return os.path.join(folder, self.module, basePath, file) def filterFiles (self, files): result = [] for file in files: if file.startswith('--'): pass else: result.append(file) return result def copyResources (self, sourceFolder, destinationFolder, fileType): - for file in self.filterFiles(self.settings[fileType]): - src = self.absolutePathForSourceFile(fileType, file) - dst = self.absolutePathForTargetFile(destinationFolder, fileType, file) - main.createFolder(os.path.dirname(dst)) - shutil.copy2(src, dst) + if fileType in self.settings: + for file in self.filterFiles(self.settings[fileType]): + src = self.absolutePathForSourceFile(fileType, file) + dst = self.absolutePathForTargetFile(destinationFolder, fileType, file) + main.createFolder(os.path.dirname(dst)) + shutil.copy2(src, dst) + else: + srcFolder = os.path.join(self.absolutePathForSources(), fileType) + dstFolder = os.path.join(destinationFolder, self.module, fileType) + if not(os.path.exists(dstFolder)): + shutil.copytree(srcFolder, dstFolder) + +# try: +# shutil.copytree(srcFolder, dstFolder) +# except: +# pass + def copyResourcesToFolder (self, targetFolder): self.copyResources(self.projectDir, targetFolder, 'css') self.copyResources(self.projectDir, targetFolder, 'js') + self.copyResources(self.projectDir, targetFolder, 'images') + self.copyStaticResources(targetFolder) def loadFilesContent (self, basePath, files): result = "" for file in self.filterFiles(files): try: fileHandler = codecs.open(self.absolutePathForSourceFile(basePath, file), 'r', 'utf-8') except: print "FILE: " + file result += fileHandler.read() + '\n' fileHandler.close() return result def template (self): processedFile = 'html_template' if not self.processedFiles.has_key(processedFile): # self.processedFiles[processedFile] = self.loadFilesContent('html', ['index_template.html']) self.processedFiles[processedFile] = self.loadFilesContent('html', [self.settings['html.template']]) return self.processedFiles[processedFile] def cssminCompressor (self, css): # package found here: # - http://stackoverflow.com/questions/222581/python-script-for-minifying-css/2396777#2396777 # actual downloaded version: http://pypi.python.org/pypi/cssmin/0.1.4 return cssmin.cssmin(css) @@ -342,49 +371,50 @@ class FrontendBuilder(object): def assemble (self, assemblyMode='INSTALL', versionType='LIVE'): if versionType == 'LIVE': pageTitle = "Clipperz - " + self.module else: pageTitle = "Clipperz - " + self.module + " [" + versionType + " - " + assemblyMode +"]" if assemblyMode == 'INSTALL': copyright = self.assembleCopyrightHeader() css = self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css']))) js = self.scriptTagForContent( self.bookmarklet() + '\n' + self.compressJS(self.loadFilesContent('js', self.settings['js']), "application") ) jsLoadMode = 'EMBEDDED' elif assemblyMode == 'DEBUG': copyright = self.assembleCopyrightHeader() css = self.cssTagsForFiles('./css', self.filterFiles(self.settings['css'])) js = self.scriptTagForContent(self.bookmarklet()) + \ '\n' + \ self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js'])) jsLoadMode = 'LINKED' elif assemblyMode == 'DEVELOPMENT': copyright = "" css = self.cssTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'css')), self.filterFiles(self.settings['css'])) js = self.scriptTagForContent(self.bookmarklet()) + \ '\n' + \ self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js'])) jsLoadMode = 'LINKED' + versionType = 'development' else: raise NotImplementedError() return self.assembleVersion( pageTitle = pageTitle, copyright = copyright, css = css, js = js, jsLoadMode = jsLoadMode, version = self.repositoryVersion, versionType = versionType ) diff --git a/scripts/builder/frontends/betaBuilder.py b/scripts/builder/frontends/betaBuilder.py new file mode 100644 index 0000000..c5a3e76 --- a/dev/null +++ b/scripts/builder/frontends/betaBuilder.py @@ -0,0 +1,14 @@ +from frontendBuilder import FrontendBuilder +import shutil + +class BetaBuilder(FrontendBuilder): + + def name(self): + return "/beta builder" + + def copyStaticResources (self, targetFolder): + for file in self.filterFiles(self.settings['staticResources']): + src = self.absolutePathForSourceFile('staticResources', file) + dst = self.absolutePathForTargetFile(targetFolder, '', file) + shutil.copy2(src, dst) + diff --git a/scripts/builder/frontends/gammaBuilder.py b/scripts/builder/frontends/gammaBuilder.py new file mode 100644 index 0000000..35fa68b --- a/dev/null +++ b/scripts/builder/frontends/gammaBuilder.py @@ -0,0 +1,26 @@ +from frontendBuilder import FrontendBuilder +import shutil + +class GammaBuilder(FrontendBuilder): + + def name(self): + return "/gamma builder" + + def copyStaticResources (self, targetFolder): + resourcesToCopy = [ + {'folder': 'html', 'source': 'exit_template.html', 'target': 'exit.html'}, + {'folder': 'css', 'source': 'static.css', 'target': 'static.css'} + ] + + for resource in resourcesToCopy: + src = self.absolutePathForSourceFile(resource['folder'], resource['source']) + dst = self.absolutePathForTargetFile(targetFolder, '', resource['target']) + shutil.copy2(src, dst) + + # src = self.absolutePathForSourceFile('html', 'exit_template.html') + # dst = self.absolutePathForTargetFile(targetFolder, '', 'exit.html') + # shutil.copy2(src, dst) + + # src = self.absolutePathForSourceFile('css', 'static.css') + # dst = self.absolutePathForTargetFile(targetFolder, '', 'static.css') + # shutil.copy2(src, dst) diff --git a/scripts/builder/frontends/gamma_mobileBuilder.py b/scripts/builder/frontends/gamma_mobileBuilder.py new file mode 100644 index 0000000..f2e80c9 --- a/dev/null +++ b/scripts/builder/frontends/gamma_mobileBuilder.py @@ -0,0 +1,9 @@ +from frontendBuilder import FrontendBuilder + +class Gamma_MobileBuilder(FrontendBuilder): + + def name(self): + return "/gamma.mobile builder" + + def copyStaticResources (self, targetFolder): + pass diff --git a/scripts/builder/main.py b/scripts/builder/main.py index 6fce65d..b9fe04a 100755 --- a/scripts/builder/main.py +++ b/scripts/builder/main.py @@ -1,177 +1,191 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- import sys import os import json import shutil import pprint import codecs import itertools from collections import deque -import frontendBuilder +#import frontendBuilder import repository pp = pprint.PrettyPrinter(indent=4, depth=4) #-------------------------------------------------------------------- def scriptDir (): return os.path.dirname(sys.argv[0]) def projectBaseDir (): return os.path.abspath(scriptDir() + '/../..') def projectTargetDir(): return projectBaseDir() + '/target/' #-------------------------------------------------------------------- def createFolder (path): if not os.path.exists(path): os.makedirs(path) #-------------------------------------------------------------------- def loadSettings (component, module): # print "MODULE: " + module if '.' in module: moduleComponents = module.split('.') module = moduleComponents[0] submodule = moduleComponents[1] else: submodule = module #settings = codecs.open(projectBaseDir() + os.sep + component + os.sep + module + os.sep + 'properties' + os.sep + submodule + '.properties.json', 'r', 'utf-8') settings = codecs.open(os.path.join(projectBaseDir(), component, module, 'properties', submodule + '.properties.json'), 'r', 'utf-8') result = json.load(settings) settings.close return result #==================================================================== # # def assembleFrontend (frontend, versions): # result = {} # settings = loadSettings('frontend', frontend) # builder = frontendBuilder.FrontendBuilder(frontend, settings, projectBaseDir()) # # for version in versions: # if version == 'install': # result[version] = builder.assembleInstallVersion() # elif version == 'debug': # result[version] = builder.assembleDebugVersion() # else: # raise Exception('unrecognized version: ' + version) # # return result # #==================================================================== def assembleBackend (backend, frontends, versions): settings = loadSettings('backend', backend) builderModuleName = backend + 'Builder' builderClassName = backend.capitalize() + 'Builder' - + #print ("BUILD BACKENDS - module: " + builderModuleName + " , class: " + builderClassName) builderModule = __import__(builderModuleName) builderClass = getattr(builderModule, builderClassName) backendBuilder = builderClass(projectTargetDir(), frontends, versions, settings) backendBuilder.run() #==================================================================== def build (settings, repository): frontends = [] if repository.areTherePendingChanges(): - print "\nWARNING: repository has pending changes\n" + if 'install' in settings['versions']: + raise Exception("repository has pending changes, can't 'install'") + else: + print "\nWARNING: repository has pending changes\n" for frontend in settings['frontends']: - frontends.append(frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend), repository.version())) + normalizedFrontendName = frontend.replace(".", "_") + builderModuleName = normalizedFrontendName + 'Builder' + builderClassName = normalizedFrontendName.title() + 'Builder' + + #print ("BUILD FRONTEND - module: " + builderModuleName + " , class: " + builderClassName) + builderModule = __import__(builderModuleName) + builderClass = getattr(builderModule, builderClassName) + builder = builderClass(frontend, loadSettings('frontend', frontend), repository.version()) + #builder = frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend), repository.version()) + frontends.append(builder) for backend in settings['backends']: assembleBackend(backend, frontends, settings['versions']) #-------------------------------------------------------------------- def clean (): # print "cleaning up …" if os.path.exists(projectTargetDir()): shutil.rmtree(projectTargetDir()) #-------------------------------------------------------------------- def usage (message): if message != None: print "ERROR: " + message print # print "build clean" # print "build clean install" print "build install --ALL" print "build install debug --ALL" + print "build install debug development --ALL" # print "build clean install debug --ALL" print "build install debug --backends php python --frontends beta gamma" print "build install debug development --backends php python --frontends beta gamma gamma.mobile" exit(1) #-------------------------------------------------------------------- def allFrontends (): - return ['beta', 'gamma', 'mobile'] + return ['beta', 'gamma', 'gamma.mobile'] def allBackends (): return ['php', 'python'] #-------------------------------------------------------------------- def main (): settings = {} parameters = list(itertools.islice(sys.argv, 1, None)) sys.path.append(os.path.join(scriptDir(), 'backends')) + sys.path.append(os.path.join(scriptDir(), 'frontends')) currentRepository = repository.repositoryWithPath(projectBaseDir()) clean() versions = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) settings['versions'] = versions; #['debug', 'install', 'development'] parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters)) if len(parameters) > 0: parameter = parameters.popleft() if parameter == "--ALL": settings['frontends'] = allFrontends() settings['backends'] = allBackends() else: while parameter != None: values = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) if parameter == "--backends": settings['backends'] = values elif parameter == "--frontends": settings['frontends'] = values parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters)) if parameters: parameter = parameters.popleft() else: parameter = None if (not settings.has_key('versions')): usage("missing 'versions'") if (not settings.has_key('frontends')): usage("missing 'frontends'") if (not settings.has_key('backends')): usage("missing 'backends'") build(settings, currentRepository) else: usage("Suggestions on how to call the 'build' script:") if __name__ == "__main__": - main() + main() diff --git a/scripts/builder/repository.py b/scripts/builder/repository.py index 0045de7..a47e249 100644 --- a/scripts/builder/repository.py +++ b/scripts/builder/repository.py @@ -27,55 +27,62 @@ def repositoryWithPath (path): class Repository(object): def __init__ (self, repository, path): self.repository = repository self.path = path def revision (self): raise NotImplementedError() def areTherePendingChanges (self): raise NotImplementedError() def version (self): result = self.revision() if self.areTherePendingChanges(): result = '>>> ' + result + ' <<<' # print "VERSION: " + result return result #=================================================================== class GitRepository(Repository): # http://gitorious.org/git-python def revision (self): - return self.repository.head.commit.hexsha + try: + return self.repository.head.commit.hexsha + except: + return self.repository.commits()[0].id def areTherePendingChanges (self): - return self.repository.is_dirty() + try: + return self.repository.is_dirty() + except TypeError, te: + return self.repository.is_dirty + #=================================================================== class HgRepository(Repository): # http://mercurial.selenic.com/wiki/MercurialApi def revision (self): return 'hg:' + str(self.repository['tip']) def areTherePendingChanges (self): # TODO: FIXME: repository.status() does not report 'unknown(?)' files. :( return not all(map(lambda fileList: len(fileList) == 0, self.repository.status())) #=================================================================== |