Skip to content

Commit 3b01db8

Browse files
show_duplicate_packages.py: use spack.lock instead of 'spack concretize' output
1 parent 78592c6 commit 3b01db8

File tree

3 files changed

+26
-61
lines changed

3 files changed

+26
-61
lines changed

doc/source/Utilities.rst

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,14 @@ Miscellaneous utilities
99
show_duplicate_packages.py
1010
------------------------------
1111

12-
The utility located at util/show_duplicate_packages.py parses the output of ``spack concretize`` and detects duplicates. Usage is as follows:
12+
The utility located at util/show_duplicate_packages.py parses ``spack.lock`` and detects duplicates. Usage is as follows:
1313

1414
.. code-block:: console
1515
16-
spack concretize | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py
17-
# - OR -
18-
spack concretize |& tee log.concretize
19-
${SPACK_STACK_DIR}/util/show_duplicate_packages.py log.concretize
16+
# In $SPACK_ENV, after concretization:
17+
${SPACK_STACK_DIR}/util/show_duplicate_packages.py
2018
21-
The ``-d`` option shows only a list of the duplicates, as opposed to the default behavior, which is to show a print-out of all packages with colorized duplicates. In any case, the identification of any duplicates will yield a return code of 1. The ``-i`` option can be invoked multiple times to skip specific package names. The ``-c`` option can be used to ignore duplicates associated with different compilers; in an environment with, say, GCC and Intel copies of any given package, those two copies of a package will not be reported as duplicates.
19+
In any case, the identification of any duplicates will yield a return code of 1. The ``-i`` option can be invoked multiple times to skip specific package names.
2220

2321
.. _Permissions_Checker:
2422

util/show_duplicate_packages.py

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,44 @@
11
#!/usr/bin/env python3
22

3-
# Check output of `spack concretize` for duplicate packages.
3+
# Check spack.lock for duplicate packages.
44
# 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
86
#
9-
# '-d' argument prints only duplicates (and disables highlighting).
107
# '-i' argument ignores a specific package, and can be invoked multiple times.
118
#
129
# Alex Richert, June 2023
1310

1411
import argparse
12+
import json
1513
import re
1614
import sys
1715
from collections import defaultdict
1816

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):
2518
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)
3625
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
4532
sys.stderr.write("===\n%suplicates found%s\n" % (("D","!") if duplicates_found else ("No d",".")))
4633
sys.stderr.flush()
4734
return int(duplicates_found)
4835

4936
if __name__ == "__main__":
5037
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")
5238
parser.add_argument("-d", action="store_true", help="Only show duplicates (default output is colorized list of all packages)")
5339
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")
5540
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)
6244
sys.exit(ret)

util/util_tests.sh

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,9 @@ run_and_check 1 "check_permissions G" ${SPACK_STACK_DIR}/util/check_permissions.
4545

4646
## Check show_duplicate_packages.py
4747
cd ${SPACK_STACK_DIR}/util/checks
48-
echo -e " - abcdefg hdf6@1.2.3%intel\n - tuvwxyz hdf6@1.2.3%gcc" > fakeconcrete.A
49-
run_and_check 1 "show_duplicate_packages.py A1" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.A
50-
run_and_check 1 "show_duplicate_packages.py A2" "cat fakeconcrete.A | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py"
51-
run_and_check 0 "show_duplicate_packages.py A3" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -c fakeconcrete.A
52-
run_and_check 0 "show_duplicate_packages.py A4" "cat fakeconcrete.A | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -c"
53-
echo -e " - abcdefg hdf6@1.2.3\n - tuvwxyz hdf6@1.2.4" > fakeconcrete.B
54-
run_and_check 1 "show_duplicate_packages.py B1" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.B
55-
run_and_check 1 "show_duplicate_packages.py B2" "cat fakeconcrete.B | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py"
56-
echo -e " - abcdefg hdf6@1.2.3\n[+] abcdefg hdf6@1.2.3" > fakeconcrete.C
57-
run_and_check 0 "show_duplicate_packages.py C1" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.C
58-
run_and_check 0 "show_duplicate_packages.py C2" "cat fakeconcrete.C | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py"
59-
echo -e " - abcdefg hdf6@1.2.3\n - tuvwxyz hdf6@1.2.3\n - hijklmn mypackage@1.1.1\n[+] opqrstu mypackage@1.1.1" > fakeconcrete.D
60-
run_and_check 0 "show_duplicate_packages.py D1" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.D -i hdf6 -i mypackage
61-
run_and_check 0 "show_duplicate_packages.py D2" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.D -i mypackage -i hdf6
62-
run_and_check 0 "show_duplicate_packages.py D3" "cat fakeconcrete.D | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -i hdf6 -i mypackage"
63-
run_and_check 0 "show_duplicate_packages.py D4" "cat fakeconcrete.D | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -i mypackage -i hdf6"
64-
run_and_check 1 "show_duplicate_packages.py D5" "cat fakeconcrete.D | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -i hdf6"
65-
run_and_check 1 "show_duplicate_packages.py D6" "cat fakeconcrete.D | ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -i mypackage"
48+
echo '{"concrete_specs": {"a2yzf2cdwz7ajifuqacnzfde5wulwyke": {"name": "w3emc", "version": "2.10.0"}, "ks553jzmi3kmx4g76t6mfeb6gpmxa5n4": {"name": "w3emc", "version": "2.11.0"}}}' > spack.lock
49+
run_and_check 1 "show_duplicate_packages.py, should find duplicates" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py
50+
run_and_check 0 "show_duplicate_packages.py, should not find duplicates" ${SPACK_STACK_DIR}/util/show_duplicate_packages.py -i w3emc
6651

6752
cmd="${SPACK_STACK_DIR}/util/show_duplicate_packages.py fakeconcrete.A 2>/dev/null | uniq | grep -c hdf6"
6853
echo "Running '$cmd' in $PWD"

0 commit comments

Comments
 (0)