ansys-pre-commit-hooks 0.4.2__tar.gz → 0.4.4__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.
Files changed (37) hide show
  1. ansys_pre_commit_hooks-0.4.4/AUTHORS +12 -0
  2. {ansys_pre_commit_hooks-0.4.2/src/ansys_pre_commit_hooks.egg-info → ansys_pre_commit_hooks-0.4.4}/PKG-INFO +17 -17
  3. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/README.rst +8 -8
  4. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/pyproject.toml +15 -0
  5. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/setup.py +7 -7
  6. ansys_pre_commit_hooks-0.4.4/src/ansys/pre_commit_hooks/VERSION +1 -0
  7. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/__pycache__/__init__.cpython-310.pyc +0 -0
  8. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/__pycache__/tech_review.cpython-310.pyc +0 -0
  9. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/add_license_headers.py +99 -92
  10. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/CONTRIBUTORS.md +2 -2
  11. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4/src/ansys_pre_commit_hooks.egg-info}/PKG-INFO +17 -17
  12. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys_pre_commit_hooks.egg-info/SOURCES.txt +1 -1
  13. ansys_pre_commit_hooks-0.4.4/src/ansys_pre_commit_hooks.egg-info/requires.txt +18 -0
  14. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/tests/test_reuse.py +83 -37
  15. ansys_pre_commit_hooks-0.4.2/AUTHORS.md +0 -12
  16. ansys_pre_commit_hooks-0.4.2/src/ansys/pre_commit_hooks/VERSION +0 -1
  17. ansys_pre_commit_hooks-0.4.2/src/ansys_pre_commit_hooks.egg-info/requires.txt +0 -18
  18. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/LICENSE +0 -0
  19. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/MANIFEST.in +0 -0
  20. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/setup.cfg +0 -0
  21. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/__init__.py +0 -0
  22. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/assets/.reuse/templates/ansys.jinja2 +0 -0
  23. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/assets/LICENSES/MIT.txt +0 -0
  24. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/assets/licenses.json +0 -0
  25. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/tech_review.py +0 -0
  26. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/AUTHORS +0 -0
  27. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/CODE_OF_CONDUCT.md +0 -0
  28. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/CONTRIBUTING.md +0 -0
  29. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/LICENSE +0 -0
  30. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/README.md +0 -0
  31. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/README.rst +0 -0
  32. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys/pre_commit_hooks/templates/dependabot.yml +0 -0
  33. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys_pre_commit_hooks.egg-info/dependency_links.txt +0 -0
  34. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys_pre_commit_hooks.egg-info/entry_points.txt +0 -0
  35. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/src/ansys_pre_commit_hooks.egg-info/top_level.txt +0 -0
  36. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/tests/test_metadata.py +0 -0
  37. {ansys_pre_commit_hooks-0.4.2 → ansys_pre_commit_hooks-0.4.4}/tests/test_tech_review.py +0 -0
@@ -0,0 +1,12 @@
1
+ # This is the list of ansys-pre-commit-hooks' significant contributors.
2
+ #
3
+ # This file does not necessarily list everyone who has contributed code.
4
+ #
5
+ # For contributions made under a Corporate CLA, the organization is
6
+ # added to this file.
7
+ #
8
+ # If you have contributed to the repository and want to be added to this file,
9
+ # submit a request.
10
+ #
11
+ #
12
+ ANSYS, Inc.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansys-pre-commit-hooks
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: A Python wrapper to create Ansys-tailored pre-commit hooks
5
5
  Home-page: https://github.com/ansys/pre-commit-hooks
6
6
  Author: ANSYS, Inc.
@@ -23,23 +23,23 @@ Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Requires-Python: >=3.9,<4
25
25
  License-File: LICENSE
26
- License-File: AUTHORS.md
26
+ License-File: AUTHORS
27
27
  Requires-Dist: GitPython==3.1.43
28
- Requires-Dist: importlib-metadata==8.2.0
28
+ Requires-Dist: importlib-metadata==8.5.0
29
29
  Requires-Dist: Jinja2==3.1.4
30
30
  Requires-Dist: reuse==4.0.3
31
31
  Requires-Dist: requests==2.32.3
32
32
  Requires-Dist: semver==3.0.2
33
33
  Requires-Dist: toml==0.10.2
34
34
  Provides-Extra: doc
35
- Requires-Dist: ansys-sphinx-theme[autoapi]==0.16.6; extra == "doc"
36
- Requires-Dist: numpydoc==1.7.0; extra == "doc"
37
- Requires-Dist: sphinx==7.4.7; extra == "doc"
38
- Requires-Dist: sphinx-autodoc-typehints==2.2.3; extra == "doc"
35
+ Requires-Dist: ansys-sphinx-theme[autoapi]==1.2.0; extra == "doc"
36
+ Requires-Dist: numpydoc==1.8.0; extra == "doc"
37
+ Requires-Dist: sphinx==8.1.3; extra == "doc"
38
+ Requires-Dist: sphinx-autodoc-typehints==2.5.0; extra == "doc"
39
39
  Requires-Dist: sphinx-copybutton==0.5.1; extra == "doc"
40
40
  Provides-Extra: tests
41
- Requires-Dist: pytest==8.3.2; extra == "tests"
42
- Requires-Dist: pytest-cov==5.0.0; extra == "tests"
41
+ Requires-Dist: pytest==8.3.3; extra == "tests"
42
+ Requires-Dist: pytest-cov==6.0.0; extra == "tests"
43
43
 
44
44
  Ansys pre-commit hooks
45
45
  ======================
@@ -127,10 +127,10 @@ Set custom arguments
127
127
  .. code:: yaml
128
128
 
129
129
  - repo: https://github.com/ansys/pre-commit-hooks
130
- rev: v0.4.2
131
- hooks:
132
- - id: add-license-headers
133
- args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
130
+ rev: v0.4.4
131
+ hooks:
132
+ - id: add-license-headers
133
+ args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
134
134
 
135
135
  ``args`` can also be formatted as follows:
136
136
 
@@ -172,7 +172,7 @@ the hook should run on, add the necessary regex to the ``files`` line in your
172
172
  .. code:: yaml
173
173
 
174
174
  - repo: https://github.com/ansys/pre-commit-hooks
175
- rev: v0.4.2
175
+ rev: v0.4.4
176
176
  hooks:
177
177
  - id: add-license-headers
178
178
  files: '(src|examples|tests|newFolder)/.*\.(py|newExtension)|\.(proto|newExtension)'
@@ -185,7 +185,7 @@ In .pre-commit-config.yaml:
185
185
  .. code:: yaml
186
186
 
187
187
  - repo: https://github.com/ansys/pre-commit-hooks
188
- rev: v0.4.2
188
+ rev: v0.4.4
189
189
  hooks:
190
190
  - id: add-license-headers
191
191
  exclude: |
@@ -238,7 +238,7 @@ Technical review hook in ``ansys/pre-commit-hooks``' .pre-commit-config.yaml fil
238
238
  .. code:: yaml
239
239
 
240
240
  - repo: https://github.com/ansys/pre-commit-hooks
241
- rev: v0.4.2
241
+ rev: v0.4.4
242
242
  hooks:
243
243
  - id: tech-review
244
244
  args:
@@ -250,7 +250,7 @@ Technical review hook in ``PyMechanical``'s .pre-commit-config.yaml file:
250
250
  .. code:: yaml
251
251
 
252
252
  - repo: https://github.com/ansys/pre-commit-hooks
253
- rev: v0.4.2
253
+ rev: v0.4.4
254
254
  hooks:
255
255
  - id: tech-review
256
256
  args:
@@ -84,10 +84,10 @@ Set custom arguments
84
84
  .. code:: yaml
85
85
 
86
86
  - repo: https://github.com/ansys/pre-commit-hooks
87
- rev: v0.4.2
88
- hooks:
89
- - id: add-license-headers
90
- args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
87
+ rev: v0.4.4
88
+ hooks:
89
+ - id: add-license-headers
90
+ args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
91
91
 
92
92
  ``args`` can also be formatted as follows:
93
93
 
@@ -129,7 +129,7 @@ the hook should run on, add the necessary regex to the ``files`` line in your
129
129
  .. code:: yaml
130
130
 
131
131
  - repo: https://github.com/ansys/pre-commit-hooks
132
- rev: v0.4.2
132
+ rev: v0.4.4
133
133
  hooks:
134
134
  - id: add-license-headers
135
135
  files: '(src|examples|tests|newFolder)/.*\.(py|newExtension)|\.(proto|newExtension)'
@@ -142,7 +142,7 @@ In .pre-commit-config.yaml:
142
142
  .. code:: yaml
143
143
 
144
144
  - repo: https://github.com/ansys/pre-commit-hooks
145
- rev: v0.4.2
145
+ rev: v0.4.4
146
146
  hooks:
147
147
  - id: add-license-headers
148
148
  exclude: |
@@ -195,7 +195,7 @@ Technical review hook in ``ansys/pre-commit-hooks``' .pre-commit-config.yaml fil
195
195
  .. code:: yaml
196
196
 
197
197
  - repo: https://github.com/ansys/pre-commit-hooks
198
- rev: v0.4.2
198
+ rev: v0.4.4
199
199
  hooks:
200
200
  - id: tech-review
201
201
  args:
@@ -207,7 +207,7 @@ Technical review hook in ``PyMechanical``'s .pre-commit-config.yaml file:
207
207
  .. code:: yaml
208
208
 
209
209
  - repo: https://github.com/ansys/pre-commit-hooks
210
- rev: v0.4.2
210
+ rev: v0.4.4
211
211
  hooks:
212
212
  - id: tech-review
213
213
  args:
@@ -74,3 +74,18 @@ showcontent = true
74
74
  directory = "miscellaneous"
75
75
  name = "Miscellaneous"
76
76
  showcontent = true
77
+
78
+ [[tool.towncrier.type]]
79
+ directory = "documentation"
80
+ name = "Documentation"
81
+ showcontent = true
82
+
83
+ [[tool.towncrier.type]]
84
+ directory = "maintenance"
85
+ name = "Maintenance"
86
+ showcontent = true
87
+
88
+ [[tool.towncrier.type]]
89
+ directory = "test"
90
+ name = "Test"
91
+ showcontent = true
@@ -69,7 +69,7 @@ setup(
69
69
  python_requires=">=3.9,<4",
70
70
  install_requires=[
71
71
  "GitPython==3.1.43",
72
- "importlib-metadata==8.2.0",
72
+ "importlib-metadata==8.5.0",
73
73
  "Jinja2==3.1.4",
74
74
  "reuse==4.0.3",
75
75
  "requests==2.32.3",
@@ -78,15 +78,15 @@ setup(
78
78
  ],
79
79
  extras_require={
80
80
  "doc": [
81
- "ansys-sphinx-theme[autoapi]==0.16.6",
82
- "numpydoc==1.7.0",
83
- "sphinx==7.4.7",
84
- "sphinx-autodoc-typehints==2.2.3",
81
+ "ansys-sphinx-theme[autoapi]==1.2.0",
82
+ "numpydoc==1.8.0",
83
+ "sphinx==8.1.3",
84
+ "sphinx-autodoc-typehints==2.5.0",
85
85
  "sphinx-copybutton==0.5.1",
86
86
  ],
87
87
  "tests": [
88
- "pytest==8.3.2",
89
- "pytest-cov==5.0.0",
88
+ "pytest==8.3.3",
89
+ "pytest-cov==6.0.0",
90
90
  ],
91
91
  },
92
92
  project_urls={
@@ -28,17 +28,17 @@ A license header consists of the Ansys copyright statement and licensing informa
28
28
  import argparse
29
29
  from datetime import date as dt
30
30
  import filecmp
31
- import fileinput
32
31
  import json
33
32
  import os
34
33
  import pathlib
35
- from platform import python_version
34
+ import re
36
35
  import shutil
37
36
  import sys
38
37
  from tempfile import NamedTemporaryFile
39
38
 
40
39
  import git
41
40
  from reuse import _annotate, _util, lint, project
41
+ from reuse.vcs import VCSStrategyGit
42
42
 
43
43
  DEFAULT_TEMPLATE = "ansys"
44
44
  """Default template to use for license headers."""
@@ -445,47 +445,43 @@ def add_hook_changes(before_hook: str, after_hook: str) -> None:
445
445
  Path to file after add-license-headers was run.
446
446
  """
447
447
  count = 0
448
- before_hook_file = open(before_hook, "r", encoding="utf8")
449
- before_hook_lines = before_hook_file.readlines()
450
448
  found_reuse_info = False
451
449
 
452
- # Check if python version is 3.9 since fileinput.input()
453
- # does not support the "encoding" keyword
454
- if "3.9" in python_version():
455
- file = fileinput.input(after_hook, inplace=True)
456
- else:
457
- file = fileinput.input(after_hook, inplace=True, encoding="utf8")
458
-
459
- # Copy file content before add-license-header was run into
460
- # the file after add-license-header was run.
461
- # stdout is redirected into the file if inplace is True
462
- for line in file:
463
- # Copy the new reuse lines into the file
464
- if _util.contains_reuse_info(line):
465
- count += 1
466
- found_reuse_info = True
467
- print(line.rstrip())
468
- else:
469
- if found_reuse_info:
470
- try:
471
- # Check the lines after the reuse info are the same
472
- # If not, print the line after the reuse info
473
- # This happens when a comment changes from one line to
474
- # multiline
475
- if line != before_hook_lines[count]:
476
- print(line.rstrip())
477
- except IndexError:
478
- pass
479
-
480
- # Copy the rest of the file after the reuse information
481
- for line_after_reuse_info in before_hook_lines[count:]:
482
- print(line_after_reuse_info.rstrip())
483
- break
484
- # Copy the header lines before reuse information is found
485
- else:
450
+ before_hook_file = pathlib.Path(before_hook).open(encoding="utf-8", newline="", mode="r")
451
+ before_hook_lines = before_hook_file.readlines()
452
+
453
+ after_hook_file = pathlib.Path(after_hook).open(encoding="utf-8", newline="", mode="r")
454
+ after_hook_lines = after_hook_file.readlines()
455
+
456
+ with pathlib.Path(after_hook).open(encoding="utf-8", newline="", mode="w") as file:
457
+ # Copy file content before add-license-header was run into
458
+ # the file after add-license-header was run.
459
+ for line in after_hook_lines:
460
+ # Copy the new reuse lines into the file
461
+ if _util.contains_reuse_info(line):
486
462
  count += 1
487
- print(line.rstrip())
488
- fileinput.close()
463
+ found_reuse_info = True
464
+ file.write(line)
465
+ else:
466
+ if found_reuse_info:
467
+ try:
468
+ # Check the lines after the reuse info are the same
469
+ # If not, print the line after the reuse info
470
+ # This happens when a comment changes from one line to
471
+ # multiline
472
+ if line != before_hook_lines[count]:
473
+ file.write(line)
474
+ except IndexError:
475
+ pass
476
+
477
+ # Copy the rest of the file after the reuse information
478
+ for line_after_reuse_info in before_hook_lines[count:]:
479
+ file.write(line_after_reuse_info)
480
+ break
481
+ # Copy the header lines before reuse information is found
482
+ else:
483
+ count += 1
484
+ file.write(line)
489
485
 
490
486
 
491
487
  def get_full_paths(file_list: list) -> list:
@@ -513,7 +509,35 @@ def get_full_paths(file_list: list) -> list:
513
509
  return full_path_files
514
510
 
515
511
 
516
- def update_license_file(arg_dict):
512
+ def update_year_range(user_start_year, match_start_year, current_year, match_end_year):
513
+ """Update the year or year range in the LICENSE file.
514
+
515
+ Parameters
516
+ ----------
517
+ user_start_year: str
518
+ The start year supplied by the user in the pre-commit hook configuration.
519
+ match_start_year: str
520
+ The start year of the year range in the LICENSE file. For example, the LICENSE file
521
+ contains the range "2023 - 2024", so match_start_year is 2023.
522
+ current_year: str
523
+ The current year based on the datetime module.
524
+ match_end_year: str
525
+ The end year of the year range in the LICENSE file. For example, the LICENSE file
526
+ contains the range "2023 - 2024", so match_end_year is 2024.
527
+ """
528
+ # If the user start year from the pre-commit hook is less than the match start year,
529
+ # set the match_start_year as the user_start_year
530
+ if user_start_year < match_start_year:
531
+ match_start_year = user_start_year
532
+ # If the match end year is less than the current year, set the match_end_year to the
533
+ # current year
534
+ if match_end_year < current_year:
535
+ match_end_year = current_year
536
+
537
+ return match_start_year, match_end_year
538
+
539
+
540
+ def update_license_file(arg_dict: dict) -> int:
517
541
  """
518
542
  Update the LICENSE file to match MIT.txt, adjusting the year span to each repository.
519
543
 
@@ -540,60 +564,43 @@ def update_license_file(arg_dict):
540
564
  # 0 is unchanged, 1 is changed
541
565
  changed = 0
542
566
 
567
+ user_start_year = str(arg_dict["start_year"])
568
+ current_year = str(arg_dict["current_year"])
569
+ # Span or single year
570
+ year_regex = r"(\d{4}) - (\d{4})|\d{4}"
571
+
543
572
  # Check if custom_license is MIT
544
573
  if os.path.isfile(repo_license_loc) and (arg_dict["license"] == DEFAULT_LICENSE):
545
- if "3.9" in python_version():
546
- file = fileinput.input(repo_license_loc, inplace=True)
574
+ with pathlib.Path(repo_license_loc).open(encoding="utf-8", newline="", mode="r") as file:
575
+ lines = file.readlines()
576
+ content = "".join(lines)
577
+
578
+ # Get the first instance of the year range, either one year or a range of years
579
+ year_range_match = re.search(year_regex, content)
580
+ # Get the group from the year_range_match
581
+ year_range = year_range_match.group()
582
+ updated_year_range = ""
583
+
584
+ # Fix the start and end years in the range
585
+ if "-" in year_range:
586
+ match_start_yr, match_end_yr = update_year_range(
587
+ user_start_year, year_range_match.group(1), current_year, year_range_match.group(2)
588
+ )
547
589
  else:
548
- file = fileinput.input(repo_license_loc, inplace=True, encoding="utf8")
549
-
550
- copyright = arg_dict["copyright"]
551
- start_year = str(arg_dict["start_year"])
552
- current_year = str(arg_dict["current_year"])
553
-
554
- for line in file:
555
- if copyright in line:
556
- # Copyright line: "Copyright (c) 2023 - 2024 ANSYS, Inc. and/or its affiliates."
557
- # Get the index of the closing parenthesis of the copyright line
558
- paren_index = line.index(")") + 2
559
- # Get the index of the start of the copyright statement
560
- cpright_index = line.index(copyright) - 1
561
- # Create the year string to be replaced in the copyright line
562
- # For example, "2024", or "2023 - 2024"
563
- year_range = (
564
- f"{start_year} - {current_year}"
565
- if (start_year != current_year)
566
- else current_year
567
- )
568
-
569
- # If the start and end year are different
570
- if start_year != current_year:
571
- if "-" in line:
572
- # Get the index of the dash in the year range of the LICENSE file
573
- dash_index = line.index("-") - 1
574
- # Get the start year of the existing copyright line in the LICENSE file
575
- existing_start_year = line[paren_index:dash_index]
576
- # If the start year argument and the existing start year are different,
577
- # replace the existing start year with the new one.
578
- # For example, the existing start year is 2023, but the start_year
579
- # argument is 2022.
580
- if start_year != existing_start_year:
581
- line = line.replace(existing_start_year, start_year)
582
- else:
583
- # Replace the existing copyright years with the new year_range
584
- line = line.replace(line[paren_index:cpright_index], year_range)
585
- print(line.rstrip())
586
- else:
587
- if "-" in line:
588
- # If there is a year range in the existing LICENSE file, but the
589
- # start_year and current_year are the same, remove the year range
590
- # and replace it with the current year
591
- line = line.replace(line[paren_index:cpright_index], current_year)
592
- print(line.rstrip())
593
- else:
594
- print(line.rstrip())
590
+ match_start_yr, match_end_yr = update_year_range(
591
+ user_start_year, year_range, current_year, year_range
592
+ )
593
+
594
+ # Update the content if the start and end years are different
595
+ if match_start_yr != match_end_yr:
596
+ updated_year_range = f"{match_start_yr} - {match_end_yr}"
597
+ # print(f"Replacing {year_range} with {updated_year_range}")
598
+ content = re.sub(year_regex, updated_year_range, content)
595
599
 
596
- fileinput.close()
600
+ with pathlib.Path(repo_license_loc).open(
601
+ encoding="utf-8", newline="", mode="w"
602
+ ) as file:
603
+ file.write(content)
597
604
 
598
605
  # If the year changed, print a message that the LICENSE file was changed
599
606
  if not check_same_content(save_repo_license, repo_license_loc):
@@ -706,7 +713,7 @@ def find_files_missing_header() -> int:
706
713
  link_assets(assets, os_git_root, args)
707
714
 
708
715
  # Project to run `REUSE <https://reuse.software/>`_ on
709
- proj = project.Project(git_root)
716
+ proj = project.Project(git_root, vcs_strategy=VCSStrategyGit)
710
717
 
711
718
  # Get files missing headers (copyright and/or license information)
712
719
  missing_headers = list(list_noncompliant_files(args, proj))
@@ -1,9 +1,9 @@
1
1
  # Contributors
2
2
 
3
- ## Project Lead or Owner
3
+ ## Project Lead
4
4
 
5
5
  * [First Last](https://github.com/ghusername)
6
6
 
7
7
  ## Individual Contributors
8
8
 
9
- * [First Last](https://github.com/ghusername)
9
+ * [First Last](https://github.com/ghusername)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansys-pre-commit-hooks
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: A Python wrapper to create Ansys-tailored pre-commit hooks
5
5
  Home-page: https://github.com/ansys/pre-commit-hooks
6
6
  Author: ANSYS, Inc.
@@ -23,23 +23,23 @@ Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Requires-Python: >=3.9,<4
25
25
  License-File: LICENSE
26
- License-File: AUTHORS.md
26
+ License-File: AUTHORS
27
27
  Requires-Dist: GitPython==3.1.43
28
- Requires-Dist: importlib-metadata==8.2.0
28
+ Requires-Dist: importlib-metadata==8.5.0
29
29
  Requires-Dist: Jinja2==3.1.4
30
30
  Requires-Dist: reuse==4.0.3
31
31
  Requires-Dist: requests==2.32.3
32
32
  Requires-Dist: semver==3.0.2
33
33
  Requires-Dist: toml==0.10.2
34
34
  Provides-Extra: doc
35
- Requires-Dist: ansys-sphinx-theme[autoapi]==0.16.6; extra == "doc"
36
- Requires-Dist: numpydoc==1.7.0; extra == "doc"
37
- Requires-Dist: sphinx==7.4.7; extra == "doc"
38
- Requires-Dist: sphinx-autodoc-typehints==2.2.3; extra == "doc"
35
+ Requires-Dist: ansys-sphinx-theme[autoapi]==1.2.0; extra == "doc"
36
+ Requires-Dist: numpydoc==1.8.0; extra == "doc"
37
+ Requires-Dist: sphinx==8.1.3; extra == "doc"
38
+ Requires-Dist: sphinx-autodoc-typehints==2.5.0; extra == "doc"
39
39
  Requires-Dist: sphinx-copybutton==0.5.1; extra == "doc"
40
40
  Provides-Extra: tests
41
- Requires-Dist: pytest==8.3.2; extra == "tests"
42
- Requires-Dist: pytest-cov==5.0.0; extra == "tests"
41
+ Requires-Dist: pytest==8.3.3; extra == "tests"
42
+ Requires-Dist: pytest-cov==6.0.0; extra == "tests"
43
43
 
44
44
  Ansys pre-commit hooks
45
45
  ======================
@@ -127,10 +127,10 @@ Set custom arguments
127
127
  .. code:: yaml
128
128
 
129
129
  - repo: https://github.com/ansys/pre-commit-hooks
130
- rev: v0.4.2
131
- hooks:
132
- - id: add-license-headers
133
- args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
130
+ rev: v0.4.4
131
+ hooks:
132
+ - id: add-license-headers
133
+ args: ["--custom_copyright", "custom copyright phrase", "--custom_template", "template_name", "--custom_license", "license_name", "--ignore_license_check", "--start_year", "2023"]
134
134
 
135
135
  ``args`` can also be formatted as follows:
136
136
 
@@ -172,7 +172,7 @@ the hook should run on, add the necessary regex to the ``files`` line in your
172
172
  .. code:: yaml
173
173
 
174
174
  - repo: https://github.com/ansys/pre-commit-hooks
175
- rev: v0.4.2
175
+ rev: v0.4.4
176
176
  hooks:
177
177
  - id: add-license-headers
178
178
  files: '(src|examples|tests|newFolder)/.*\.(py|newExtension)|\.(proto|newExtension)'
@@ -185,7 +185,7 @@ In .pre-commit-config.yaml:
185
185
  .. code:: yaml
186
186
 
187
187
  - repo: https://github.com/ansys/pre-commit-hooks
188
- rev: v0.4.2
188
+ rev: v0.4.4
189
189
  hooks:
190
190
  - id: add-license-headers
191
191
  exclude: |
@@ -238,7 +238,7 @@ Technical review hook in ``ansys/pre-commit-hooks``' .pre-commit-config.yaml fil
238
238
  .. code:: yaml
239
239
 
240
240
  - repo: https://github.com/ansys/pre-commit-hooks
241
- rev: v0.4.2
241
+ rev: v0.4.4
242
242
  hooks:
243
243
  - id: tech-review
244
244
  args:
@@ -250,7 +250,7 @@ Technical review hook in ``PyMechanical``'s .pre-commit-config.yaml file:
250
250
  .. code:: yaml
251
251
 
252
252
  - repo: https://github.com/ansys/pre-commit-hooks
253
- rev: v0.4.2
253
+ rev: v0.4.4
254
254
  hooks:
255
255
  - id: tech-review
256
256
  args:
@@ -1,4 +1,4 @@
1
- AUTHORS.md
1
+ AUTHORS
2
2
  LICENSE
3
3
  MANIFEST.in
4
4
  README.rst
@@ -0,0 +1,18 @@
1
+ GitPython==3.1.43
2
+ importlib-metadata==8.5.0
3
+ Jinja2==3.1.4
4
+ reuse==4.0.3
5
+ requests==2.32.3
6
+ semver==3.0.2
7
+ toml==0.10.2
8
+
9
+ [doc]
10
+ ansys-sphinx-theme[autoapi]==1.2.0
11
+ numpydoc==1.8.0
12
+ sphinx==8.1.3
13
+ sphinx-autodoc-typehints==2.5.0
14
+ sphinx-copybutton==0.5.1
15
+
16
+ [tests]
17
+ pytest==8.3.3
18
+ pytest-cov==6.0.0
@@ -23,6 +23,7 @@
23
23
  import argparse
24
24
  from datetime import date as dt
25
25
  import os
26
+ from pathlib import Path
26
27
  import shutil
27
28
  import sys
28
29
  from tempfile import NamedTemporaryFile
@@ -32,7 +33,7 @@ import pytest
32
33
 
33
34
  import ansys.pre_commit_hooks.add_license_headers as hook
34
35
 
35
- git_repo = git.Repo(os.getcwd(), search_parent_directories=True)
36
+ git_repo = git.Repo(Path.cwd(), search_parent_directories=True)
36
37
  REPO_PATH = git_repo.git.rev_parse("--show-toplevel")
37
38
  START_YEAR = "2023"
38
39
 
@@ -70,12 +71,12 @@ def init_repo(tmp_path):
70
71
  def make_asset_dirs(tmp_path, template_path, template_name, license_path, license_name):
71
72
  """Make asset directories if using a custom license or template."""
72
73
  if template_name != "ansys.jinja2":
73
- reuse_dir = os.path.join(tmp_path, ".reuse", "templates")
74
+ reuse_dir = Path(tmp_path) / ".reuse" / "templates"
74
75
  os.makedirs(reuse_dir)
75
76
  shutil.copyfile(template_path, f"{reuse_dir}/{template_name}")
76
77
 
77
78
  if license_name != "MIT.txt":
78
- license_dir = os.path.join(tmp_path, "LICENSES")
79
+ license_dir = Path(tmp_path) / "LICENSES"
79
80
  os.makedirs(license_dir)
80
81
  shutil.copyfile(license_path, f"{license_dir}/{license_name}")
81
82
 
@@ -83,8 +84,8 @@ def make_asset_dirs(tmp_path, template_path, template_name, license_path, licens
83
84
  def cp_LICENSE_file(tmp_path):
84
85
  # Create LICENSE file in tmp_path repo
85
86
  license = "LICENSE"
86
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license)
87
- tmp_license = os.path.join(tmp_path, license)
87
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "LICENSES" / license
88
+ tmp_license = Path(tmp_path) / license
88
89
 
89
90
  os.chdir(tmp_path)
90
91
 
@@ -94,8 +95,8 @@ def cp_LICENSE_file(tmp_path):
94
95
 
95
96
  def create_test_file(tmp_path):
96
97
  """Create temporary file for reuse testing."""
97
- with NamedTemporaryFile(mode="w", delete=False, dir=tmp_path) as tmp:
98
- tmp.write("# test message")
98
+ with NamedTemporaryFile(mode="w", delete=False, dir=tmp_path, newline="") as tmp:
99
+ tmp.write(f"# test message\n")
99
100
  tmp.close()
100
101
  filename = tmp.name
101
102
 
@@ -140,8 +141,8 @@ def test_custom_start_year(tmp_path: pytest.TempPathFactory):
140
141
  # Set template and license names
141
142
  template_name = "ansys.jinja2"
142
143
  license_name = "MIT.txt"
143
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
144
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
144
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
145
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
145
146
 
146
147
  # Set up git repository in tmp_path with temporary file
147
148
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -171,8 +172,8 @@ def test_start_year_same_as_current(tmp_path: pytest.TempPathFactory):
171
172
  # Set template and license names
172
173
  template_name = "ansys.jinja2"
173
174
  license_name = "MIT.txt"
174
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
175
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
175
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
176
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
176
177
 
177
178
  # Set up git repository in tmp_path with temporary file
178
179
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -200,8 +201,8 @@ def test_custom_args(tmp_path: pytest.TempPathFactory):
200
201
  # Set template and license names
201
202
  template_name = "test_template.jinja2"
202
203
  license_name = "ECL-1.0.txt"
203
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name)
204
- license_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license_name)
204
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "templates" / template_name
205
+ license_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "LICENSES" / license_name
205
206
 
206
207
  # Set up git repository in tmp_path with temporary file
207
208
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -244,8 +245,8 @@ def test_multiple_files(tmp_path: pytest.TempPathFactory):
244
245
  # Set template and license names
245
246
  template_name = "ansys.jinja2"
246
247
  license_name = "MIT.txt"
247
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
248
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
248
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
249
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
249
250
 
250
251
  # Set up git repository in tmp_path with temporary file
251
252
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -279,8 +280,8 @@ def test_main_fails(tmp_path: pytest.TempPathFactory):
279
280
  # Set template and license names
280
281
  template_name = "ansys.jinja2"
281
282
  license_name = "MIT.txt"
282
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
283
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
283
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
284
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
284
285
 
285
286
  # Set up git repository in tmp_path with temporary file
286
287
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -319,8 +320,8 @@ def test_no_license_check(tmp_path: pytest.TempPathFactory):
319
320
  # Set template and license names
320
321
  template_name = "copyright_only.jinja2"
321
322
  license_name = "MIT.txt"
322
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name)
323
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
323
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "templates" / template_name
324
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
324
325
 
325
326
  # Set up git repository in tmp_path with temporary file
326
327
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -355,8 +356,8 @@ def test_header_doesnt_change(tmp_path: pytest.TempPathFactory):
355
356
  # Set template and license names
356
357
  template_name = "ansys.jinja2"
357
358
  license_name = "MIT.txt"
358
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
359
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
359
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
360
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
360
361
 
361
362
  # Set up git repository in tmp_path with temporary file
362
363
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -394,8 +395,8 @@ def test_update_changed_header(tmp_path: pytest.TempPathFactory):
394
395
  # Set template and license names
395
396
  template_name = "test_template.jinja2"
396
397
  license_name = "ECL-1.0.txt"
397
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name)
398
- license_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license_name)
398
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "templates" / template_name
399
+ license_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "LICENSES" / license_name
399
400
 
400
401
  # Set up git repository in tmp_path with temporary file
401
402
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -482,8 +483,8 @@ def test_bad_chars(tmp_path: pytest.TempPathFactory):
482
483
  template_name = "ansys.jinja2"
483
484
  license_name = "MIT.txt"
484
485
  bad_chars_name = "bad_chars.py"
485
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
486
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
486
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
487
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
487
488
 
488
489
  # Change dir to tmp_path
489
490
  os.chdir(tmp_path)
@@ -499,9 +500,7 @@ def test_bad_chars(tmp_path: pytest.TempPathFactory):
499
500
  cp_LICENSE_file(tmp_path)
500
501
 
501
502
  # Copy file with bad characters to git repository
502
- shutil.copyfile(
503
- os.path.join(REPO_PATH, "tests", "test_reuse_files", bad_chars_name), bad_chars_name
504
- )
503
+ shutil.copyfile(Path(REPO_PATH) / "tests" / "test_reuse_files" / bad_chars_name, bad_chars_name)
505
504
 
506
505
  # Assert the hook failed
507
506
  assert add_argv_run(repo, bad_chars_name, [bad_chars_name]) == 1
@@ -518,8 +517,8 @@ def test_index_exception(tmp_path: pytest.TempPathFactory):
518
517
  template_name = "copyright_only.jinja2"
519
518
  license_name = "MIT.txt"
520
519
  test_filename = "index_error.scss"
521
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name)
522
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
520
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "templates" / template_name
521
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
523
522
 
524
523
  # Change dir to tmp_path
525
524
  os.chdir(tmp_path)
@@ -535,9 +534,7 @@ def test_index_exception(tmp_path: pytest.TempPathFactory):
535
534
  cp_LICENSE_file(tmp_path)
536
535
 
537
536
  # Copy file that will cause an IndexError to git repository
538
- shutil.copyfile(
539
- os.path.join(REPO_PATH, "tests", "test_reuse_files", test_filename), test_filename
540
- )
537
+ shutil.copyfile(Path(REPO_PATH) / "tests" / "test_reuse_files" / test_filename, test_filename)
541
538
 
542
539
  custom_args = [
543
540
  test_filename,
@@ -589,8 +586,8 @@ def test_license_year_update(tmp_path: pytest.TempPathFactory):
589
586
  """Tests if the year in the license header is updated."""
590
587
  # license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
591
588
  license = "LICENSE"
592
- template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license)
593
- tmp_license = os.path.join(tmp_path, license)
589
+ template_path = Path(REPO_PATH) / "tests" / "test_reuse_files" / "LICENSES" / license
590
+ tmp_license = Path(tmp_path) / license
594
591
  custom_args = []
595
592
 
596
593
  os.chdir(tmp_path)
@@ -630,6 +627,7 @@ def test_license_year_update(tmp_path: pytest.TempPathFactory):
630
627
  os.chdir(REPO_PATH)
631
628
 
632
629
 
630
+ @pytest.mark.license_headers
633
631
  def test_no_recursion(tmp_path: pytest.TempPathFactory):
634
632
  """Test license headers with function that does not use recursion."""
635
633
  # Set template and license names
@@ -640,8 +638,8 @@ def test_no_recursion(tmp_path: pytest.TempPathFactory):
640
638
  # Set template and license names
641
639
  template_name = "ansys.jinja2"
642
640
  license_name = "MIT.txt"
643
- template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name)
644
- license_path = os.path.join(REPO_PATH, "LICENSES", license_name)
641
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
642
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
645
643
 
646
644
  # Set up git repository in tmp_path with temporary file
647
645
  repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
@@ -671,3 +669,51 @@ def test_no_recursion(tmp_path: pytest.TempPathFactory):
671
669
  check_ansys_header(file)
672
670
 
673
671
  os.chdir(REPO_PATH)
672
+
673
+
674
+ def get_line_endings(tmp_file):
675
+ """Get the line endings from the file."""
676
+ with open(tmp_file, "rb") as file:
677
+ # Read the file
678
+ content = file.read()
679
+ # Determine which line endings are in the content
680
+ if b"\r\n" in content:
681
+ return "Windows"
682
+ elif b"\n" in content:
683
+ return "Linux"
684
+ elif b"\r" in content:
685
+ return "Mac"
686
+
687
+
688
+ @pytest.mark.license_headers
689
+ def test_line_endings(tmp_path: pytest.TempPathFactory):
690
+ """Test line endings remain the same before and after running the hook."""
691
+ # List of files to be git added
692
+ new_files = []
693
+
694
+ # Set template and license names
695
+ template_name = "ansys.jinja2"
696
+ license_name = "MIT.txt"
697
+ template_path = Path(REPO_PATH) / ".reuse" / "templates" / template_name
698
+ license_path = Path(REPO_PATH) / "LICENSES" / license_name
699
+
700
+ # Set up git repository in tmp_path with temporary file
701
+ repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name)
702
+ tmp_license = Path(tmp_path) / "LICENSE"
703
+ new_files.append(tmp_file)
704
+
705
+ # Get the line endings from the file before the hook is run
706
+ file_line_endings_before = get_line_endings(tmp_file)
707
+ license_line_endings_before = get_line_endings(tmp_license)
708
+
709
+ # Add header to tmp_file
710
+ add_argv_run(repo, new_files, new_files)
711
+
712
+ # Update header file that has no changes
713
+ assert add_argv_run(repo, new_files, new_files) == 0
714
+
715
+ # Assert line endings haven't changed
716
+ assert file_line_endings_before == get_line_endings(tmp_file)
717
+ assert license_line_endings_before == get_line_endings(tmp_license)
718
+
719
+ os.chdir(REPO_PATH)
@@ -1,12 +0,0 @@
1
- # This is the list of ansys-pre-commit-hooks's significant contributors.
2
- #
3
- # This file does not necessarily list everyone who has contributed code.
4
- #
5
- # For contributions made under a Corporate CLA, the organization is
6
- # added to this file.
7
- #
8
- # If you have contributed to the repository and wish to be added to this file
9
- # please submit a request.
10
- #
11
- #
12
- ANSYS, Inc.
@@ -1,18 +0,0 @@
1
- GitPython==3.1.43
2
- importlib-metadata==8.2.0
3
- Jinja2==3.1.4
4
- reuse==4.0.3
5
- requests==2.32.3
6
- semver==3.0.2
7
- toml==0.10.2
8
-
9
- [doc]
10
- ansys-sphinx-theme[autoapi]==0.16.6
11
- numpydoc==1.7.0
12
- sphinx==7.4.7
13
- sphinx-autodoc-typehints==2.2.3
14
- sphinx-copybutton==0.5.1
15
-
16
- [tests]
17
- pytest==8.3.2
18
- pytest-cov==5.0.0