Skip to content

Commit 79b2f5d

Browse files
committed
xxx
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
1 parent 0a04022 commit 79b2f5d

3 files changed

Lines changed: 167 additions & 7 deletions

File tree

copier.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,14 @@ author_name:
1616
help: Who is the author?
1717
default: Zephyr Developer
1818

19-
board:
20-
type: str
21-
help: Which board are you targeting?
22-
default: native_sim
23-
2419
include_ci:
2520
type: bool
2621
help: Do you want to include GitHub Actions CI?
2722
default: true
2823

2924
include_docs:
3025
type: bool
31-
help: Do you want to include documentation setup?
26+
help: Do you want to include documentation infrastructure?
3227
default: true
3328

3429
include_drivers:
@@ -46,12 +41,26 @@ include_tests:
4641
help: Do you want to include example tests?
4742
default: true
4843

44+
zephyr_version:
45+
type: str
46+
help: Which Zephyr version are you targeting? (e.g. v4.2.0, v4.3.0, main)
47+
default: main
48+
49+
configure_modules:
50+
type: bool
51+
help: Do you want to interactively select Zephyr modules to include? (Requires internet access)
52+
default: false
53+
54+
_tasks:
55+
- "{% if configure_modules %}python3 scripts/setup_modules.py{% endif %}"
56+
4957
_exclude:
5058
- "copier.yml"
5159
- ".git"
5260
- ".copier-answers.yml"
5361
- "{% if not include_ci %}.github{% endif %}"
5462
- "{% if not include_docs %}doc{% endif %}"
63+
- "{% if not include_docs %}.github/workflows/docs.yml{% endif %}"
5564
- "{% if not include_drivers %}drivers{% endif %}"
5665
- "{% if not include_lib %}lib{% endif %}"
5766
- "{% if not include_tests %}tests{% endif %}"

scripts/setup_modules.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import os
2+
import sys
3+
import urllib.request
4+
import subprocess
5+
6+
import yaml
7+
from InquirerPy import inquirer
8+
9+
def get_zephyr_revision():
10+
try:
11+
with open("west.yml", "r") as f:
12+
content = f.read()
13+
14+
try:
15+
west_config = yaml.safe_load(content)
16+
projects = west_config.get("manifest", {}).get("projects", [])
17+
for project in projects:
18+
if project.get("name") == "zephyr":
19+
return project.get("revision", "main")
20+
except Exception:
21+
# Fallback to regex if YAML fails (e.g. jinja tags)
22+
import re
23+
# Look for revision: <something>
24+
# This is a simple heuristic.
25+
match = re.search(r"revision:\s*(.+)", content)
26+
if match:
27+
rev = match.group(1).strip()
28+
# If it's a jinja tag, default to main
29+
if "{{" in rev:
30+
return "main"
31+
return rev
32+
33+
except Exception as e:
34+
print(f"Error reading west.yml: {e}")
35+
sys.exit(1)
36+
return "main"
37+
38+
def fetch_upstream_manifest(revision):
39+
url = f"https://raw.githubusercontent.com/zephyrproject-rtos/zephyr/{revision}/west.yml"
40+
print(f"Fetching upstream west.yml from {url}...")
41+
try:
42+
with urllib.request.urlopen(url) as response:
43+
return yaml.safe_load(response.read())
44+
except Exception as e:
45+
print(f"Error fetching upstream west.yml: {e}")
46+
if revision != "main":
47+
print("Retrying with 'main'...")
48+
return fetch_upstream_manifest("main")
49+
return None
50+
51+
def get_modules_from_manifest(manifest):
52+
if not manifest:
53+
return []
54+
55+
projects = manifest.get("manifest", {}).get("projects", [])
56+
# Filter out zephyr itself
57+
return [p["name"] for p in projects if p.get("name") != "zephyr"]
58+
59+
def select_modules(modules):
60+
if not modules:
61+
print("No modules found in upstream manifest.")
62+
return []
63+
64+
65+
print("\nInteractive Module Selection")
66+
67+
try:
68+
selected_modules = inquirer.fuzzy(
69+
message="Select Zephyr modules to include:",
70+
choices=modules,
71+
multiselect=True,
72+
max_height="70%",
73+
instruction="Type to search, TAB/Space to select, ENTER to confirm",
74+
).execute()
75+
except Exception as e:
76+
print(f"Error during selection: {e}")
77+
return []
78+
79+
print(f"\nSelected {len(selected_modules)} modules.")
80+
return selected_modules
81+
82+
def update_west_yml(selected_modules):
83+
# We use simple string replacement for the allowlist to avoid reformatting the whole file with PyYAML
84+
# which might lose comments or formatting.
85+
if not selected_modules:
86+
print("No modules selected (or all selected). Removing name-allowlist to include everything.")
87+
88+
try:
89+
with open("west.yml", "r") as f:
90+
lines = f.readlines()
91+
92+
with open("west.yml", "w") as f:
93+
skip_allowlist = False
94+
for line in lines:
95+
if "name-allowlist:" in line:
96+
if not selected_modules:
97+
# If we want all modules, we skip writing the allowlist block
98+
skip_allowlist = True
99+
continue
100+
else:
101+
f.write(line)
102+
# Write our new list
103+
for module in selected_modules:
104+
f.write(f" - {module}\n")
105+
skip_allowlist = True # Skip the old list
106+
continue
107+
108+
if skip_allowlist:
109+
stripped = line.strip()
110+
# If line starts with -, it's a list item.
111+
# If it's empty or comment, we might keep it or skip it.
112+
# If it unindents, we stop skipping.
113+
# But indentation is hard to track line by line without state.
114+
# The template has:
115+
# - cmsis_6
116+
# - ...
117+
# Next line is usually end of file or next section.
118+
# We assume allowlist is the last thing in the import block or followed by less indentation.
119+
# Simple heuristic: if it starts with - and has same indentation, skip.
120+
# Or just skip until we see something that doesn't look like a list item.
121+
if stripped.startswith("-"):
122+
continue
123+
else:
124+
skip_allowlist = False
125+
126+
f.write(line)
127+
128+
except Exception as e:
129+
print(f"Error updating west.yml: {e}")
130+
131+
def main():
132+
133+
print("Setting up Zephyr modules...")
134+
revision = get_zephyr_revision()
135+
print(f"Detected Zephyr revision: {revision}")
136+
137+
manifest = fetch_upstream_manifest(revision)
138+
139+
if manifest:
140+
modules = get_modules_from_manifest(manifest)
141+
selected = select_modules(modules)
142+
update_west_yml(selected)
143+
144+
# Self-destruct
145+
try:
146+
os.remove(__file__)
147+
except:
148+
pass
149+
150+
if __name__ == "__main__":
151+
main()

west.yml renamed to west.yml.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ manifest:
1212
projects:
1313
- name: zephyr
1414
remote: zephyrproject-rtos
15-
revision: main
15+
revision: {{ zephyr_version }}
1616
import:
1717
# By using name-allowlist we can clone only the modules that are
1818
# strictly needed by the application.

0 commit comments

Comments
 (0)