99import re
1010from collections import defaultdict
1111
12+ import llnl .util .filesystem as fs
1213import llnl .util .tty as tty
1314
1415import 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
8687def 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
9495OLD_LICENSE , SPDX_MISMATCH , GENERAL_MISMATCH = range (1 , 4 )
9596
97+ strict_date = r'Copyright 2013-2021'
98+
9699
97100class LicenseError (object ):
98101 def __init__ (self ):
@@ -118,17 +121,15 @@ def error_messages(self):
118121
119122def _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
203217def 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 )
0 commit comments