build/release/info.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 from datetime import datetime
michael@0 2 import os
michael@0 3 from os import path
michael@0 4 import re
michael@0 5 import shutil
michael@0 6 import sys
michael@0 7 from urllib2 import urlopen
michael@0 8
michael@0 9 from release.paths import makeCandidatesDir
michael@0 10
michael@0 11 import logging
michael@0 12 log = logging.getLogger(__name__)
michael@0 13
michael@0 14 # If version has two parts with no trailing specifiers like "rc", we
michael@0 15 # consider it a "final" release for which we only create a _RELEASE tag.
michael@0 16 FINAL_RELEASE_REGEX = "^\d+\.\d+$"
michael@0 17
michael@0 18
michael@0 19 class ConfigError(Exception):
michael@0 20 pass
michael@0 21
michael@0 22
michael@0 23 def getBuildID(platform, product, version, buildNumber, nightlyDir='nightly',
michael@0 24 server='stage.mozilla.org'):
michael@0 25 infoTxt = makeCandidatesDir(product, version, buildNumber, nightlyDir,
michael@0 26 protocol='http', server=server) + \
michael@0 27 '%s_info.txt' % platform
michael@0 28 try:
michael@0 29 buildInfo = urlopen(infoTxt).read()
michael@0 30 except:
michael@0 31 log.error("Failed to retrieve %s" % infoTxt)
michael@0 32 raise
michael@0 33
michael@0 34 for line in buildInfo.splitlines():
michael@0 35 key, value = line.rstrip().split('=', 1)
michael@0 36 if key == 'buildID':
michael@0 37 return value
michael@0 38
michael@0 39
michael@0 40 def findOldBuildIDs(product, version, buildNumber, platforms,
michael@0 41 nightlyDir='nightly', server='stage.mozilla.org'):
michael@0 42 ids = {}
michael@0 43 if buildNumber <= 1:
michael@0 44 return ids
michael@0 45 for n in range(1, buildNumber):
michael@0 46 for platform in platforms:
michael@0 47 if platform not in ids:
michael@0 48 ids[platform] = []
michael@0 49 try:
michael@0 50 id = getBuildID(platform, product, version, n, nightlyDir,
michael@0 51 server)
michael@0 52 ids[platform].append(id)
michael@0 53 except Exception, e:
michael@0 54 log.error("Hit exception: %s" % e)
michael@0 55 return ids
michael@0 56
michael@0 57
michael@0 58 def getReleaseConfigName(product, branch, version=None, staging=False):
michael@0 59 # XXX: Horrible hack for bug 842741. Because Thunderbird release
michael@0 60 # and esr both build out of esr17 repositories we'll bump the wrong
michael@0 61 # config for release without this.
michael@0 62 if product == 'thunderbird' and 'esr17' in branch and version and 'esr' not in version:
michael@0 63 cfg = 'release-thunderbird-comm-release.py'
michael@0 64 else:
michael@0 65 cfg = 'release-%s-%s.py' % (product, branch)
michael@0 66 if staging:
michael@0 67 cfg = 'staging_%s' % cfg
michael@0 68 return cfg
michael@0 69
michael@0 70
michael@0 71 def readReleaseConfig(configfile, required=[]):
michael@0 72 return readConfig(configfile, keys=['releaseConfig'], required=required)
michael@0 73
michael@0 74
michael@0 75 def readBranchConfig(dir, localconfig, branch, required=[]):
michael@0 76 shutil.copy(localconfig, path.join(dir, "localconfig.py"))
michael@0 77 oldcwd = os.getcwd()
michael@0 78 os.chdir(dir)
michael@0 79 sys.path.append(".")
michael@0 80 try:
michael@0 81 return readConfig("config.py", keys=['BRANCHES', branch],
michael@0 82 required=required)
michael@0 83 finally:
michael@0 84 os.chdir(oldcwd)
michael@0 85 sys.path.remove(".")
michael@0 86
michael@0 87
michael@0 88 def readConfig(configfile, keys=[], required=[]):
michael@0 89 c = {}
michael@0 90 execfile(configfile, c)
michael@0 91 for k in keys:
michael@0 92 c = c[k]
michael@0 93 items = c.keys()
michael@0 94 err = False
michael@0 95 for key in required:
michael@0 96 if key not in items:
michael@0 97 err = True
michael@0 98 log.error("Required item `%s' missing from %s" % (key, c))
michael@0 99 if err:
michael@0 100 raise ConfigError("Missing at least one item in config, see above")
michael@0 101 return c
michael@0 102
michael@0 103
michael@0 104 def isFinalRelease(version):
michael@0 105 return bool(re.match(FINAL_RELEASE_REGEX, version))
michael@0 106
michael@0 107
michael@0 108 def getBaseTag(product, version):
michael@0 109 product = product.upper()
michael@0 110 version = version.replace('.', '_')
michael@0 111 return '%s_%s' % (product, version)
michael@0 112
michael@0 113
michael@0 114 def getTags(baseTag, buildNumber, buildTag=True):
michael@0 115 t = ['%s_RELEASE' % baseTag]
michael@0 116 if buildTag:
michael@0 117 t.append('%s_BUILD%d' % (baseTag, int(buildNumber)))
michael@0 118 return t
michael@0 119
michael@0 120
michael@0 121 def getRuntimeTag(tag):
michael@0 122 return "%s_RUNTIME" % tag
michael@0 123
michael@0 124
michael@0 125 def getReleaseTag(tag):
michael@0 126 return "%s_RELEASE" % tag
michael@0 127
michael@0 128
michael@0 129 def generateRelbranchName(version, prefix='GECKO'):
michael@0 130 return '%s%s_%s_RELBRANCH' % (
michael@0 131 prefix, version.replace('.', ''),
michael@0 132 datetime.now().strftime('%Y%m%d%H'))
michael@0 133
michael@0 134
michael@0 135 def getReleaseName(product, version, buildNumber):
michael@0 136 return '%s-%s-build%s' % (product.title(), version, str(buildNumber))
michael@0 137
michael@0 138
michael@0 139 def getRepoMatchingBranch(branch, sourceRepositories):
michael@0 140 for sr in sourceRepositories.values():
michael@0 141 if branch in sr['path']:
michael@0 142 return sr
michael@0 143 return None
michael@0 144
michael@0 145
michael@0 146 def fileInfo(filepath, product):
michael@0 147 """Extract information about a release file. Returns a dictionary with the
michael@0 148 following keys set:
michael@0 149 'product', 'version', 'locale', 'platform', 'contents', 'format',
michael@0 150 'pathstyle'
michael@0 151
michael@0 152 'contents' is one of 'complete', 'installer'
michael@0 153 'format' is one of 'mar' or 'exe'
michael@0 154 'pathstyle' is either 'short' or 'long', and refers to if files are all in
michael@0 155 one directory, with the locale as part of the filename ('short' paths,
michael@0 156 firefox 3.0 style filenames), or if the locale names are part of the
michael@0 157 directory structure, but not the file name itself ('long' paths,
michael@0 158 firefox 3.5+ style filenames)
michael@0 159 """
michael@0 160 try:
michael@0 161 # Mozilla 1.9.0 style (aka 'short') paths
michael@0 162 # e.g. firefox-3.0.12.en-US.win32.complete.mar
michael@0 163 filename = os.path.basename(filepath)
michael@0 164 m = re.match("^(%s)-([0-9.]+)\.([-a-zA-Z]+)\.(win32)\.(complete|installer)\.(mar|exe)$" % product, filename)
michael@0 165 if not m:
michael@0 166 raise ValueError("Could not parse: %s" % filename)
michael@0 167 return {'product': m.group(1),
michael@0 168 'version': m.group(2),
michael@0 169 'locale': m.group(3),
michael@0 170 'platform': m.group(4),
michael@0 171 'contents': m.group(5),
michael@0 172 'format': m.group(6),
michael@0 173 'pathstyle': 'short',
michael@0 174 'leading_path': '',
michael@0 175 }
michael@0 176 except:
michael@0 177 # Mozilla 1.9.1 and on style (aka 'long') paths
michael@0 178 # e.g. update/win32/en-US/firefox-3.5.1.complete.mar
michael@0 179 # win32/en-US/Firefox Setup 3.5.1.exe
michael@0 180 ret = {'pathstyle': 'long'}
michael@0 181 if filepath.endswith('.mar'):
michael@0 182 ret['format'] = 'mar'
michael@0 183 m = re.search("update/(win32|linux-i686|linux-x86_64|mac|mac64)/([-a-zA-Z]+)/(%s)-(\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?)\.(complete)\.mar" % product, filepath)
michael@0 184 if not m:
michael@0 185 raise ValueError("Could not parse: %s" % filepath)
michael@0 186 ret['platform'] = m.group(1)
michael@0 187 ret['locale'] = m.group(2)
michael@0 188 ret['product'] = m.group(3)
michael@0 189 ret['version'] = m.group(4)
michael@0 190 ret['contents'] = m.group(5)
michael@0 191 ret['leading_path'] = ''
michael@0 192 elif filepath.endswith('.exe'):
michael@0 193 ret['format'] = 'exe'
michael@0 194 ret['contents'] = 'installer'
michael@0 195 # EUballot builds use a different enough style of path than others
michael@0 196 # that we can't catch them in the same regexp
michael@0 197 if filepath.find('win32-EUballot') != -1:
michael@0 198 ret['platform'] = 'win32'
michael@0 199 m = re.search("(win32-EUballot/)([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+\d+)?(?:\ \w+\ \d+)?)\.exe" % product, filepath)
michael@0 200 if not m:
michael@0 201 raise ValueError("Could not parse: %s" % filepath)
michael@0 202 ret['leading_path'] = m.group(1)
michael@0 203 ret['locale'] = m.group(2)
michael@0 204 ret['product'] = m.group(3).lower()
michael@0 205 ret['version'] = m.group(4)
michael@0 206 else:
michael@0 207 m = re.search("(partner-repacks/[-a-zA-Z0-9_]+/|)(win32|mac|linux-i686)/([-a-zA-Z]+)/((?i)%s) Setup (\d+\.\d+(?:\.\d+)?(?:\w+(?:\d+)?)?(?:\ \w+\ \d+)?)\.exe" % product, filepath)
michael@0 208 if not m:
michael@0 209 raise ValueError("Could not parse: %s" % filepath)
michael@0 210 ret['leading_path'] = m.group(1)
michael@0 211 ret['platform'] = m.group(2)
michael@0 212 ret['locale'] = m.group(3)
michael@0 213 ret['product'] = m.group(4).lower()
michael@0 214 ret['version'] = m.group(5)
michael@0 215 else:
michael@0 216 raise ValueError("Unknown filetype for %s" % filepath)
michael@0 217
michael@0 218 return ret

mercurial