Skip to content

Commit 836b73e

Browse files
committed
Fix parse_flavors result to comply expected formats and flags handling
Signed-off-by: Tobias Wolf <[email protected]>
1 parent 51712b3 commit 836b73e

File tree

5 files changed

+303
-336
lines changed

5 files changed

+303
-336
lines changed

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ python = "^3.10"
1212
networkx = "^3.3"
1313
PyYAML = "^6.0.2"
1414
pytest = "^8.3.2"
15-
gitpython = "^3.1.43"
15+
gitpython = "^3.1.44"
1616
sphinx-rtd-theme = "^2.0.0"
1717
apt-repo = "^0.5"
1818
jsonschema = "^4.23.0"
@@ -27,8 +27,8 @@ black = "^24.8.0"
2727

2828
[tool.poetry.scripts]
2929
gl-cname = "python_gardenlinux_lib.cname:main"
30-
gl-flavors-parse = "python_gardenlinux_lib.flavors.parse_flavors:main"
31-
flavors-parse = "python_gardenlinux_lib.flavors.parse_flavors:main"
30+
gl-flavors-parse = "python_gardenlinux_lib.flavors.__main__:main"
31+
flavors-parse = "python_gardenlinux_lib.flavors.__main__:main"
3232

3333
[tool.pytest.ini_options]
3434
pythonpath = [

src/python_gardenlinux_lib/constants.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,40 @@
1-
#!/usr/bin/env python3
1+
# GardenLinux flavors schema for validation
2+
GL_FLAVORS_SCHEMA = {
3+
"type": "object",
4+
"version": {"type": "integer"},
5+
"properties": {
6+
"targets": {
7+
"type": "array",
8+
"items": {
9+
"type": "object",
10+
"properties": {
11+
"name": {"type": "string"},
12+
"category": {"type": "string"},
13+
"flavors": {
14+
"type": "array",
15+
"items": {
16+
"type": "object",
17+
"properties": {
18+
"features": {
19+
"type": "array",
20+
"items": {"type": "string"},
21+
},
22+
"arch": {"type": "string"},
23+
"build": {"type": "boolean"},
24+
"test": {"type": "boolean"},
25+
"test-platform": {"type": "boolean"},
26+
"publish": {"type": "boolean"},
27+
},
28+
"required": ["features", "arch", "build", "test", "test-platform", "publish"],
29+
},
30+
},
31+
},
32+
"required": ["name", "category", "flavors"],
33+
},
34+
},
35+
},
36+
"required": ["targets"]
37+
}
238

339
# It is important that this list is sorted in descending length of the entries
440
GL_MEDIA_TYPES = [
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python3
2+
3+
from argparse import ArgumentParser
4+
from git import Git
5+
import json
6+
import os
7+
import sys
8+
import yaml
9+
10+
from jsonschema import ValidationError
11+
from .parser import group_by_arch, parse_flavors, validate_flavors
12+
13+
14+
def generate_markdown_table(combinations, no_arch):
15+
"""Generate a markdown table of platforms and their flavors."""
16+
table = "| Platform | Architecture | Flavor |\n"
17+
table += "|------------|--------------------|------------------------------------------|\n"
18+
19+
for arch, combination in combinations:
20+
platform = combination.split("-")[0]
21+
table += f"| {platform:<10} | {arch:<18} | `{combination}` |\n"
22+
23+
return table
24+
25+
def parse_args():
26+
parser = ArgumentParser(description="Parse flavors.yaml and generate combinations.")
27+
28+
parser.add_argument("--no-arch", action="store_true", help="Exclude architecture from the flavor output.")
29+
parser.add_argument(
30+
"--include-only",
31+
action="append",
32+
default=[],
33+
help="Restrict combinations to those matching wildcard patterns (can be specified multiple times)."
34+
)
35+
parser.add_argument(
36+
"--exclude",
37+
action="append",
38+
default=[],
39+
help="Exclude combinations based on wildcard patterns (can be specified multiple times)."
40+
)
41+
parser.add_argument(
42+
"--build",
43+
action="store_true",
44+
help="Filter combinations to include only those with build enabled."
45+
)
46+
parser.add_argument(
47+
"--publish",
48+
action="store_true",
49+
help="Filter combinations to include only those with publish enabled."
50+
)
51+
parser.add_argument(
52+
"--test",
53+
action="store_true",
54+
help="Filter combinations to include only those with test enabled."
55+
)
56+
parser.add_argument(
57+
"--test-platform",
58+
action="store_true",
59+
help="Filter combinations to include only platforms with test-platform: true."
60+
)
61+
parser.add_argument(
62+
"--category",
63+
action="append",
64+
default=[],
65+
help="Filter combinations to include only platforms belonging to the specified categories (can be specified multiple times)."
66+
)
67+
parser.add_argument(
68+
"--exclude-category",
69+
action="append",
70+
default=[],
71+
help="Exclude platforms belonging to the specified categories (can be specified multiple times)."
72+
)
73+
parser.add_argument(
74+
"--json-by-arch",
75+
action="store_true",
76+
help="Output a JSON dictionary where keys are architectures and values are lists of flavors."
77+
)
78+
parser.add_argument(
79+
"--markdown-table-by-platform",
80+
action="store_true",
81+
help="Generate a markdown table by platform."
82+
)
83+
84+
return parser.parse_args()
85+
86+
def main():
87+
args = parse_args()
88+
89+
repo_path = Git(".").rev_parse("--show-superproject-working-tree")
90+
flavors_file = os.path.join(repo_path, 'flavors.yaml')
91+
92+
if not os.path.isfile(flavors_file):
93+
sys.exit(f"Error: {flavors_file} does not exist.")
94+
95+
# Load and validate the flavors.yaml
96+
with open(flavors_file, 'r') as file:
97+
flavors_data = yaml.safe_load(file)
98+
99+
try:
100+
validate_flavors(flavors_data)
101+
except ValidationError as e:
102+
sys.exit(f"Validation Error: {e.message}")
103+
104+
combinations = parse_flavors(
105+
flavors_data,
106+
include_only_patterns=args.include_only,
107+
wildcard_excludes=args.exclude,
108+
only_build=args.build,
109+
only_test=args.test,
110+
only_test_platform=args.test_platform,
111+
only_publish=args.publish,
112+
filter_categories=args.category,
113+
exclude_categories=args.exclude_category
114+
)
115+
116+
if args.json_by_arch:
117+
grouped_combinations = group_by_arch(combinations)
118+
119+
# If --no-arch, strip architectures from the grouped output
120+
if args.no_arch:
121+
grouped_combinations = {
122+
arch: sorted(set(item.replace(f"-{arch}", "") for item in items))
123+
for arch, items in grouped_combinations.items()
124+
}
125+
126+
print(json.dumps(grouped_combinations, indent=2))
127+
elif args.markdown_table_by_platform:
128+
print(generate_markdown_table(combinations, args.no_arch))
129+
else:
130+
if args.no_arch:
131+
printable_combinations = sorted(set(remove_arch(combinations)))
132+
else:
133+
printable_combinations = sorted(set(comb[1] for comb in combinations))
134+
135+
print("\n".join(sorted(set(printable_combinations))))
136+
137+
138+
if __name__ == "__main__":
139+
# Create a null logger as default
140+
main()

0 commit comments

Comments
 (0)