def runBuild(baseDir, scriptName, opts, args, type): locales = None buildNum = None multicompartment = False releaseBuild = False keyFile = None experimentalAPI = False for option, value in opts: if option in ('-l', '--locales'): locales = value.split(',') elif option in ('-b', '--build'): buildNum = int(value) elif option in ('-k', '--key'): keyFile = value elif option in ('-m', '--multi-compartment'): multicompartment = True elif option in ('-r', '--release'): releaseBuild = True elif option == '--experimental': experimentalAPI = True outFile = args[0] if len(args) > 0 else None if type == 'gecko': import buildtools.packagerGecko as packager packager.createBuild(baseDir, type=type, outFile=outFile, locales=locales, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile, multicompartment=multicompartment) elif type == 'chrome' or type == 'opera': import buildtools.packagerChrome as packager packager.createBuild(baseDir, type=type, outFile=outFile, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile, experimentalAPI=experimentalAPI)
def runBuild(baseDir, scriptName, opts, args, type): kwargs = {} for option, value in opts: if option in {'-l', '--locales'} and type == 'gecko': kwargs['locales'] = value.split(',') elif option in {'-b', '--build'}: kwargs['buildNum'] = value if type != 'gecko' and not kwargs['buildNum'].isdigit(): raise TypeError('Build number must be numerical') elif option in {'-k', '--key'}: kwargs['keyFile'] = value elif option in {'-m', '--multi-compartment'} and type == 'gecko': kwargs['multicompartment'] = True elif option in {'-r', '--release'}: kwargs['releaseBuild'] = True if len(args) > 0: kwargs['outFile'] = args[0] if type == 'gecko': import buildtools.packagerGecko as packager elif type in {'chrome', 'gecko-webext'}: import buildtools.packagerChrome as packager elif type == 'safari': import buildtools.packagerSafari as packager elif type == 'edge': import buildtools.packagerEdge as packager packager.createBuild(baseDir, type=type, **kwargs)
def runBuild(baseDir, scriptName, opts, args, type): kwargs = {} for option, value in opts: if option in {'-l', '--locales'} and type == 'gecko': kwargs['locales'] = value.split(',') elif option in {'-b', '--build'}: kwargs['buildNum'] = value if type != 'gecko' and not kwargs['buildNum'].isdigit(): raise TypeError('Build number must be numerical') elif option in {'-k', '--key'}: kwargs['keyFile'] = value elif option in {'-m', '--multi-compartment'} and type == 'gecko': kwargs['multicompartment'] = True elif option in {'-r', '--release'}: kwargs['releaseBuild'] = True if len(args) > 0: kwargs['outFile'] = args[0] if type == 'gecko': import buildtools.packagerGecko as packager elif type == 'chrome': import buildtools.packagerChrome as packager elif type == 'safari': import buildtools.packagerSafari as packager elif type == 'edge': import buildtools.packagerEdge as packager packager.createBuild(baseDir, type=type, **kwargs)
def run(baseDir, version, keyFile, downloadsRepo): # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. handle = open(packager.getMetadataPath(baseDir), 'rb') rawMetadata = handle.read() handle.close() versionRegExp = re.compile(r'^(\s*version\s*=\s*).*', re.I | re.M) rawMetadata = re.sub(versionRegExp, r'\g<1>%s' % version, rawMetadata) handle = open(packager.getMetadataPath(baseDir), 'wb') handle.write(rawMetadata) handle.close() # Read extension name and branch name locales = packager.readLocaleMetadata(baseDir, [packager.defaultLocale]) extensionName = locales[packager.defaultLocale]['name'] metadata = packager.readMetadata(baseDir) # Now commit the change and tag it subprocess.Popen(['hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version)]).communicate() subprocess.Popen(['hg', 'tag', '-R', baseDir, '-f', version]).communicate() # Create a release build buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version)) packager.createBuild(baseDir, outFile=buildPath, releaseBuild=True, keyFile=keyFile) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' archiveHandle = open(archivePath, 'wb') archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz') (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', baseDir, '-t', 'tar', '-S', '-'], stdout=subprocess.PIPE).communicate() repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:') for fileInfo in repoArchive: if os.path.basename(fileInfo.name) in ('.hgtags', '.hgignore'): continue fileData = repoArchive.extractfile(fileInfo) fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name) archive.addfile(fileInfo, fileData) repoArchive.close() archive.close() archiveHandle.close() # Now add the downloads and commit subprocess.Popen(['hg', 'add', '-R', downloadsRepo, buildPath, archivePath]).communicate() subprocess.Popen(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]).communicate() # Push all changes subprocess.Popen(['hg', 'push', '-R', baseDir]).communicate() subprocess.Popen(['hg', 'push', '-R', downloadsRepo]).communicate()
def createDevEnv(baseDir, scriptName, opts, args, type): if type == 'safari': import buildtools.packagerSafari as packager else: import buildtools.packagerChrome as packager file = StringIO() packager.createBuild(baseDir, type=type, outFile=file, devenv=True, releaseBuild=True) devenv_dir = os.path.join(baseDir, 'devenv') shutil.rmtree(devenv_dir, ignore_errors=True) file.seek(0) with ZipFile(file, 'r') as zip_file: zip_file.extractall(devenv_dir)
def runBuild(baseDir, scriptName, opts, args, type): locales = None buildNum = None multicompartment = False releaseBuild = False keyFile = None limitMetadata = False experimentalAPI = False for option, value in opts: if option in ('-l', '--locales'): locales = value.split(',') elif option in ('-b', '--build'): buildNum = int(value) elif option in ('-k', '--key'): keyFile = value elif option in ('-m', '--multi-compartment'): multicompartment = True elif option in ('-r', '--release'): releaseBuild = True elif option == '--experimental': experimentalAPI = True outFile = args[0] if len(args) > 0 else None if type == 'gecko': import buildtools.packagerGecko as packager packager.createBuild(baseDir, outFile=outFile, locales=locales, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile, limitMetadata=limitMetadata, multicompartment=multicompartment) elif type == 'chrome': import buildtools.packagerChrome as packager packager.createBuild(baseDir, outFile=outFile, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile, experimentalAPI=experimentalAPI)
def runBuild(baseDir, scriptName, opts, args, type): locales = None buildNum = None multicompartment = False releaseBuild = False keyFile = None for option, value in opts: if option in ('-l', '--locales'): locales = value.split(',') elif option in ('-b', '--build'): buildNum = value if type != 'gecko' and not re.search(r'^\d+$', buildNum): raise TypeError('Build number must be numerical') elif option in ('-k', '--key'): keyFile = value elif option in ('-m', '--multi-compartment'): multicompartment = True elif option in ('-r', '--release'): releaseBuild = True outFile = args[0] if len(args) > 0 else None if type == 'gecko': import buildtools.packagerGecko as packager packager.createBuild(baseDir, type=type, outFile=outFile, locales=locales, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile, multicompartment=multicompartment) elif type == 'chrome': import buildtools.packagerChrome as packager packager.createBuild(baseDir, type=type, outFile=outFile, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile) elif type == 'safari': import buildtools.packagerSafari as packager packager.createBuild(baseDir, type=type, outFile=outFile, buildNum=buildNum, releaseBuild=releaseBuild, keyFile=keyFile)
def build(self): """ run the build command in the tempdir """ baseDir = os.path.join(self.config.nightliesDirectory, self.basename) if not os.path.exists(baseDir): os.makedirs(baseDir) outputFile = "%s-%s%s" % (self.basename, self.version, self.config.packageSuffix) outputPath = os.path.join(baseDir, outputFile) self.updateURL = urlparse.urljoin(self.config.nightliesURL, self.basename + '/' + outputFile + '?update') if self.config.type == 'android': apkFile = open(outputPath, 'wb') try: try: port = get_config().get('extensions', 'androidBuildPort') except ConfigParser.NoOptionError: port = '22' buildCommand = ['ssh', '-p', port, get_config().get('extensions', 'androidBuildHost')] buildCommand.extend(map(pipes.quote, ['/home/android/bin/makedebugbuild.py', '--revision', self.revision, '--version', self.version, '--stdout'])) subprocess.check_call(buildCommand, stdout=apkFile, close_fds=True) except: # clear broken output if any if os.path.exists(outputPath): os.remove(outputPath) raise elif self.config.type == 'chrome' or self.config.type == 'opera': import buildtools.packagerChrome as packager packager.createBuild(self.tempdir, type=self.config.type, outFile=outputPath, buildNum=self.revision, keyFile=self.config.keyFile, experimentalAPI=self.config.experimental) elif self.config.type == 'safari': import buildtools.packagerSafari as packager packager.createBuild(self.tempdir, type=self.config.type, outFile=outputPath, buildNum=self.revision, keyFile=self.config.keyFile) else: import buildtools.packagerGecko as packager packager.createBuild(self.tempdir, outFile=outputPath, buildNum=self.revision, keyFile=self.config.keyFile) if not os.path.exists(outputPath): raise Exception("Build failed, output file hasn't been created") linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffix) if hasattr(os, 'symlink'): if os.path.exists(linkPath): os.remove(linkPath) os.symlink(os.path.basename(outputPath), linkPath) else: shutil.copyfile(outputPath, linkPath)
def run(): parser = argparse.ArgumentParser(description='Run crawler') parser.add_argument('-b', '--binary', type=str, help='path to the Firefox binary') parser.add_argument('-a', '--abpdir', type=str, help='path to the Adblock Plus repository') parser.add_argument( '-f', '--filters', metavar='url', type=str, nargs='+', default=[ "https://easylist-downloads.adblockplus.org/easylist.txt", "https://easylist-downloads.adblockplus.org/exceptionrules.txt" ], help= 'filter lists to install in Adblock Plus. The arguments can also have the format path=url, the data will be read from the specified path then.' ) parser.add_argument('-t', '--timeout', type=int, default=300, help='Load timeout (seconds)') parser.add_argument('-x', '--maxtabs', type=int, default=15, help='Maximal number of tabs to open in parallel') parser.add_argument('list', type=str, help='URL list to process') parser.add_argument('outdir', type=str, help='directory to write data into') parameters = parser.parse_args() import buildtools.packagerGecko as packager cleanup = [] try: base_dir = os.path.dirname(__file__) handle, crawlerxpi = tempfile.mkstemp(suffix='.xpi') os.close(handle) cleanup.append(crawlerxpi) packager.createBuild(base_dir, outFile=crawlerxpi, releaseBuild=True) abpxpi = 'https://addons.mozilla.org/firefox/downloads/latest/1865/addon-1865-latest.xpi' if parameters.abpdir: handle, abpxpi = tempfile.mkstemp(suffix='.xpi') os.close(handle) cleanup.append(abpxpi) packager.createBuild(parameters.abpdir, outFile=abpxpi, releaseBuild=True) profile = FirefoxProfile(addons=[ crawlerxpi, abpxpi, ], preferences={ 'browser.uitour.enabled': False, 'prompts.tab_modal.enabled': False, }) abpsettings = os.path.join(profile.profile, 'adblockplus') os.makedirs(abpsettings) with open(os.path.join(abpsettings, 'patterns.ini'), 'w') as handle: print >> handle, '# Adblock Plus preferences' print >> handle, 'version=4' for url in parameters.filters: if '=' in url: path, url = url.split('=', 1) with open(path, 'r') as source: data = source.read() else: data = urllib.urlopen(url).read() print >> handle, '[Subscription]' print >> handle, 'url=%s' % url print >> handle, '[Subscription filters]' print >> handle, '\n'.join(data.splitlines()[1:]) finally: for path in cleanup: os.unlink(path) server = None try: port = random.randrange(2000, 60000) print "Communicating with client on port %i" % port app = CrawlerApp(parameters) server = make_server('localhost', port, app) app.server = server threading.Thread(target=lambda: server.serve_forever()).start() runner = FirefoxRunner( profile=profile, binary=parameters.binary, cmdargs=['--crawler-port', str(port)], env=dict(os.environ, MOZ_CRASHREPORTER_DISABLE='1'), ) while app.urls: runner.start() runner.wait() finally: if server: server.shutdown() profile.cleanup()
def run_tests(firefox_path=None): basedir = os.path.dirname(__file__) driver = None profile = FirefoxProfile() if firefox_path: if sys.platform == "darwin" and os.path.isdir(firefox_path): firefox_path = os.path.join(firefox_path, "Contents", "MacOS", "firefox") binary = FirefoxBinary(firefox_path) else: binary = None try: build1 = tempfile.NamedTemporaryFile(mode="wb", suffix=".xpi", delete=False) build2 = tempfile.NamedTemporaryFile(mode="wb", suffix=".xpi", delete=False) try: createBuild(basedir, type="gecko", outFile=build1) createBuild(os.path.join(basedir, "testhelper"), type="gecko", outFile=build2) profile.add_extension(build1.name) profile.add_extension(build2.name) finally: os.unlink(build1.name) os.unlink(build2.name) driver = WebDriver(profile, firefox_binary=binary) driver.wait_until = lambda method: WebDriverWait( driver, default_timeout).until(lambda d: method()) driver.accept_alert = Alert(driver).accept driver.keys = Keys def chain(*actions): for action in actions: c = ActionChains(driver) action(c) c.perform() driver.chain = chain max_timestamp = {"value": 0} def get_urls(): result = [] prefix = "[testhelper] Loading: " new_timestamp = max_timestamp["value"] for item in driver.get_log("browser"): timestamp = item["timestamp"] if timestamp <= max_timestamp["value"] or not item[ "message"].startswith(prefix): continue if timestamp > new_timestamp: new_timestamp = timestamp result.append(item["message"][len(prefix):]) max_timestamp["value"] = new_timestamp return result driver.get_urls = get_urls def close_background_tabs(): driver.execute_script(''' var event = document.createEvent("Events"); event.initEvent("testhelper_closeBackgroundTabs", true, false); document.dispatchEvent(event); ''') driver.close_background_tabs = close_background_tabs def middle_click(self): driver.execute_script( ''' var event = document.createEvent("Events"); event.initEvent("testhelper_middleclick", true, false); arguments[0].dispatchEvent(event); ''', self) WebElement.middle_click = middle_click environment = { "__builtins__": __builtins__, "driver": driver, } testdir = os.path.join(basedir, "tests") for filename in os.listdir(testdir): if filename.startswith(".") or not filename.endswith(".py"): continue filepath = os.path.join(testdir, filename) environment["__file__"] = filepath with open(filepath, "rb") as handle: exec handle in environment finally: if driver: driver.quit() shutil.rmtree(profile.path, ignore_errors=True)
def run(baseDir, type, version, keyFile, downloadsRepo): if type == "gecko": import buildtools.packagerGecko as packager elif type == "chrome": import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. handle = open(packager.getMetadataPath(baseDir, type), 'rb') rawMetadata = handle.read() handle.close() versionRegExp = re.compile(r'^(\s*version\s*=\s*).*', re.I | re.M) rawMetadata = re.sub(versionRegExp, r'\g<1>%s' % version, rawMetadata) handle = open(packager.getMetadataPath(baseDir, type), 'wb') handle.write(rawMetadata) handle.close() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == "gecko": locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, "adblockplus") locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]['name'] # Now commit the change and tag it subprocess.check_call([ 'hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version) ]) subprocess.check_call(['hg', 'tag', '-R', baseDir, '-f', version]) # Create a release build downloads = [] if type == "gecko": metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join( downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'xpi')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == "chrome": # We actually have to create three different builds for Chrome: signed a unsigned Chrome builds # (the latter for Chrome Web Store) and a signed Opera build. metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join( downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'crx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) buildPathUnsigned = os.path.join( baseDir, packager.getDefaultFileName(baseDir, metadata, version, 'zip')) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) metadataOpera = packager.readMetadata(baseDir, "opera") buildPathOpera = os.path.join( downloadsRepo, packager.getDefaultFileName(baseDir, metadataOpera, version, 'crx')) packager.createBuild(baseDir, type="opera", outFile=buildPathOpera, releaseBuild=True, keyFile=keyFile) downloads.append(buildPathOpera) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' archiveHandle = open(archivePath, 'wb') archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz') data = subprocess.check_output( ['hg', 'archive', '-R', baseDir, '-t', 'tar', '-S', '-']) repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:') for fileInfo in repoArchive: if os.path.basename(fileInfo.name) in ('.hgtags', '.hgignore'): continue fileData = repoArchive.extractfile(fileInfo) fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name) archive.addfile(fileInfo, fileData) repoArchive.close() archive.close() archiveHandle.close() downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) subprocess.check_call([ 'hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version) ]) # Push all changes subprocess.check_call(['hg', 'push', '-R', baseDir]) subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
def run(baseDir, type, version, keyFiles, downloadsRepo): if type == "gecko": import buildtools.packagerGecko as packager elif type == "chrome": import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. metadata = packager.readMetadata(baseDir, type) with open(metadata.option_source("general", "version"), 'r+b') as file: rawMetadata = file.read() rawMetadata = re.sub( r'^(\s*version\s*=\s*).*', r'\g<1>%s' % version, rawMetadata, flags=re.I | re.M ) file.seek(0) file.write(rawMetadata) file.truncate() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == "gecko": locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, "adblockcash") locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]['name'] # Now commit the change and tag it subprocess.check_call(['hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version)]) subprocess.check_call(['hg', 'tag', '-R', baseDir, '-f', version]) # Create a release build downloads = [] if type == "gecko": keyFile = keyFiles[0] if keyFiles else None metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'xpi')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == "chrome": # We actually have to create four different builds for Chrome: signed a unsigned Chrome builds # (the latter for Chrome Web Store), a signed Opera build and a signed Safari build. metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'crx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFiles[0]) downloads.append(buildPath) buildPathUnsigned = os.path.join(baseDir, packager.getDefaultFileName(baseDir, metadata, version, 'zip')) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) metadataOpera = packager.readMetadata(baseDir, "opera") buildPathOpera = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadataOpera, version, 'crx')) packager.createBuild(baseDir, type="opera", outFile=buildPathOpera, releaseBuild=True, keyFile=keyFiles[0]) downloads.append(buildPathOpera) import buildtools.packagerSafari as packagerSafari metadataSafari = packagerSafari.readMetadata(baseDir, "safari") buildPathSafari = os.path.join(downloadsRepo, packagerSafari.getDefaultFileName(baseDir, metadataSafari, version, 'safariextz')) packagerSafari.createBuild(baseDir, type="safari", outFile=buildPathSafari, releaseBuild=True, keyFile=keyFiles[1]) downloads.append(buildPathSafari) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' create_sourcearchive(baseDir, archivePath) downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) subprocess.check_call(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]) # Push all changes subprocess.check_call(['hg', 'push', '-R', baseDir]) subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
def build(self): """ run the build command in the tempdir """ baseDir = os.path.join(self.config.nightliesDirectory, self.basename) if not os.path.exists(baseDir): os.makedirs(baseDir) outputFile = "%s-%s%s" % (self.basename, self.version, self.config.packageSuffix) self.path = os.path.join(baseDir, outputFile) self.updateURL = urlparse.urljoin( self.config.nightliesURL, self.basename + '/' + outputFile + '?update') if self.config.type == 'android': apkFile = open(self.path, 'wb') try: try: port = get_config().get('extensions', 'androidBuildPort') except ConfigParser.NoOptionError: port = '22' buildCommand = [ 'ssh', '-p', port, get_config().get('extensions', 'androidBuildHost') ] buildCommand.extend( map(pipes.quote, [ '/home/android/bin/makedebugbuild.py', '--revision', self.revision, '--version', self.version, '--stdout' ])) subprocess.check_call(buildCommand, stdout=apkFile, close_fds=True) except: # clear broken output if any if os.path.exists(self.path): os.remove(self.path) raise elif self.config.type == 'chrome': import buildtools.packagerChrome as packager packager.createBuild(self.tempdir, type=self.config.type, outFile=self.path, buildNum=self.revision, keyFile=self.config.keyFile) elif self.config.type == 'safari': import buildtools.packagerSafari as packager packager.createBuild(self.tempdir, type=self.config.type, outFile=self.path, buildNum=self.revision, keyFile=self.config.keyFile) else: import buildtools.packagerGecko as packager packager.createBuild(self.tempdir, outFile=self.path, buildNum=self.revision, keyFile=self.config.keyFile) if not os.path.exists(self.path): raise Exception("Build failed, output file hasn't been created") linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffix) if hasattr(os, 'symlink'): if os.path.exists(linkPath): os.remove(linkPath) os.symlink(os.path.basename(self.path), linkPath) else: shutil.copyfile(self.path, linkPath)
def run(baseDir, type, version, keyFile, downloadsRepo): if type == "gecko": import buildtools.packagerGecko as packager elif type == "chrome": import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. metadata = packager.readMetadata(baseDir, type) with open(metadata.option_source("general", "version"), 'r+b') as file: rawMetadata = file.read() rawMetadata = re.sub( r'^(\s*version\s*=\s*).*', r'\g<1>%s' % version, rawMetadata, flags=re.I | re.M ) file.seek(0) file.write(rawMetadata) file.truncate() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == "gecko": locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, "adblockplus") locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]['name'] # Now commit the change and tag it subprocess.check_call(['hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version)]) subprocess.check_call(['hg', 'tag', '-R', baseDir, '-f', version]) # Create a release build downloads = [] if type == "gecko": metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'xpi')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == "chrome": # We actually have to create three different builds for Chrome: signed a unsigned Chrome builds # (the latter for Chrome Web Store) and a signed Opera build. metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'crx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) buildPathUnsigned = os.path.join(baseDir, packager.getDefaultFileName(baseDir, metadata, version, 'zip')) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) metadataOpera = packager.readMetadata(baseDir, "opera") buildPathOpera = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadataOpera, version, 'crx')) packager.createBuild(baseDir, type="opera", outFile=buildPathOpera, releaseBuild=True, keyFile=keyFile) downloads.append(buildPathOpera) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' archiveHandle = open(archivePath, 'wb') archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz') data = subprocess.check_output(['hg', 'archive', '-R', baseDir, '-t', 'tar', '-S', '-']) repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:') for fileInfo in repoArchive: if os.path.basename(fileInfo.name) in ('.hgtags', '.hgignore'): continue fileData = repoArchive.extractfile(fileInfo) fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name) archive.addfile(fileInfo, fileData) repoArchive.close() archive.close() archiveHandle.close() downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) subprocess.check_call(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]) # Push all changes subprocess.check_call(['hg', 'push', '-R', baseDir]) subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
def run(baseDir, type, version, keyFile, downloadsRepo): if type == "gecko": import buildtools.packagerGecko as packager elif type == "safari": import buildtools.packagerSafari as packager elif type == "edge": import buildtools.packagerEdge as packager elif type == "chrome": import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. metadata = readMetadata(baseDir, type) with open(metadata.option_source("general", "version"), "r+b") as file: rawMetadata = file.read() rawMetadata = re.sub(r"^(\s*version\s*=\s*).*", r"\g<1>%s" % version, rawMetadata, flags=re.I | re.M) file.seek(0) file.write(rawMetadata) file.truncate() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == "gecko": locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, "adblockplus") locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]["name"] # Now commit the change and tag it subprocess.check_call(["hg", "commit", "-R", baseDir, "-m", "Releasing %s %s" % (extensionName, version)]) tag_name = version if type in {"safari", "edge"}: tag_name = "{}-{}".format(tag_name, type) subprocess.check_call(["hg", "tag", "-R", baseDir, "-f", tag_name]) # Create a release build downloads = [] if type == "gecko": buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, "xpi")) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True) downloads.append(buildPath) elif type == "chrome": # Create both signed and unsigned Chrome builds (the latter for Chrome Web Store). buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, "crx")) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) buildPathUnsigned = os.path.join(baseDir, getDefaultFileName(metadata, version, "zip")) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) elif type == "safari": buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, "safariextz")) packager.createBuild(baseDir, type="safari", outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == "edge": # We only offer the Edge extension for use through the Windows Store buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, "appx")) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True) downloads.append(buildPath) # Create source archive archivePath = os.path.splitext(buildPath)[0] + "-source.tgz" create_sourcearchive(baseDir, archivePath) downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(["hg", "add", "-R", downloadsRepo] + downloads) subprocess.check_call(["hg", "commit", "-R", downloadsRepo, "-m", "Releasing %s %s" % (extensionName, version)]) # Push all changes subprocess.check_call(["hg", "push", "-R", baseDir]) subprocess.check_call(["hg", "push", "-R", downloadsRepo])
def run(): parser = argparse.ArgumentParser(description="Run crawler") parser.add_argument("-b", "--binary", type=str, help="path to the Firefox binary") parser.add_argument("-a", "--abpdir", type=str, help="path to the Adblock Plus repository") parser.add_argument( "-f", "--filters", metavar="url", type=str, nargs="+", default=[ "https://easylist-downloads.adblockplus.org/easylist.txt", "https://easylist-downloads.adblockplus.org/exceptionrules.txt", ], help="filter lists to install in Adblock Plus. The arguments can also have the format path=url, the data will be read from the specified path then.", ) parser.add_argument("-t", "--timeout", type=int, default=300, help="Load timeout (seconds)") parser.add_argument("-x", "--maxtabs", type=int, default=15, help="Maximal number of tabs to open in parallel") parser.add_argument("list", type=str, help="URL list to process") parser.add_argument("outdir", type=str, help="directory to write data into") parameters = parser.parse_args() import buildtools.packagerGecko as packager cleanup = [] try: base_dir = os.path.dirname(os.path.abspath(__file__)) handle, crawlerxpi = tempfile.mkstemp(suffix=".xpi") os.close(handle) cleanup.append(crawlerxpi) packager.createBuild(base_dir, outFile=crawlerxpi, releaseBuild=True) abpxpi = "https://addons.mozilla.org/firefox/downloads/latest/1865/addon-1865-latest.xpi" if parameters.abpdir: handle, abpxpi = tempfile.mkstemp(suffix=".xpi") os.close(handle) cleanup.append(abpxpi) packager.createBuild(parameters.abpdir, outFile=abpxpi, releaseBuild=True) profile = FirefoxProfile( addons=[crawlerxpi, abpxpi], preferences={ "browser.startup.homepage": "about:blank", "browser.tabs.warnOnCloseOtherTabs": False, "browser.uitour.enabled": False, "prompts.tab_modal.enabled": False, "startup.homepage_welcome_url": "about:blank", "startup.homepage_welcome_url.additional": "about:blank", "xpinstall.signatures.required": False, }, ) abpsettings = os.path.join(profile.profile, "adblockplus") os.makedirs(abpsettings) with open(os.path.join(abpsettings, "patterns.ini"), "w") as handle: print >> handle, "# Adblock Plus preferences" print >> handle, "version=4" for url in parameters.filters: if "=" in url: path, url = url.split("=", 1) with open(path, "r") as source: data = source.read() else: data = urllib.urlopen(url).read() print >> handle, "[Subscription]" print >> handle, "url=%s" % url print >> handle, "[Subscription filters]" print >> handle, "\n".join(data.splitlines()[1:]) finally: for path in cleanup: os.unlink(path) server = None try: port = random.randrange(2000, 60000) print "Communicating with client on port %i" % port app = CrawlerApp(parameters) server = make_server("localhost", port, app) app.server = server threading.Thread(target=lambda: server.serve_forever()).start() runner = FirefoxRunner( profile=profile, binary=parameters.binary, cmdargs=["--crawler-port", str(port)], env=dict(os.environ, MOZ_CRASHREPORTER_DISABLE="1"), ) while app.urls: runner.start() runner.wait() finally: if server: server.shutdown() profile.cleanup()
def run(): parser = argparse.ArgumentParser(description='Run crawler') parser.add_argument( '-b', '--binary', type=str, help='path to the Firefox binary' ) parser.add_argument( '-a', '--abpdir', type=str, help='path to the Adblock Plus repository' ) parser.add_argument( '-f', '--filters', metavar='url', type=str, nargs='+', default=["https://easylist-downloads.adblockplus.org/easylist.txt", "https://easylist-downloads.adblockplus.org/exceptionrules.txt"], help='filter lists to install in Adblock Plus. The arguments can also have the format path=url, the data will be read from the specified path then.' ) parser.add_argument( '-t', '--timeout', type=int, default=300, help='Load timeout (seconds)' ) parser.add_argument( '-x', '--maxtabs', type=int, default=15, help='Maximal number of tabs to open in parallel' ) parser.add_argument( 'list', type=str, help='URL list to process' ) parser.add_argument( 'outdir', type=str, help='directory to write data into' ) parameters = parser.parse_args() import buildtools.packagerGecko as packager cleanup = [] try: base_dir = os.path.dirname(__file__) handle, crawlerxpi = tempfile.mkstemp(suffix='.xpi') os.close(handle) cleanup.append(crawlerxpi) packager.createBuild(base_dir, outFile=crawlerxpi, releaseBuild=True) abpxpi = 'https://addons.mozilla.org/firefox/downloads/latest/1865/addon-1865-latest.xpi' if parameters.abpdir: handle, abpxpi = tempfile.mkstemp(suffix='.xpi') os.close(handle) cleanup.append(abpxpi) packager.createBuild(parameters.abpdir, outFile=abpxpi, releaseBuild=True) profile = FirefoxProfile( addons=[ crawlerxpi, abpxpi, ], preferences={ 'browser.uitour.enabled': False, 'prompts.tab_modal.enabled': False, } ) abpsettings = os.path.join(profile.profile, 'adblockplus') os.makedirs(abpsettings) with open(os.path.join(abpsettings, 'patterns.ini'), 'w') as handle: print >>handle, '# Adblock Plus preferences' print >>handle, 'version=4' for url in parameters.filters: if '=' in url: path, url = url.split('=', 1) with open(path, 'r') as source: data = source.read() else: data = urllib.urlopen(url).read() print >>handle, '[Subscription]' print >>handle, 'url=%s' % url print >>handle, '[Subscription filters]' print >>handle, '\n'.join(data.splitlines()[1:]) finally: for path in cleanup: os.unlink(path) server = None try: port = random.randrange(2000, 60000) print "Communicating with client on port %i" % port app = CrawlerApp(parameters) server = make_server('localhost', port, app) app.server = server threading.Thread(target=lambda: server.serve_forever()).start() runner = FirefoxRunner( profile=profile, binary=parameters.binary, cmdargs=['--crawler-port', str(port)], env=dict(os.environ, MOZ_CRASHREPORTER_DISABLE='1'), ) while app.urls: runner.start() runner.wait() finally: if server: server.shutdown() profile.cleanup()
def run_tests(firefox_path=None): basedir = os.path.dirname(__file__) driver = None profile = FirefoxProfile() if firefox_path: if sys.platform == "darwin" and os.path.isdir(firefox_path): firefox_path = os.path.join(firefox_path, "Contents", "MacOS", "firefox") binary = FirefoxBinary(firefox_path) else: binary = None try: build1 = tempfile.NamedTemporaryFile(mode="wb", suffix=".xpi", delete=False) build2 = tempfile.NamedTemporaryFile(mode="wb", suffix=".xpi", delete=False) try: createBuild(basedir, type="gecko", outFile=build1) createBuild(os.path.join(basedir, "testhelper"), type="gecko", outFile=build2) profile.add_extension(build1.name) profile.add_extension(build2.name) finally: os.unlink(build1.name) os.unlink(build2.name) driver = WebDriver(profile, firefox_binary=binary) driver.wait_until = lambda method: WebDriverWait(driver, default_timeout).until(lambda d: method()) driver.accept_alert = Alert(driver).accept driver.keys = Keys def chain(*actions): for action in actions: c = ActionChains(driver) action(c) c.perform() driver.chain = chain max_timestamp = {"value": 0} def get_urls(): result = [] prefix = "[testhelper] Loading: " new_timestamp = max_timestamp["value"] for item in driver.get_log("browser"): timestamp = item["timestamp"] if timestamp <= max_timestamp["value"] or not item["message"].startswith(prefix): continue if timestamp > new_timestamp: new_timestamp = timestamp result.append(item["message"][len(prefix):]) max_timestamp["value"] = new_timestamp return result driver.get_urls = get_urls def close_background_tabs(): driver.execute_script(''' var event = document.createEvent("Events"); event.initEvent("testhelper_closeBackgroundTabs", true, false); document.dispatchEvent(event); ''') driver.close_background_tabs = close_background_tabs def middle_click(self): driver.execute_script(''' var event = document.createEvent("Events"); event.initEvent("testhelper_middleclick", true, false); arguments[0].dispatchEvent(event); ''', self) WebElement.middle_click = middle_click environment = { "__builtins__": __builtins__, "driver": driver, } testdir = os.path.join(basedir, "tests") for filename in os.listdir(testdir): if filename.startswith(".") or not filename.endswith(".py"): continue filepath = os.path.join(testdir, filename) environment["__file__"] = filepath with open(filepath, "rb") as handle: exec handle in environment finally: if driver: driver.quit() shutil.rmtree(profile.path, ignore_errors=True)
def run(baseDir, type, version, keyFiles, downloadsRepo): if type == "gecko": import buildtools.packagerGecko as packager elif type == "chrome": import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. metadata = packager.readMetadata(baseDir, type) with open(metadata.option_source("general", "version"), 'r+b') as file: rawMetadata = file.read() rawMetadata = re.sub( r'^(\s*version\s*=\s*).*', r'\g<1>%s' % version, rawMetadata, flags=re.I | re.M ) file.seek(0) file.write(rawMetadata) file.truncate() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == "gecko": locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, "adblockplus") locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]['name'] # Now commit the change and tag it subprocess.check_call(['hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version)]) subprocess.check_call(['hg', 'tag', '-R', baseDir, '-f', version]) # Create a release build downloads = [] if type == "gecko": keyFile = keyFiles[0] if keyFiles else None metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(metadata, version, 'xpi')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == "chrome": # We actually have to create three different builds: signed and unsigned # Chrome builds (the latter for Chrome Web Store), and a signed Safari build. metadata = packager.readMetadata(baseDir, type) buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(metadata, version, 'crx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFiles[0]) downloads.append(buildPath) buildPathUnsigned = os.path.join(baseDir, packager.getDefaultFileName(metadata, version, 'zip')) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) import buildtools.packagerSafari as packagerSafari metadataSafari = packagerSafari.readMetadata(baseDir, "safari") buildPathSafari = os.path.join(downloadsRepo, packagerSafari.getDefaultFileName(metadataSafari, version, 'safariextz')) packagerSafari.createBuild(baseDir, type="safari", outFile=buildPathSafari, releaseBuild=True, keyFile=keyFiles[1]) downloads.append(buildPathSafari) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' create_sourcearchive(baseDir, archivePath) downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) subprocess.check_call(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]) # Push all changes subprocess.check_call(['hg', 'push', '-R', baseDir]) subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
def run(baseDir, type, version, keyFile, downloadsRepo): if type == 'gecko': import buildtools.packagerGecko as packager elif type == 'safari': import buildtools.packagerSafari as packager elif type == 'edge': import buildtools.packagerEdge as packager elif type == 'chrome': import buildtools.packagerChrome as packager # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. metadata = readMetadata(baseDir, type) with open(metadata.option_source('general', 'version'), 'r+b') as file: rawMetadata = file.read() rawMetadata = re.sub(r'^(\s*version\s*=\s*).*', r'\g<1>%s' % version, rawMetadata, flags=re.I | re.M) file.seek(0) file.write(rawMetadata) file.truncate() # Read extension name from locale data import buildtools.packagerGecko as packagerGecko if type == 'gecko': locales_base = baseDir else: # This is somewhat of a hack but reading out locale import config here would be too much locales_base = os.path.join(baseDir, 'adblockplus') locales = packagerGecko.readLocaleMetadata(locales_base, [packagerGecko.defaultLocale]) extensionName = locales[packagerGecko.defaultLocale]['name'] # Now commit the change and tag it subprocess.check_call([ 'hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version) ]) tag_name = version if type in {'safari', 'edge'}: tag_name = '{}-{}'.format(tag_name, type) subprocess.check_call(['hg', 'tag', '-R', baseDir, '-f', tag_name]) # Create a release build downloads = [] if type == 'gecko': buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, 'xpi')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True) downloads.append(buildPath) elif type == 'chrome': # Create both signed and unsigned Chrome builds (the latter for Chrome Web Store). buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, 'crx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) buildPathUnsigned = os.path.join( baseDir, getDefaultFileName(metadata, version, 'zip')) packager.createBuild(baseDir, type=type, outFile=buildPathUnsigned, releaseBuild=True, keyFile=None) elif type == 'safari': buildPath = os.path.join( downloadsRepo, getDefaultFileName(metadata, version, 'safariextz')) packager.createBuild(baseDir, type='safari', outFile=buildPath, releaseBuild=True, keyFile=keyFile) downloads.append(buildPath) elif type == 'edge': # We only offer the Edge extension for use through the Windows Store buildPath = os.path.join(downloadsRepo, getDefaultFileName(metadata, version, 'appx')) packager.createBuild(baseDir, type=type, outFile=buildPath, releaseBuild=True) downloads.append(buildPath) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' create_sourcearchive(baseDir, archivePath) downloads.append(archivePath) # Now add the downloads and commit subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) subprocess.check_call([ 'hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version) ]) # Push all changes subprocess.check_call(['hg', 'push', '-R', baseDir]) subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
def run(baseDir, version, keyFile, downloadsRepo): # Replace version number in metadata file "manually", ConfigParser will mess # up the order of lines. handle = open(packager.getMetadataPath(baseDir), 'rb') rawMetadata = handle.read() handle.close() versionRegExp = re.compile(r'^(\s*version\s*=\s*).*', re.I | re.M) rawMetadata = re.sub(versionRegExp, r'\g<1>%s' % version, rawMetadata) handle = open(packager.getMetadataPath(baseDir), 'wb') handle.write(rawMetadata) handle.close() # Read extension name and branch name locales = packager.readLocaleMetadata(baseDir, [packager.defaultLocale]) extensionName = locales[packager.defaultLocale]['name'] metadata = packager.readMetadata(baseDir) # Now commit the change and tag it subprocess.Popen([ 'hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version) ]).communicate() subprocess.Popen(['hg', 'tag', '-R', baseDir, '-f', version]).communicate() # Create a release build buildPath = os.path.join( downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version)) packager.createBuild(baseDir, outFile=buildPath, releaseBuild=True, keyFile=keyFile) # Create source archive archivePath = os.path.splitext(buildPath)[0] + '-source.tgz' archiveHandle = open(archivePath, 'wb') archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz') (data, dummy) = subprocess.Popen( ['hg', 'archive', '-R', baseDir, '-t', 'tar', '-S', '-'], stdout=subprocess.PIPE).communicate() repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:') for fileInfo in repoArchive: if os.path.basename(fileInfo.name) in ('.hgtags', '.hgignore'): continue fileData = repoArchive.extractfile(fileInfo) fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name) archive.addfile(fileInfo, fileData) repoArchive.close() archive.close() archiveHandle.close() # Now add the downloads and commit subprocess.Popen( ['hg', 'add', '-R', downloadsRepo, buildPath, archivePath]).communicate() subprocess.Popen([ 'hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version) ]).communicate() # Push all changes subprocess.Popen(['hg', 'push', '-R', baseDir]).communicate() subprocess.Popen(['hg', 'push', '-R', downloadsRepo]).communicate()