#!/usr/bin/env python3 import os import json import subprocess import sys if "avoid-pep8-E402-import-not-top-of-file": _tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, _tdir) from cloudinit import version as ci_version def tiny_p(cmd, capture=True): # python 2.6 doesn't have check_output stdout = subprocess.PIPE stderr = subprocess.PIPE sp = subprocess.Popen(cmd, stdout=stdout, stderr=stderr, stdin=None, universal_newlines=True) (out, err) = sp.communicate() ret = sp.returncode if ret not in [0]: raise RuntimeError("Failed running %s [rc=%s] (%s, %s)" % (cmd, ret, out, err)) return out def which(program): # Return path of program for execution if found in path def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) _fpath, _ = os.path.split(program) if _fpath: if is_exe(program): return program else: for path in os.environ.get("PATH", "").split(os.pathsep): path = path.strip('"') exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None def is_gitdir(path): # Return boolean indicating if path is a git tree. git_meta = os.path.join(path, '.git') if os.path.isdir(git_meta): return True if os.path.exists(git_meta): # in a git worktree, .git is a file with 'gitdir: x' with open(git_meta, "rb") as fp: if b'gitdir:' in fp.read(): return True return False use_long = '--long' in sys.argv or os.environ.get('CI_RV_LONG') use_tags = '--tags' in sys.argv or os.environ.get('CI_RV_TAGS') output_json = '--json' in sys.argv src_version = ci_version.version_string() version_long = None # If we're performing CI for a new release branch (which our tooling creates # with an "upstream/" prefix), then we don't want to enforce strict version # matching because we know it will fail. is_release_branch_ci = ( os.environ.get("TRAVIS_PULL_REQUEST_BRANCH", "").startswith("upstream/") ) if is_gitdir(_tdir) and which("git") and not is_release_branch_ci: flags = [] if use_tags: flags = ['--tags'] cmd = ['git', 'describe', '--abbrev=8', '--match=[0-9]*'] + flags try: version = tiny_p(cmd).strip() except RuntimeError: version = None if version is None or not version.startswith(src_version): sys.stderr.write("git describe version (%s) differs from " "cloudinit.version (%s)\n" % (version, src_version)) sys.stderr.write( "Please get the latest upstream tags.\n" "As an example, this can be done with the following:\n" "$ git remote add upstream https://git.launchpad.net/cloud-init\n" "$ git fetch upstream --tags\n" ) sys.exit(1) version_long = tiny_p(cmd + ["--long"]).strip() else: version = src_version version_long = None # version is X.Y.Z[+xxx.gHASH] # version_long is None or X.Y.Z-xxx-gHASH release = version.partition("-")[0] extra = None commit = None distance = None if version_long: info = version_long.partition("-")[2] extra = "-" + info distance, commit = info.split("-") # remove the 'g' from gHASH commit = commit[1:] data = { 'release': release, 'version': version, 'version_long': version_long, 'extra': extra, 'commit': commit, 'distance': distance, 'is_release_branch_ci': is_release_branch_ci, } if output_json: sys.stdout.write(json.dumps(data, indent=1) + "\n") else: sys.stdout.write(release + "\n") sys.exit(0) # vi: ts=4 expandtab