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
|
#!/usr/bin/env python3
import os
import json
import subprocess
import sys
_tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.insert(0, _tdir)
from cloudinit import version as ci_version # noqa: E402
def tiny_p(cmd):
stderr = subprocess.PIPE
return subprocess.check_output(
cmd, stderr=stderr, stdin=None, universal_newlines=True
)
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()
# upstream/MM.NN.x tracks our patch level releases so ignore trailing '.x'
major_minor_version = ".".join(src_version.split(".")[:2])
version_long = ""
# 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.
github_ci_release_br = bool(
os.environ.get("GITHUB_HEAD_REF", "").startswith(
f"upstream/{major_minor_version}"
)
)
travis_ci_release_br = bool(
os.environ.get("TRAVIS_PULL_REQUEST_BRANCH", "").startswith("upstream/")
)
is_release_branch_ci = bool(github_ci_release_br or travis_ci_release_br)
if is_gitdir(_tdir) and which("git") and not is_release_branch_ci:
# This cmd can be simplified to ["git", "branch", "--show-current"]
# after bionic EOL.
branch_name = tiny_p(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip()
if branch_name.startswith(f"upstream/{major_minor_version}"):
version = src_version
version_long = ""
else:
flags = []
if use_tags:
flags = ["--tags"]
cmd = [
"git",
"describe",
branch_name,
] + flags
try:
version = tiny_p(cmd).strip()
version_long = tiny_p(cmd + ["--long"]).strip()
except subprocess.CalledProcessError as e:
if "No tags can describe" in e.stderr:
print(f"{cmd} found no tags. Using cloudinit.verison.py ")
version = src_version
version_long = ""
else:
raise
version_long = tiny_p(cmd + ["--long"]).strip()
else:
version = src_version
version_long = ""
# 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 = f"-{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(version + "\n")
sys.exit(0)
|