summaryrefslogtreecommitdiff
path: root/scripts
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2012-02-11 23:34:25 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2012-02-11 23:34:25 (UTC)
commit185949cb778dd13a566781bbfa8ef7ed344cc705 (patch) (unidiff)
tree8fc4ff8cf1efead7610e4141041dd440eb9febbd /scripts
parent17efce23d9f205f56f5ebbe8e4f4ca581ea47bcb (diff)
downloadclipperz-185949cb778dd13a566781bbfa8ef7ed344cc705.zip
clipperz-185949cb778dd13a566781bbfa8ef7ed344cc705.tar.gz
clipperz-185949cb778dd13a566781bbfa8ef7ed344cc705.tar.bz2
Improved build scripts
Signed-off-by: Giulio Cesare Solaroli <giulio.cesare@clipperz.com>
Diffstat (limited to 'scripts') (more/less context) (show whitespace changes)
-rw-r--r--scripts/builder/backendBuilder.py81
-rw-r--r--scripts/builder/backends/phpBuilder.py (renamed from scripts/builder/phpBuilder.py)7
-rw-r--r--scripts/builder/backends/pythonBuilder.py27
-rw-r--r--scripts/builder/backends/scriptLanguageBuilder.py20
-rw-r--r--scripts/builder/frontendBuilder.py133
-rwxr-xr-xscripts/builder/main.py79
-rw-r--r--scripts/builder/pythonBuilder.py14
-rw-r--r--scripts/builder/repository.py75
8 files changed, 287 insertions, 149 deletions
diff --git a/scripts/builder/backendBuilder.py b/scripts/builder/backendBuilder.py
index 16dbe2f..5ecdda0 100644
--- a/scripts/builder/backendBuilder.py
+++ b/scripts/builder/backendBuilder.py
@@ -3,10 +3,14 @@
3 3
4import sys, os, json 4import sys, os, json
5import shutil 5import shutil
6import main
7import hashlib 6import hashlib
8 7
9class BackendBuilder: 8import main
9
10#===================================================================
11
12
13class BackendBuilder(object):
10 14
11 def __init__ (self, projectTargetDir, frontends, versions, settings): 15 def __init__ (self, projectTargetDir, frontends, versions, settings):
12 self.projectTargetDir = projectTargetDir 16 self.projectTargetDir = projectTargetDir
@@ -14,46 +18,54 @@ class BackendBuilder:
14 self.versions = versions 18 self.versions = versions
15 self.settings = settings 19 self.settings = settings
16 20
21 # --------------------------------------------------------------------------
22
17 def name (self): 23 def name (self):
18 raise NotImplementedError() 24 raise NotImplementedError()
19 25
26
20 def relativePath (self): 27 def relativePath (self):
21 raise NotImplementedError() 28 raise NotImplementedError()
22 29
30
23 def compileCode (self): 31 def compileCode (self):
24 pass 32 raise NotImplementedError()
33
25 34
26 def copyCompiledCodeToTargetDir (self): 35 def createPackage (self):
27 src = self.sourceFolder() 36 raise NotImplementedError()
28 dst = self.targetFolder() 37
29 main.createFolder(os.path.dirname(dst)) 38 # --------------------------------------------------------------------------
30 shutil.copytree(src, dst)
31 39
32 def sourceFolder (self): 40 def sourceFolder (self):
33 return main.projectBaseDir() + '/backend/' + self.relativePath() + '/src' 41 return os.path.join(main.projectBaseDir() , 'backend', self.relativePath(), 'src')
34 42
35 43
36 def targetFolder (self): 44 def tempFolder (self):
37 return self.projectTargetDir + self.relativePath() 45 return os.path.join(self.projectTargetDir, '.tmp', self.relativePath())
38 46
39 def createTargetFolder (self):
40 main.createFolder(self.targetFolder())
41 47
48 def frontEndTempFolder (self):
49 return self.tempFolder()
42 50
43 #def copyFrontendResources (self, frontend):
44 # print "copying resources for frontend: " + frontend
45 # print "SETTINGS: " + str(self.settings)
46 51
52 def developmentTargetFolder (self):
53 return os.path.join(self.projectTargetDir, 'development', self.relativePath())
47 54
48 def writeToTargetFolder (self, filename, content): 55 def targetFolder (self):
49 file = open(self.targetFolder() + '/' + filename, 'w') 56 return os.path.join(self.projectTargetDir, self.relativePath())
57
58 # --------------------------------------------------------------------------
59
60 def writeToFolder (self, folder, filename, content):
61 file = open(os.path.join(folder, filename), 'w')
50 file.write(content.encode('utf-8')) 62 file.write(content.encode('utf-8'))
51 file.close() 63 file.close()
52 64
53 65
54 def configureIndexContent (self, indexContent): 66 def configureIndexContent (self, indexContent, requestPathPrefix = ".."):
55 result = indexContent 67 result = indexContent
56 result = result.replace( '@request.path@', self.settings['request.path'] ) 68 result = result.replace( '@request.path@', requestPathPrefix + '/' + self.settings['request.path'] )
57 result = result.replace( '@should.pay.toll@', self.settings['should.pay.toll'] ) 69 result = result.replace( '@should.pay.toll@', self.settings['should.pay.toll'] )
58 70
59 return result 71 return result
@@ -68,22 +80,39 @@ class BackendBuilder:
68 print message + ": " + sha256Digest + " (sha256)" 80 print message + ": " + sha256Digest + " (sha256)"
69 81
70 82
83 def shouldCompileCode (self):
84 return ('debug' in self.versions) or ('install' in self.versions)
85
71 86
72 def run (self): 87 def run (self):
73 print self.name() + " - RUN" 88 print self.name() + " - RUN"
74 89
90 if self.shouldCompileCode():
75 self.compileCode() 91 self.compileCode()
76 self.copyCompiledCodeToTargetDir()
77 92
78 for frontend in self.frontends: 93 for frontend in self.frontends:
79 frontendPath = frontend.module + '/' 94 main.createFolder(os.path.join(self.frontEndTempFolder(), frontend.module))
95
80 if 'debug' in self.versions: 96 if 'debug' in self.versions:
81 frontend.copyResourcesToTargetFolder(self.targetFolder()) 97 frontend.copyResourcesToFolder(self.frontEndTempFolder())
82 #self.writeToTargetFolder(frontendPath + 'index_debug.html', self.configureIndexContent(frontend.assembleDebugVersion())) 98
83 self.writeToTargetFolder(frontendPath + 'index_debug.html', self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))) 99 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEBUG', versionType='DEBUG'))
100 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index_debug.html'), index)
84 101
85 if 'install' in self.versions: 102 if 'install' in self.versions:
86 index = self.configureIndexContent(frontend.assemble()) 103 index = self.configureIndexContent(frontend.assemble())
87 self.writeToTargetFolder(frontendPath + 'index.html', index) 104 self.writeToFolder(self.frontEndTempFolder(), os.path.join(frontend.module, 'index.html'), index)
105
88 self.logChecksums(index, "[" + self.name() + " - " + frontend.module + "] index.html checksum") 106 self.logChecksums(index, "[" + self.name() + " - " + frontend.module + "] index.html checksum")
89 107
108 self.createPackage()
109
110 if 'development' in self.versions:
111 for frontend in self.frontends:
112 main.createFolder(os.path.join(self.developmentTargetFolder(), frontend.module))
113
114 index = self.configureIndexContent(frontend.assemble(assemblyMode='DEVELOPMENT', versionType='DEBUG'), self.settings['development.settings']['url'])
115 self.writeToFolder(self.developmentTargetFolder(), os.path.join(frontend.module, 'index_development.html'), index)
116
117
118#===================================================================
diff --git a/scripts/builder/phpBuilder.py b/scripts/builder/backends/phpBuilder.py
index cb4661d..c928aa0 100644
--- a/scripts/builder/phpBuilder.py
+++ b/scripts/builder/backends/phpBuilder.py
@@ -1,14 +1,13 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: UTF-8 -*- 2# -*- coding: UTF-8 -*-
3 3
4from backendBuilder import BackendBuilder 4from scriptLanguageBuilder import ScriptLanguageBuilder
5 5
6class PhpBuilder(BackendBuilder): 6class PhpBuilder(ScriptLanguageBuilder):
7 7
8 def name(self): 8 def name(self):
9 return "PHP builder" 9 return "PHP builder"
10 10
11
11 def relativePath(self): 12 def relativePath(self):
12 return 'php' 13 return 'php'
13
14
diff --git a/scripts/builder/backends/pythonBuilder.py b/scripts/builder/backends/pythonBuilder.py
new file mode 100644
index 0000000..1e44209
--- a/dev/null
+++ b/scripts/builder/backends/pythonBuilder.py
@@ -0,0 +1,27 @@
1#!/usr/bin/env python
2# -*- coding: UTF-8 -*-
3
4from scriptLanguageBuilder import ScriptLanguageBuilder
5
6class PythonBuilder(ScriptLanguageBuilder):
7
8 def name(self):
9 return "Python builder"
10
11
12 def relativePath(self):
13 return 'python'
14
15
16 def compileCode (self):
17 src = self.sourceFolder()
18 dst = self.targetFolder()
19
20 shutil.copytree(src, dst)
21
22
23 #def copyCompiledCodeToTargetDir (self):
24 # src = self.sourceFolder()
25 # dst = self.targetFolder()
26#
27 # shutil.copytree(src, dst)
diff --git a/scripts/builder/backends/scriptLanguageBuilder.py b/scripts/builder/backends/scriptLanguageBuilder.py
new file mode 100644
index 0000000..7d5b31c
--- a/dev/null
+++ b/scripts/builder/backends/scriptLanguageBuilder.py
@@ -0,0 +1,20 @@
1#!/usr/bin/env python
2# -*- coding: UTF-8 -*-
3
4import shutil
5from backendBuilder import BackendBuilder
6
7class ScriptLanguageBuilder(BackendBuilder):
8
9 def compileCode (self):
10 src = self.sourceFolder()
11 dst = self.tempFolder()
12
13 shutil.copytree(src, dst)
14
15
16 def createPackage (self):
17 src = self.tempFolder()
18 dst = self.targetFolder()
19
20 shutil.copytree(src, dst)
diff --git a/scripts/builder/frontendBuilder.py b/scripts/builder/frontendBuilder.py
index 55054ee..dae837b 100644
--- a/scripts/builder/frontendBuilder.py
+++ b/scripts/builder/frontendBuilder.py
@@ -9,17 +9,11 @@ import shutil
9import StringIO 9import StringIO
10import urllib 10import urllib
11 11
12#from mercurial import ui, hg
13#from mercurial.node import hex
14from dulwich.repo import Repo
15
16import main 12import main
17 13
14class FrontendBuilder(object):
18 15
19 16 def __init__ (self, frontend, settings, repositoryVersion):
20class FrontendBuilder:
21
22 def __init__ (self, frontend, settings):
23 if '.' in frontend: 17 if '.' in frontend:
24 moduleComponents = frontend.split('.') 18 moduleComponents = frontend.split('.')
25 self.module = moduleComponents[0] 19 self.module = moduleComponents[0]
@@ -30,53 +24,26 @@ class FrontendBuilder:
30 24
31 self.settings = settings 25 self.settings = settings
32 self.projectDir = main.projectBaseDir() 26 self.projectDir = main.projectBaseDir()
27 # self.repository = repository.repositoryWithPath(self.projectDir)
28 self.repositoryVersion = repositoryVersion
33 self.processedFiles = {} 29 self.processedFiles = {}
34 30
35 31
36 def mercurialRepositoryVersion (self):
37 repo = hg.repository(ui.ui(), self.projectDir)
38 context = repo['tip']
39 result = str(context)
40
41 return result
42
43
44 def gitRepositoryVersion (self):
45 repo = Repo(self.projectDir)
46 #if repo.is_dirty():
47 #print "WARNING: build run with dirty repository"
48 result = repo.refs['HEAD']
49
50 return result
51
52
53
54 def repositoryVersion (self):
55 cacheKey = 'repositoryVersion'
56 if not self.processedFiles.has_key(cacheKey):
57 #result = self.mercurialRepositoryVersion()
58 result = self.gitRepositoryVersion()
59 self.processedFiles[cacheKey] = result
60 else:
61 result = self.processedFiles[cacheKey]
62
63 return result
64
65
66 #def relativePath (self):
67 #return self.module
68 #
69
70 def log (self, message): 32 def log (self, message):
71 print "frontend [" + self.module + "]: " + message 33 print "frontend [" + self.module + "]: " + message
72 34
73 35
74 def absolutePathForSourceFile (self, folder, basePath, file): 36 def absolutePathForSources (self):
75 return folder + '/frontend/' + self.module + '/' + basePath + '/' + file 37 return os.path.join(self.projectDir, 'frontend', self.module)
38
39
40 def absolutePathForSourceFile (self, basePath, file):
41 return os.path.join(self.absolutePathForSources(), basePath, file)
76 42
77 43
78 def absolutePathForTargetFile (self, folder, basePath, file): 44 def absolutePathForTargetFile (self, folder, basePath, file):
79 return folder + '/' + self.module + '/' + basePath + '/' + file 45 return os.path.join(folder, self.module, basePath, file)
46
80 47
81 def filterFiles (self, files): 48 def filterFiles (self, files):
82 result = [] 49 result = []
@@ -92,13 +59,13 @@ class FrontendBuilder:
92 59
93 def copyResources (self, sourceFolder, destinationFolder, fileType): 60 def copyResources (self, sourceFolder, destinationFolder, fileType):
94 for file in self.filterFiles(self.settings[fileType]): 61 for file in self.filterFiles(self.settings[fileType]):
95 src = self.absolutePathForSourceFile(sourceFolder, fileType, file) 62 src = self.absolutePathForSourceFile(fileType, file)
96 dst = self.absolutePathForTargetFile(destinationFolder, fileType, file) 63 dst = self.absolutePathForTargetFile(destinationFolder, fileType, file)
97 main.createFolder(os.path.dirname(dst)) 64 main.createFolder(os.path.dirname(dst))
98 shutil.copy2(src, dst) 65 shutil.copy2(src, dst)
99 66
100 67
101 def copyResourcesToTargetFolder (self, targetFolder): 68 def copyResourcesToFolder (self, targetFolder):
102 self.copyResources(self.projectDir, targetFolder, 'css') 69 self.copyResources(self.projectDir, targetFolder, 'css')
103 self.copyResources(self.projectDir, targetFolder, 'js') 70 self.copyResources(self.projectDir, targetFolder, 'js')
104 71
@@ -108,7 +75,7 @@ class FrontendBuilder:
108 75
109 for file in self.filterFiles(files): 76 for file in self.filterFiles(files):
110 try: 77 try:
111 fileHandler = codecs.open(self.absolutePathForSourceFile(self.projectDir, basePath, file), 'r', 'utf-8') 78 fileHandler = codecs.open(self.absolutePathForSourceFile(basePath, file), 'r', 'utf-8')
112 except: 79 except:
113 print "FILE: " + file 80 print "FILE: " + file
114 81
@@ -181,8 +148,8 @@ class FrontendBuilder:
181 148
182 #========================================================================== 149 #==========================================================================
183 150
184 def compressJS_jsmin (self, js): 151 def compressJS_jsmin (self, js, description):
185 self.log("compressing JS code") 152 self.log("compressing " + description + " code")
186 original = StringIO.StringIO(js) 153 original = StringIO.StringIO(js)
187 output = StringIO.StringIO() 154 output = StringIO.StringIO()
188 155
@@ -196,7 +163,7 @@ class FrontendBuilder:
196 163
197 return result 164 return result
198 165
199 def compressJS_closureCompiler (self, js): 166 def compressJS_closureCompiler (self, js, description):
200 #Googles Closure compiler 167 #Googles Closure compiler
201 #java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js 168 #java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js
202 169
@@ -205,14 +172,14 @@ class FrontendBuilder:
205 return result 172 return result
206 173
207 174
208 def compressJS (self, js): 175 def compressJS (self, js, description):
209 return self.compressJS_jsmin(js) 176 return self.compressJS_jsmin(js, description)
210 #return self.compressJS_closureCompiler(js) 177 #return self.compressJS_closureCompiler(js, description)
211 178
212 179
213 #========================================================================== 180 #==========================================================================
214 181
215 def packBookmarklet (self, bookmakeletCode): 182 def packBookmarklet (self, bookmakeletCode, version):
216 replacers = [ 183 replacers = [
217 ('isLoginForm', 'ilf'), 184 ('isLoginForm', 'ilf'),
218 ('findLoginForm', 'flf'), 185 ('findLoginForm', 'flf'),
@@ -227,7 +194,7 @@ class FrontendBuilder:
227 ('parameters', 'p' ), 194 ('parameters', 'p' ),
228 ('inputElementValues', 'iev'), 195 ('inputElementValues', 'iev'),
229 ] 196 ]
230 result = self.compressJS(bookmakeletCode) 197 result = self.compressJS(bookmakeletCode, version + " bookmarklet")
231 198
232 result = re.sub('\n', ' ', result) #Fit all in a single line 199 result = re.sub('\n', ' ', result) #Fit all in a single line
233 # result = re.sub('\s+', ' ', result) #Collapse "redundant" spaces. WARNING: this could have some evil side effects on constant strings used inside to code!! 200 # result = re.sub('\s+', ' ', result) #Collapse "redundant" spaces. WARNING: this could have some evil side effects on constant strings used inside to code!!
@@ -300,7 +267,7 @@ class FrontendBuilder:
300 def bookmarklet (self): 267 def bookmarklet (self):
301 cacheKey = 'bookmarklet' 268 cacheKey = 'bookmarklet'
302 if not self.processedFiles.has_key(cacheKey): 269 if not self.processedFiles.has_key(cacheKey):
303 result = 'bookmarklet="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet.js'])) + '";bookmarklet_ie="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet_IE.js'])) + '";' 270 result = 'bookmarklet="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet.js']), "regular") + '";bookmarklet_ie="' + self.packBookmarklet(self.loadFilesContent('js', ['Bookmarklet_IE.js']), "IE") + '";'
304 self.processedFiles[cacheKey] = result 271 self.processedFiles[cacheKey] = result
305 else: 272 else:
306 result = self.processedFiles[cacheKey] 273 result = self.processedFiles[cacheKey]
@@ -308,7 +275,7 @@ class FrontendBuilder:
308 return result 275 return result
309 276
310 277
311 def replaceTemplatePlaceholders (self, assemblyMode, pageTitle, copyright, css, code, version, versionType): 278 def replaceTemplatePlaceholders (self, pageTitle, copyright, css, code, jsLoadMode, version, versionType):
312 result = self.template() 279 result = self.template()
313 280
314 result = result.replace('@page.title@', pageTitle, 1) 281 result = result.replace('@page.title@', pageTitle, 1)
@@ -317,7 +284,7 @@ class FrontendBuilder:
317 #result = result.replace('@bookmarklet@', bookmarklet,1) 284 #result = result.replace('@bookmarklet@', bookmarklet,1)
318 result = result.replace('@application.version@', version, 1) 285 result = result.replace('@application.version@', version, 1)
319 result = result.replace('@application.version.type@', versionType,1) 286 result = result.replace('@application.version.type@', versionType,1)
320 result = result.replace('@js_' + assemblyMode + '@', code, 1) 287 result = result.replace('@js_' + jsLoadMode + '@', code, 1)
321 288
322 result = re.sub('@js_[^@]+@', '', result) 289 result = re.sub('@js_[^@]+@', '', result)
323 290
@@ -343,7 +310,7 @@ class FrontendBuilder:
343 310
344 def cssTagsForFiles (self, basePath, files): 311 def cssTagsForFiles (self, basePath, files):
345 #<link rel="stylesheet" type="text/css" href="./css/reset-min.css" /> 312 #<link rel="stylesheet" type="text/css" href="./css/reset-min.css" />
346 return '\n'.join(map(lambda file: '<link rel="stylesheet" type="text/css" href="./' + basePath + '/' + file + '" />', files)) 313 return '\n'.join(map(lambda file: '<link rel="stylesheet" type="text/css" href="' + basePath + '/' + file + '" />', files))
347 314
348 315
349 def cssTagForContent (self, content): 316 def cssTagForContent (self, content):
@@ -352,17 +319,17 @@ class FrontendBuilder:
352 319
353 def scriptTagsForFiles (self, basePath, files): 320 def scriptTagsForFiles (self, basePath, files):
354 #<script type='text/javascript' src='./js/src/bookmarklet.js'></script> 321 #<script type='text/javascript' src='./js/src/bookmarklet.js'></script>
355 return '\n'.join(map(lambda file: '<script type="text/javascript" src="./' + basePath + '/' + file + '"></script>', files)) 322 return '\n'.join(map(lambda file: '<script type="text/javascript" src="' + basePath + '/' + file + '"></script>', files))
356 323
357 324
358 def scriptTagForContent (self, content): 325 def scriptTagForContent (self, content):
359 return '<script>' + content + '</script>' 326 return '<script>' + content + '</script>'
360 327
361 328
362 def assembleVersion (self, assemblyMode, pageTitle, copyright, css, js, version, versionType): 329 def assembleVersion (self, pageTitle, copyright, css, js, jsLoadMode, version, versionType):
363 cacheKey = version + "-" + versionType 330 cacheKey = version + "-" + versionType
364 if not self.processedFiles.has_key(cacheKey): 331 if not self.processedFiles.has_key(cacheKey):
365 result = self.replaceTemplatePlaceholders(assemblyMode, pageTitle, copyright, css, js, version, versionType) 332 result = self.replaceTemplatePlaceholders(pageTitle, copyright, css, js, jsLoadMode, version, versionType)
366 self.processedFiles[cacheKey] = result 333 self.processedFiles[cacheKey] = result
367 else: 334 else:
368 result = self.processedFiles[cacheKey] 335 result = self.processedFiles[cacheKey]
@@ -372,24 +339,48 @@ class FrontendBuilder:
372 339
373 340
374 def assemble (self, assemblyMode='INSTALL', versionType='LIVE'): 341 def assemble (self, assemblyMode='INSTALL', versionType='LIVE'):
342
343 if versionType == 'LIVE':
375 pageTitle = "Clipperz - " + self.module 344 pageTitle = "Clipperz - " + self.module
376 if versionType != 'LIVE': 345 else:
377 pageTitle += " [" + versionType + " - " + assemblyMode +"]" 346 pageTitle = "Clipperz - " + self.module + " [" + versionType + " - " + assemblyMode +"]"
378 347
379 if assemblyMode == 'INSTALL': 348 if assemblyMode == 'INSTALL':
349 copyright = self.assembleCopyrightHeader()
380 css= self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css']))) 350 css= self.cssTagForContent(self.compressCSS(self.loadFilesContent('css', self.settings['css'])))
381 js= self.scriptTagForContent(self.bookmarklet() + '\n' + self.compressJS(self.loadFilesContent('js', self.settings['js']))) 351 js =self.scriptTagForContent(
352 self.bookmarklet() +
353 '\n' +
354 self.compressJS(self.loadFilesContent('js', self.settings['js']), "application")
355 )
356 jsLoadMode = 'EMBEDDED'
357
358 elif assemblyMode == 'DEBUG':
359 copyright = self.assembleCopyrightHeader()
360 css =self.cssTagsForFiles('./css', self.filterFiles(self.settings['css']))
361 js =self.scriptTagForContent(self.bookmarklet()) + \
362 '\n' + \
363 self.scriptTagsForFiles('./js', self.filterFiles(self.settings['js']))
364 jsLoadMode = 'LINKED'
365
366 elif assemblyMode == 'DEVELOPMENT':
367 copyright = ""
368 css =self.cssTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'css')), self.filterFiles(self.settings['css']))
369 js =self.scriptTagForContent(self.bookmarklet()) + \
370 '\n' + \
371 self.scriptTagsForFiles('file://' + str(os.path.join(self.absolutePathForSources(), 'js')), self.filterFiles(self.settings['js']))
372 jsLoadMode = 'LINKED'
373
382 else: 374 else:
383 css= self.cssTagsForFiles('css', self.filterFiles(self.settings['css'])) 375 raise NotImplementedError()
384 js= self.scriptTagForContent(self.bookmarklet()) + '\n' + self.scriptTagsForFiles('js', self.filterFiles(self.settings['js']))
385 376
386 return self.assembleVersion( 377 return self.assembleVersion(
387 assemblyMode= assemblyMode,
388 pageTitle = pageTitle, 378 pageTitle = pageTitle,
389 copyright = self.assembleCopyrightHeader(), 379 copyright = copyright,
390 css = css, 380 css = css,
391 js = js, 381 js = js,
392 version = self.repositoryVersion(), 382 jsLoadMode = jsLoadMode,
383 version = self.repositoryVersion,
393 versionType = versionType 384 versionType = versionType
394 ) 385 )
395 386
diff --git a/scripts/builder/main.py b/scripts/builder/main.py
index 94f738f..6fce65d 100755
--- a/scripts/builder/main.py
+++ b/scripts/builder/main.py
@@ -1,16 +1,17 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2# -*- coding: UTF-8 -*- 2# -*- coding: UTF-8 -*-
3 3
4import sys, os, json 4import sys
5import os
6import json
5import shutil 7import shutil
6import pprint 8import pprint
7import frontendBuilder
8import codecs 9import codecs
9import itertools 10import itertools
10
11from collections import deque 11from collections import deque
12from phpBuilder import PhpBuilder 12
13from pythonBuilder import PythonBuilder 13import frontendBuilder
14import repository
14 15
15pp = pprint.PrettyPrinter(indent=4, depth=4) 16pp = pprint.PrettyPrinter(indent=4, depth=4)
16 17
@@ -34,7 +35,7 @@ def createFolder (path):
34#-------------------------------------------------------------------- 35#--------------------------------------------------------------------
35 36
36def loadSettings (component, module): 37def loadSettings (component, module):
37 print "MODULE: " + module 38 # print "MODULE: " + module
38 39
39 if '.' in module: 40 if '.' in module:
40 moduleComponents = module.split('.') 41 moduleComponents = module.split('.')
@@ -43,7 +44,8 @@ def loadSettings (component, module):
43 else: 44 else:
44 submodule = module 45 submodule = module
45 46
46 settings = codecs.open(projectBaseDir() + '/' + component + '/' + module + '/properties/' + submodule + '.properties.json', 'r', 'utf-8') 47 #settings = codecs.open(projectBaseDir() + os.sep + component + os.sep + module + os.sep + 'properties' + os.sep + submodule + '.properties.json', 'r', 'utf-8')
48 settings = codecs.open(os.path.join(projectBaseDir(), component, module, 'properties', submodule + '.properties.json'), 'r', 'utf-8')
47 result = json.load(settings) 49 result = json.load(settings)
48 settings.close 50 settings.close
49 51
@@ -71,24 +73,25 @@ def loadSettings (component, module):
71def assembleBackend (backend, frontends, versions): 73def assembleBackend (backend, frontends, versions):
72 settings = loadSettings('backend', backend) 74 settings = loadSettings('backend', backend)
73 75
74 if backend == 'php': 76 builderModuleName = backend + 'Builder'
75 backendBuilder = PhpBuilder(projectTargetDir(), frontends, versions, settings) 77 builderClassName = backend.capitalize() + 'Builder'
76 elif backend == 'python': 78
77 backendBuilder = PythonBuilder(projectTargetDir(), frontends, versions, settings) 79 builderModule = __import__(builderModuleName)
78 #elif backend == 'java': 80 builderClass = getattr(builderModule, builderClassName)
79 #buildJavaBackend (frontends, versions, settings)
80 else:
81 raise Exception('unrecognized backend: ' + backend)
82 81
82 backendBuilder = builderClass(projectTargetDir(), frontends, versions, settings)
83 backendBuilder.run() 83 backendBuilder.run()
84 84
85#==================================================================== 85#====================================================================
86 86
87def build (settings): 87def build (settings, repository):
88 frontends = [] 88 frontends = []
89 89
90 if repository.areTherePendingChanges():
91 print "\nWARNING: repository has pending changes\n"
92
90 for frontend in settings['frontends']: 93 for frontend in settings['frontends']:
91 frontends.append(frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend))) 94 frontends.append(frontendBuilder.FrontendBuilder(frontend, loadSettings('frontend', frontend), repository.version()))
92 95
93 for backend in settings['backends']: 96 for backend in settings['backends']:
94 assembleBackend(backend, frontends, settings['versions']) 97 assembleBackend(backend, frontends, settings['versions'])
@@ -96,7 +99,7 @@ def build (settings):
96#-------------------------------------------------------------------- 99#--------------------------------------------------------------------
97 100
98def clean (): 101def clean ():
99 print "cleaning up …" 102 # print "cleaning up …"
100 if os.path.exists(projectTargetDir()): 103 if os.path.exists(projectTargetDir()):
101 shutil.rmtree(projectTargetDir()) 104 shutil.rmtree(projectTargetDir())
102 105
@@ -107,35 +110,42 @@ def usage (message):
107 print "ERROR: " + message 110 print "ERROR: " + message
108 111
109 print 112 print
110 print "build.py clean" 113 # print "build clean"
111 print "build.py clean install" 114 # print "build clean install"
112 print "build.py install --ALL" 115 print "build install --ALL"
113 print "build.py install debug --ALL" 116 print "build install debug --ALL"
114 print "build.py clean install debug --ALL" 117 # print "build clean install debug --ALL"
115 print "build.ph install, debug --backends php java --frontends beta gamma" 118 print "build install debug --backends php python --frontends beta gamma"
116 print "build.ph install, debug --backends php java --frontends beta gamma gamma.mobile" 119 print "build install debug development --backends php python --frontends beta gamma gamma.mobile"
117 exit(1) 120 exit(1)
118 121
119#-------------------------------------------------------------------- 122#--------------------------------------------------------------------
120 123
124def allFrontends ():
125 return ['beta', 'gamma', 'mobile']
126
127def allBackends ():
128 return ['php', 'python']
129
130#--------------------------------------------------------------------
131
121def main (): 132def main ():
122 settings = {} 133 settings = {}
123 parameters = list(itertools.islice(sys.argv, 1, None)) 134 parameters = list(itertools.islice(sys.argv, 1, None))
124 135
125 shouldClean = len(filter(lambda x: x == 'clean', parameters)) > 0 136 sys.path.append(os.path.join(scriptDir(), 'backends'))
126 if (shouldClean): 137 currentRepository = repository.repositoryWithPath(projectBaseDir())
127 clean ()
128 138
129 parameters = filter(lambda x: x != 'clean', parameters) 139 clean()
130 versions = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) 140 versions = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters))
131 settings['versions'] = versions; #['debug', 'install'] 141 settings['versions'] = versions; #['debug', 'install', 'development']
132 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters)) 142 parameters = deque(itertools.dropwhile(lambda x: not x.startswith('--'), parameters))
133 143
134 if len(parameters) > 0: 144 if len(parameters) > 0:
135 parameter = parameters.popleft() 145 parameter = parameters.popleft()
136 if parameter == "--ALL": 146 if parameter == "--ALL":
137 settings['frontends'] = ['beta', 'gamma', 'mobile'] 147 settings['frontends'] = allFrontends()
138 settings['backends'] = ['php', 'python', 'java'] 148 settings['backends'] = allBackends()
139 else: 149 else:
140 while parameter != None: 150 while parameter != None:
141 values = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters)) 151 values = list(itertools.takewhile(lambda x: not x.startswith('--'), parameters))
@@ -158,8 +168,9 @@ def main ():
158 if (not settings.has_key('backends')): 168 if (not settings.has_key('backends')):
159 usage("missing 'backends'") 169 usage("missing 'backends'")
160 170
161 build (settings) 171 build(settings, currentRepository)
162 172 else:
173 usage("Suggestions on how to call the 'build' script:")
163 174
164 175
165if __name__ == "__main__": 176if __name__ == "__main__":
diff --git a/scripts/builder/pythonBuilder.py b/scripts/builder/pythonBuilder.py
deleted file mode 100644
index a84598d..0000000
--- a/scripts/builder/pythonBuilder.py
+++ b/dev/null
@@ -1,14 +0,0 @@
1#!/usr/bin/env python
2# -*- coding: UTF-8 -*-
3
4from backendBuilder import BackendBuilder
5
6class PythonBuilder(BackendBuilder):
7
8 def name(self):
9 return "Python builder"
10
11 def relativePath(self):
12 return 'python'
13
14
diff --git a/scripts/builder/repository.py b/scripts/builder/repository.py
new file mode 100644
index 0000000..89db9a5
--- a/dev/null
+++ b/scripts/builder/repository.py
@@ -0,0 +1,75 @@
1#!/usr/bin/env python
2# -*- coding: UTF-8 -*-
3
4
5def repositoryWithPath (path):
6 try:
7 from dulwich.repo import Repo
8
9 repo = Repo(path)
10 result = GitRepository(repo, path)
11 except:
12 from mercurial import ui, hg
13
14 repo = hg.repository(ui.ui(), path)
15 result = HgRepository(repo, path)
16
17 return result
18
19
20#===================================================================
21
22
23class Repository(object):
24
25 def __init__ (self, repository, path):
26 self.repository = repository
27 self.path = path
28
29
30 def revision (self):
31 raise NotImplementedError()
32
33
34 def areTherePendingChanges (self):
35 raise NotImplementedError()
36
37
38 def version (self):
39 result = self.revision()
40 if self.areTherePendingChanges():
41 result = '>>> ' + result + ' <<<'
42
43 # print "VERSION: " + result
44 return result
45
46
47#===================================================================
48
49
50class GitRepository(Repository):
51
52 def revision (self):
53 return repository.refs['HEAD']
54
55
56 def areTherePendingChanges (self):
57 return repository.is_dirty()
58
59
60#===================================================================
61
62
63class HgRepository(Repository):
64 #http://mercurial.selenic.com/wiki/MercurialApi
65
66 def revision (self):
67 return 'hg:' + str(self.repository['tip'])
68
69
70 def areTherePendingChanges (self):
71 # TODO: FIXME: repository.status() does not report 'unknown(?)' files. :(
72 return not all(map(lambda fileList: len(fileList) == 0, self.repository.status()))
73
74
75#===================================================================