Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: packagerChrome.py

Issue 8627097: Moved Chrome extension scripts to buildtools repository (Closed)
Patch Set: Added build.py gettranslations support for Chrome Created Oct. 22, 2012, 11:25 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # coding: utf-8
2
3 # This Source Code is subject to the terms of the Mozilla Public License
4 # version 2.0 (the "License"). You can obtain a copy of the License at
5 # http://mozilla.org/MPL/2.0/.
6
7 import sys, os, subprocess, re, json, codecs, struct
8 from ConfigParser import SafeConfigParser
9 from StringIO import StringIO
10 from zipfile import ZipFile, ZIP_DEFLATED
11
12 defaultLocale = 'en_US'
13
14 def getDefaultFileName(baseDir, metadata, version, ext):
15 return os.path.join(baseDir, '%s-%s.%s' % (metadata.get('general', 'baseName') , version, ext))
16
17 def getMetadataPath(baseDir):
18 return os.path.join(baseDir, 'metadata')
19
20 def getBuildNum(baseDir):
21 try:
22 (result, dummy) = subprocess.Popen(['hg', 'id', '-n'], stdout=subprocess.PIP E).communicate()
23 return re.sub(r'\D', '', result)
24 except Exception:
25 return '0'
26
27 def readMetadata(baseDir):
28 metadata = SafeConfigParser()
29 file = codecs.open(getMetadataPath(baseDir), 'rb', encoding='utf-8')
30 metadata.readfp(file)
31 file.close()
32 return metadata
33
34 def readVersion(baseDir):
35 file = open(os.path.join(baseDir, 'manifest.json'))
36 data = json.load(file)
37 file.close()
38 return data['version']
39
40 def setUpdateURL(updateName, zip, dir, fileName, fileData):
41 if fileName == 'manifest.json':
42 data = json.loads(fileData)
43 data['update_url'] = 'https://adblockplus.org/devbuilds/%s/updates.xml' % up dateName
44 return json.dumps(data, sort_keys=True, indent=2)
Felix Dahlke 2013/01/10 16:36:20 Pretty much the same line is repeated a few times
Wladimir Palant 2013/01/16 14:20:15 Actually, it's four occasions and only two are rea
45 return fileData
46
47 def setExperimentalSettings(zip, dir, fileName, fileData):
48 if fileName == 'manifest.json':
49 data = json.loads(fileData)
50 data['permissions'] += ['experimental']
51 data['name'] += ' experimental build'
52 return json.dumps(data, sort_keys=True, indent=2)
53 return fileData
54
55 def addBuildNumber(revision, zip, dir, fileName, fileData):
56 if fileName == 'manifest.json':
57 if len(revision) > 0:
58 data = json.loads(fileData)
59 while data['version'].count('.') < 2:
60 data['version'] += '.0'
61 data['version'] += '.' + revision
62 return json.dumps(data, sort_keys=True, indent=2)
63 return fileData
64
65 def mergeContentScripts(zip, dir, fileName, fileData):
66 if fileName == 'manifest.json':
67 data = json.loads(fileData)
68 if 'content_scripts' in data:
69 scriptIndex = 1
70 for contentScript in data['content_scripts']:
71 if 'js' in contentScript:
72 scriptData = ''
73 for scriptFile in contentScript['js']:
74 parts = [dir] + scriptFile.split('/')
75 scriptPath = os.path.join(*parts)
76 handle = open(scriptPath, 'rb')
77 scriptData += handle.read()
78 handle.close()
79 contentScript['js'] = ['contentScript' + str(scriptIndex) + '.js']
80 zip.writestr('contentScript' + str(scriptIndex) + '.js', scriptData)
81 scriptIndex += 1
82 return json.dumps(data, sort_keys=True, indent=2)
83 return fileData
84
85 def addToZip(zip, filters, dir, baseName):
86 for file in os.listdir(dir):
87 filelc = file.lower()
88 if (file.startswith('.') or
89 file == 'buildtools' or file == 'qunit' or file == 'metadata' or
Felix Dahlke 2013/01/10 16:36:20 How about this instead? file in ['buildtools', 'q
Wladimir Palant 2013/01/16 14:20:15 This code has been replaced by a whitelist approac
90 filelc.endswith('.py') or filelc.endswith('.pyc') or
Felix Dahlke 2013/01/10 16:36:20 How about using a regex here? Definitely more conc
Wladimir Palant 2013/01/16 14:20:15 See above.
91 filelc.endswith('.crx') or filelc.endswith('.zip') or
92 filelc.endswith('.sh') or filelc.endswith('.bat') or
93 filelc.endswith('.txt')):
94 # skip special files, scripts, existing archives
95 continue
96 if file.startswith('include.'):
97 # skip includes, they will be added by other means
98 continue
99
100 filePath = os.path.join(dir, file)
101 if os.path.isdir(filePath):
102 addToZip(zip, filters, filePath, baseName + file + '/')
103 else:
104 handle = open(filePath, 'rb')
105 fileData = handle.read()
106 handle.close()
107
108 for filter in filters:
109 fileData = filter(zip, dir, baseName + file, fileData)
110 zip.writestr(baseName + file, fileData)
111
112 def packDirectory(dir, filters):
113 buffer = StringIO()
114 zip = ZipFile(buffer, 'w', ZIP_DEFLATED)
115 addToZip(zip, filters, dir, '')
116 zip.close()
117 return buffer.getvalue()
118
119 def signBinary(zipdata, keyFile):
120 import M2Crypto
121 if not os.path.exists(keyFile):
122 M2Crypto.RSA.gen_key(1024, 65537, callback=lambda x: None).save_key(keyFile, cipher=None)
123 key = M2Crypto.EVP.load_key(keyFile)
124 key.sign_init()
125 key.sign_update(zipdata)
126 return key.final()
127
128 def getPublicKey(keyFile):
129 import M2Crypto
130 return M2Crypto.EVP.load_key(keyFile).as_der()
131
132 def writePackage(outputFile, pubkey, signature, zipdata):
133 file = open(outputFile, 'wb')
134 if pubkey != None and signature != None:
135 file.write(struct.pack('<4sIII', 'Cr24', 2, len(pubkey), len(signature)))
136 file.write(pubkey)
137 file.write(signature)
138 file.write(zipdata)
139 file.close()
140
141 def createBuild(baseDir, outFile=None, buildNum=None, releaseBuild=False, keyFil e=None, experimentalAPI=False):
142 metadata = readMetadata(baseDir)
143 version = readVersion(baseDir)
144 if outFile == None:
145 outFile = getDefaultFileName(baseDir, metadata, version, 'crx' if keyFile el se 'zip')
146
147 filters = []
148 if not releaseBuild:
149 if buildNum == None:
150 buildNum = getBuildNum(baseDir)
151 filters.append(lambda zip, dir, fileName, fileData: addBuildNumber(buildNum, zip, dir, fileName, fileData))
152
153 baseName = metadata.get('general', 'baseName')
154 updateName = baseName + '-experimental' if experimentalAPI else baseName
155 filters.append(lambda zip, dir, fileName, fileData: setUpdateURL(updateName, zip, dir, fileName, fileData))
156 if experimentalAPI:
157 filters.append(setExperimentalSettings)
158 filters.append(mergeContentScripts)
159
160 zipdata = packDirectory(baseDir, filters)
161 signature = None
162 pubkey = None
163 if keyFile != None:
164 signature = signBinary(zipdata, keyFile)
165 pubkey = getPublicKey(keyFile)
166 writePackage(outFile, pubkey, signature, zipdata)
OLDNEW
« localeTools.py ('K') | « localeTools.py ('k') | packagerGecko.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld