|
"""Generate binary installer for Mercurial or TortoiseHg
Usage: setup.py [OPTIONS]
Options:
-h --help Print this message and exit
--pull Pull from upstream, implied by stable and unstable targets
--nopull Disable pull for all targets
--config Show build configuration and exit
-f --force-hg Force the build-hg directory to be recloned
-F --force-thg Force the build-thg directory to be recloned
-c --clean Clean all build remnants
--thg-release Build a TortoiseHg release package
--thg-stable Build a TortoiseHg nightly stable package
--thg-unstable Build a TortoiseHg nightly unstable package
--thg-doc Only build TortoiseHg documentation in tortoisehg/
--hg-release Build a Mercurial release package
--hg-stable Build a Mercurial nightly stable package
--hg-unstable Build a Mercurial nightly unstable package
--all Build all four nightly targets
--cert <file> Sign output using the specified cert file (pfx)
--only-msi Only build new msi packages (implies nopull)
"""
#### Package Respins ####
# TortoiseHg 0.9.2-1 used mercurial.iss from changeset 275690997c5f
# TortoiseHg 1.1.1 used Mercurial revision 6f44bd4cc4f2, tag -l 1.6.1023
import os
import sys
import datetime
import subprocess
import fileinput
import getopt
import re
import shutil
import uuid
import urllib2
import getpass
import hashlib
from distutils.spawn import find_executable
installenv = os.environ
win7sdk = None
sdkenvs = {}
# default to TortoiseHg nightly stable build config
hgbranch = 'stable'
hgtag = 'tip'
thgbranch = 'stable'
thgtag = 'tip'
forcehg = False
forcethg = False
buildhg = False
builddoc = False
buildthg = False
dopull = None
showconfig = False
cert = None
all = False
onlymsi = False
sslcertfile = 'misc/cacert.pem'
URL = {
'hg' : 'http://selenic.com/repo/hg/',
'cacert.pem': 'http://curl.haxx.se/ca/cacert.pem',
'perfarce' : 'http://www.kingswood-consulting.co.uk/hg/perfarce/',
'thg' : 'https://bitbucket.org/tortoisehg/thg/',
'hgfold' : 'https://bitbucket.org/bradobro/hgfold/',
'zipdoc' : 'https://bitbucket.org/gobell/hg-zipdoc/',
'keyring' : 'https://bitbucket.org/kang/python-keyring-lib/',
'hgkeyring' : 'https://bitbucket.org/Mekk/mercurial_keyring/',
'dulwich' : 'https://bitbucket.org/abderrahim/dulwich/',
'iniparse' : 'https://bitbucket.org/sborho/iniparse/',
'hgcr-gui' : 'https://bitbucket.org/glimchb/hgcr-gui/',
}
extensions = [
'hgfold',
'perfarce',
'keyring',
'hgkeyring',
'dulwich',
'iniparse',
'zipdoc',
'hgcr-gui',
]
thg_source_repos = ['thg', 'hg'] + extensions
extfiles = {
'hgfold': ['hgfold/fold.py'],
'zipdoc': ['zipdoc/zipdoc.py'],
'perfarce': ['perfarce/perfarce.py'],
'hgkeyring': ['hgkeyring/mercurial_keyring.py'],
'hgcr-gui': ['hgcr-gui/hgcr-gui-qt.py'],
}
# Extensions which require PYTHONPATH insertion
path_extensions = ('dulwich', 'keyring', 'iniparse')
# Specify the exact revision to ship for given extension
extversions = {
'iniparse': 'bd83edee7300ce0a4fdddc3eddf743dc6ea98602', # 0.4
'dulwich' : 'ed3596b25fd1039b880c2f46cb38202a6289be95', # 0.8.0
}
# Extensions which require compiled C++ Python extensions
compiled_extensions = ('dulwich', 'keyring')
locales = ('cs', 'da', 'de', 'es', 'fr', 'it', 'ja', 'pt', 'pt_BR',
'ru', 'uk', 'zh_CN')
import platform
if platform.architecture()[0] == '64bit':
arch = 'x64'
else:
arch = 'x86'
def run(cmd, cwd='.', hide=False, env=installenv):
if not hide:
print cwd + "> " + cmd
try:
subprocess.check_call(cmd, shell=True, cwd=cwd, env=env)
except subprocess.CalledProcessError:
if hide:
raise StandardError("subprocess.CalledProcessError was raised")
else:
raise
def run_python(cmd, cwd='.', hide=False, env=installenv):
cmd = ' '.join([sys.executable, cmd])
run(cmd, cwd, hide, env)
sdkenv_vars = ('include', 'lib', 'mssdk', 'path', 'regkeypath', 'sdksetupdir',
'sdktools', 'targetos', 'vcinstalldir', 'vcroot', 'vsregkeypath')
def get_pruned_env(arch):
# Remove folders from %PATH% that contain QtCore4.dll, unless it is the
# PyQt4\bin folder for the executing Python environment
prefix = sys.exec_prefix.lower() + os.sep
deletions = []
fenv = get_sdkenv(arch).copy()
path = fenv.get('PATH', '').split(os.pathsep)
for dir in path:
if dir.lower().startswith(prefix):
continue
if os.path.exists(os.path.join(dir, 'QtCore4.dll')):
deletions.append(dir)
for dir in deletions:
print 'removing', dir, 'from PATH'
path.remove(dir)
fenv['PATH'] = os.pathsep.join(path)
return fenv
def get_sdkenv(arch):
if arch in sdkenvs:
return sdkenvs[arch]
p = subprocess.Popen(r'cmd /e:on /v:on /c call "%s\Bin\SetEnv.cmd" /xp /%s /release && set' %
(win7sdk, arch),
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = p.communicate()
newenv = {}
for line in out.splitlines():
if '=' in line:
k, v = line.split('=', 1)
if k.lower() in sdkenv_vars:
newenv[k.upper()] = v
env = installenv.copy()
env.update(newenv)
sdkenvs[arch] = env
return env
def lasttag(reponame, branch):
"return latest tag that lives on specified branch"
cmd = ('hg', '--repository', reponame, 'log',
'--rev', 'tagged() and branch(%s)' % branch,
'--template={tags}$')
p = subprocess.Popen(cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=False)
stdout_text, stderr_text = p.communicate('')
# use -2 to ignore trailing blank output
return stdout_text.split('$')[-2]
def repoversion(verfile):
globals = {}
execfile(verfile, globals)
return globals.get('version', 'unknown')
def windowsversion(name, version):
extra = None
if '+' in version:
version, extra = version.split('+', 1)
v = [int(x) for x in version.split('.')]
while len(v) < 3:
v.append(0)
major, minor, periodic = v[:3]
if extra != None:
tagdistance = int(extra.split('-', 1)[0])
periodic *= 1000
if 'unstable' in name:
periodic += tagdistance + 500
else:
periodic += tagdistance + 100
return [str(x) for x in (major, minor, periodic)]
def pipetofile(cmdlist, outfile, cwd):
print '> ', ' '.join(cmdlist), '>', outfile
p = subprocess.Popen( cmdlist,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=False,
cwd=cwd)
out, err = p.communicate('')
fp = open(outfile, 'wb')
fp.write(out)
fp.close
def candle(file, sourcedir=None, cwd='.', defines=None):
args = []
if sourcedir:
args.append('-dSourceDir="%s"' % sourcedir)
if defines:
args += ['-d%s="%s"' % item for item in defines]
run(r'candle -nologo "%s" %s' % (file, ' '.join(args)), cwd)
def light(output, cwd, *files):
run(r'light -nologo -ext WixUIExtension -sw1076 -spdb -o %s %s' %
(output, ' '.join(f + '.wixobj' for f in files)), cwd)
def generate_hgext_index(branch):
"""Generate list of extensions under hgext/"""
run(r'del build-hg\hgext\__index__.*')
run_python(r'setup.py build_hgextindex', 'build-hg')
def build_hg(force, branch, tag, arch):
if onlymsi:
return
if force or not os.path.exists('build-hg'):
run(r'if exist build-hg rmdir /s /q build-hg')
run(r'hg clone file:../hg -u %s file:build-hg' % branch)
else:
run(r'hg -R build-hg pull')
run(r'hg -R build-hg update ' + branch)
if tag == 'tip':
run(r'hg -R build-hg update')
else:
run(r'hg -R build-hg update ' + tag)
# Clear files added by previous installer runs
run(r'hg -R build-hg --config extensions.purge= purge --all')
run(r'copy misc\setup.cfg build-hg')
run_python(r'setup.py --version', 'build-hg')
run_python(r'setup.py build_py -c -d . build_mo', 'build-hg')
run_python(r'setup.py build_ext -i', 'build-hg', env=get_sdkenv(arch))
generate_hgext_index(branch)
# Build man pages
pipetofile((sys.executable, 'gendoc.py'),
'build-hg/doc/hg.1.gendoc.txt',
'build-hg/doc')
cmd = 'runrst html'
cmdtemplate = r'%s --link-stylesheet --stylesheet-path style.css %s %s'
manfiles = ('hg.1.txt', 'hgignore.5.txt', 'hgrc.5.txt')
for man in manfiles:
outfile = man[:-3] + 'html'
run_python(cmdtemplate % (cmd, man, outfile), 'build-hg/doc')
pwd = None
if '--cert' in sys.argv:
# Seed the password at startup
pwd = getpass.getpass('password for signing: ')
def sign(file, desc, cwd):
global pwd
while True:
try:
if not pwd:
pwd = getpass.getpass('password for signing: ')
run(r'..\misc\sign.cmd %s %s %s "%s"' % (cert, pwd, file, desc),
cwd, hide=True)
return
except StandardError:
pwd = None
def build_hg_installer(name, arch):
version = repoversion('build-hg/mercurial/__version__.py')
comments = 'Installs Mercurial version %s' % version
version = '.'.join(windowsversion(name, version))
if not onlymsi:
run_python(r'setup.py py2exe -b3', 'build-hg', env=get_sdkenv(arch))
if cert is not None:
print "signing using cert '%s'" % (cert,)
desc = '%s %s' % (name, version)
sign(r'dist\hg.exe', desc, 'build-hg')
package = r'..\..\output\%s-%s-%s.msi' % (name, version, arch)
wixobj = [
(r'..\build-hg\contrib\wix\help.wxs', r'..\build-hg\mercurial\help'),
(r'..\build-hg\contrib\wix\templates.wxs', r'..\build-hg\mercurial\templates'),
(r'..\build-hg\contrib\wix\locale.wxs', r'..\build-hg\mercurial\locale'),
(r'..\build-hg\contrib\wix\i18n.wxs', r'..\build-hg\i18n'),
(r'..\build-hg\contrib\wix\doc.wxs', r'..\build-hg\doc'),
(r'..\build-hg\contrib\wix\dist.wxs', r'..\build-hg\dist'),
(r'..\build-hg\contrib\wix\contrib.wxs', r'..\build-hg\contrib')]
for file, sourcedir in wixobj:
candle(file, sourcedir=sourcedir, cwd='build-hg', defines=[('Platform', arch)])
candle(r'..\build-hg\contrib\wix\mercurial.wxs', cwd='build-hg', defines=[
('Platform', arch),
('Version', version),
('Comments', comments),
('VCRedistSrcDir', win7sdk + r'\Redist\VC')])
light(package, 'build-hg', 'help', 'templates', 'locale', 'i18n', 'doc',
'contrib', 'dist', 'mercurial')
if cert is not None:
print "signing using cert '%s'" % (cert,)
desc = '%s %s' % (name, version)
sign(package, desc, 'build-hg')
def build_thg(force, branch, tag, name, productid, arch):
if onlymsi:
return
if force or not os.path.exists('build-thg'):
run(r'if exist build-thg rmdir /s /q build-thg')
run(r'hg clone file:../thg -u %s file:build-thg' % branch)
else:
run(r'hg pull ../../thg', 'build-thg')
run(r'hg update ' + branch, 'build-thg')
if tag == 'tip':
run(r'hg update', 'build-thg')
else:
run(r'hg update ' + tag, 'build-thg')
# Clear files added by previous installer runs
run(r'hg -R build-thg --config extensions.purge= purge --all')
run_python(r'setup.py --version', 'build-thg')
# Build locales
run_python(r'setup.py build_mo', 'build-thg')
# Build cmenu translation registry files
run_python(r'reggen.py', 'build-thg/win32')
# Use build helpers from win32
run(r'copy win32\config.py tortoisehg\util', 'build-thg')
run(r'copy win32\setup.cfg .', 'build-thg')
# Copy bundled Mercurial extensions into build-hg/hgext
for ext in extensions:
for loc in extfiles.get(ext, []):
loc = '../' + loc
if os.path.exists(loc):
shutil.copy(loc, 'build-hg/hgext')
if ext == 'hgcr-gui':
shutil.copy('../hgcr-gui/hgcr.ui', 'build-thg/tortoisehg/hgqt')
generate_hgext_index(branch)
# Build docs
run(r'build chm', 'build-thg/doc')
run(r'build pdf', 'build-thg/doc')
# compile all Mercurial extensions that have C++ Python extensions
for ext in extensions:
if ext in compiled_extensions:
ext = '../' + ext
run(r'hg --config extensions.purge= purge --all', ext)
run_python(r'setup.py build_ext -i', ext, env=get_sdkenv(arch))
# Build x64 and x86 shell extensions
hgversion = repoversion('build-hg/mercurial/__version__.py')
hgperiodic = windowsversion(name, hgversion)[2]
thgversion = repoversion('build-thg/tortoisehg/util/__version__.py')
v = windowsversion(name, thgversion)
if 'stable' in name:
v.append(hgperiodic)
thgversion = '.'.join(v)
a, b, c, d = v
else:
thgversion = '.'.join(v)
a, b, c = v
def compile_shell_ext(arch):
print '*************** %s ******************' % arch
env = get_sdkenv(arch).copy()
env['DEBUG'] = '1'
env['THG_PLATFORM'] = arch
env['THG_EXTRA_CPPFLAGS'] = '/DTHG_PRODUCT_ID=%s' % productid
env['THG_EXTRA_RCFLAGS'] = (
'/dTHG_VERSION_FIRST=%s /dTHG_VERSION_SECOND=%s /dTHG_VERSION_THIRD=%s /dTHG_PRODUCT_ID="%s"' %
(a, b, c, productid))
targetdir = r'build-thg\win32'
builddir = targetdir + r'\shellext'
run('nmake.exe /nologo /f Makefile.nmake clean', builddir, env=env)
run('nmake.exe /nologo /f Makefile.nmake', builddir, env=env)
for file in ('ThgShell%s.dll', 'terminate-%s.exe', 'terminate-%s.dll'):
f = file % arch
try:
shutil.copy(builddir + '\\' + f, targetdir)
except IOError:
print "warning: skipped copying nonexistent '%s'" % f
pass
if cert is not None:
print "signing using cert '%s'" % (cert,)
package = r'win32\ThgShell%s.dll' % arch
desc = "%s %s %s shell extension" % (name, arch, thgversion)
sign(package, desc, 'build-thg')
if arch == 'x86':
compile_shell_ext(arch)
else:
compile_shell_ext('x86')
compile_shell_ext('x64')
def build_thg_docs():
run(r'build clean', r'thg\doc')
run(r'build chm', r'thg\doc')
run(r'build pdf', r'thg\doc')
def build_thg_installer(name, productid, arch):
if not onlymsi:
run(r'if exist dist rmdir /s /q dist', 'build-thg')
run_python(r'setup.py py2exe -b3', 'build-thg', env=get_pruned_env(arch))
path = os.path.join(sys.exec_prefix, 'lib', 'site-packages', 'PyQt4')
binpath = os.path.join(path, 'bin')
if os.path.exists(binpath):
path = binpath
for f in ('qscintilla2.dll', 'QtSvg4.dll', 'QtXml4.dll'):
p = os.path.join(path, f)
run(r'copy %s dist' % p, r'build-thg')
hgversion = repoversion('build-hg/mercurial/__version__.py')
hgperiodic = windowsversion(name, hgversion)[2]
longthgversion = repoversion('build-thg/tortoisehg/util/__version__.py')
v = windowsversion(name, longthgversion)
if 'stable' in name:
v.append(hgperiodic)
thgversion = '.'.join(v)
if not onlymsi and cert is not None:
print "signing using cert '%s'" % (cert,)
desc = 'TortoiseHg %s' % thgversion
for exe in ('hg', 'thg', 'thgw', 'TortoiseHgOverlayServer'):
package = r'dist\%s.exe' % exe
if os.path.exists('build-thg\\' + package):
sign(package, desc, 'build-thg')
wixobj = [
(r'..\misc\diff-scripts.wxs', r'..\contrib\diff-scripts'),
(r'win32\wix\dist.wxs', r'dist'),
(r'win32\wix\icons.wxs', r'dist/icons'),
(r'win32\wix\thg-locale.wxs', r'locale'),
(r'win32\wix\thg-i18n.wxs', r'i18n'),
(r'win32\wix\cmenu-i18n.wxs', r'win32'),
(r'win32\wix\help.wxs', r'..\build-hg\mercurial\help'),
(r'win32\wix\templates.wxs', r'..\build-hg\mercurial\templates'),
(r'win32\wix\locale.wxs', r'..\build-hg\mercurial\locale'),
(r'win32\wix\i18n.wxs', r'..\build-hg\i18n'),
(r'win32\wix\doc.wxs', r'..\build-hg\doc'),
(r'win32\wix\contrib.wxs', r'..\build-hg\contrib')]
defs = [('Platform', arch)]
for file, sourcedir in wixobj:
candle(file, sourcedir=sourcedir, cwd='build-thg', defines=defs)
package = r"..\..\output\%s-%s" % (name, thgversion)
commentsfmt = 'Installs TortoiseHg %s, Mercurial %s on %s'
comments = commentsfmt % (longthgversion, hgversion, arch)
productid = productid.lower()
defines = [('Version', thgversion),
('ProductId', productid),
('Platform', arch),
('Comments', comments),
('VCRedistSrcDir', win7sdk + r'\Redist\VC')]
candle(r'win32\wix\tortoisehg.wxs', cwd='build-thg', defines=defines)
m = hashlib.sha1()
m.update(comments)
m.update(productid)
msifile = '%s-%s-%s.msi' % (package, arch, m.hexdigest()[:12])
light(msifile, 'build-thg', 'help', 'templates', 'locale', 'i18n',
'doc', 'contrib', 'diff-scripts', 'icons', 'thg-locale',
'dist', 'thg-i18n', 'cmenu-i18n', 'tortoisehg')
if cert is not None:
print "signing using cert '%s'" % (cert,)
desc = '%s %s %s' % (name, arch, thgversion)
sign(msifile, desc, 'build-thg')
def try_paths(paths):
for env in ('ProgramFiles', 'ProgramFiles(x86)', 'ProgramW6432'):
if env not in installenv: continue
prefix = installenv[env]
for file in paths:
candidate = prefix + file
if os.path.exists(candidate):
return candidate
else:
return None
def verify_hg_env():
global installenv
global win7sdk
win7sdk = try_paths([r'\Microsoft SDKs\Windows\v7.0\Bin'])
if not win7sdk:
print 'Unable to find Microsoft Windows SDK 7.0, please install'
sys.exit(1)
win7sdk = win7sdk[:-4]
try:
from mercurial import hg, ui, util
except ImportError:
print 'Mercurial must be installed as Python source.'
print 'You can get this from http://bitbucket.org/tortoisehg/thg-winbuild/downloads/'
print 'Look for a package like: mercurial-1.6.2.win32-py2.6.exe\n'
print 'Or simply build it yourself.'
sys.exit(1)
try:
import py2exe
except ImportError:
print 'Unable to find py2exe'
print 'http://sourceforge.net/projects/py2exe/'
sys.exit(1)
try:
import win32api
except ImportError:
print 'Unable to find pywin32'
print 'http://sourceforge.net/projects/pywin32/'
sys.exit(1)
path = installenv.get('PATH', '').split(os.pathsep)
scrpath = sys.exec_prefix + os.sep + 'Scripts'
path.append(scrpath)
if not os.path.exists(os.path.join(scrpath, 'rst2html.py')):
print 'Unable to find rst2html'
print 'easy_install docutils'
sys.exit(1)
msgfmt = find_executable('msgfmt')
if not msgfmt:
found = try_paths([r'\GnuWin32\bin\msgfmt.exe'])
if found:
path.append(os.path.dirname(found))
else:
if os.path.exists(r'\MinGW\bin\msgfmt.exe'):
path.append(r'\MinGW\bin')
else:
print 'Unable to find msgfmt. Please download from'
print 'http://gnuwin32.sourceforge.net/packages/gettext.htm'
sys.exit(1)
if 'WIX' in installenv:
path.append(installenv['WIX'] + 'bin')
else:
print 'Unable to find WIX. Please download from'
print 'http://sourceforge.net/projects/wix/files/'
sys.exit(1)
installenv['HGPLAIN'] = '1'
installenv['PATH'] = os.pathsep.join(path)
installenv['DISTUTILS_USE_SDK'] = '1'
installenv['hhc_compiler'] = 'hhc.exe'
def verify_doc_env():
global installenv
try:
from mercurial import hg, ui, util
except ImportError:
print 'Mercurial must be installed as Python source.'
print 'You can get this from http://bitbucket.org/tortoisehg/thg-winbuild/downloads/'
print 'Look for a package like: mercurial-1.6.2.win32-py2.6.exe\n'
print 'Or simply build it yourself.'
sys.exit(1)
path = installenv.get('PATH', '').split(os.pathsep)
scrpath = os.path.dirname(sys.executable) + os.sep + 'Scripts'
path.append(scrpath)
# Find HTML Help compiler, add to path
hhc = find_executable('hhc')
if not hhc:
found = try_paths([r'\HTML Help Workshop\hhc.exe'])
if found:
path.append(os.path.dirname(found))
else:
print 'Unable to find HTML Help Workshop'
print 'http://go.microsoft.com/fwlink/?LinkId=14188'
sys.exit(1)
# Find MiKTex, add to path
pdflatex = find_executable('pdflatex')
if not pdflatex:
found = try_paths([r'\MiKTeX 2.7\miktex\bin\Pdflatex.exe',
r'\MiKTeX 2.8\miktex\bin\Pdflatex.exe'])
if found:
path.append(os.path.dirname(found))
else:
print 'Unable to find MiKTeX'
print 'http://miktex.org/2.8/setup'
sys.exit(1)
# Verify sphinx
if not os.path.exists(os.path.join(scrpath, 'sphinx-build.exe')):
print 'Unable to find sphinx'
print 'easy_install sphinx'
sys.exit(1)
installenv['PATH'] = os.pathsep.join(path)
def verify_thg_env():
global installenv
try:
from mercurial import hg, ui, util
except ImportError:
print 'Mercurial must be installed as Python source.'
print 'You can get this from http://bitbucket.org/tortoisehg/thg-winbuild/downloads/'
print 'Look for a package like: mercurial-1.6.2.win32-py2.6.exe\n'
print 'Or simply build it yourself.'
sys.exit(1)
try:
import comtypes
except ImportError:
print 'comtypes not found'
print 'download and install comtypes-0.6.2.win32.exe from'
print 'http://sourceforge.net/projects/comtypes/files/'
sys.exit(1)
try:
from svn import core
except ImportError:
print 'svn bindings not found'
print 'See README for download location and install instructions'
sys.exit(1)
oldpath = os.environ.get('PYTHONPATH', '').split(os.pathsep)
path = ['../build-hg']
for ext in extensions:
if ext in path_extensions:
path.append('../../' + ext)
path.extend(oldpath)
installenv['PYTHONPATH'] = os.pathsep.join(path)
def usage(code, msg=''):
print >> sys.stderr, __doc__
if msg:
print >> sys.stderr, msg
sys.exit(code)
if len(sys.argv) < 2:
usage(0)
try:
opts, args = getopt.getopt(sys.argv[1:], 'hcfF',
['clean', 'forcehg', 'forcethg',
'thg-release', 'thg-stable', 'thg-unstable', 'thg-doc',
'hg-release', 'hg-stable', 'hg-unstable',
'pull', 'nopull', 'config', 'all', 'cert=', 'only-msi'])
except getopt.error, msg:
usage(1, msg)
# parse options (first pass)
for opt, arg in opts:
if opt == '--cert':
cert = os.path.abspath(arg)
# parse options (second pass)
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-f', '--force-hg'):
forcehg = True
elif opt in ('-F', '--force-thg'):
forcethg = True
elif opt in ('-c', '--clean'):
run(r'if exist build-hg rmdir /s /q build-hg')
run(r'if exist build-thg rmdir /s /q build-thg')
if os.path.exists(sslcertfile):
os.unlink(sslcertfile)
sys.exit(0)
elif opt == '--thg-doc':
builddoc = True
elif opt == '--thg-release':
if dopull is None:
dopull = True
buildthg = True
thgbranch = 'stable'
thgtag = lasttag('thg', 'stable')
hgbranch = 'stable'
hgtag = lasttag('hg', 'stable')
packagename = 'tortoisehg'
elif opt == '--thg-stable':
if dopull is None:
dopull = True
buildthg = True
thgbranch = 'stable'
thgtag = 'tip'
hgbranch = 'stable'
hgtag = 'tip'
packagename = 'tortoisehg-stable'
elif opt == '--thg-unstable':
if dopull is None:
dopull = True
buildthg = True
thgbranch = 'default'
thgtag = 'tip'
hgbranch = 'default'
hgtag = 'tip'
packagename = 'tortoisehg-unstable'
elif opt == '--hg-release':
buildhg = True
hgbranch = 'stable'
hgtag = lasttag('hg', 'stable')
packagename = 'mercurial'
elif opt == '--hg-stable':
if dopull is None:
dopull = True
buildhg = True
hgbranch = 'stable'
hgtag = 'tip'
packagename = 'mercurial-stable'
elif opt == '--hg-unstable':
if dopull is None:
dopull = True
buildhg = True
hgbranch = 'default'
hgtag = 'tip'
packagename = 'mercurial-unstable'
elif opt == '--pull':
dopull = True
elif opt == '--nopull':
dopull = False
elif opt == '--config':
showconfig = True
elif opt == '--only-msi':
onlymsi = True
elif opt == '--all':
all = True
onlymsi = False
if dopull is None:
dopull = True
print 'Build config:'
print '[tortoisehg] branch=%s, tag=%s' % (thgbranch, thgtag)
print '[mercurial] branch=%s, tag=%s\n' % (hgbranch, hgtag)
if showconfig:
sys.exit(0)
if not os.path.exists(sslcertfile) or all:
print 'fetching cacert.pem from', URL['cacert.pem']
contents = urllib2.urlopen(URL['cacert.pem']).read()
file(sslcertfile, 'wb').write(contents)
if dopull and not onlymsi:
run(r'hg -R ../hg pull')
if buildthg or all:
run(r'hg -R ../thg pull')
from mercurial import ui, hg
out = 'extension-versions.txt'
f = open(out, 'w')
f.write('Extensions/modules included in this TortoiseHg package:\n\n')
for ext in extensions:
run(r'hg -R ../%s pull' % ext)
if ext in extversions:
run(r'hg update -R ../%s %s' % (ext, extversions[ext]))
else:
run(r'hg update -R ../' + ext)
repo = hg.repository(ui.ui(), path='../'+ext)
f.write('%12s:\t%s\t%s\n' % (ext, str(repo['.']), URL[ext]))
try:
from svn import core
ver = '%d.%d.%d' % (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_MICRO)
url = 'http://bitbucket.org/tortoisehg/thg/downloads'
f.write('%12s:\t%-12s\t%s\n' % ('python-svn', ver, url))
except ImportError:
pass
try:
import pygments
ver = pygments.__version__
url = 'http://pygments.org/download/'
f.write('%12s:\t%-12s\t%s\n' % ('pygments', ver, url))
except ImportError:
pass
pywin32file = sys.prefix + r'\lib\site-packages\pywin32.version.txt'
if os.path.exists(pywin32file):
ver = open(pywin32file, 'r').read().strip()
url = 'http://sourceforge.net/projects/pywin32/'
f.write('%12s:\t%-12s\t%s\n' % ('pywin32', ver, url))
f.close()
if all:
verify_hg_env()
verify_doc_env()
verify_thg_env()
run(r'title Building hg-stable...')
build_hg(True, 'stable', 'tip', arch)
build_hg_installer('mercurial-stable', arch)
run(r'title Building hg-unstable...')
build_hg(False, 'default', 'tip', arch)
build_hg_installer('mercurial-unstable', arch)
run(r'title Building thg-stable...')
productid = str(uuid.uuid4()).upper()
build_hg(False, 'stable', 'tip', arch)
build_thg(True, 'stable', 'tip', 'tortoisehg-stable', productid, arch)
build_thg_installer('tortoisehg-stable', productid, arch)
run(r'title Building thg-unstable...')
productid = str(uuid.uuid4()).upper()
build_hg(False, 'default', 'tip', arch)
build_thg(True, 'default', 'tip', 'tortoisehg-unstable', productid, arch)
build_thg_installer('tortoisehg-unstable', productid, arch)
elif builddoc:
verify_doc_env()
build_thg_docs()
elif buildhg:
verify_hg_env()
build_hg(forcehg, hgbranch, hgtag, arch)
build_hg_installer(packagename, arch)
elif buildthg:
verify_hg_env()
verify_doc_env()
verify_thg_env()
build_hg(forcehg, hgbranch, hgtag, arch)
productid = str(uuid.uuid4()).upper()
build_thg(forcethg, thgbranch, thgtag, packagename, productid, arch)
build_thg_installer(packagename, productid, arch)
|
Loading...