-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathutil.py
More file actions
179 lines (150 loc) · 5.23 KB
/
util.py
File metadata and controls
179 lines (150 loc) · 5.23 KB
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
import os
import re
from typing import Optional
from packaging.version import Version
import subprocess
def get_branch_tag_suffix() -> Optional[str]:
ref_name = os.getenv("GITHUB_REF_NAME", "")
if not ref_name or ref_name == "main":
return None
return re.sub(r'[^a-zA-Z0-9._-]', '_', ref_name)
def format_image_name(
image_name_format: str, flavor: str, version_info: Version, name: str, tag: str
) -> str:
result = image_name_format
result = result.replace("[image]", name)
result = result.replace("[flavor]", flavor)
result = result.replace("[major]", str(version_info.major))
result = result.replace("[minor]", str(version_info.minor))
result = result.replace("[patch]", str(version_info.micro))
result = result.replace(
"[series]", "%s.%s" % (version_info.major, version_info.minor)
)
result = result.replace("[tag]", tag)
return result
def maybe(m: dict[str, any], k: str, default_value: any = None) -> any:
if k in m:
return m[k]
else:
return default_value
def matches_constraints(
version: Version, flavor: str, constraints: dict[str, any], is_current_release=None
) -> bool:
if "any" in constraints:
for constraint in constraints["any"]:
if matches_constraints(version, flavor, constraint, is_current_release=is_current_release):
return True
return False
major_minor_series = "%s.%s" % (version.major, version.minor)
major_series = str(version.major)
flavors = maybe(constraints, "flavors")
lower = maybe(constraints, "lower")
only_series = maybe(constraints, "series")
upper = maybe(constraints, "upper")
exact = maybe(constraints, "exact")
current = maybe(constraints, "current")
if lower is not None:
lower = Version(lower)
if upper is not None:
upper = Version(upper)
if exact is str:
exact = [exact]
applies = True
if is_current_release is not None and current is not None:
if is_current_release != current:
applies = False
if lower is None and upper is not None:
if version > upper:
applies = False
if lower is not None and upper is None:
if version < lower:
applies = False
if lower is not None and upper is not None:
if version < lower or version > upper:
applies = False
if type(only_series) is str:
only_series = [only_series]
if only_series is not None and (
(major_minor_series not in only_series) and (major_series not in only_series)
):
applies = False
if flavors is not None and flavor not in flavors:
applies = False
version_string = str(version)
if exact is not None and not version_string in exact:
applies = False
return applies
def list_rsync_dir(url: str):
result = subprocess.run(
["rsync", "--list-only", "--out-format='%n'", url],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
result.check_returncode()
files = []
for line in result.stdout.splitlines(keepends=False):
line = line.decode("utf-8")
if len(line.strip()) == 0:
continue
if line.startswith("MOTD:"):
continue
file_name = str(line.split(" ")[-1])
if file_name != ".":
files.append(file_name)
return files
def parse_text_bool(text: str) -> bool:
return text.lower() in ["1", "true", "yes"]
def parse_text_constraint(text: str) -> dict[str, any]:
constraint = {}
for item in text.split(";"):
item = item.strip()
parts = item.split("=", maxsplit=1)
if len(parts) != 2:
parts = [parts[0], ""]
key = parts[0]
value = parts[1]
if key == "current":
constraint[key] = parse_text_bool(value)
elif key == "lower" or key == "upper":
constraint[key] = value
elif key == "flavors" or key == "flavor" or key == "series" or key == "exact":
if key == "flavor":
key = "flavors"
constraint[key] = value.split(",")
else:
raise Exception("unknown constraint key: %s" % key)
return constraint
def smart_script_split(
command: list[str], description: Optional[str] = None
) -> list[str]:
sections = []
current = []
is_potentially_value = False
for item in command:
arm_potentially_value = False
if item.startswith("-"):
if len(current) > 0:
sections.append(current)
current = []
is_potentially_value = False
arm_potentially_value = True
current.append(item)
if is_potentially_value:
is_potentially_value = False
sections.append(current)
current = []
if arm_potentially_value:
is_potentially_value = True
if len(current) > 0:
sections.append(current)
lines = []
if description is not None:
lines.append("# %s" % description)
for i, section in enumerate(sections):
line = " ".join(section)
if i != 0:
line = " " + line
if i != len(sections) - 1:
line += " \\"
lines.append(line)
return lines