ansys-pre-commit-hooks 0.5.2__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/LICENSE +1 -1
- {ansys_pre_commit_hooks-0.5.2/src/ansys_pre_commit_hooks.egg-info → ansys_pre_commit_hooks-0.6.0}/PKG-INFO +23 -31
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/pyproject.toml +58 -4
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/setup.py +16 -47
- ansys_pre_commit_hooks-0.6.0/src/ansys/pre_commit_hooks/VERSION +1 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/__init__.py +1 -1
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/add_license_headers.py +85 -74
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/assets/licenses.json +68 -1
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/tech_review.py +15 -8
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/dependabot.yml +4 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0/src/ansys_pre_commit_hooks.egg-info}/PKG-INFO +23 -31
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys_pre_commit_hooks.egg-info/SOURCES.txt +0 -3
- ansys_pre_commit_hooks-0.6.0/src/ansys_pre_commit_hooks.egg-info/requires.txt +18 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/tests/test_add_license_headers.py +105 -113
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/tests/test_metadata.py +1 -1
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/tests/test_tech_review.py +1 -1
- ansys_pre_commit_hooks-0.5.2/AUTHORS +0 -12
- ansys_pre_commit_hooks-0.5.2/src/ansys/pre_commit_hooks/VERSION +0 -1
- ansys_pre_commit_hooks-0.5.2/src/ansys/pre_commit_hooks/__pycache__/__init__.cpython-312.pyc +0 -0
- ansys_pre_commit_hooks-0.5.2/src/ansys/pre_commit_hooks/__pycache__/tech_review.cpython-312.pyc +0 -0
- ansys_pre_commit_hooks-0.5.2/src/ansys_pre_commit_hooks.egg-info/requires.txt +0 -19
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/MANIFEST.in +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/README.rst +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/setup.cfg +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/assets/.reuse/templates/ansys.jinja2 +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/assets/LICENSES/MIT.txt +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/AUTHORS +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/CODE_OF_CONDUCT.md +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/CONTRIBUTING.md +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/CONTRIBUTORS.md +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/LICENSE +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/README.md +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys/pre_commit_hooks/templates/README.rst +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys_pre_commit_hooks.egg-info/dependency_links.txt +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys_pre_commit_hooks.egg-info/entry_points.txt +0 -0
- {ansys_pre_commit_hooks-0.5.2 → ansys_pre_commit_hooks-0.6.0}/src/ansys_pre_commit_hooks.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2023 -
|
|
3
|
+
Copyright (c) 2023 - 2026 ANSYS, Inc. and/or its affiliates.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
6
|
this software and associated documentation files (the "Software"), to deal in
|
|
@@ -1,59 +1,51 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: ansys-pre-commit-hooks
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A Python wrapper to create Ansys-tailored pre-commit hooks
|
|
3
|
+
Version: 0.6.0
|
|
5
4
|
Home-page: https://github.com/ansys/pre-commit-hooks
|
|
6
5
|
Author: ANSYS, Inc.
|
|
7
|
-
Author-email: pyansys.core@ansys.com
|
|
6
|
+
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
8
7
|
Maintainer: ANSYS, Inc.
|
|
9
|
-
Maintainer-email: pyansys.core@ansys.com
|
|
10
|
-
License: MIT
|
|
8
|
+
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
9
|
+
License-Expression: MIT
|
|
11
10
|
Project-URL: Source, https://github.com/ansys/pre-commit-hooks/
|
|
12
|
-
Project-URL:
|
|
13
|
-
Project-URL:
|
|
11
|
+
Project-URL: Issues, https://github.com/ansys/pre-commit-hooks/issues
|
|
12
|
+
Project-URL: Discussions, https://github.com/ansys/pre-commit-hooks/discussions
|
|
14
13
|
Project-URL: Documentation, https://pre-commit-hooks.docs.pyansys.com
|
|
14
|
+
Project-URL: Releases, https://github.com/ansys/pre-commit-hooks/releases
|
|
15
|
+
Project-URL: Changelog, https://github.com/ansys/pre-commit-hooks/blob/main/doc/source/changelog.rst
|
|
15
16
|
Classifier: Development Status :: 4 - Beta
|
|
16
17
|
Classifier: Intended Audience :: Science/Research
|
|
17
18
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
18
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
19
19
|
Classifier: Operating System :: OS Independent
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
-
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Requires-Python: >=3.10,<4
|
|
25
|
+
Description-Content-Type: text/x-rst
|
|
25
26
|
License-File: LICENSE
|
|
26
|
-
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist: requests==2.32.3
|
|
27
|
+
Requires-Dist: GitPython==3.1.46
|
|
28
|
+
Requires-Dist: importlib-metadata==8.7.1
|
|
29
|
+
Requires-Dist: Jinja2==3.1.6
|
|
30
|
+
Requires-Dist: reuse==6.2.0
|
|
31
|
+
Requires-Dist: requests==2.32.5
|
|
32
32
|
Requires-Dist: semver==3.0.4
|
|
33
33
|
Requires-Dist: toml==0.10.2
|
|
34
34
|
Provides-Extra: doc
|
|
35
|
-
Requires-Dist: ansys-sphinx-theme[autoapi]==1.
|
|
36
|
-
Requires-Dist: numpydoc==1.
|
|
37
|
-
Requires-Dist: sphinx==8.2.
|
|
35
|
+
Requires-Dist: ansys-sphinx-theme[autoapi]==1.7.2; extra == "doc"
|
|
36
|
+
Requires-Dist: numpydoc==1.10.0; extra == "doc"
|
|
37
|
+
Requires-Dist: sphinx==8.2.3; extra == "doc"
|
|
38
38
|
Requires-Dist: sphinx-autodoc-typehints==3.1.0; extra == "doc"
|
|
39
39
|
Requires-Dist: sphinx-copybutton==0.5.1; extra == "doc"
|
|
40
|
-
Requires-Dist: sphinx_design==0.6.1; extra == "doc"
|
|
41
40
|
Provides-Extra: tests
|
|
42
|
-
Requires-Dist: pytest==
|
|
43
|
-
Requires-Dist: pytest-cov==
|
|
41
|
+
Requires-Dist: pytest==9.0.2; extra == "tests"
|
|
42
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "tests"
|
|
44
43
|
Dynamic: author
|
|
45
|
-
Dynamic: author-email
|
|
46
44
|
Dynamic: classifier
|
|
47
|
-
Dynamic: description
|
|
48
45
|
Dynamic: home-page
|
|
49
|
-
Dynamic: license
|
|
46
|
+
Dynamic: license-file
|
|
50
47
|
Dynamic: maintainer
|
|
51
|
-
Dynamic: maintainer-email
|
|
52
|
-
Dynamic: project-url
|
|
53
|
-
Dynamic: provides-extra
|
|
54
|
-
Dynamic: requires-dist
|
|
55
48
|
Dynamic: requires-python
|
|
56
|
-
Dynamic: summary
|
|
57
49
|
|
|
58
50
|
Ansys pre-commit hooks
|
|
59
51
|
======================
|
|
@@ -1,16 +1,70 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
requires = [
|
|
3
3
|
"setuptools>=42.0",
|
|
4
|
-
"GitPython==3.1.
|
|
5
|
-
"Jinja2==3.1.
|
|
6
|
-
"reuse==
|
|
7
|
-
"requests==2.32.
|
|
4
|
+
"GitPython==3.1.46",
|
|
5
|
+
"Jinja2==3.1.6",
|
|
6
|
+
"reuse==6.2.0",
|
|
7
|
+
"requests==2.32.5",
|
|
8
8
|
"semver==3.0.4",
|
|
9
9
|
"toml==0.10.2",
|
|
10
10
|
"wheel",
|
|
11
11
|
]
|
|
12
12
|
build-backend = "setuptools.build_meta"
|
|
13
13
|
|
|
14
|
+
[project]
|
|
15
|
+
name = "ansys-pre-commit-hooks"
|
|
16
|
+
dynamic = ["version", "classifiers", "description", "readme", "scripts"]
|
|
17
|
+
requires-python = ">=3.10,<4"
|
|
18
|
+
license = "MIT"
|
|
19
|
+
license-files = ["LICENSE"]
|
|
20
|
+
authors = [{ name = "ANSYS, Inc.", email = "pyansys.core@ansys.com" }]
|
|
21
|
+
maintainers = [{ name = "ANSYS, Inc.", email = "pyansys.core@ansys.com" }]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"GitPython==3.1.46",
|
|
24
|
+
"importlib-metadata==8.7.1",
|
|
25
|
+
"Jinja2==3.1.6",
|
|
26
|
+
"reuse==6.2.0",
|
|
27
|
+
"requests==2.32.5",
|
|
28
|
+
"semver==3.0.4",
|
|
29
|
+
"toml==0.10.2",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.dynamic]
|
|
33
|
+
version = {file = "src/ansys/pre_commit_hooks/VERSION"}
|
|
34
|
+
readme = {file = ["README.rst"]}
|
|
35
|
+
description = {file = "A Python wrapper to create Ansys-tailored pre-commit hooks"}
|
|
36
|
+
classifiers = {file = """
|
|
37
|
+
"Development Status :: 4 - Beta",
|
|
38
|
+
"Intended Audience :: Science/Research",
|
|
39
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
40
|
+
"Operating System :: OS Independent",
|
|
41
|
+
"Programming Language :: Python :: 3.10",
|
|
42
|
+
"Programming Language :: Python :: 3.11",
|
|
43
|
+
"Programming Language :: Python :: 3.12",
|
|
44
|
+
"Programming Language :: Python :: 3.13",
|
|
45
|
+
"""}
|
|
46
|
+
|
|
47
|
+
[project.optional-dependencies]
|
|
48
|
+
doc = [
|
|
49
|
+
"ansys-sphinx-theme[autoapi]==1.7.2",
|
|
50
|
+
"numpydoc==1.10.0",
|
|
51
|
+
"sphinx==8.2.3",
|
|
52
|
+
"sphinx-autodoc-typehints==3.1.0",
|
|
53
|
+
"sphinx-copybutton==0.5.1",
|
|
54
|
+
]
|
|
55
|
+
tests = [
|
|
56
|
+
"pytest==9.0.2",
|
|
57
|
+
"pytest-cov==7.0.0",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[project.urls]
|
|
61
|
+
Source = "https://github.com/ansys/pre-commit-hooks/"
|
|
62
|
+
Issues = "https://github.com/ansys/pre-commit-hooks/issues"
|
|
63
|
+
Discussions = "https://github.com/ansys/pre-commit-hooks/discussions"
|
|
64
|
+
Documentation = "https://pre-commit-hooks.docs.pyansys.com"
|
|
65
|
+
Releases = "https://github.com/ansys/pre-commit-hooks/releases"
|
|
66
|
+
Changelog = "https://github.com/ansys/pre-commit-hooks/blob/main/doc/source/changelog.rst"
|
|
67
|
+
|
|
14
68
|
[tool.black]
|
|
15
69
|
line-length = 100
|
|
16
70
|
|
|
@@ -1,36 +1,8 @@
|
|
|
1
1
|
"""Installation file for ansys-pre-commit-hooks."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
import sys
|
|
5
4
|
|
|
6
5
|
from setuptools import find_namespace_packages, setup
|
|
7
|
-
from setuptools.command.develop import develop
|
|
8
|
-
from setuptools.command.install import install
|
|
9
|
-
|
|
10
|
-
SCRIPT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "src", "ansys")
|
|
11
|
-
|
|
12
|
-
sys.path.append(os.path.dirname(SCRIPT_DIR))
|
|
13
|
-
|
|
14
|
-
from ansys.pre_commit_hooks.tech_review import JSON_URL, LICENSES_JSON, download_license_json
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class CustomInstallCommand(install):
|
|
18
|
-
"""Custom install command to download the license json file."""
|
|
19
|
-
|
|
20
|
-
def run(self):
|
|
21
|
-
"""Download the license json file."""
|
|
22
|
-
install.run(self)
|
|
23
|
-
download_license_json(JSON_URL, LICENSES_JSON)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class CustomDevelopCommand(develop):
|
|
27
|
-
"""Custom develop command to download the license json file."""
|
|
28
|
-
|
|
29
|
-
def run(self):
|
|
30
|
-
"""Download the license json file."""
|
|
31
|
-
develop.run(self)
|
|
32
|
-
download_license_json(JSON_URL, LICENSES_JSON)
|
|
33
|
-
|
|
34
6
|
|
|
35
7
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
|
36
8
|
with open(os.path.join(HERE, "src", "ansys", "pre_commit_hooks", "VERSION"), encoding="utf-8") as f:
|
|
@@ -58,49 +30,46 @@ setup(
|
|
|
58
30
|
"Development Status :: 4 - Beta",
|
|
59
31
|
"Intended Audience :: Science/Research",
|
|
60
32
|
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
61
|
-
"License :: OSI Approved :: MIT License",
|
|
62
33
|
"Operating System :: OS Independent",
|
|
63
|
-
"Programming Language :: Python :: 3.9",
|
|
64
34
|
"Programming Language :: Python :: 3.10",
|
|
65
35
|
"Programming Language :: Python :: 3.11",
|
|
66
36
|
"Programming Language :: Python :: 3.12",
|
|
37
|
+
"Programming Language :: Python :: 3.13",
|
|
67
38
|
],
|
|
68
39
|
url="https://github.com/ansys/pre-commit-hooks",
|
|
69
|
-
python_requires=">=3.
|
|
40
|
+
python_requires=">=3.10,<4",
|
|
70
41
|
install_requires=[
|
|
71
|
-
"GitPython==3.1.
|
|
72
|
-
"importlib-metadata==8.
|
|
73
|
-
"Jinja2==3.1.
|
|
74
|
-
"reuse==
|
|
75
|
-
"requests==2.32.
|
|
42
|
+
"GitPython==3.1.46",
|
|
43
|
+
"importlib-metadata==8.7.1",
|
|
44
|
+
"Jinja2==3.1.6",
|
|
45
|
+
"reuse==6.2.0",
|
|
46
|
+
"requests==2.32.5",
|
|
76
47
|
"semver==3.0.4",
|
|
77
48
|
"toml==0.10.2",
|
|
78
49
|
],
|
|
79
50
|
extras_require={
|
|
80
51
|
"doc": [
|
|
81
|
-
"ansys-sphinx-theme[autoapi]==1.
|
|
82
|
-
"numpydoc==1.
|
|
83
|
-
"sphinx==8.2.
|
|
52
|
+
"ansys-sphinx-theme[autoapi]==1.7.2",
|
|
53
|
+
"numpydoc==1.10.0",
|
|
54
|
+
"sphinx==8.2.3",
|
|
84
55
|
"sphinx-autodoc-typehints==3.1.0",
|
|
85
56
|
"sphinx-copybutton==0.5.1",
|
|
86
57
|
"sphinx_design==0.6.1",
|
|
87
58
|
],
|
|
88
59
|
"tests": [
|
|
89
|
-
"pytest==
|
|
90
|
-
"pytest-cov==
|
|
60
|
+
"pytest==9.0.2",
|
|
61
|
+
"pytest-cov==7.0.0",
|
|
91
62
|
],
|
|
92
63
|
},
|
|
93
64
|
project_urls={
|
|
94
65
|
"Source": "https://github.com/ansys/pre-commit-hooks/",
|
|
95
|
-
"
|
|
96
|
-
"
|
|
66
|
+
"Issues": "https://github.com/ansys/pre-commit-hooks/issues",
|
|
67
|
+
"Discussions": "https://github.com/ansys/pre-commit-hooks/discussions",
|
|
97
68
|
"Documentation": "https://pre-commit-hooks.docs.pyansys.com",
|
|
69
|
+
"Releases": "https://github.com/ansys/pre-commit-hooks/releases",
|
|
70
|
+
"Changelog": "https://github.com/ansys/pre-commit-hooks/blob/main/doc/source/changelog.rst",
|
|
98
71
|
},
|
|
99
72
|
include_package_data=True,
|
|
100
|
-
cmdclass={
|
|
101
|
-
"develop": CustomDevelopCommand,
|
|
102
|
-
"install": CustomInstallCommand,
|
|
103
|
-
},
|
|
104
73
|
entry_points={
|
|
105
74
|
"console_scripts": [
|
|
106
75
|
"add-license-headers=ansys.pre_commit_hooks.add_license_headers:main",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.6.0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2023 -
|
|
1
|
+
# Copyright (C) 2023 - 2026 ANSYS, Inc. and/or its affiliates.
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
#
|
|
4
4
|
#
|
|
@@ -25,6 +25,7 @@ Module for running `REUSE <https://reuse.software/>`_ to add missing license hea
|
|
|
25
25
|
|
|
26
26
|
A license header consists of the Ansys copyright statement and licensing information.
|
|
27
27
|
"""
|
|
28
|
+
|
|
28
29
|
import argparse
|
|
29
30
|
from datetime import date as dt
|
|
30
31
|
import filecmp
|
|
@@ -35,12 +36,6 @@ import sys
|
|
|
35
36
|
from tempfile import NamedTemporaryFile
|
|
36
37
|
from typing import IO, Union
|
|
37
38
|
|
|
38
|
-
import git
|
|
39
|
-
from jinja2 import Environment, FileSystemLoader
|
|
40
|
-
from reuse import extract
|
|
41
|
-
from reuse.cli import common
|
|
42
|
-
from reuse.cli.annotate import add_header_to_file, get_comment_style, get_reuse_info, get_template
|
|
43
|
-
|
|
44
39
|
DEFAULT_TEMPLATE = "ansys"
|
|
45
40
|
"""Default template to use for license headers."""
|
|
46
41
|
DEFAULT_COPYRIGHT = "ANSYS, Inc. and/or its affiliates."
|
|
@@ -190,6 +185,9 @@ def link_assets(assets: dict, git_root: str, args: argparse.Namespace) -> None:
|
|
|
190
185
|
"""
|
|
191
186
|
Link the default template and/or license from the assets folder to your git repo.
|
|
192
187
|
|
|
188
|
+
Only creates symlinks or generates files if they don't already exist or
|
|
189
|
+
point to the wrong target, avoiding unnecessary filesystem churn.
|
|
190
|
+
|
|
193
191
|
Parameters
|
|
194
192
|
----------
|
|
195
193
|
assets: dict
|
|
@@ -199,9 +197,6 @@ def link_assets(assets: dict, git_root: str, args: argparse.Namespace) -> None:
|
|
|
199
197
|
args: argparse.Namespace
|
|
200
198
|
Namespace of arguments with their values.
|
|
201
199
|
"""
|
|
202
|
-
# Unlink default files & remove .reuse and LICENSES folders if empty
|
|
203
|
-
cleanup(assets, git_root)
|
|
204
|
-
|
|
205
200
|
# Get the location of the hook in the file system
|
|
206
201
|
hook_loc = Path(__file__).parent.resolve()
|
|
207
202
|
|
|
@@ -224,7 +219,8 @@ def link_assets(assets: dict, git_root: str, args: argparse.Namespace) -> None:
|
|
|
224
219
|
repo_license_file = repo_asset_dir / value["default_file"]
|
|
225
220
|
if not repo_asset_dir.is_dir():
|
|
226
221
|
repo_asset_dir.mkdir(parents=True)
|
|
227
|
-
|
|
222
|
+
if not repo_license_file.is_file():
|
|
223
|
+
generate_license_file(hook_license_file.parent, dt.today().year, repo_license_file)
|
|
228
224
|
|
|
229
225
|
|
|
230
226
|
def generate_license_file(
|
|
@@ -242,6 +238,8 @@ def generate_license_file(
|
|
|
242
238
|
license_file_name: Path
|
|
243
239
|
Path to the license file in the repository to generate.
|
|
244
240
|
"""
|
|
241
|
+
from jinja2 import Environment, FileSystemLoader
|
|
242
|
+
|
|
245
243
|
loader = FileSystemLoader(searchpath=template_parent_dir)
|
|
246
244
|
env = Environment(loader=loader) # nosec
|
|
247
245
|
# Get the template for the specified file
|
|
@@ -260,6 +258,9 @@ def mkdirs_and_link(
|
|
|
260
258
|
"""
|
|
261
259
|
Make .reuse or LICENSES directory and create symbolic link to file.
|
|
262
260
|
|
|
261
|
+
Skips symlink creation if destination already points to the correct source,
|
|
262
|
+
avoiding unnecessary filesystem operations on every invocation.
|
|
263
|
+
|
|
263
264
|
Parameters
|
|
264
265
|
----------
|
|
265
266
|
asset_dir: str
|
|
@@ -273,67 +274,57 @@ def mkdirs_and_link(
|
|
|
273
274
|
"""
|
|
274
275
|
src = Path(hook_asset_dir) / filename
|
|
275
276
|
dest = Path(repo_asset_dir) / filename
|
|
277
|
+
|
|
278
|
+
# If symlink already points to the correct target, skip
|
|
279
|
+
if dest.is_symlink() and dest.resolve() == src.resolve():
|
|
280
|
+
return
|
|
281
|
+
|
|
276
282
|
# If .reuse/templates or LICENSES directories do not exist, create them
|
|
277
283
|
if not Path(asset_dir).is_dir():
|
|
278
284
|
Path(asset_dir).mkdir(parents=True)
|
|
285
|
+
|
|
286
|
+
# Remove stale symlink or file before creating new one
|
|
287
|
+
if dest.exists() or dest.is_symlink():
|
|
288
|
+
dest.unlink()
|
|
289
|
+
|
|
279
290
|
# Make symbolic links to files within the assets folder
|
|
280
291
|
dest.symlink_to(src)
|
|
281
292
|
|
|
282
293
|
|
|
283
|
-
def
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
294
|
+
def _has_current_header(file_path: str, copyright: list, years: str) -> bool:
|
|
295
|
+
"""Fast check if the file already has the expected copyright and year range.
|
|
296
|
+
|
|
297
|
+
Reads only the first 1024 bytes to avoid the overhead of full REUSE parsing.
|
|
298
|
+
This is a heuristic — files that pass this check are very likely compliant
|
|
299
|
+
and don't need the expensive update_header flow.
|
|
287
300
|
|
|
288
301
|
Parameters
|
|
289
302
|
----------
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
Dictionary containing the values of files, copyright,
|
|
297
|
-
template, license, changed_headers, year, and git_repo.
|
|
298
|
-
args: argparse.Namespace
|
|
299
|
-
Namespace of arguments with their values.
|
|
300
|
-
count: int
|
|
301
|
-
Integer of the location in the files array.
|
|
303
|
+
file_path: str
|
|
304
|
+
Path to the file to check.
|
|
305
|
+
copyright: list
|
|
306
|
+
List containing the copyright string. For example, ["ANSYS, Inc. and/or its affiliates."].
|
|
307
|
+
years: str
|
|
308
|
+
The expected year span. For example, "2023 - 2026" or "2026".
|
|
302
309
|
|
|
303
310
|
Returns
|
|
304
311
|
-------
|
|
305
|
-
|
|
306
|
-
``
|
|
307
|
-
``
|
|
312
|
+
bool
|
|
313
|
+
``True`` if the file header appears to already have the correct copyright and years.
|
|
314
|
+
``False`` if the file may need a header update.
|
|
308
315
|
"""
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
# Get the file name at count from pre_commit_files
|
|
315
|
-
file = pre_commit_files[count]
|
|
316
|
-
# Get the reuse information of the file
|
|
317
|
-
file_reuse_info = project.reuse_info_of(file)
|
|
318
|
-
|
|
319
|
-
if (not file_reuse_info) or (Path(file).stat().st_size == 0):
|
|
320
|
-
changed_headers = 1
|
|
321
|
-
# Add the header to the file
|
|
322
|
-
add_header(copyright, license, years, file, template, commented, sys.stdout)
|
|
323
|
-
# Check if the next file is in missing_headers
|
|
324
|
-
return recursive_file_check(changed_headers, obj, values, args, count + 1)
|
|
325
|
-
elif file_reuse_info:
|
|
326
|
-
# Update the header
|
|
327
|
-
changed_headers = update_header(
|
|
328
|
-
changed_headers, file, copyright, license, years, template, commented
|
|
329
|
-
)
|
|
330
|
-
return recursive_file_check(changed_headers, obj, values, args, count + 1)
|
|
316
|
+
try:
|
|
317
|
+
with Path(file_path).open(encoding="utf-8", errors="ignore") as f:
|
|
318
|
+
head = f.read(1024)
|
|
319
|
+
except OSError:
|
|
320
|
+
return False
|
|
331
321
|
|
|
332
|
-
|
|
322
|
+
# Check both the copyright holder and year range are present in the header
|
|
323
|
+
return copyright[0] in head and years in head
|
|
333
324
|
|
|
334
325
|
|
|
335
326
|
def non_recursive_file_check(
|
|
336
|
-
changed_headers: int, obj: common.ClickObj, values: dict, args: argparse.Namespace
|
|
327
|
+
changed_headers: int, obj: "common.ClickObj", values: dict, args: argparse.Namespace
|
|
337
328
|
) -> int:
|
|
338
329
|
"""
|
|
339
330
|
Check if the committed file is missing its header.
|
|
@@ -362,6 +353,10 @@ def non_recursive_file_check(
|
|
|
362
353
|
)
|
|
363
354
|
|
|
364
355
|
for file in pre_commit_files:
|
|
356
|
+
# Fast check: skip files that already have the correct header
|
|
357
|
+
if _has_current_header(file, copyright, years):
|
|
358
|
+
continue
|
|
359
|
+
|
|
365
360
|
# Get the reuse information of the file
|
|
366
361
|
file_reuse_info = project.reuse_info_of(file)
|
|
367
362
|
|
|
@@ -369,7 +364,7 @@ def non_recursive_file_check(
|
|
|
369
364
|
if (not file_reuse_info) or (Path(file).stat().st_size == 0):
|
|
370
365
|
changed_headers = 1
|
|
371
366
|
add_header(copyright, license, years, file, template, commented, sys.stdout)
|
|
372
|
-
|
|
367
|
+
else:
|
|
373
368
|
changed_headers = update_header(
|
|
374
369
|
changed_headers, file, copyright, license, years, template, commented
|
|
375
370
|
)
|
|
@@ -377,7 +372,7 @@ def non_recursive_file_check(
|
|
|
377
372
|
return changed_headers
|
|
378
373
|
|
|
379
374
|
|
|
380
|
-
def set_variables(obj: common.ClickObj, values: dict, args: argparse.Namespace) -> tuple:
|
|
375
|
+
def set_variables(obj: "common.ClickObj", values: dict, args: argparse.Namespace) -> tuple:
|
|
381
376
|
"""Set variables to run `REUSE <https://reuse.software/>`_ on the project.
|
|
382
377
|
|
|
383
378
|
Parameters
|
|
@@ -395,6 +390,8 @@ def set_variables(obj: common.ClickObj, values: dict, args: argparse.Namespace)
|
|
|
395
390
|
tuple
|
|
396
391
|
Tuple containing the project, template, commented, license, files, copyright, and years.
|
|
397
392
|
"""
|
|
393
|
+
from reuse.cli.annotate import get_template
|
|
394
|
+
|
|
398
395
|
project = obj.project
|
|
399
396
|
template, commented = get_template(values["template"], project)
|
|
400
397
|
|
|
@@ -461,16 +458,16 @@ def update_header(
|
|
|
461
458
|
# Check if the file before add-license-headers was run is the same as the one
|
|
462
459
|
# after add-license-headers was run. If not, apply the syntax changes
|
|
463
460
|
# from other hooks before add-license-headers was run to the file
|
|
464
|
-
if check_same_content(before_hook, file)
|
|
461
|
+
if check_same_content(before_hook, file) is False:
|
|
465
462
|
apply_hook_changes(before_hook, file)
|
|
466
463
|
|
|
467
464
|
# Update the year span in the header if necessary
|
|
468
465
|
years_list = years.split(" - ")
|
|
469
466
|
if len(years_list) == 1:
|
|
470
|
-
if years_list != DEFAULT_START_YEAR:
|
|
467
|
+
if int(years_list[0]) != DEFAULT_START_YEAR:
|
|
471
468
|
years_list.append(DEFAULT_START_YEAR)
|
|
472
469
|
else:
|
|
473
|
-
years_list.append(years_list)
|
|
470
|
+
years_list.append(years_list[0])
|
|
474
471
|
changed_headers = update_year_range(
|
|
475
472
|
changed_headers, file, YEAR_REGEX, years_list[0], years_list[1]
|
|
476
473
|
)
|
|
@@ -478,7 +475,7 @@ def update_header(
|
|
|
478
475
|
# Check if the file content before add-license-headers was run has been changed
|
|
479
476
|
# Assuming the syntax was fixed in the above if statement, this check is
|
|
480
477
|
# solely for the file's content
|
|
481
|
-
if check_same_content(before_hook, file)
|
|
478
|
+
if check_same_content(before_hook, file) is False:
|
|
482
479
|
changed_headers = 1
|
|
483
480
|
print(f"Successfully changed header of {file}")
|
|
484
481
|
|
|
@@ -517,12 +514,18 @@ def add_header(
|
|
|
517
514
|
tmp: Union[NamedTemporaryFile, IO[str]]
|
|
518
515
|
Temporary file to capture the stdout of the add_header_to_file() function or ``sys.stdout``.
|
|
519
516
|
"""
|
|
517
|
+
from reuse.cli.annotate import add_header_to_file, get_comment_style, get_reuse_info
|
|
518
|
+
from reuse.copyright import YearRange
|
|
519
|
+
|
|
520
|
+
# Create a YearRange object from the years string to pass into the get_reuse_info function
|
|
521
|
+
year_range = YearRange.tuple_from_string(years)
|
|
522
|
+
|
|
520
523
|
# Get the REUSE information from the file.
|
|
521
524
|
reuse_info = get_reuse_info(
|
|
522
525
|
copyrights=copyright,
|
|
523
526
|
licenses=license,
|
|
524
527
|
copyright_prefix="string-c",
|
|
525
|
-
|
|
528
|
+
years=year_range,
|
|
526
529
|
contributors="",
|
|
527
530
|
)
|
|
528
531
|
|
|
@@ -537,6 +540,15 @@ def add_header(
|
|
|
537
540
|
out=out,
|
|
538
541
|
)
|
|
539
542
|
|
|
543
|
+
# Add a space before and after the year range if there is not already one
|
|
544
|
+
with Path(file).open(encoding="utf-8", newline="", mode="r") as read_file:
|
|
545
|
+
content = read_file.read()
|
|
546
|
+
content = re.sub(r"(\d{4})-(\d{4})", r"\1 - \2", content)
|
|
547
|
+
|
|
548
|
+
# Write the updated content back to the file
|
|
549
|
+
with Path(file).open(encoding="utf-8", newline="", mode="w") as write_file:
|
|
550
|
+
write_file.write(content)
|
|
551
|
+
|
|
540
552
|
|
|
541
553
|
def check_same_content(before_hook: str, after_hook: str) -> bool:
|
|
542
554
|
"""
|
|
@@ -556,12 +568,7 @@ def check_same_content(before_hook: str, after_hook: str) -> bool:
|
|
|
556
568
|
``False`` if the files have different content.
|
|
557
569
|
"""
|
|
558
570
|
# Check if the files have the same content
|
|
559
|
-
|
|
560
|
-
# If the files are different, return False. Otherwise, return True
|
|
561
|
-
if same_files == False:
|
|
562
|
-
return False
|
|
563
|
-
else:
|
|
564
|
-
return True
|
|
571
|
+
return filecmp.cmp(before_hook, after_hook, shallow=False)
|
|
565
572
|
|
|
566
573
|
|
|
567
574
|
def apply_hook_changes(before_hook: str, after_hook: str) -> None:
|
|
@@ -586,6 +593,8 @@ def apply_hook_changes(before_hook: str, after_hook: str) -> None:
|
|
|
586
593
|
# the file after add-license-header was run.
|
|
587
594
|
for line in after_hook_lines:
|
|
588
595
|
# Copy the new reuse lines into the file
|
|
596
|
+
from reuse import extract
|
|
597
|
+
|
|
589
598
|
if extract.contains_reuse_info(line):
|
|
590
599
|
count += 1
|
|
591
600
|
found_reuse_info = True
|
|
@@ -625,8 +634,8 @@ def get_content(file: str) -> str:
|
|
|
625
634
|
str
|
|
626
635
|
Content of the file.
|
|
627
636
|
"""
|
|
628
|
-
|
|
629
|
-
|
|
637
|
+
with Path(file).open(encoding="utf-8", newline="", mode="r") as read_file:
|
|
638
|
+
content = read_file.readlines()
|
|
630
639
|
|
|
631
640
|
return content
|
|
632
641
|
|
|
@@ -767,6 +776,8 @@ def main():
|
|
|
767
776
|
else:
|
|
768
777
|
raise Exception("Please ensure the start year is a number.")
|
|
769
778
|
|
|
779
|
+
import git
|
|
780
|
+
|
|
770
781
|
# Get root directory of the git repository.
|
|
771
782
|
git_repo = git.Repo(Path.cwd(), search_parent_directories=True)
|
|
772
783
|
# Get the root of the git repository and fix the line separators
|
|
@@ -818,22 +829,22 @@ def main():
|
|
|
818
829
|
# Update the year span in the LICENSE file
|
|
819
830
|
license_return_code = update_license_file(repo_license_path, year_span)
|
|
820
831
|
|
|
832
|
+
from reuse.cli import common
|
|
833
|
+
|
|
821
834
|
# Create click object for the project
|
|
822
835
|
obj = common.ClickObj(git_root)
|
|
823
836
|
|
|
824
837
|
# Add or update headers of required files.
|
|
825
838
|
# Return 1 if files were added or updated, and return 0 if no files were altered.
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
else:
|
|
829
|
-
file_return_code = non_recursive_file_check(changed_headers, obj, values, args)
|
|
839
|
+
# No recursion needed because simply iterating over a flat list
|
|
840
|
+
file_return_code = non_recursive_file_check(changed_headers, obj, values, args)
|
|
830
841
|
|
|
831
842
|
# Unlink default files & remove .reuse and LICENSES folders if empty
|
|
832
843
|
cleanup(assets, git_root)
|
|
833
844
|
|
|
834
845
|
# Returns 1 if REUSE changes noncompliant files or the year was updated in LICENSE
|
|
835
846
|
# Returns 0 if all files are compliant
|
|
836
|
-
return 1 if
|
|
847
|
+
return 1 if license_return_code or file_return_code else 0
|
|
837
848
|
|
|
838
849
|
|
|
839
850
|
if __name__ == "__main__":
|