Alien-SVN
view release on metacpan or search on metacpan
src/subversion/tools/dist/release.py view on Meta::CPAN
if not dep.have_usable():
raise RuntimeError('Cannot find usable %s' % dep.label)
if branch != 'trunk':
# Make sure CHANGES is sync'd.
compare_changes(repos, branch, args.revnum)
# Ensure the output directory doesn't already exist
if os.path.exists(get_deploydir(args.base_dir)):
raise RuntimeError('output directory \'%s\' already exists'
% get_deploydir(args.base_dir))
os.mkdir(get_deploydir(args.base_dir))
# For now, just delegate to dist.sh to create the actual artifacts
extra_args = ''
if args.version.is_prerelease():
if args.version.pre == 'nightly':
extra_args = '-nightly'
else:
extra_args = '-%s %d' % (args.version.pre, args.version.pre_num)
# Build Unix last to leave Unix-style svn_version.h for tagging
logging.info('Buildling Windows tarballs')
run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d -zip %s'
% (sys.path[0], args.version.base, branch, args.revnum,
extra_args) )
logging.info('Building UNIX tarballs')
run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d %s'
% (sys.path[0], args.version.base, branch, args.revnum,
extra_args) )
# Move the results to the deploy directory
logging.info('Moving artifacts and calculating checksums')
for e in extns:
if args.version.pre == 'nightly':
filename = 'subversion-nightly.%s' % e
else:
filename = 'subversion-%s.%s' % (args.version, e)
shutil.move(filename, get_deploydir(args.base_dir))
filename = os.path.join(get_deploydir(args.base_dir), filename)
m = hashlib.sha1()
m.update(open(filename, 'r').read())
open(filename + '.sha1', 'w').write(m.hexdigest())
shutil.move('svn_version.h.dist',
get_deploydir(args.base_dir) + '/' + 'svn_version.h.dist'
+ '-' + str(args.version))
# And we're done!
#----------------------------------------------------------------------
# Sign the candidate release artifacts
def sign_candidates(args):
'Sign candidate artifacts in the dist development directory.'
def sign_file(filename):
asc_file = open(filename + '.asc', 'a')
logging.info("Signing %s" % filename)
proc = subprocess.Popen(['gpg', '-ba', '-o', '-', filename],
stdout=asc_file)
proc.wait()
asc_file.close()
if args.target:
target = args.target
else:
target = get_deploydir(args.base_dir)
for e in extns:
filename = os.path.join(target, 'subversion-%s.%s' % (args.version, e))
sign_file(filename)
if args.version.major >= 1 and args.version.minor <= 6:
filename = os.path.join(target,
'subversion-deps-%s.%s' % (args.version, e))
sign_file(filename)
#----------------------------------------------------------------------
# Post the candidate release artifacts
def post_candidates(args):
'Post candidate artifacts to the dist development directory.'
logging.info('Importing tarballs to %s' % dist_dev_url)
svn_cmd = ['svn', 'import', '-m',
'Add %s candidate release artifacts' % args.version.base,
'--auto-props', '--config-option',
'config:auto-props:*.asc=svn:eol-style=native;svn:mime-type=text/plain',
get_deploydir(args.base_dir), dist_dev_url]
if (args.username):
svn_cmd += ['--username', args.username]
proc = subprocess.Popen(svn_cmd)
(stdout, stderr) = proc.communicate()
proc.wait()
#----------------------------------------------------------------------
# Create tag
def create_tag(args):
'Create tag in the repository'
logging.info('Creating tag for %s' % str(args.version))
if args.branch:
branch = secure_repos + '/' + args.branch
else:
branch = secure_repos + '/branches/%d.%d.x' % (args.version.major,
args.version.minor)
tag = secure_repos + '/tags/' + str(args.version)
svnmucc_cmd = ['svnmucc', '-m',
'Tagging release ' + str(args.version)]
if (args.username):
svnmucc_cmd += ['--username', args.username]
svnmucc_cmd += ['cp', str(args.revnum), branch, tag]
svnmucc_cmd += ['put', os.path.join(get_deploydir(args.base_dir),
'svn_version.h.dist'),
tag + '/subversion/include/svn_version.h']
src/subversion/tools/dist/release.py view on Meta::CPAN
if replace:
# replace the version number with the [version] reference
i.filename = Version.regex.sub('[version]', fname)
else:
i.filename = fname
i.sha1 = open(s, 'r').read()
sha1info.append(i)
return sha1info
def write_announcement(args):
'Write the release announcement.'
sha1info = get_sha1info(args)
siginfo = "\n".join(get_siginfo(args, True)) + "\n"
data = { 'version' : str(args.version),
'sha1info' : sha1info,
'siginfo' : siginfo,
'major-minor' : '%d.%d' % (args.version.major,
args.version.minor),
'major-minor-patch' : args.version.base,
}
if args.version.is_prerelease():
template_filename = 'rc-release-ann.ezt'
else:
template_filename = 'stable-release-ann.ezt'
template = ezt.Template(compress_whitespace = False)
template.parse(get_tmplfile(template_filename).read())
template.generate(sys.stdout, data)
def write_downloads(args):
'Output the download section of the website.'
sha1info = get_sha1info(args, replace=True)
data = { 'version' : str(args.version),
'fileinfo' : sha1info,
}
template = ezt.Template(compress_whitespace = False)
template.parse(get_tmplfile('download.ezt').read())
template.generate(sys.stdout, data)
#----------------------------------------------------------------------
# Validate the signatures for a release
key_start = '-----BEGIN PGP SIGNATURE-----'
fp_pattern = re.compile(r'^pub\s+(\w+\/\w+)[^\n]*\n\s+Key\sfingerprint\s=((\s+[0-9A-F]{4}){10})\nuid\s+([^<\(]+)\s')
def get_siginfo(args, quiet=False):
'Returns a list of signatures for the release.'
try:
import gnupg
except ImportError:
import _gnupg as gnupg
gpg = gnupg.GPG()
if args.target:
target = args.target
else:
target = get_deploydir(args.base_dir)
good_sigs = {}
fingerprints = {}
output = []
glob_pattern = os.path.join(target, 'subversion*-%s*.asc' % args.version)
for filename in glob.glob(glob_pattern):
text = open(filename).read()
keys = text.split(key_start)
if not quiet:
logging.info("Checking %d sig(s) in %s" % (len(keys[1:]), filename))
for key in keys[1:]:
fd, fn = tempfile.mkstemp()
os.write(fd, key_start + key)
os.close(fd)
verified = gpg.verify_file(open(fn, 'rb'), filename[:-4])
os.unlink(fn)
if verified.valid:
good_sigs[verified.key_id[-8:]] = True
else:
sys.stderr.write("BAD SIGNATURE for %s\n" % filename)
if verified.key_id:
sys.stderr.write(" key id: %s\n" % verified.key_id)
sys.exit(1)
for id in good_sigs.keys():
gpg = subprocess.Popen(['gpg', '--fingerprint', id],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
rc = gpg.wait()
gpg_output = gpg.stdout.read()
if rc:
print(gpg_output)
sys.stderr.write("UNABLE TO GET FINGERPRINT FOR %s" % id)
sys.exit(1)
gpg_output = "\n".join([ l for l in gpg_output.splitlines()
if l[0:7] != 'Warning' ])
fp = fp_pattern.match(gpg_output).groups()
fingerprints["%s [%s] %s" % (fp[3], fp[0], fp[1])] = fp
for entry in sorted(fingerprints.keys()):
fp = fingerprints[entry]
output.append(" %s [%s] with fingerprint:" % (fp[3], fp[0]))
output.append(" %s" % fp[1])
return output
def check_sigs(args):
'Check the signatures for the release.'
output = get_siginfo(args)
for line in output:
print(line)
def get_keys(args):
'Import the LDAP-based KEYS file to gpg'
# We use a tempfile because urlopen() objects don't have a .fileno()
with tempfile.SpooledTemporaryFile() as fd:
fd.write(urllib2.urlopen(KEYS).read())
fd.flush()
fd.seek(0)
subprocess.check_call(['gpg', '--import'], stdin=fd)
#----------------------------------------------------------------------
# Main entry point for argument parsing and handling
def main():
'Parse arguments, and drive the appropriate subcommand.'
# Setup our main parser
parser = argparse.ArgumentParser(
description='Create an Apache Subversion release.')
parser.add_argument('--clean', action='store_true', default=False,
help='Remove any directories previously created by %(prog)s')
parser.add_argument('--verbose', action='store_true', default=False,
help='Increase output verbosity')
parser.add_argument('--base-dir', default=os.getcwd(),
help='''The directory in which to create needed files and
folders. The default is the current working
directory.''')
subparsers = parser.add_subparsers(title='subcommands')
# Setup the parser for the build-env subcommand
subparser = subparsers.add_parser('build-env',
help='''Download release prerequisistes, including autoconf,
libtool, and swig.''')
subparser.set_defaults(func=build_env)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('--sf-mirror', default='softlayer',
help='''The mirror to use for downloading files from
SourceForge. If in the EU, you may want to use
'kent' for this value.''')
subparser.add_argument('--use-existing', action='store_true', default=False,
help='''Attempt to use existing build dependencies before
downloading and building a private set.''')
# Setup the parser for the roll subcommand
subparser = subparsers.add_parser('roll',
help='''Create the release artifacts.''')
subparser.set_defaults(func=roll_tarballs)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('revnum', type=int,
help='''The revision number to base the release on.''')
subparser.add_argument('--branch',
help='''The branch to base the release on.''')
# Setup the parser for the sign-candidates subcommand
subparser = subparsers.add_parser('sign-candidates',
help='''Sign the release artifacts.''')
subparser.set_defaults(func=sign_candidates)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('--target',
help='''The full path to the directory containing
release artifacts.''')
# Setup the parser for the post-candidates subcommand
subparser = subparsers.add_parser('post-candidates',
help='''Commit candidates to the release development area
of the dist.apache.org repository.''')
src/subversion/tools/dist/release.py view on Meta::CPAN
subparser = subparsers.add_parser('clean-dist',
help='''Clean the distribution directory (and mirrors) of
all but the most recent MAJOR.MINOR release.''')
subparser.set_defaults(func=clean_dist)
subparser.add_argument('--dist-dir',
help='''The directory to clean.''')
subparser.add_argument('--username',
help='''Username for ''' + dist_repos + '''.''')
# The move-to-dist subcommand
subparser = subparsers.add_parser('move-to-dist',
help='''Move candiates and signatures from the temporary
release dev location to the permanent distribution
directory.''')
subparser.set_defaults(func=move_to_dist)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('--username',
help='''Username for ''' + dist_repos + '''.''')
# The write-news subcommand
subparser = subparsers.add_parser('write-news',
help='''Output to stdout template text for use in the news
section of the Subversion website.''')
subparser.set_defaults(func=write_news)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
# write-announcement
subparser = subparsers.add_parser('write-announcement',
help='''Output to stdout template text for the emailed
release announcement.''')
subparser.set_defaults(func=write_announcement)
subparser.add_argument('--target',
help='''The full path to the directory containing
release artifacts.''')
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
# write-downloads
subparser = subparsers.add_parser('write-downloads',
help='''Output to stdout template text for the download
table for subversion.apache.org''')
subparser.set_defaults(func=write_downloads)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
# check-sigs
subparser = subparsers.add_parser('check-sigs',
help='''Output to stdout the signatures collected for this
release''')
subparser.set_defaults(func=check_sigs)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('--target',
help='''The full path to the directory containing
release artifacts.''')
# get-keys
subparser = subparsers.add_parser('get-keys',
help='''Import committers' public keys to ~/.gpg/''')
subparser.set_defaults(func=get_keys)
# A meta-target
subparser = subparsers.add_parser('clean',
help='''The same as the '--clean' switch, but as a
separate subcommand.''')
subparser.set_defaults(func=cleanup)
# Parse the arguments
args = parser.parse_args()
# first, process any global operations
if args.clean:
cleanup(args)
# Set up logging
logger = logging.getLogger()
if args.verbose:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
# Fix up our path so we can use our installed versions
os.environ['PATH'] = os.path.join(get_prefix(args.base_dir), 'bin') + ':' \
+ os.environ['PATH']
# finally, run the subcommand, and give it the parsed arguments
args.func(args)
if __name__ == '__main__':
main()
( run in 0.952 second using v1.01-cache-2.11-cpan-df04353d9ac )