-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
020ae71
commit 6e194a7
Showing
2 changed files
with
146 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import sys | ||
import re | ||
|
||
|
||
def get_manifest(manifest_path) -> str: | ||
""" | ||
This function reads in the manifest file give the path and checks to | ||
see if it has the manifest keyword at the beginning of the line | ||
somewhere in the file. | ||
It then reads in the file as a single string. | ||
:param manifest_path: The path to a west manifest yml file. | ||
:type manifest_path: str | ||
:return: String containing the raw file contents. | ||
:rtype: str | ||
""" | ||
try: | ||
manifest_file = open(manifest_path, "r") | ||
except FileNotFoundError: | ||
print("Manifest file not found at: " + manifest_path) | ||
sys.exit(255) | ||
except Exception as e: | ||
print("Error opening manifest file.") | ||
print(e) | ||
sys.exit(255) | ||
|
||
try: | ||
file_contents = manifest_file.read() | ||
except Exception as e: | ||
print("Error reading manifest File Contents.") | ||
print(e) | ||
sys.exit(255) | ||
|
||
file_match = re.search("\nmanifest:", file_contents) | ||
if file_match is None: | ||
print("File does not appear to be a manifest file.") | ||
print("Missing \"manifest\" key in file.") | ||
sys.exit(255) | ||
|
||
return file_contents | ||
|
||
|
||
def parse_revisions(manifest_contents) -> dict: | ||
""" | ||
Parses the contents of the manifest file using a regex and then stores the | ||
output of the matches in a dictionary using the project name as the key and | ||
the returned revision as the value. | ||
:param manifest_contents: Raw contents of the manifest file. | ||
:type manifest_contents: str | ||
:return: Dictionary containing project name and revision as key, values. | ||
:rtype: dict | ||
""" | ||
regex_pattern = r"- name:[ ]*([^ \n]*)[\s\S]*?revision:[ ]*([a-z,0-9,\.]*)" | ||
matches = re.findall(regex_pattern, manifest_contents, re.M) | ||
|
||
revisions = {} | ||
for revision_pair in matches: | ||
if revision_pair is not None and len(revision_pair) == 2: | ||
revisions[revision_pair[0]] = revision_pair[1] | ||
|
||
return revisions | ||
|
||
|
||
def print_all_revisions(revisions): | ||
""" | ||
If no project name is supplied on the command line this function will be | ||
used to print out all project revisions. It will print a single project and | ||
it's revision per line. | ||
:param revisions: A dictionary containing project name and revisions. | ||
:type revisions: dict | ||
""" | ||
if len(revisions) == 0: | ||
print("No projects and revisions could be parsed from manifest.") | ||
sys.exit(255) | ||
|
||
for project, revision in revisions.items(): | ||
print(project + " " + revision) | ||
|
||
|
||
def print_revision(project, revisions): | ||
""" | ||
Attempts to print the revision for the given project if it exists. | ||
:param project: The project name to print. | ||
:type project: str | ||
:param revisions: A dictionary contain project names and revisions. | ||
:type revisions: dict | ||
""" | ||
if len(revisions) == 0: | ||
print("No projects and revisions could be parsed from manifest.") | ||
return | ||
|
||
if project not in revisions: | ||
print("Could not find project " + project + " in manifest.") | ||
print("Possible projects in manifest with revisions:") | ||
for project, revision in revisions.items(): | ||
print("- " + project) | ||
sys.exit(255) | ||
|
||
else: | ||
print(revisions[project]) | ||
|
||
|
||
def get_revision(project, manifest_path): | ||
""" | ||
Main work function that takes the CLI input and loads the file, parses | ||
the revisions, and prints the requested revision(s) if possible. | ||
:param project: The project name to print, or None if none supplied. | ||
:type project: str | ||
:param manifest_path: The path to the manifest file to parse. | ||
:type manifest_path: str | ||
""" | ||
manifest_contents = get_manifest(manifest_path) | ||
project_revisions = parse_revisions(manifest_contents) | ||
|
||
if project is None: | ||
print_all_revisions(project_revisions) | ||
else: | ||
print_revision(project, project_revisions) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser( | ||
description='Get revision from the specified project') | ||
|
||
parser.add_argument( | ||
'-p', | ||
'--project', | ||
help="The name of the project to retrieve the revision for. " | ||
"If this option is not used then all revisions " | ||
"will be printed") | ||
parser.add_argument( | ||
'-m', '--manifest', required=True, | ||
help="The path to the west manifest file to parse for the requested " | ||
"revision") | ||
|
||
args = parser.parse_args() | ||
get_revision(args.project, args.manifest) |