-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add config-finder make target * Add recursive functionality * Add config finder to CI * Workaround bash argument limit failures
- Loading branch information
1 parent
538ac6a
commit 87054e9
Showing
4 changed files
with
110 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
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,76 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import subprocess | ||
from collections import defaultdict | ||
import re | ||
from copy import deepcopy | ||
import os | ||
|
||
cy_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | ||
|
||
# from https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 | ||
def deep_merge(a: dict, b: dict) -> dict: | ||
"""Merge two dicts and return a singular dict""" | ||
result = deepcopy(a) | ||
for bk, bv in b.items(): | ||
av = result.get(bk) | ||
if isinstance(av, dict) and isinstance(bv, dict): | ||
result[bk] = deep_merge(av, bv) | ||
else: | ||
result[bk] = deepcopy(bv) | ||
return result | ||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description='Pretty print all configs given a filelist of scala files') | ||
parser.add_argument('FILE', type=str, help='Filelist of scala files to search within') | ||
parser.add_argument('-l', '--levels', default=0, type=int, help='Number of levels to recursively look for configs') | ||
args = parser.parse_args() | ||
|
||
files = [] | ||
with open(args.FILE, 'r') as f: | ||
files = f.read().splitlines() | ||
|
||
cmd = ['grep', '-o', r"class \+.* \+extends \+Config"] + files | ||
r = subprocess.run(cmd, check=True, capture_output=True) | ||
|
||
base_file_path_dict = defaultdict(list) | ||
for l in r.stdout.decode("UTF-8").splitlines(): | ||
match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) | ||
if match: | ||
base_file_path_dict[match.group(1)].append(match.group(2)) | ||
|
||
levels = [] | ||
for level in range(args.levels): | ||
if level == 0: | ||
# use the base | ||
dict_to_use = base_file_path_dict | ||
else: | ||
# use the level-1 dict | ||
assert len(levels) > 0 | ||
dict_to_use = levels[-1] | ||
|
||
file_path_dict = defaultdict(list) | ||
|
||
for configs in dict_to_use.values(): | ||
for config in configs: | ||
cmd = ['grep', '-o', r"class \+.* \+extends \+" + f"{config}"] + files | ||
r = subprocess.run(cmd, capture_output=True) | ||
|
||
for l in r.stdout.decode("UTF-8").splitlines(): | ||
match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) | ||
if match: | ||
file_path_dict[match.group(1)].append(match.group(2)) | ||
|
||
levels.append(file_path_dict) | ||
|
||
final_dict = base_file_path_dict | ||
for dct in levels: | ||
final_dict = deep_merge(final_dict, dct) | ||
|
||
print(f"Finding all one-line config. fragments (up to {args.levels} levels)\n") | ||
for k, v in final_dict.items(): | ||
print(f"{k.replace(cy_path, 'chipyard')}:") | ||
for e in v: | ||
print(f" {e}") | ||
print("") |