Skip to content

Commit 78f39bd

Browse files
committed
commands: add spack license update-copyright-year
This adds a new subcommand to `spack license` that automatically updates the copyright year in files that should have a license header. - [x] add `spack license update-copyright-year` command - [x] add test
1 parent 4d94c4c commit 78f39bd

File tree

3 files changed

+65
-20
lines changed

3 files changed

+65
-20
lines changed

lib/spack/spack/cmd/license.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import re
1010
from collections import defaultdict
1111

12+
import llnl.util.filesystem as fs
1213
import llnl.util.tty as tty
1314

1415
import spack.paths
@@ -77,22 +78,24 @@ def _all_spack_files(root=spack.paths.prefix):
7778
visited.add(path)
7879

7980

80-
def _licensed_files(root=spack.paths.prefix):
81-
for relpath in _all_spack_files(root):
81+
def _licensed_files(args):
82+
for relpath in _all_spack_files(args.root):
8283
if any(regex.match(relpath) for regex in licensed_files):
8384
yield relpath
8485

8586

8687
def list_files(args):
8788
"""list files in spack that should have license headers"""
88-
for relpath in sorted(_licensed_files()):
89+
for relpath in sorted(_licensed_files(args)):
8990
print(os.path.join(spack.paths.spack_root, relpath))
9091

9192

9293
# Error codes for license verification. All values are chosen such that
9394
# bool(value) evaluates to True
9495
OLD_LICENSE, SPDX_MISMATCH, GENERAL_MISMATCH = range(1, 4)
9596

97+
strict_date = r'Copyright 2013-2021'
98+
9699

97100
class LicenseError(object):
98101
def __init__(self):
@@ -118,17 +121,15 @@ def error_messages(self):
118121

119122
def _check_license(lines, path):
120123
license_lines = [
121-
r'Copyright 2013-(?:201[789]|202\d) Lawrence Livermore National Security, LLC and other', # noqa: E501
124+
r'Copyright 2013-(?:202[01]) Lawrence Livermore National Security, LLC and other', # noqa: E501
122125
r'Spack Project Developers\. See the top-level COPYRIGHT file for details.', # noqa: E501
123126
r'SPDX-License-Identifier: \(Apache-2\.0 OR MIT\)'
124127
]
125128

126-
strict_date = r'Copyright 2013-2020'
127-
128129
found = []
129130

130131
for line in lines:
131-
line = re.sub(r'^[\s#\.]*', '', line)
132+
line = re.sub(r'^[\s#\%\.]*', '', line)
132133
line = line.rstrip()
133134
for i, license_line in enumerate(license_lines):
134135
if re.match(license_line, line):
@@ -175,7 +176,7 @@ def verify(args):
175176

176177
license_errors = LicenseError()
177178

178-
for relpath in _licensed_files(args.root):
179+
for relpath in _licensed_files(args):
179180
path = os.path.join(args.root, relpath)
180181
with open(path) as f:
181182
lines = [line for line in f][:license_lines]
@@ -190,15 +191,28 @@ def verify(args):
190191
tty.msg('No license issues found.')
191192

192193

193-
def setup_parser(subparser):
194-
sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command')
195-
sp.add_parser('list-files', help=list_files.__doc__)
194+
def update_copyright_year(args):
195+
"""update copyright for the current year in all licensed files"""
196+
197+
llns_and_other = ' Lawrence Livermore National Security, LLC and other'
198+
for filename in _licensed_files(args):
199+
fs.filter_file(
200+
r'Copyright \d{4}-\d{4}' + llns_and_other,
201+
strict_date + llns_and_other,
202+
os.path.join(args.root, filename)
203+
)
196204

197-
verify_parser = sp.add_parser('verify', help=verify.__doc__)
198-
verify_parser.add_argument(
205+
206+
def setup_parser(subparser):
207+
subparser.add_argument(
199208
'--root', action='store', default=spack.paths.prefix,
200209
help='scan a different prefix for license issues')
201210

211+
sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command')
212+
sp.add_parser('list-files', help=list_files.__doc__)
213+
sp.add_parser('verify', help=verify.__doc__)
214+
sp.add_parser('update-copyright-year', help=update_copyright_year.__doc__)
215+
202216

203217
def license(parser, args):
204218
if not git:
@@ -209,5 +223,6 @@ def license(parser, args):
209223
commands = {
210224
'list-files': list_files,
211225
'verify': verify,
226+
'update-copyright-year': update_copyright_year,
212227
}
213228
return commands[args.license_command](args)

lib/spack/spack/test/cmd/license.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
1+
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
22
# Spack Project Developers. See the top-level COPYRIGHT file for details.
33
#
44
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
@@ -8,6 +8,7 @@
88

99
from llnl.util.filesystem import touch, mkdirp
1010

11+
import spack.cmd.license
1112
import spack.paths
1213
from spack.main import SpackCommand
1314

@@ -31,7 +32,7 @@ def test_verify(tmpdir):
3132
lgpl_header = source_dir.join('lgpl_header.py')
3233
with lgpl_header.open('w') as f:
3334
f.write("""\
34-
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
35+
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
3536
# Spack Project Developers. See the top-level COPYRIGHT file for details.
3637
#
3738
# SPDX-License-Identifier: LGPL-2.1-only
@@ -48,13 +49,13 @@ def test_verify(tmpdir):
4849
correct_header = source_dir.join('correct_header.py')
4950
with correct_header.open('w') as f:
5051
f.write("""\
51-
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
52+
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
5253
# Spack Project Developers. See the top-level COPYRIGHT file for details.
5354
#
5455
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
5556
""")
5657

57-
out = license('verify', '--root', str(tmpdir), fail_on_error=False)
58+
out = license('--root', str(tmpdir), 'verify', fail_on_error=False)
5859

5960
assert str(no_header) in out
6061
assert str(lgpl_header) in out
@@ -66,3 +67,28 @@ def test_verify(tmpdir):
6667
assert re.search(r'files with old license header:\s*1', out)
6768

6869
assert license.returncode == 1
70+
71+
72+
def test_update_copyright_year(tmpdir):
73+
source_dir = tmpdir.join('lib', 'spack', 'spack')
74+
mkdirp(str(source_dir))
75+
76+
years = list(range(2018, 2021))
77+
78+
for year in years:
79+
outdated = source_dir.join('header_%d.py' % year)
80+
with outdated.open('w') as f:
81+
f.write("""\
82+
# Copyright 2013-%d Lawrence Livermore National Security, LLC and other
83+
# Spack Project Developers. See the top-level COPYRIGHT file for details.
84+
#
85+
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
86+
""" % year)
87+
88+
license('--root', str(tmpdir), 'update-copyright-year')
89+
90+
for year in years:
91+
outdated = source_dir.join('header_%d.py' % year)
92+
first_line = outdated.open().read().split("\n")[0]
93+
assert str(year) not in first_line
94+
assert spack.cmd.license.strict_date in first_line

share/spack/spack-completion.bash

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,9 +1042,9 @@ _spack_install() {
10421042
_spack_license() {
10431043
if $list_options
10441044
then
1045-
SPACK_COMPREPLY="-h --help"
1045+
SPACK_COMPREPLY="-h --help --root"
10461046
else
1047-
SPACK_COMPREPLY="list-files verify"
1047+
SPACK_COMPREPLY="list-files verify update-copyright-year"
10481048
fi
10491049
}
10501050

@@ -1053,7 +1053,11 @@ _spack_license_list_files() {
10531053
}
10541054

10551055
_spack_license_verify() {
1056-
SPACK_COMPREPLY="-h --help --root"
1056+
SPACK_COMPREPLY="-h --help"
1057+
}
1058+
1059+
_spack_license_update_copyright_year() {
1060+
SPACK_COMPREPLY="-h --help"
10571061
}
10581062

10591063
_spack_list() {

0 commit comments

Comments
 (0)