| LEFT | RIGHT |
| 1 # This file is part of the Adblock Plus web scripts, | 1 # This file is part of the Adblock Plus web scripts, |
| 2 # Copyright (C) 2006-present eyeo GmbH | 2 # Copyright (C) 2006-present eyeo GmbH |
| 3 # | 3 # |
| 4 # Adblock Plus is free software: you can redistribute it and/or modify | 4 # Adblock Plus is free software: you can redistribute it and/or modify |
| 5 # it under the terms of the GNU General Public License version 3 as | 5 # it under the terms of the GNU General Public License version 3 as |
| 6 # published by the Free Software Foundation. | 6 # published by the Free Software Foundation. |
| 7 # | 7 # |
| 8 # Adblock Plus is distributed in the hope that it will be useful, | 8 # Adblock Plus is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 import zipfile | 44 import zipfile |
| 45 import contextlib | 45 import contextlib |
| 46 | 46 |
| 47 from xml.dom.minidom import parse as parseXml | 47 from xml.dom.minidom import parse as parseXml |
| 48 | 48 |
| 49 from sitescripts.extensions.utils import ( | 49 from sitescripts.extensions.utils import ( |
| 50 compareVersions, Configuration, | 50 compareVersions, Configuration, |
| 51 writeAndroidUpdateManifest | 51 writeAndroidUpdateManifest |
| 52 ) | 52 ) |
| 53 from sitescripts.utils import get_config, get_template | 53 from sitescripts.utils import get_config, get_template |
| 54 from sitescripts.extensions.bin.legacy import xarfile | |
| 55 | 54 |
| 56 MAX_BUILDS = 50 | 55 MAX_BUILDS = 50 |
| 57 | 56 |
| 58 | 57 |
| 59 # Google and Microsoft APIs use HTTP error codes with error message in | 58 # Google and Microsoft APIs use HTTP error codes with error message in |
| 60 # body. So we add the response body to the HTTPError to get more | 59 # body. So we add the response body to the HTTPError to get more |
| 61 # meaningful error messages. | 60 # meaningful error messages. |
| 62 class HTTPErrorBodyHandler(urllib2.HTTPDefaultErrorHandler): | 61 class HTTPErrorBodyHandler(urllib2.HTTPDefaultErrorHandler): |
| 63 def http_error_default(self, req, fp, code, msg, hdrs): | 62 def http_error_default(self, req, fp, code, msg, hdrs): |
| 64 raise urllib2.HTTPError(req.get_full_url(), code, | 63 raise urllib2.HTTPError(req.get_full_url(), code, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 'defaults.id=', self.config.repository | 98 'defaults.id=', self.config.repository |
| 100 ] | 99 ] |
| 101 return subprocess.check_output(command).strip() | 100 return subprocess.check_output(command).strip() |
| 102 | 101 |
| 103 def getCurrentBuild(self): | 102 def getCurrentBuild(self): |
| 104 """ | 103 """ |
| 105 calculates the (typically numerical) build ID for the current build | 104 calculates the (typically numerical) build ID for the current build |
| 106 """ | 105 """ |
| 107 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir] | 106 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir] |
| 108 build = subprocess.check_output(command).strip() | 107 build = subprocess.check_output(command).strip() |
| 109 if self.config.type == 'gecko': | 108 if self.config.type in {'gecko', 'gecko-webext'}: |
| 110 build += 'beta' | 109 build += 'beta' |
| 111 return build | 110 return build |
| 112 | 111 |
| 113 def getChanges(self): | 112 def getChanges(self): |
| 114 """ | 113 """ |
| 115 retrieve changes between the current and previous ("first") revision | 114 retrieve changes between the current and previous ("first") revision |
| 116 """ | 115 """ |
| 117 command = [ | 116 command = [ |
| 118 'hg', 'log', '-R', self.tempdir, '-r', | 117 'hg', 'log', '-R', self.tempdir, '-r', |
| 119 'reverse(ancestors({}))'.format(self.config.revision), '-l', '50', | 118 'reverse(ancestors({}))'.format(self.config.revision), '-l', '50', |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 os.symlink(os.path.basename(changelogPath), linkPath) | 162 os.symlink(os.path.basename(changelogPath), linkPath) |
| 164 else: | 163 else: |
| 165 shutil.copyfile(changelogPath, linkPath) | 164 shutil.copyfile(changelogPath, linkPath) |
| 166 | 165 |
| 167 def readGeckoMetadata(self): | 166 def readGeckoMetadata(self): |
| 168 """ | 167 """ |
| 169 read Gecko-specific metadata file from a cloned repository | 168 read Gecko-specific metadata file from a cloned repository |
| 170 and parse id, version, basename and the compat section | 169 and parse id, version, basename and the compat section |
| 171 out of the file | 170 out of the file |
| 172 """ | 171 """ |
| 173 import buildtools.packagerChrome as packager | 172 import buildtools.packagerGecko as packager |
| 174 metadata = packager.readMetadata(self.tempdir, self.config.type) | 173 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 175 self.extensionID = metadata.get('general', 'id') | 174 self.extensionID = metadata.get('general', 'id') |
| 176 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 175 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 177 self.buildNum) | 176 self.buildNum) |
| 178 self.basename = metadata.get('general', 'basename') | 177 self.basename = metadata.get('general', 'basename') |
| 179 | 178 |
| 180 def readAndroidMetadata(self): | 179 def readAndroidMetadata(self): |
| 181 """ | 180 """ |
| 182 Read Android-specific metadata from AndroidManifest.xml file. | 181 Read Android-specific metadata from AndroidManifest.xml file. |
| 183 """ | 182 """ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 214 metadata = packager.readMetadata(self.tempdir, self.config.type) | 213 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 215 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 214 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 216 self.buildNum) | 215 self.buildNum) |
| 217 self.basename = metadata.get('general', 'basename') | 216 self.basename = metadata.get('general', 'basename') |
| 218 | 217 |
| 219 self.compat = [] | 218 self.compat = [] |
| 220 if metadata.has_section('compat') and metadata.has_option('compat', 'chr
ome'): | 219 if metadata.has_section('compat') and metadata.has_option('compat', 'chr
ome'): |
| 221 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp
at', 'chrome')}) | 220 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp
at', 'chrome')}) |
| 222 | 221 |
| 223 def readSafariMetadata(self): | 222 def readSafariMetadata(self): |
| 224 import sitescripts.extensions.bin.legacy.packagerSafari as packager | 223 import buildtools.packagerSafari as packager |
| 224 from buildtools import xarfile |
| 225 metadata = packager.readMetadata(self.tempdir, self.config.type) | 225 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 226 certs = xarfile.read_certificates_and_key(self.config.keyFile)[0] | 226 certs = xarfile.read_certificates_and_key(self.config.keyFile)[0] |
| 227 | 227 |
| 228 self.certificateID = packager.get_developer_identifier(certs) | 228 self.certificateID = packager.get_developer_identifier(certs) |
| 229 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 229 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 230 self.buildNum) | 230 self.buildNum) |
| 231 self.shortVersion = metadata.get('general', 'version') | 231 self.shortVersion = metadata.get('general', 'version') |
| 232 self.basename = metadata.get('general', 'basename') | 232 self.basename = metadata.get('general', 'basename') |
| 233 self.updatedFromGallery = False | 233 self.updatedFromGallery = False |
| 234 | 234 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 os.remove(self.path) | 340 os.remove(self.path) |
| 341 raise | 341 raise |
| 342 else: | 342 else: |
| 343 env = os.environ | 343 env = os.environ |
| 344 spiderMonkeyBinary = self.config.spiderMonkeyBinary | 344 spiderMonkeyBinary = self.config.spiderMonkeyBinary |
| 345 if spiderMonkeyBinary: | 345 if spiderMonkeyBinary: |
| 346 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary) | 346 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary) |
| 347 | 347 |
| 348 command = [os.path.join(self.tempdir, 'build.py'), | 348 command = [os.path.join(self.tempdir, 'build.py'), |
| 349 'build', '-t', self.config.type, '-b', self.buildNum] | 349 'build', '-t', self.config.type, '-b', self.buildNum] |
| 350 if self.config.type not in {'gecko', 'edge'}: | 350 if self.config.type not in {'gecko', 'gecko-webext', 'edge'}: |
| 351 command.extend(['-k', self.config.keyFile]) | 351 command.extend(['-k', self.config.keyFile]) |
| 352 command.append(self.path) | 352 command.append(self.path) |
| 353 subprocess.check_call(command, env=env) | 353 subprocess.check_call(command, env=env) |
| 354 | 354 |
| 355 if not os.path.exists(self.path): | 355 if not os.path.exists(self.path): |
| 356 raise Exception("Build failed, output file hasn't been created") | 356 raise Exception("Build failed, output file hasn't been created") |
| 357 | 357 |
| 358 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi
x) | 358 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi
x) |
| 359 if hasattr(os, 'symlink'): | 359 if hasattr(os, 'symlink'): |
| 360 if os.path.exists(linkPath): | 360 if os.path.exists(linkPath): |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 self.copyRepository() | 646 self.copyRepository() |
| 647 self.buildNum = self.getCurrentBuild() | 647 self.buildNum = self.getCurrentBuild() |
| 648 | 648 |
| 649 # get meta data from the repository | 649 # get meta data from the repository |
| 650 if self.config.type == 'android': | 650 if self.config.type == 'android': |
| 651 self.readAndroidMetadata() | 651 self.readAndroidMetadata() |
| 652 elif self.config.type == 'chrome': | 652 elif self.config.type == 'chrome': |
| 653 self.readChromeMetadata() | 653 self.readChromeMetadata() |
| 654 elif self.config.type == 'safari': | 654 elif self.config.type == 'safari': |
| 655 self.readSafariMetadata() | 655 self.readSafariMetadata() |
| 656 elif self.config.type == 'gecko': | 656 elif self.config.type in {'gecko', 'gecko-webext'}: |
| 657 self.readGeckoMetadata() | 657 self.readGeckoMetadata() |
| 658 elif self.config.type == 'edge': | 658 elif self.config.type == 'edge': |
| 659 self.read_edge_metadata() | 659 self.read_edge_metadata() |
| 660 else: | 660 else: |
| 661 raise Exception('Unknown build type {}' % self.config.type) | 661 raise Exception('Unknown build type {}' % self.config.type) |
| 662 | 662 |
| 663 # create development build | 663 # create development build |
| 664 self.build() | 664 self.build() |
| 665 | 665 |
| 666 # write out changelog | 666 # write out changelog |
| 667 self.writeChangelog(self.getChanges()) | 667 self.writeChangelog(self.getChanges()) |
| 668 | 668 |
| 669 # write update manifest | 669 # write update manifest |
| 670 self.writeUpdateManifest() | 670 self.writeUpdateManifest() |
| 671 | 671 |
| 672 # retire old builds | 672 # retire old builds |
| 673 versions = self.retireBuilds() | 673 versions = self.retireBuilds() |
| 674 | 674 |
| 675 if self.config.type == 'ie': | 675 if self.config.type == 'ie': |
| 676 self.writeIEUpdateManifest(versions) | 676 self.writeIEUpdateManifest(versions) |
| 677 | 677 |
| 678 # update index page | 678 # update index page |
| 679 self.updateIndex(versions) | 679 self.updateIndex(versions) |
| 680 | 680 |
| 681 # update nightlies config | 681 # update nightlies config |
| 682 self.config.latestRevision = self.revision | 682 self.config.latestRevision = self.revision |
| 683 | 683 |
| 684 if (self.config.type == 'gecko' and | 684 if (self.config.type in {'gecko', 'gecko-webext'} and |
| 685 self.config.galleryID and | 685 self.config.galleryID and |
| 686 get_config().has_option('extensions', 'amo_key')): | 686 get_config().has_option('extensions', 'amo_key')): |
| 687 self.uploadToMozillaAddons() | 687 self.uploadToMozillaAddons() |
| 688 elif self.config.type == 'chrome' and self.config.clientID and self.
config.clientSecret and self.config.refreshToken: | 688 elif self.config.type == 'chrome' and self.config.clientID and self.
config.clientSecret and self.config.refreshToken: |
| 689 self.uploadToChromeWebStore() | 689 self.uploadToChromeWebStore() |
| 690 elif self.config.type == 'edge' and self.config.clientID and self.co
nfig.clientSecret and self.config.refreshToken and self.config.tenantID: | 690 elif self.config.type == 'edge' and self.config.clientID and self.co
nfig.clientSecret and self.config.refreshToken and self.config.tenantID: |
| 691 self.upload_to_windows_store() | 691 self.upload_to_windows_store() |
| 692 | 692 |
| 693 finally: | 693 finally: |
| 694 # clean up | 694 # clean up |
| (...skipping 22 matching lines...) Expand all Loading... |
| 717 except Exception as ex: | 717 except Exception as ex: |
| 718 logging.error('The build for %s failed:', repo) | 718 logging.error('The build for %s failed:', repo) |
| 719 logging.exception(ex) | 719 logging.exception(ex) |
| 720 | 720 |
| 721 file = open(nightlyConfigFile, 'wb') | 721 file = open(nightlyConfigFile, 'wb') |
| 722 nightlyConfig.write(file) | 722 nightlyConfig.write(file) |
| 723 | 723 |
| 724 | 724 |
| 725 if __name__ == '__main__': | 725 if __name__ == '__main__': |
| 726 main() | 726 main() |
| LEFT | RIGHT |