diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 51f1427..b6bcf1a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,4 +22,4 @@ jobs: - name: Build docker run: docker build . -t header-validator:py3.8.13-alpine - name: Run action - run: docker run --workdir /github/workspace -v "/home/runner/work/validate-python-headers/validate-python-headers":"/github/workspace" header-validator:py3.8.13-alpine Apache-2.0 'François-Guillaume Fernandez' 2022 src/ __init__.py + run: docker run --workdir /github/workspace -v "/home/runner/work/validate-python-headers/validate-python-headers":"/github/workspace" header-validator:py3.8.13-alpine Apache-2.0 'François-Guillaume Fernandez' 2022 src/ __init__.py .github/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3abaf08..b7982f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,10 +8,10 @@ Whatever the way you wish to contribute to the project, please respect the [code ## Codebase structure -- [src](https://github.com/frgfm/validate-python-headers/blob/main/src) - The actual script used for header verification -- [action.yml](https://github.com/frgfm/validate-python-headers/blob/main/tests) - The marketplace action configuration file -- [Dockerfile](https://github.com/frgfm/validate-python-headers/blob/main/Dockerfile) - The dockerfile of the action -- [entrypoint.sh](https://github.com/frgfm/validate-python-headers/blob/main/entrypoint.sh) - The bash script executed by the Docker container +- [`./src`](https://github.com/frgfm/validate-python-headers/blob/main/src) - The actual script used for header verification +- [`action.yml`](https://github.com/frgfm/validate-python-headers/blob/main/tests) - The marketplace action configuration file +- [`Dockerfile`](https://github.com/frgfm/validate-python-headers/blob/main/Dockerfile) - The dockerfile of the action +- [`entrypoint.sh`](https://github.com/frgfm/validate-python-headers/blob/main/entrypoint.sh) - The bash script executed by the Docker container ## Continuous Integration diff --git a/Makefile b/Makefile index 99d3a94..b13ae8a 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,4 @@ build: # Run tests for the library test: docker build . -t header-validator:py3.8.13-alpine - docker run --workdir /github/workspace -v src:/github/workspace/src header-validator:py3.8.13-alpine Apache-2.0 'François-Guillaume Fernandez' 2022 src/ __init__.py + docker run --workdir /github/workspace -v src:/github/workspace/src header-validator:py3.8.13-alpine Apache-2.0 'François-Guillaume Fernandez' 2022 src/ __init__.py .github/ diff --git a/README.md b/README.md index 7a41594..02d47fa 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,14 @@ This action checks the copyright and license notices in the headers of your Pyth The folders to inspect, separated by a comma. Default `"."`. -### `ignores` +### `ignore-files` The files to ignore, separated by a comma. Default `"__init__.py"`. +### `ignore-folders` + +The folders to ignore, separated by a comma. Default `".github/"`. + ## Outputs The list of files with header issues. diff --git a/action.yml b/action.yml index 8869089..5cef6f5 100644 --- a/action.yml +++ b/action.yml @@ -20,10 +20,14 @@ inputs: description: 'Folders to inspect' required: false default: '.' - ignores: + ignore-files: description: 'Files to ignore' required: false default: '__init__.py' + ignore-folders: + description: 'Folders to ignore' + required: false + default: '.github/' outputs: issues: # id of output @@ -37,4 +41,5 @@ runs: - ${{ inputs.owner }} - ${{ inputs.starting-year }} - ${{ inputs.folders }} - - ${{ inputs.ignores }} + - ${{ inputs.ignore-files }} + - ${{ inputs.ignore-folders }} diff --git a/entrypoint.sh b/entrypoint.sh index 7decd8d..05e5b41 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/sh -l set -eax -python /validate_headers.py "${1}" "${2}" $3 --folders $4 --ignores $5 +python /validate_headers.py "${1}" "${2}" $3 --folders $4 --ignore-files $5 --ignore-folders $6 diff --git a/src/validate_headers.py b/src/validate_headers.py index 9208c54..a3d7307 100644 --- a/src/validate_headers.py +++ b/src/validate_headers.py @@ -62,7 +62,8 @@ def main(args): # Check args & define all header options header_options = get_header_options(args.license, args.owner, args.year) - ignored_files = args.ignores.split(",") + ignored_files = args.ignore_files.split(",") + ignored_folders = [Path(folder) for folder in args.ignore_folders.split(",")] folders = args.folders.split(",") invalid_files = [] @@ -72,21 +73,22 @@ def main(args): folder_path = Path(folder) assert folder_path.is_dir(), f"Invalid folder path: {folder}" for source_path in folder_path.rglob("**/*.py"): - if source_path.name not in ignored_files: - # Parse header - header_length = max(len(option) for option in header_options) - current_header = [] - with open(source_path) as f: - for idx, line in enumerate(f): - current_header.append(line) - if idx == header_length - 1: - break - # Validate it - if not any( - "".join(current_header[: min(len(option), len(current_header))]) == "".join(option) - for option in header_options - ): - invalid_files.append(source_path) + if source_path.name in ignored_files or any(folder in source_path.parents for folder in ignored_folders): + continue + # Parse header + header_length = max(len(option) for option in header_options) + current_header = [] + with open(source_path) as f: + for idx, line in enumerate(f): + current_header.append(line) + if idx == header_length - 1: + break + # Validate it + if not any( + "".join(current_header[: min(len(option), len(current_header))]) == "".join(option) + for option in header_options + ): + invalid_files.append(source_path) if len(invalid_files) > 0: invalid_str = "\n- " + "\n- ".join(map(str, invalid_files)) @@ -105,7 +107,8 @@ def parse_args(): parser.add_argument("owner", type=str, help="name of the copyright owner") parser.add_argument("year", type=int, help="first copyright year of the project") parser.add_argument("--folders", type=str, default=".", help="folders to inspect") - parser.add_argument("--ignores", type=str, default="", help="files to ignore") + parser.add_argument("--ignore-files", type=str, default="", help="files to ignore") + parser.add_argument("--ignore-folders", type=str, default="", help="folders to ignore") args = parser.parse_args() return args