Commit c7a74351 authored by Steve Borho's avatar Steve Borho
Browse files

switch setup.py from getopt to argparse

There are a few command line behavior changes.

* The build targets no longer use -- prefixes, aka:
   setup.py thg-release [OPTIONS]
* --all has been removed, I don't believe worked anymore
* --pull is now the default, and is implied
* Unless --nopull is specified, repos are pulled before detecting latest tags
parent 5c26358f8e35
"""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 dev 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 <tag> Build a TortoiseHg release package
--thg-stable Build a TortoiseHg nightly stable package
--thg-dev Build a TortoiseHg nightly dev package
--thg-doc Only build TortoiseHg documentation in tortoisehg/
--hg-release <tag> Build a Mercurial release package
--hg-stable Build a Mercurial nightly stable package
--hg-dev Build a Mercurial nightly dev package
--all Build all four nightly targets
--cert <file> Sign output using the specified cert file (pfx)
--certpwd <pwd> Password used to open the cert file (does not work witn certsn)
--certsn <name> Sign output using a certificate having this SubjectName
--only-msi Only build new msi packages (implies nopull)
--update Update parent repos to the built revisions
"""
"""Generate binary installer for Mercurial or TortoiseHg"""
#### Package Respins ####
# TortoiseHg 0.9.2-1 used mercurial.iss from changeset 275690997c5f
......@@ -34,15 +9,46 @@ Options:
import os
import sys
import subprocess
import getopt
import argparse
p = argparse.ArgumentParser()
p.add_argument('--nopull', action='store_true',
help='do not pull upstream repositories')
p.add_argument('--update', action='store_true',
help='Update parent repos to the built revisions')
p.add_argument('--only-msi', action='store_true',
help='Only build new msi packages (implies nopull)')
p.add_argument('--config', action='store_true',
help='Show build configuration and exit')
p.add_argument('--clean', '-c', action='store_true',
help='Clean all build remnants and exit')
p.add_argument('--force-hg', '-f', action='store_true',
help='Force the build/hg directory to be recloned')
p.add_argument('--force-thg', '-F', action='store_true',
help='Force the build/thg directory to be recloned')
p.add_argument('--cert', default=None,
help='Sign output using the specified cert file (pfx)')
p.add_argument('--certpwd', default=None,
help='Password used to open the cert file')
p.add_argument('--certpsn', default=None,
help='Sign output using a certificate having this SubjectName')
p.add_argument('--thgtag', default=None,
help='Specify the TortoiseHg tag to build')
p.add_argument('--hgtag', default=None,
help='Specify the Mercurial tag to build')
p.add_argument('target', choices=('thg-release', 'thg-stable', 'thg-dev',
'thg-doc', 'hg-release', 'hg-stable',
'hg-dev'), nargs='?',
help='Specify the target package to be built')
args = p.parse_args(sys.argv[1:])
import shutil
import uuid
import getpass
import hashlib
import subprocess
from distutils.spawn import find_executable
import distutils.sysconfig
def set_syspath():
......@@ -81,24 +87,6 @@ installenv = get_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
certsn = None
all = False
onlymsi = False
doupdate = False
URL = {
'hg' : 'https://www.mercurial-scm.org/repo/hg/',
'thg' : 'https://bitbucket.org/tortoisehg/thg/',
......@@ -178,31 +166,25 @@ if platform.architecture()[0] == '64bit':
else:
arch = 'x86'
pwd = None
if '--cert' in sys.argv and '--certpwd' not 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: ')
if not args.certpwd:
args.certpwd = getpass.getpass('password for signing: ')
miscabspath = os.path.abspath('misc')
run(r'%s\sign.cmd %s %s %s "%s"' % (miscabspath, cert, pwd, file, desc),
run(r'%s\sign.cmd %s %s %s "%s"' % (miscabspath, args.cert,
args.certpwd, file, desc),
cwd, hide=True)
return
except StandardError:
if '--certpwd' in sys.argv:
if args.certpwd:
raise
pwd = None
args.certpwd = None
def signsn(file, desc, cwd):
miscabspath = os.path.abspath('misc')
run(r'%s\signsn.cmd "%s" "%s" "%s"' % (miscabspath, certsn, file, desc),
run(r'%s\signsn.cmd "%s" "%s" "%s"' % (miscabspath, args.certsn, file, desc),
cwd, hide=True)
......@@ -338,7 +320,7 @@ def generate_hgext_index(branch):
run_python(r'setup.py build_hgextindex', 'build/hg')
def build_hg(force, branch, tag, arch):
if onlymsi:
if args.only_msi:
return
if force or not os.path.exists('build/hg'):
......@@ -348,7 +330,7 @@ def build_hg(force, branch, tag, arch):
else:
run(r'hg -R build/hg pull')
run(r'hg -R build/hg update ' + branch)
if tag == 'tip':
if tag is None:
run(r'hg -R build/hg update')
else:
run(r'hg -R build/hg update ' + tag)
......@@ -381,14 +363,14 @@ 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:
if not args.only_msi:
run_python(r'setup.py py2exe -b3', 'build/hg', env=get_sdkenv(arch))
if cert is not None:
print "signing using cert '%s'" % (cert,)
if args.cert is not None:
print "signing using cert '%s'" % (args.cert,)
desc = '%s %s' % (name, version)
sign(r'dist\hg.exe', desc, 'build/hg')
elif certsn is not None:
print "signing using cert '%s'" % (certsn,)
elif args.certsn is not None:
print "signing using cert '%s'" % (args.certsn,)
desc = '%s %s' % (name, version)
signsn(r'dist\hg.exe', desc, 'build/hg')
package = r'..\..\output\%s-%s-%s.msi' % (name, version, arch)
......@@ -407,15 +389,15 @@ def build_hg_installer(name, arch):
('Version', version),
('Comments', comments),
('VCRedistSrcDir', win7sdk + r'\Redist\VC')])
light(package, 'build', 'hg/help', 'hg/templates', 'hg/locale', 'hg/i18n', 'hg/doc',
'hg/contrib', 'hg/dist', 'hg/mercurial')
if cert is not None:
print "signing using cert '%s'" % (cert,)
if args.cert is not None:
print "signing using cert '%s'" % (args.cert,)
desc = '%s %s' % (name, version)
sign(package, desc, 'build')
elif certsn is not None:
print "signing using cert '%s'" % (certsn,)
elif args.certsn is not None:
print "signing using cert '%s'" % (args.certsn,)
desc = '%s %s' % (name, version)
signsn(package, desc, 'build')
......@@ -425,7 +407,7 @@ def build_hg_installer(name, arch):
run(r'copy dist\*.msi ..\..\..\output', 'build/hg')
def build_thg(force, branch, tag, name, productid, arch):
if onlymsi:
if args.only_msi:
return
if force or not os.path.exists('build/thg'):
......@@ -435,7 +417,7 @@ def build_thg(force, branch, tag, name, productid, arch):
else:
run(r'hg pull ../../../thg', 'build/thg')
run(r'hg update ' + branch, 'build/thg')
if tag == 'tip':
if tag is None:
run(r'hg update', 'build/thg')
else:
run(r'hg update ' + tag, 'build/thg')
......@@ -484,8 +466,9 @@ def build_thg(force, branch, tag, name, productid, arch):
run(r'hg --config extensions.purge= purge --all', ext)
run_python(r'setup.py build_ext -i', ext, env=get_sdkenv(arch))
def build_shellext(force, branch, tag, name, productid, arch):
if onlymsi:
if args.only_msi:
return
if force or not os.path.exists('build/shellext'):
......@@ -494,7 +477,7 @@ def build_shellext(force, branch, tag, name, productid, arch):
else:
run(r'hg pull ../../../shellext', 'build/shellext')
run(r'hg update ' + branch, 'build/shellext')
if tag == 'tip':
if tag is None:
run(r'hg update', 'build/shellext')
else:
run(r'hg update ' + tag, 'build/shellext')
......@@ -528,13 +511,13 @@ def build_shellext(force, branch, tag, name, productid, arch):
run('nmake.exe /nologo /f Makefile.nmake clean', builddir, env=env)
run('nmake.exe /nologo /f Makefile.nmake', builddir, env=env)
if cert is not None:
print "signing using cert '%s'" % (cert,)
if args.cert is not None:
print "signing using cert '%s'" % (args.cert,)
package = r'src\ThgShell%s.dll' % arch
desc = "%s %s %s shell extension" % (name, arch, thgversion)
sign(package, desc, 'build/shellext')
elif certsn is not None:
print "signing using cert '%s'" % (certsn,)
elif args.certsn is not None:
print "signing using cert '%s'" % (args.certsn,)
package = r'src\ThgShell%s.dll' % arch
desc = "%s %s %s shell extension" % (name, arch, thgversion)
signsn(package, desc, 'build/shellext')
......@@ -552,7 +535,7 @@ def build_thg_docs():
def build_thg_installer(name, productid, arch):
if not onlymsi:
if not args.only_msi:
env = get_pruned_env(arch)
env['MERCURIAL_PATH'] = '../hg/mercurial'
env['HGEXT_PATH'] = '../hg/hgext'
......@@ -585,14 +568,14 @@ def build_thg_installer(name, productid, arch):
v.append(hgperiodic)
thgversion = '.'.join(v)
if not onlymsi:
if not args.only_msi:
signfunc = None
if cert is not None:
print "signing using cert '%s'" % (cert,)
if args.cert is not None:
print "signing using cert '%s'" % (args.cert,)
desc = 'TortoiseHg %s' % thgversion
signfunc = sign
elif certsn is not None:
print "signing using cert '%s'" % (certsn,)
elif args.certsn is not None:
print "signing using cert '%s'" % (args.certsn,)
desc = 'TortoiseHg %s' % thgversion
signfunc = signsn
if signfunc is not None:
......@@ -643,12 +626,12 @@ def build_thg_installer(name, productid, arch):
'thg/i18n', 'thg/doc', 'thg/contrib', 'thg/diff-scripts',
'thg/icons', 'thg/thg-locale', 'thg/dist',
'thg/cmenu-i18n', 'thg/thgshell', 'thg/tortoisehg')
if cert is not None:
print "signing using cert '%s'" % (cert,)
if args.cert is not None:
print "signing using cert '%s'" % (args.cert,)
desc = '%s %s %s' % (name, arch, thgversion)
sign(msifile, desc, 'build')
elif certsn is not None:
print "signing using cert '%s'" % (certsn,)
elif args.certsn is not None:
print "signing using cert '%s'" % (args.certsn,)
desc = '%s %s %s' % (name, arch, thgversion)
signsn(msifile, desc, 'build')
......@@ -822,172 +805,98 @@ def verify_thg_env():
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-dev', 'thg-doc',
'hg-release=', 'hg-stable', 'hg-dev', 'pull', 'nopull', 'config',
'all', 'cert=', 'certpwd=', 'certsn=', 'only-msi', 'update'])
except getopt.error, msg:
usage(1, msg)
# parse options (first pass)
for opt, arg in opts:
if opt == '--cert':
cert = arg
elif opt == '--certpwd':
pwd = arg
elif opt == '--certsn':
certsn = 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 rmdir /s /q build')
sys.exit(0)
elif opt == '--thg-doc':
builddoc = True
elif opt == '--thg-release':
if dopull is None:
dopull = True
buildthg = True
thgbranch = 'stable'
thgtag = arg
if not thgtag:
thgtag = lasttag('thg', 'stable')
hgbranch = 'stable'
hgtag = lasttag('hg', 'stable', maxtag=thgtag)
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-dev':
if dopull is None:
dopull = True
buildthg = True
thgbranch = 'default'
thgtag = 'tip'
hgbranch = 'default'
hgtag = 'tip'
packagename = 'tortoisehg-dev'
elif opt == '--hg-release':
buildhg = True
hgbranch = 'stable'
hgtag = arg
if not hgtag:
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-dev':
if dopull is None:
dopull = True
buildhg = True
hgbranch = 'default'
hgtag = 'tip'
packagename = 'mercurial-dev'
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
elif opt == '--update':
doupdate = True
print 'Build config:'
print '[tortoisehg] branch=%s, tag=%s' % (thgbranch, thgtag)
print '[mercurial] branch=%s, tag=%s\n' % (hgbranch, hgtag)
if showconfig:
if args.clean:
run(r'if exist build rmdir /s /q build')
sys.exit(0)
if dopull and not onlymsi:
if args.certpwd and args.certpsn:
print('--certpwd and --certpsn cannot be used together')
if args.only_msi:
args.nopull = True
if not args.nopull:
run(r'hg -R ../hg pull --insecure')
run(r'hg -R ../thg pull')
for mod in ['shellext'] + extensions:
run(r'hg -R ../%s pull' % mod)
if buildthg or all:
if args.target == 'thg-release':
packagename = 'tortoisehg'
thgbranch = 'stable'
hgbranch = 'stable'
thgtag = args.thgtag or lasttag('thg', 'stable')
hgtag = args.hgtag or lasttag('hg', 'stable', maxtag=thgtag)
elif args.target == 'thg-stable':
packagename = 'tortoisehg-stable'
thgbranch = 'stable'
hgbranch = 'stable'
thgtag = None
hgtag = None
elif args.target == 'thg-dev':
packagename = 'tortoisehg-dev'
thgbranch = 'default'
hgbranch = 'default'
thgtag = None
hgtag = None
elif args.target == 'hg-release':
packagename = 'mercurial'
hgbranch = 'stable'
hgtag = args.hgtag or lasttag('hg', 'stable')
elif args.target == 'hg-stable':
packagename = 'mercurial-stable'
hgbranch = 'stable'
hgtag = None
elif args.target == 'hg-dev':
packagename = 'mercurial-dev'
hgbranch = 'default'
hgtag = None
elif args.target == 'thg-doc':
pass
else:
p.print_help()
sys.exit(0)
print '\nBuild config:'
print '[tortoisehg] branch=%s, tag=%s' % (thgbranch, thgtag)
print '[mercurial] branch=%s, tag=%s\n' % (hgbranch, hgtag)
if args.config:
sys.exit(0)
if args.cert:
args.cert = os.path.abspath(args.cert)
if not args.certpwd:
# Seed the password at startup
args.certpwd = getpass.getpass('password for signing: ')
if not args.nopull:
if args.target.startswith('thg'):
for mod in ['shellext'] + extensions:
run(r'hg -R ../%s pull' % mod)
for mod in extensions:
if mod in extversions:
run(r'hg update -R ../%s %s' % (mod, extversions[mod]))
elif mod in ['keyring']:
elif mod in ('keyring',):
pass
else:
run(r'hg update -R ../' + mod)
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-dev...')
build_hg(False, 'default', 'tip', arch)
build_hg_installer('mercurial-dev', 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_shellext(True, 'default', 'tip', 'tortoisehg-stable', productid, arch)
build_thg_installer('tortoisehg-stable', productid, arch)
run(r'title Building thg-dev...')
productid = str(uuid.uuid4()).upper()
build_hg(False, 'default', 'tip', arch)
build_thg(True, 'default', 'tip', 'tortoisehg-dev', productid, arch)
build_shellext(True, 'default', 'tip', 'tortoisehg-dev', productid, arch)
build_thg_installer('tortoisehg-dev', productid, arch)
elif builddoc:
if args.target == 'thg-doc':
verify_doc_env()
build_thg_docs()
elif buildhg:
elif args.target.startswith('hg'):
verify_hg_env()
build_hg(forcehg, hgbranch, hgtag, arch)
build_hg(args.force_hg, hgbranch, hgtag, arch)
build_hg_installer(packagename, arch)
elif buildthg:
elif args.target.startswith('thg'):
verify_hg_env()
verify_doc_env()
verify_thg_env()
build_hg(forcehg, hgbranch, hgtag, arch)
build_hg(args.force_hg, hgbranch, hgtag, arch)
productid = str(uuid.uuid4()).upper()
build_thg(forcethg, thgbranch, thgtag, packagename, productid, arch)
build_shellext(forcethg, 'default', thgtag, packagename, productid, arch)
build_thg(args.force_thg, thgbranch, thgtag, packagename, productid, arch)
build_shellext(args.force_thg, 'default', thgtag, packagename, productid, arch)
build_thg_installer(packagename, productid, arch)
if doupdate:
if args.update:
update()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment