From 78f39bdfee511f4236339ecf2f2fabdfba944d99 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Fri, 1 Jan 2021 23:09:18 -0800 Subject: 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 --- lib/spack/spack/cmd/license.py | 41 +++++++++++++++++++++++++------------ lib/spack/spack/test/cmd/license.py | 34 ++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/license.py b/lib/spack/spack/cmd/license.py index 84a4a02282..ed57fccc6c 100644 --- a/lib/spack/spack/cmd/license.py +++ b/lib/spack/spack/cmd/license.py @@ -9,6 +9,7 @@ import os import re from collections import defaultdict +import llnl.util.filesystem as fs import llnl.util.tty as tty import spack.paths @@ -77,15 +78,15 @@ def _all_spack_files(root=spack.paths.prefix): visited.add(path) -def _licensed_files(root=spack.paths.prefix): - for relpath in _all_spack_files(root): +def _licensed_files(args): + for relpath in _all_spack_files(args.root): if any(regex.match(relpath) for regex in licensed_files): yield relpath def list_files(args): """list files in spack that should have license headers""" - for relpath in sorted(_licensed_files()): + for relpath in sorted(_licensed_files(args)): print(os.path.join(spack.paths.spack_root, relpath)) @@ -93,6 +94,8 @@ def list_files(args): # bool(value) evaluates to True OLD_LICENSE, SPDX_MISMATCH, GENERAL_MISMATCH = range(1, 4) +strict_date = r'Copyright 2013-2021' + class LicenseError(object): def __init__(self): @@ -118,17 +121,15 @@ class LicenseError(object): def _check_license(lines, path): license_lines = [ - r'Copyright 2013-(?:201[789]|202\d) Lawrence Livermore National Security, LLC and other', # noqa: E501 + r'Copyright 2013-(?:202[01]) Lawrence Livermore National Security, LLC and other', # noqa: E501 r'Spack Project Developers\. See the top-level COPYRIGHT file for details.', # noqa: E501 r'SPDX-License-Identifier: \(Apache-2\.0 OR MIT\)' ] - strict_date = r'Copyright 2013-2020' - found = [] for line in lines: - line = re.sub(r'^[\s#\.]*', '', line) + line = re.sub(r'^[\s#\%\.]*', '', line) line = line.rstrip() for i, license_line in enumerate(license_lines): if re.match(license_line, line): @@ -175,7 +176,7 @@ def verify(args): license_errors = LicenseError() - for relpath in _licensed_files(args.root): + for relpath in _licensed_files(args): path = os.path.join(args.root, relpath) with open(path) as f: lines = [line for line in f][:license_lines] @@ -190,15 +191,28 @@ def verify(args): tty.msg('No license issues found.') -def setup_parser(subparser): - sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command') - sp.add_parser('list-files', help=list_files.__doc__) +def update_copyright_year(args): + """update copyright for the current year in all licensed files""" + + llns_and_other = ' Lawrence Livermore National Security, LLC and other' + for filename in _licensed_files(args): + fs.filter_file( + r'Copyright \d{4}-\d{4}' + llns_and_other, + strict_date + llns_and_other, + os.path.join(args.root, filename) + ) - verify_parser = sp.add_parser('verify', help=verify.__doc__) - verify_parser.add_argument( + +def setup_parser(subparser): + subparser.add_argument( '--root', action='store', default=spack.paths.prefix, help='scan a different prefix for license issues') + sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command') + sp.add_parser('list-files', help=list_files.__doc__) + sp.add_parser('verify', help=verify.__doc__) + sp.add_parser('update-copyright-year', help=update_copyright_year.__doc__) + def license(parser, args): if not git: @@ -209,5 +223,6 @@ def license(parser, args): commands = { 'list-files': list_files, 'verify': verify, + 'update-copyright-year': update_copyright_year, } return commands[args.license_command](args) diff --git a/lib/spack/spack/test/cmd/license.py b/lib/spack/spack/test/cmd/license.py index 614d093c5f..6063a8d9a8 100644 --- a/lib/spack/spack/test/cmd/license.py +++ b/lib/spack/spack/test/cmd/license.py @@ -1,4 +1,4 @@ -# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) @@ -8,6 +8,7 @@ import re from llnl.util.filesystem import touch, mkdirp +import spack.cmd.license import spack.paths from spack.main import SpackCommand @@ -31,7 +32,7 @@ def test_verify(tmpdir): lgpl_header = source_dir.join('lgpl_header.py') with lgpl_header.open('w') as f: f.write("""\ -# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: LGPL-2.1-only @@ -48,13 +49,13 @@ def test_verify(tmpdir): correct_header = source_dir.join('correct_header.py') with correct_header.open('w') as f: f.write("""\ -# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) """) - out = license('verify', '--root', str(tmpdir), fail_on_error=False) + out = license('--root', str(tmpdir), 'verify', fail_on_error=False) assert str(no_header) in out assert str(lgpl_header) in out @@ -66,3 +67,28 @@ def test_verify(tmpdir): assert re.search(r'files with old license header:\s*1', out) assert license.returncode == 1 + + +def test_update_copyright_year(tmpdir): + source_dir = tmpdir.join('lib', 'spack', 'spack') + mkdirp(str(source_dir)) + + years = list(range(2018, 2021)) + + for year in years: + outdated = source_dir.join('header_%d.py' % year) + with outdated.open('w') as f: + f.write("""\ +# Copyright 2013-%d Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) +""" % year) + + license('--root', str(tmpdir), 'update-copyright-year') + + for year in years: + outdated = source_dir.join('header_%d.py' % year) + first_line = outdated.open().read().split("\n")[0] + assert str(year) not in first_line + assert spack.cmd.license.strict_date in first_line -- cgit v1.2.3-70-g09d2