From 6b90ef357fc00a97722fd89084cd02b5b992a3b3 Mon Sep 17 00:00:00 2001 From: klmcadams Date: Fri, 12 Jan 2024 16:28:48 -0500 Subject: [PATCH 1/6] add python version matrix to pytest --- .github/workflows/ci_cd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 785ea389..e15299af 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -54,6 +54,7 @@ jobs: - uses: ansys/actions/tests-pytest@v5 with: pytest-extra-args: "--cov=ansys.pre_commit_hooks --cov-report=term --cov-report=html:.cov/html" + python-version: ${{ matrix.python-version }} doc-build: name: "Build documentation" From 373d1b3b59e003abfd73605a65177df94afab27b Mon Sep 17 00:00:00 2001 From: klmcadams Date: Fri, 12 Jan 2024 16:44:19 -0500 Subject: [PATCH 2/6] check python version for fileinput --- src/ansys/pre_commit_hooks/add_license_headers.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ansys/pre_commit_hooks/add_license_headers.py b/src/ansys/pre_commit_hooks/add_license_headers.py index 30bae08a..dccdfdc1 100644 --- a/src/ansys/pre_commit_hooks/add_license_headers.py +++ b/src/ansys/pre_commit_hooks/add_license_headers.py @@ -32,6 +32,7 @@ import json import os import pathlib +from platform import python_version import shutil import sys from tempfile import NamedTemporaryFile @@ -382,10 +383,17 @@ def add_hook_changes(before_hook: str, after_hook: str) -> None: before_hook_lines = before_hook_file.readlines() found_reuse_info = False + # Check if python version is 3.9 since fileinput.input() + # does not support the "encoding" keyword + if "3.9" in python_version(): + file = fileinput.input(after_hook, inplace=True) + else: + file = fileinput.input(after_hook, inplace=True, encoding="utf8") + # Copy file content before add-license-header was run into # the file after add-license-header was run. # stdout is redirected into the file if inplace is True - for line in fileinput.input(after_hook, inplace=True, encoding="utf8"): + for line in file: # Copy the new reuse lines into the file if _util.contains_reuse_info(line): count += 1 From 90c381bb8066f3de02a7402799a8a6cd3af8c9ce Mon Sep 17 00:00:00 2001 From: klmcadams Date: Fri, 12 Jan 2024 17:16:11 -0500 Subject: [PATCH 3/6] add test for reading bad characters --- tests/bad_chars.py | 24 ++++++++++++++++++++++++ tests/test_reuse.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/bad_chars.py diff --git a/tests/bad_chars.py b/tests/bad_chars.py new file mode 100644 index 00000000..0ba2d190 --- /dev/null +++ b/tests/bad_chars.py @@ -0,0 +1,24 @@ +# Copyright (C) 2024 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Test if fileinput.input() in add-license-headers decodes bad characters.""" +print("ÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴ") diff --git a/tests/test_reuse.py b/tests/test_reuse.py index 125c9ba4..303f5c9a 100644 --- a/tests/test_reuse.py +++ b/tests/test_reuse.py @@ -96,7 +96,7 @@ def add_argv_run(repo, tmp_file, custom_args): def check_ansys_header(file_name): """Check file contains all copyright and license header components.""" - file = open(file_name, "r") + file = open(file_name, "r", encoding="utf8") count = 0 for line in file: count += 1 @@ -496,3 +496,35 @@ def test_copy_assets(tmp_path: pytest.TempPathFactory): assert add_argv_run(repo, new_files, new_files) == 1 check_ansys_header(tmp_file) + + +def test_bad_chars(tmp_path: pytest.TempPathFactory): + # Set template and license names + template_name = "ansys.jinja2" + license_name = "MIT.txt" + bad_chars_name = "bad_chars.py" + template_path = os.path.join(REPO_PATH, ".reuse", "templates", template_name) + license_path = os.path.join(REPO_PATH, "LICENSES", license_name) + + # Change dir to tmp_path + os.chdir(tmp_path) + + # Make asset directories if using a custom license or template + # Asset directories are .reuse and LICENSES + make_asset_dirs(tmp_path, template_path, template_name, license_path, license_name) + + # Set up git repository in tmp_path + git.Repo.init(tmp_path) + repo = git.Repo(tmp_path) + repo.index.commit("initialized git repo for tmp_path") + + # Copy file with bad characters to git repository + shutil.copyfile(os.path.join(REPO_PATH, "tests", bad_chars_name), bad_chars_name) + + # Assert the hook failed + assert add_argv_run(repo, bad_chars_name, [bad_chars_name]) == 1 + + # Assert the hook added the license header correctly + check_ansys_header(bad_chars_name) + + os.chdir(REPO_PATH) From 34c7b84f3bca389489e44d5251f86152ee21a07a Mon Sep 17 00:00:00 2001 From: klmcadams Date: Fri, 12 Jan 2024 17:27:41 -0500 Subject: [PATCH 4/6] remove header from bad_chars.py --- .pre-commit-config.yaml | 12 +++++++++--- tests/bad_chars.py | 24 ++---------------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 30b73589..32ab4903 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,6 +41,12 @@ repos: - id: check-github-workflows - repo: https://github.com/ansys/pre-commit-hooks - rev: v0.2.4 - hooks: - - id: add-license-headers \ No newline at end of file + rev: v0.2.6 + hooks: + - id: add-license-headers + args: + - --start_year=2023 + exclude: | + (?x)^( + tests/bad_chars.py + )$ \ No newline at end of file diff --git a/tests/bad_chars.py b/tests/bad_chars.py index 0ba2d190..319368ba 100644 --- a/tests/bad_chars.py +++ b/tests/bad_chars.py @@ -1,24 +1,4 @@ -# Copyright (C) 2024 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - """Test if fileinput.input() in add-license-headers decodes bad characters.""" +# This intentionally does not have a header, so we can test the +# license header is added in test_reuse.py - test_bad_chars() print("ÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴ") From 1de2160ddc8aefd167950c65661dce34f6d2c167 Mon Sep 17 00:00:00 2001 From: klmcadams Date: Fri, 12 Jan 2024 18:18:13 -0500 Subject: [PATCH 5/6] add test for indexerror check --- .pre-commit-config.yaml | 3 +- test-repo | 1 + tests/test_reuse.py | 80 ++++++++++++++++--- .../LICENSES/ECL-1.0.txt | 0 tests/{ => test_reuse_files}/bad_chars.py | 0 tests/test_reuse_files/index_error.scss | 2 + .../templates/copyright_only.jinja2 | 0 .../templates/test_template.jinja2 | 0 8 files changed, 75 insertions(+), 11 deletions(-) create mode 160000 test-repo rename tests/{ => test_reuse_files}/LICENSES/ECL-1.0.txt (100%) rename tests/{ => test_reuse_files}/bad_chars.py (100%) create mode 100644 tests/test_reuse_files/index_error.scss rename tests/{ => test_reuse_files}/templates/copyright_only.jinja2 (100%) rename tests/{ => test_reuse_files}/templates/test_template.jinja2 (100%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 32ab4903..397cacec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,5 +48,6 @@ repos: - --start_year=2023 exclude: | (?x)^( - tests/bad_chars.py + tests/test_reuse_files/bad_chars.py | + tests/test_reuse_files/index_error.scss )$ \ No newline at end of file diff --git a/test-repo b/test-repo new file mode 160000 index 00000000..a59a0587 --- /dev/null +++ b/test-repo @@ -0,0 +1 @@ +Subproject commit a59a0587ae6746ae9e8eca1780d8176ea933a4e7 diff --git a/tests/test_reuse.py b/tests/test_reuse.py index 303f5c9a..87f4ebf2 100644 --- a/tests/test_reuse.py +++ b/tests/test_reuse.py @@ -58,12 +58,12 @@ def set_up_repo(tmp_path, template_path, template_name, license_path, license_na def make_asset_dirs(tmp_path, template_path, template_name, license_path, license_name): """Make asset directories if using a custom license or template.""" - if "ansys" not in template_name: + if template_name != "ansys.jinja2": reuse_dir = os.path.join(tmp_path, ".reuse", "templates") os.makedirs(reuse_dir) shutil.copyfile(template_path, f"{reuse_dir}/{template_name}") - if "MIT" not in license_name: + if license_name != "MIT.txt": license_dir = os.path.join(tmp_path, "LICENSES") os.makedirs(license_dir) shutil.copyfile(license_path, f"{license_dir}/{license_name}") @@ -175,8 +175,8 @@ def test_custom_args(tmp_path: pytest.TempPathFactory): # Set template and license names template_name = "test_template.jinja2" license_name = "ECL-1.0.txt" - template_path = os.path.join(REPO_PATH, "tests", "templates", template_name) - license_path = os.path.join(REPO_PATH, "tests", "LICENSES", license_name) + template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name) + license_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license_name) # Set up git repository in tmp_path with temporary file repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name) @@ -291,7 +291,7 @@ def test_no_license_check(tmp_path: pytest.TempPathFactory): # Set template and license names template_name = "copyright_only.jinja2" license_name = "MIT.txt" - template_path = os.path.join(REPO_PATH, "tests", "templates", template_name) + template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name) license_path = os.path.join(REPO_PATH, "LICENSES", license_name) # Set up git repository in tmp_path with temporary file @@ -364,8 +364,8 @@ def test_update_changed_header(tmp_path: pytest.TempPathFactory): # Set template and license names template_name = "test_template.jinja2" license_name = "ECL-1.0.txt" - template_path = os.path.join(REPO_PATH, "tests", "templates", template_name) - license_path = os.path.join(REPO_PATH, "tests", "LICENSES", license_name) + template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name) + license_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license_name) # Set up git repository in tmp_path with temporary file repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name) @@ -425,8 +425,8 @@ def test_missing_licenses(tmp_path: pytest.TempPathFactory): # Set template and license names template_name = "test_template.jinja2" license_name = "ECL-1.0.txt" - template_path = os.path.join(REPO_PATH, "tests", "templates", template_name) - license_path = os.path.join(REPO_PATH, "tests", "LICENSES", license_name) + template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name) + license_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "LICENSES", license_name) # Set up git repository in tmp_path with temporary file repo, tmp_file = set_up_repo(tmp_path, template_path, template_name, license_path, license_name) @@ -519,7 +519,9 @@ def test_bad_chars(tmp_path: pytest.TempPathFactory): repo.index.commit("initialized git repo for tmp_path") # Copy file with bad characters to git repository - shutil.copyfile(os.path.join(REPO_PATH, "tests", bad_chars_name), bad_chars_name) + shutil.copyfile( + os.path.join(REPO_PATH, "tests", "test_reuse_files", bad_chars_name), bad_chars_name + ) # Assert the hook failed assert add_argv_run(repo, bad_chars_name, [bad_chars_name]) == 1 @@ -528,3 +530,61 @@ def test_bad_chars(tmp_path: pytest.TempPathFactory): check_ansys_header(bad_chars_name) os.chdir(REPO_PATH) + + +def test_index_exception(tmp_path: pytest.TempPathFactory): + # Set template and license names + template_name = "copyright_only.jinja2" + license_name = "MIT.txt" + test_filename = "index_error.scss" + template_path = os.path.join(REPO_PATH, "tests", "test_reuse_files", "templates", template_name) + license_path = os.path.join(REPO_PATH, "LICENSES", license_name) + + # Change dir to tmp_path + os.chdir(tmp_path) + + # Make asset directories if using a custom license or template + # Asset directories are .reuse and LICENSES + make_asset_dirs(tmp_path, template_path, template_name, license_path, license_name) + + # Set up git repository in tmp_path + git.Repo.init(tmp_path) + repo = git.Repo(tmp_path) + repo.index.commit("initialized git repo for tmp_path") + + # Copy file that will cause an IndexError to git repository + shutil.copyfile( + os.path.join(REPO_PATH, "tests", "test_reuse_files", test_filename), test_filename + ) + + custom_args = [ + test_filename, + "--custom_template=copyright_only", + "--custom_copyright=ANSYS, Inc. Unauthorized use, distribution, \ + or duplication is prohibited.", + "--ignore_license_check", + "--start_year=2023", + ] + + # Assert the hook failed + assert add_argv_run(repo, test_filename, custom_args) == 1 + + # Assert the single line comment changed to + # a multiline comment. This causes an IndexError in the hook + file = open(test_filename, "r") + count = 0 + for line in file: + count += 1 + if count == 1: + assert "/*" in line + # Ensure header was updated correctly and didn't add + # an extra SPDX-Identifier line + if count == 2: + assert f" * Copyright (C) 2023 - {dt.today().year} ANSYS, Inc. Unauthorized use" in line + if count == 3: + assert "*/" in line + if count > 4: + break + file.close() + + os.chdir(REPO_PATH) diff --git a/tests/LICENSES/ECL-1.0.txt b/tests/test_reuse_files/LICENSES/ECL-1.0.txt similarity index 100% rename from tests/LICENSES/ECL-1.0.txt rename to tests/test_reuse_files/LICENSES/ECL-1.0.txt diff --git a/tests/bad_chars.py b/tests/test_reuse_files/bad_chars.py similarity index 100% rename from tests/bad_chars.py rename to tests/test_reuse_files/bad_chars.py diff --git a/tests/test_reuse_files/index_error.scss b/tests/test_reuse_files/index_error.scss new file mode 100644 index 00000000..ef3378b9 --- /dev/null +++ b/tests/test_reuse_files/index_error.scss @@ -0,0 +1,2 @@ +// Copyright (C) 2023 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. +// This tests the before_hook index exception in add-license-headers. \ No newline at end of file diff --git a/tests/templates/copyright_only.jinja2 b/tests/test_reuse_files/templates/copyright_only.jinja2 similarity index 100% rename from tests/templates/copyright_only.jinja2 rename to tests/test_reuse_files/templates/copyright_only.jinja2 diff --git a/tests/templates/test_template.jinja2 b/tests/test_reuse_files/templates/test_template.jinja2 similarity index 100% rename from tests/templates/test_template.jinja2 rename to tests/test_reuse_files/templates/test_template.jinja2 From 08c3a8da7119eaf20ddff05bcda30a86f2010be0 Mon Sep 17 00:00:00 2001 From: klmcadams Date: Sat, 13 Jan 2024 13:35:29 -0500 Subject: [PATCH 6/6] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56321513..fb9ed93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ This document follows the conventions laid out in [Keep a CHANGELOG](https://keepachangelog.com/en/1.0.0). +## [Unreleased]() + +### Fixed + +- Fix pytest python versions and fileinput [#118](https://github.com/ansys/pre-commit-hooks/pull/118) + ## [0.2.6](https://github.com/ansys/pre-commit-hooks/releases/tag/v0.2.6) - January 11 2024 ### Added