The add_license_headers.py module#
Summary#
Return the year of the first (oldest) commit in the git repository. |
|
Add lint arguments to the parser for REUSE. |
|
Update file paths to be absolute paths with system separators. |
|
Update the LICENSE file to match the license template, adjusting the year span for each repo. |
|
Link the default template and/or license from the assets folder to your git repo. |
|
Generate the license file from the assets/LICENSES/ |
|
Make .reuse or LICENSES directory and create symbolic link to file. |
|
Check if the committed file is missing its header. |
|
Set variables to run REUSE on the project. |
|
Update the license header of the file. |
|
Add the license header to the file. |
|
Check if file before the hook ran is the same as after the hook ran. |
|
Add earlier hook changes to updated file with header. |
|
Read a file and return its content. |
|
Update the year in the copyright statement of a file. |
|
Get the start and end years from the year range in the file. |
|
Unlink the default asset files, and remove directories if empty. |
|
Add and update file headers with REUSE. |
Default template to use for license headers. |
|
Default copyright line for license headers. |
|
Default license for headers. |
|
Fallback start year used when git history is unavailable. |
|
Year regex to match year or year range in files. |
|
Number of bytes read from the top of a file to check for an existing license header. |
Description#
Module for running REUSE to add missing license headers to files.
A license header consists of the Ansys copyright statement and licensing information.
Module detail#
- add_license_headers.get_start_year_from_git(git_repo) int#
Return the year of the first (oldest) commit in the git repository.
Uses
git log --reverseto find the oldest commit and extracts its year. When the repository is a shallow clone (e.g.fetch-depth: 1in CI/CD), attemptsgit fetch --unshallowto retrieve the full history before reading the first commit year. If unshallowing fails (no network access, no remote configured, etc.) the function continues with the limited history that is locally available. Falls back toDEFAULT_START_YEAR(the current year) when the repository has no commits yet.- Parameters:
- git_repo: git.Repo
The git repository object.
- Returns:
intThe four-digit year of the first commit, or the current year if the repository has no commits.
- add_license_headers.set_lint_args(parser: argparse.ArgumentParser) argparse.Namespace#
Add lint arguments to the parser for REUSE.
- Parameters:
- parser: argparse.ArgumentParser
Parser without any lint arguments.
- Returns:
argparse.NamespaceParser namespace containing lint arguments.
- add_license_headers.get_full_paths(file_list: list) list#
Update file paths to be absolute paths with system separators.
- Parameters:
- file_list: list
List containing committed files.
- Returns:
listList containing the full paths of committed files.
- add_license_headers.update_license_file(repo_license_path: pathlib.Path, year_span: str, license: str = DEFAULT_LICENSE) int#
Update the LICENSE file to match the license template, adjusting the year span for each repo.
- Parameters:
- repo_license_path: Path
Path to the LICENSE file in the repository.
- year_span: str
The user start year to the current year. If they are the same, default to the current year.
- license: str
The license identifier to use. Defaults to
DEFAULT_LICENSE(MIT).
- Returns:
int0if the year in the LICENSE file was not updated.1if the year in the LICENSE file was updated.
- add_license_headers.link_assets(assets: dict, git_root: str, args: argparse.Namespace) None#
Link the default template and/or license from the assets folder to your git repo.
Only creates symlinks or generates files if they don’t already exist or point to the wrong target, avoiding unnecessary filesystem churn.
- Parameters:
- assets: dict
Dictionary containing the asset folder information.
- git_root: str
Full path of the repository’s root directory.
- args: argparse.Namespace
Namespace of arguments with their values.
- add_license_headers.generate_license_file(template_parent_dir: pathlib.Path, year_span: int | str, license_file_name: pathlib.Path, license: str = DEFAULT_LICENSE) None#
Generate the license file from the assets/LICENSES/
.txt template. - Parameters:
- template_parent_dir: Path
Path to the parent directory of the template file.
- year_span: int
The user start year to the current year. If they are the same, default to the current year. For example, “2024” or “2023 - 2025”.
- license_file_name: Path
Path to the license file in the repository to generate.
- license: str
The license identifier. Defaults to
DEFAULT_LICENSE(MIT).
- add_license_headers.mkdirs_and_link(asset_dir: str, hook_asset_dir: str, repo_asset_dir: str, filename: str) None#
Make .reuse or LICENSES directory and create symbolic link to file.
Skips symlink creation if destination already points to the correct source, avoiding unnecessary filesystem operations on every invocation.
- Parameters:
- asset_dir: str
Path of the asset directory required for REUSE (.reuse/templates or LICENSES).
- hook_asset_dir: str
Full path of the hook’s asset directory.
- repo_asset_dir: str
Full path of the git repository’s asset directory.
- filename: str
Name of the file to be linked from the hook_asset_dir to the repo_asset_dir.
- add_license_headers.non_recursive_file_check(changed_headers: int, obj: common.ClickObj, values: dict, args: argparse.Namespace) int#
Check if the committed file is missing its header.
- Parameters:
- changed_headers: int
0if no headers were added or updated.1if headers were added or updated.- obj: common.ClickObj
A click object used in REUSE to annotate files.
- values: dict
Dictionary containing the values of files, copyright, template, license, changed_headers, year, and git_repo.
- args: argparse.Namespace
Namespace of arguments with their values.
- Returns:
int0if all files contain headers and are up to date.1ifREUSEchanged all noncompliant files.
- add_license_headers.set_variables(obj: common.ClickObj, values: dict, args: argparse.Namespace) tuple#
Set variables to run REUSE on the project.
- Parameters:
- obj: common.ClickObj
A click object used in REUSE to annotate files.
- values: dict
Dictionary containing the values of files, copyright, template, license, changed_headers, year, and git_repo.
- args: argparse.Namespace
Namespace of arguments with their values.
- Returns:
tupleTuple containing the project, template, commented, license, files, copyright, and years.
- add_license_headers.update_header(changed_headers: int, file: str, copyright: str, license: str, years: str, template: str, commented: bool, force_license: bool = False) int#
Update the license header of the file.
- Parameters:
- changed_headers: int
0if no headers were added or updated.1if headers were added or updated.- file: str
The file whose header is being updated.
- copyright: str
The copyright string of the header. For example, “Synopsys, Inc. and ANSYS, Inc. All rights reserved.”
- license: str
The license of the header. For example, “MIT”.
- years: str
The year span of the header. For example, “2024” or “2023 - 2025”.
- template: str
The template to use for the header. For example, “ansys” for “ansys.jinja2”.
- commented: bool
Whether the template is commented or not.
- force_license: bool
When
True, pass the full license list toadd_header()so that a mismatchedSPDX-License-Identifier(e.g. MIT when Apache-2.0 is requested) is fully replaced instead of being left unchanged. Defaults toFalse.
- Returns:
int0if all files contain headers and are up to date.1ifREUSEchanged all noncompliant files.
- add_license_headers.add_header(copyright: str, license: str, years: str, file: str, template: str, commented: bool, out: tempfile.NamedTemporaryFile | IO[str]) None#
Add the license header to the file.
- Parameters:
- copyright: str
The copyright line for the license header. For example, “Synopsys, Inc. and ANSYS, Inc. All rights reserved.”
- license: str
The license for the license header. For example, “MIT”.
- years: str
The year span in the license header. For example, “2024” or “2023 - 2025”.
- file: str
The file path to add the license header to.
- template: str
The template to use for the license header. For example, “ansys.jinja2”.
- commented: bool
Whether the template is commented or not.
- out: Union[NamedTemporaryFile, IO[str]]
Temporary file to capture the stdout of the add_header_to_file() function or
sys.stdout.
- add_license_headers.check_same_content(before_hook: str, after_hook: str) bool#
Check if file before the hook ran is the same as after the hook ran.
- Parameters:
- before_hook: str
Path to file before add-license-headers was run.
- after_hook: str
Path to file after add-license-headers was run.
- Returns:
- bool
Trueif the files have the same content.Falseif the files have different content.
- add_license_headers.apply_hook_changes(before_hook: str, after_hook: str) None#
Add earlier hook changes to updated file with header.
- Parameters:
- before_hook: str
Path to file before add-license-headers was run.
- after_hook: str
Path to file after add-license-headers was run.
- add_license_headers.get_content(file: str) str#
Read a file and return its content.
- Parameters:
- file: str
Path to the file to read.
- Returns:
strContent of the file.
- add_license_headers.update_year_range(changed_headers: int, file: str, year_regex: str, user_start_year: str, current_year: str) int#
Update the year in the copyright statement of a file.
- Parameters:
- changed_headers: int
0if no headers were added or updated.1if headers were added or updated.- file: str
The file to update the year in the header.
- year_regex: str
The regex to match the year or year range in the file.
- user_start_year: str
The start year provided by the user.
- current_year: str
The current year.
- Returns:
int0if the year is up to date.1if the year was updated.
- add_license_headers.get_years_from_file(content: str, year_regex: str) tuple#
Get the start and end years from the year range in the file.
- Parameters:
- content: str
The content of the file.
- year_regex: str
The regex to match the year or year range in the file.
- add_license_headers.cleanup(assets: dict, os_git_root: str) None#
Unlink the default asset files, and remove directories if empty.
- Parameters:
- assets: dict
Dictionary containing assets information
- os_git_root: str
Full path of the repository’s root directory.
- add_license_headers.main()#
Add and update file headers with REUSE.
- Returns:
int0if all files contain headers and are up to date.1ifREUSEchanged all noncompliant files.
- add_license_headers.DEFAULT_TEMPLATE = 'ansys'#
Default template to use for license headers.
- add_license_headers.DEFAULT_COPYRIGHT = 'Synopsys, Inc. and ANSYS, Inc. All rights reserved.'#
Default copyright line for license headers.
- add_license_headers.DEFAULT_LICENSE = 'MIT'#
Default license for headers.
- add_license_headers.DEFAULT_START_YEAR#
Fallback start year used when git history is unavailable.
- add_license_headers.YEAR_REGEX = '(\\d{4}) - (\\d{4})|\\d{4}'#
Year regex to match year or year range in files.
- add_license_headers.HEADER_PEEK_BYTES = 1024#
Number of bytes read from the top of a file to check for an existing license header.
License headers always appear at the very start of a file and are at most a few hundred bytes, so reading only this many bytes avoids loading the full file for every checked file.
- add_license_headers.logger#