1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
#!/usr/bin/python3
# Tool to generate the manifest.xml will the correct datetime of bundle
# creation as well as add git sha and bamboo build metadata
import argparse
import datetime
import json
import os.path as op
import os
import subprocess
import sys
from xml.dom import minidom
from xml.etree.ElementTree import Element, SubElement, tostring
__version__ = "0.3.0"
class Constants:
# there's an Id versus name issue here
NAME = "SMRT Link Software Update"
AUTHOR = "build"
def get_parser():
desc = "Update the manifest.xml"
p = argparse.ArgumentParser(description=desc,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
p.add_argument("bundle_id", help="ID of the software bundle")
p.add_argument("version",
help="Version string or path to filename that contains it")
p.add_argument("-o", dest="output_manifest_xml", default="manifest.xml",
help="Path to the version.txt file. Must have a single line with Major.Minor.Tiny format")
p.add_argument(
"-j",
dest="pacbio_manifest_json",
default="pacbio-manifest.json",
help="Output path output manifest JSON used by SMRT Link")
p.add_argument(
'--author',
dest="author",
default=Constants.AUTHOR,
help="Bundle creation Author")
p.add_argument("--name", dest="name", default=Constants.NAME,
help="Name of software bundle")
p.add_argument("--desc", dest="description", default="No Description",
help="Description to appear in the manifest")
return p
def git_short_sha():
args = "git rev-parse --short HEAD".split()
return subprocess.check_output(args, encoding="utf-8").strip()
def git_branch():
args = "git rev-parse --abbrev-ref HEAD".split()
return subprocess.check_output(args, encoding="utf-8").strip()
def get_bamboo_buildnumber(default=0):
return int(os.environ.get('bamboo_globalBuildNumber', default))
def to_semver(major, minor, patch, git_sha,
build_number=None, prerelease_tag=None):
"""Convert to semver format"""
base = ".".join(str(i) for i in (major, minor, patch))
prerelease = "" if prerelease_tag is None else "-{}".format(prerelease_tag)
# need the trailing . as the sep for the other metadata
number = "" if build_number is None else str(build_number) + "."
metadata = "+{b}{s}".format(b=number, s=git_sha[:7])
return "{b}{p}{m}".format(b=base, p=prerelease, m=metadata)
def to_undocumented_pacbio_version_format(major, minor, tiny, other):
return ".".join([str(i) for i in (major, minor, tiny, other)])
def get_version(major, minor, tiny):
build_number = get_bamboo_buildnumber()
git_sha = git_short_sha()
# The build number is being abused for the patch version
return to_semver(major, minor, tiny, git_sha, build_number=None)
def read_version_txt(version):
if op.isfile(version):
with open(version, 'r') as f:
x = f.readline()
else:
x = version
major, minor, patch = [int(i) for i in x.split(".")[:3]]
return major, minor, patch
def to_pacbio_manifest_d(bundle_id, version, name, desc):
return dict(id=bundle_id,
name=name,
version=version,
description=desc,
dependencies=[])
def prettify(elem):
return minidom.parseString(
tostring(elem, 'utf-8')).toprettyxml(indent=" ")
def write_manifest_xml(bundle_id, version, name,
description, author, manifest_xml):
root = Element("Manifest")
def sub(n, value_):
e = SubElement(root, n)
e.text = value_
return e
sub("Package", bundle_id)
sub("Name", name)
sub("Version", version)
sub("Created", datetime.datetime.utcnow().isoformat())
sub("Author", author)
sub("Description", description)
with open(manifest_xml, 'w') as f:
f.write(prettify(root))
return root
def write_pacbio_manifest_json(bundle_id, version, name, desc, output_json):
with open(output_json, 'w') as f:
f.write(
json.dumps(
to_pacbio_manifest_d(
bundle_id,
version,
name,
desc),
indent=True))
def runner(bundle_id, version, output_manifest_xml,
pacbio_manifest_json, author, name, desc):
major, minor, patch = read_version_txt(version)
sem_ver = get_version(major, minor, patch)
branch = git_branch()
other = get_bamboo_buildnumber()
if not (branch.startswith("master") or branch.startswith("release")):
other = "SNAPSHOT" + str(other)
version_str = to_undocumented_pacbio_version_format(
major, minor, patch, other)
# this is to get the git SHA1 and build number propagated to SL services
# data model
author = "User {} created {} bundle {}".format(
Constants.AUTHOR, bundle_id, sem_ver)
# there's some tragic duplication of models between ICS and Secondary
# hence this duplication of these very similar ideas
write_manifest_xml(
bundle_id,
version_str,
name,
desc,
author,
output_manifest_xml)
write_pacbio_manifest_json(
bundle_id,
version_str,
name,
desc,
pacbio_manifest_json)
return 0
def main(argv_):
p = get_parser()
args = p.parse_args(argv_)
return runner(args.bundle_id,
args.version,
args.output_manifest_xml,
args.pacbio_manifest_json,
args.author,
args.name,
args.description)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
|