|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 |
|
3 | | -# Check output of `spack concretize` for duplicate packages. |
| 3 | +# Check spack.lock for duplicate packages. |
4 | 4 | # Usage: |
5 | | -# show_duplicate_packages.py log.concretize |
6 | | -# -OR- |
7 | | -# spack concretize | tee log.concretize | show_duplicate_packages.py > list_of_duplicates.txt |
| 5 | +# show_duplicate_packages.py |
8 | 6 | # |
9 | | -# '-d' argument prints only duplicates (and disables highlighting). |
10 | 7 | # '-i' argument ignores a specific package, and can be invoked multiple times. |
11 | 8 | # |
12 | 9 | # Alex Richert, June 2023 |
13 | 10 |
|
14 | 11 | import argparse |
| 12 | +import json |
15 | 13 | import re |
16 | 14 | import sys |
17 | 15 | from collections import defaultdict |
18 | 16 |
|
19 | | -def colorize_spec(line, package_name, colorize=False): |
20 | | - if not colorize: return line |
21 | | - c1 = r'\033[93m' ; c2 = r'\033[0m' |
22 | | - return re.sub("(\w{7}\s+)(%s)@"%package_name, f"\\1{c1}\\2{c2}@", line) |
23 | | - |
24 | | -def show_duplicate_packages(txt_to_check, ignore_list=[], only_show_dups=False, include_compiler=False): |
| 17 | +def show_duplicate_packages(json_to_check, ignore_list=[], only_show_dups=False): |
25 | 18 | dd = defaultdict(set) |
26 | | - for line in txt_to_check.split("\n"): |
27 | | - line = line.replace("^", "") |
28 | | - package_name = re.findall("\s\w{7}\s+(\^?[^\s@]+)@", line) |
29 | | - if not package_name: continue |
30 | | - if [package_name[0]] in ignore_list: continue |
31 | | - line = " ".join(line.split()[1:]) |
32 | | - if include_compiler: |
33 | | - compiler = re.findall(r"%[^@]+", line)[0] |
34 | | - package_name[0] += compiler |
35 | | - dd[package_name[0]].add(line) |
| 19 | + json_dict = json.loads(json_to_check) |
| 20 | + for _hash in json_dict["concrete_specs"].keys(): |
| 21 | + pkg_name = json_dict["concrete_specs"][_hash]["name"] |
| 22 | + pkg_version = json_dict["concrete_specs"][_hash]["version"] |
| 23 | + key = pkg_name + "@" + pkg_version + "/" +_hash |
| 24 | + dd[pkg_name].add(key) |
36 | 25 | duplicates_found = False |
37 | | - for key in sorted(dd.keys()): |
38 | | - multiple = len(dd[key])>1 |
39 | | - if only_show_dups and not multiple: continue |
40 | | - if only_show_dups: colorize = False |
41 | | - else: colorize = multiple |
42 | | - if multiple: duplicates_found = True |
43 | | - for line in dd[key]: |
44 | | - print(colorize_spec(line, re.sub(r"%.+", "", key), colorize=colorize)) |
| 26 | + for pkg_name in sorted(dd.keys()): |
| 27 | + if [pkg_name] in ignore_list: |
| 28 | + continue |
| 29 | + if len(dd[pkg_name])>1: |
| 30 | + print(dd[pkg_name]) |
| 31 | + duplicates_found = True |
45 | 32 | sys.stderr.write("===\n%suplicates found%s\n" % (("D","!") if duplicates_found else ("No d","."))) |
46 | 33 | sys.stderr.flush() |
47 | 34 | return int(duplicates_found) |
48 | 35 |
|
49 | 36 | if __name__ == "__main__": |
50 | 37 | parser = argparse.ArgumentParser(description="Check output of `spack concretize` for duplicate packages") |
51 | | - parser.add_argument("filename", nargs="?", help="'log.concretize' or other concretization output; if not set, stdin will be used") |
52 | 38 | parser.add_argument("-d", action="store_true", help="Only show duplicates (default output is colorized list of all packages)") |
53 | 39 | parser.add_argument("-i", default=[], nargs="*", action="append", help="Ignore package name (e.g., 'hdf5', 'netcdf-c')") |
54 | | - parser.add_argument("-c", action="store_true", help="Ignore duplicates that have different compilers") |
55 | 40 | args = parser.parse_args() |
56 | | - if args.filename: |
57 | | - with open(args.filename, "r") as f: |
58 | | - txt_to_check = f.read() |
59 | | - else: |
60 | | - txt_to_check = sys.stdin.read() |
61 | | - ret = show_duplicate_packages(txt_to_check, only_show_dups=args.d, ignore_list=args.i, include_compiler=args.c) |
| 41 | + with open("spack.lock", "r") as f: |
| 42 | + json_to_check = f.read() |
| 43 | + ret = show_duplicate_packages(json_to_check, only_show_dups=args.d, ignore_list=args.i) |
62 | 44 | sys.exit(ret) |
0 commit comments