Skip to content

Commit 6e194a7

Browse files
GoldenBugfacebook-github-bot
authored andcommitted
main_v2: Created Script to Fetch Revision Info From Manifest
Summary: West isn't able to retrieve the revision information from the manifest before the repo has been updated. In order to facilitate retrieving dependencies from alternative locations we need to know the revision first. This scrip can naively parse the manifest file and print the requested project revision(s) Reviewed By: garnermic Differential Revision: D35794313 fbshipit-source-id: 3bf6a2ba4e5cb597b0f212e7b2210d76b311a44f
1 parent 020ae71 commit 6e194a7

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ src/.config
1212
src/include/config.h
1313
src/tools/Kconfiglib/__pycache__/kconfiglib.cpython-38.pyc
1414
*.o
15-
build
15+
/build
1616

1717
# Ignore Vim swap files
1818
*.swp

scripts/build/get_revision.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import sys
5+
import re
6+
7+
8+
def get_manifest(manifest_path) -> str:
9+
"""
10+
This function reads in the manifest file give the path and checks to
11+
see if it has the manifest keyword at the beginning of the line
12+
somewhere in the file.
13+
14+
It then reads in the file as a single string.
15+
16+
:param manifest_path: The path to a west manifest yml file.
17+
:type manifest_path: str
18+
:return: String containing the raw file contents.
19+
:rtype: str
20+
"""
21+
try:
22+
manifest_file = open(manifest_path, "r")
23+
except FileNotFoundError:
24+
print("Manifest file not found at: " + manifest_path)
25+
sys.exit(255)
26+
except Exception as e:
27+
print("Error opening manifest file.")
28+
print(e)
29+
sys.exit(255)
30+
31+
try:
32+
file_contents = manifest_file.read()
33+
except Exception as e:
34+
print("Error reading manifest File Contents.")
35+
print(e)
36+
sys.exit(255)
37+
38+
file_match = re.search("\nmanifest:", file_contents)
39+
if file_match is None:
40+
print("File does not appear to be a manifest file.")
41+
print("Missing \"manifest\" key in file.")
42+
sys.exit(255)
43+
44+
return file_contents
45+
46+
47+
def parse_revisions(manifest_contents) -> dict:
48+
"""
49+
Parses the contents of the manifest file using a regex and then stores the
50+
output of the matches in a dictionary using the project name as the key and
51+
the returned revision as the value.
52+
53+
:param manifest_contents: Raw contents of the manifest file.
54+
:type manifest_contents: str
55+
:return: Dictionary containing project name and revision as key, values.
56+
:rtype: dict
57+
"""
58+
regex_pattern = r"- name:[ ]*([^ \n]*)[\s\S]*?revision:[ ]*([a-z,0-9,\.]*)"
59+
matches = re.findall(regex_pattern, manifest_contents, re.M)
60+
61+
revisions = {}
62+
for revision_pair in matches:
63+
if revision_pair is not None and len(revision_pair) == 2:
64+
revisions[revision_pair[0]] = revision_pair[1]
65+
66+
return revisions
67+
68+
69+
def print_all_revisions(revisions):
70+
"""
71+
If no project name is supplied on the command line this function will be
72+
used to print out all project revisions. It will print a single project and
73+
it's revision per line.
74+
75+
:param revisions: A dictionary containing project name and revisions.
76+
:type revisions: dict
77+
"""
78+
if len(revisions) == 0:
79+
print("No projects and revisions could be parsed from manifest.")
80+
sys.exit(255)
81+
82+
for project, revision in revisions.items():
83+
print(project + " " + revision)
84+
85+
86+
def print_revision(project, revisions):
87+
"""
88+
Attempts to print the revision for the given project if it exists.
89+
90+
:param project: The project name to print.
91+
:type project: str
92+
:param revisions: A dictionary contain project names and revisions.
93+
:type revisions: dict
94+
"""
95+
if len(revisions) == 0:
96+
print("No projects and revisions could be parsed from manifest.")
97+
return
98+
99+
if project not in revisions:
100+
print("Could not find project " + project + " in manifest.")
101+
print("Possible projects in manifest with revisions:")
102+
for project, revision in revisions.items():
103+
print("- " + project)
104+
sys.exit(255)
105+
106+
else:
107+
print(revisions[project])
108+
109+
110+
def get_revision(project, manifest_path):
111+
"""
112+
Main work function that takes the CLI input and loads the file, parses
113+
the revisions, and prints the requested revision(s) if possible.
114+
115+
:param project: The project name to print, or None if none supplied.
116+
:type project: str
117+
:param manifest_path: The path to the manifest file to parse.
118+
:type manifest_path: str
119+
"""
120+
manifest_contents = get_manifest(manifest_path)
121+
project_revisions = parse_revisions(manifest_contents)
122+
123+
if project is None:
124+
print_all_revisions(project_revisions)
125+
else:
126+
print_revision(project, project_revisions)
127+
128+
129+
if __name__ == '__main__':
130+
parser = argparse.ArgumentParser(
131+
description='Get revision from the specified project')
132+
133+
parser.add_argument(
134+
'-p',
135+
'--project',
136+
help="The name of the project to retrieve the revision for. "
137+
"If this option is not used then all revisions "
138+
"will be printed")
139+
parser.add_argument(
140+
'-m', '--manifest', required=True,
141+
help="The path to the west manifest file to parse for the requested "
142+
"revision")
143+
144+
args = parser.parse_args()
145+
get_revision(args.project, args.manifest)

0 commit comments

Comments
 (0)