diff --git a/CHANGELOG.md b/CHANGELOG.md index fe34eb20..63002c56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log for spellcheck-github-actions +## 0.43.1, 2024-10-17, bug fix release, update recommended + +- This is an attempt at addressing the conflict between using the PySpelling `--source` parameter and the `sources` parameter in the PySpelling configuration file introduced by this action. With the recommendation of using the GitHub Action: [tj-actions/changed-files](https://github.com/marketplace/actions/changed-files), the use of the `--source` flag was adopted, but this bypasses the filtering mechanism, which can be enabled in the configuration file. The update recommendation is due to the fact that you might experience unwanted behaviour if your `sources` contain negated file patterns. The patch enables application of the configured filter to the source parameters, so the action can be used with the `--source` parameter and the `sources` configuration parameter in combination. + + - Issue [#213](https://github.com/rojopolis/spellcheck-github-actions/issues/213) + ## 0.43.0, 2024-10-08, maintenance release, update not required - Docker image updated to Python 3.12.7 slim via PR [#215](https://github.com/rojopolis/spellcheck-github-actions/pull/215) from Dependabot. [Release notes for Python 3.12.7](https://docs.python.org/release/3.12.7/whatsnew/changelog.html) diff --git a/Dockerfile b/Dockerfile index c6cdf5e4..5da81630 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,13 +6,14 @@ LABEL "com.github.actions.description"="Check spelling of files in repository" LABEL "com.github.actions.icon"="clipboard" LABEL "com.github.actions.color"="green" LABEL "repository"="http://github.com/rojopolis/spellcheck-github-actions" -LABEL "homepage"="http://github.com/actions" +LABEL "homepage"="https://github.com/marketplace/actions/github-spellcheck-action" LABEL "maintainer"="rojopolis " COPY entrypoint.sh /entrypoint.sh COPY requirements.txt /requirements.txt COPY constraint.txt /constraint.txt COPY spellcheck.yaml /spellcheck.yaml +COPY pwc.py /pwc.py ENV PIP_CONSTRAINT=/constraint.txt RUN pip3 install -r /requirements.txt diff --git a/entrypoint.sh b/entrypoint.sh index 8d23f641..5a047d9c 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -31,6 +31,8 @@ SPLIT=false if [ -n "$INPUT_SOURCE_FILES" ]; then + echo "Source files to check: >$INPUT_SOURCE_FILES<" + if grep -q $SINGLE <<< "$INPUT_SOURCE_FILES"; then OIFS=$IFS IFS=$SINGLE @@ -58,6 +60,15 @@ if [ -n "$INPUT_SOURCE_FILES" ]; then for FILE in "${arr[@]}"; do + echo "$FILE" | python3 /pwc.py "$SPELLCHECK_CONFIG_FILE" + + PATTERN_MATCH_EXITCODE=$? + + if [ $PATTERN_MATCH_EXITCODE -eq 1 ]; then + echo "Skipping file >$FILE<" + continue + fi + # Skip null items if [ -z "$FILE" ]; then continue @@ -79,34 +90,59 @@ if [ -n "$INPUT_SOURCE_FILES" ]; then read -r -a arr <<< "$INPUT_SOURCE_FILES" for FILE in "${arr[@]}"; do + echo "$FILE" | python3 /pwc.py "$SPELLCHECK_CONFIG_FILE" + + PATTERN_MATCH_EXITCODE=$? + + if [ $PATTERN_MATCH_EXITCODE -eq 1 ]; then + echo "Skipping file >$FILE<" + continue + fi SOURCES_LIST="$SOURCES_LIST --source $FILE" echo "Checking file >$FILE<" done fi + echo "Checking files specification in sources_list as: >$SOURCES_LIST<" + else - echo "Checking files matching specified outlined in >$SPELLCHECK_CONFIG_FILE<" + echo "Checking files matching specification outlined in: >$SPELLCHECK_CONFIG_FILE<" fi if [ -n "$INPUT_TASK_NAME" ]; then TASK_NAME="--name $INPUT_TASK_NAME" fi -echo "----------------------------------------------------------------" - EXITCODE=0 # shellcheck disable=SC2086 -if [ -n "$INPUT_OUTPUT_FILE" ]; then +if [ -n "$INPUT_OUTPUT_FILE" ] && [ -n "$SOURCES_LIST" ]; then pyspelling --verbose --config "$SPELLCHECK_CONFIG_FILE" $TASK_NAME $SOURCES_LIST | tee "$INPUT_OUTPUT_FILE" EXITCODE=${PIPESTATUS[0]} -else +elif [ -n "$INPUT_OUTPUT_FILE" ]; then + pyspelling --verbose --config "$SPELLCHECK_CONFIG_FILE" $TASK_NAME | tee "$INPUT_OUTPUT_FILE" + EXITCODE=${PIPESTATUS[0]} +elif [ -n "$SOURCES_LIST" ]; then pyspelling --verbose --config "$SPELLCHECK_CONFIG_FILE" $TASK_NAME $SOURCES_LIST EXITCODE=$? +elif [ -z "$INPUT_SOURCE_FILES" ]; then + pyspelling --verbose --config "$SPELLCHECK_CONFIG_FILE" $TASK_NAME + EXITCODE=$? +else + echo "No files to check, exiting" + EXITCODE=0 fi -test "$EXITCODE" -gt 1 && echo "::error title=Spelling check::Spelling check action failed, please check diagnostics"; +echo "----------------------------------------------------------------" + +if [ -n "$GITHUB_ACTIONS" ]; then + test "$EXITCODE" -gt 1 && echo "::error title=Spelling check::Spelling check action failed, please check diagnostics"; -test "$EXITCODE" -eq 1 && echo "::error title=Spelling errors::Files in repository contain spelling errors"; + test "$EXITCODE" -eq 1 && echo "::error title=Spelling errors::Files in repository contain spelling errors"; +else + test "$EXITCODE" -gt 1 && echo "Spelling check action failed, please check diagnostics"; + + test "$EXITCODE" -eq 1 && echo "Files in repository contain spelling errors"; +fi exit "$EXITCODE" diff --git a/pwc.py b/pwc.py new file mode 100755 index 00000000..65bd85ae --- /dev/null +++ b/pwc.py @@ -0,0 +1,36 @@ +#!python3 + +# This little helper script was implemented to extract the sources from the spellcheck configuration file +# The name pwc comes from Python WCMatch, which is used to match the files against the sources +# That is the short name I call it PriceWaterhouseCoopers, since it revises the file listing + +# read file and interpret it as yaml +def read_yaml(file): + + with open(file) as f: + data = yaml.safe_load(f) + return data + +import sys +import yaml +from wcmatch import glob + +# read filename from command line as first argument +spellcheck_configuration_file = sys.argv[1] + +data = read_yaml(spellcheck_configuration_file) + +# fetch the sources from the YAML data +sources = data.get('matrix')[0].get('sources') + +for changed_file in sys.stdin: + if 'q' == changed_file.rstrip(): + break + changed_file = changed_file.rstrip() + + matched = glob.globmatch(changed_file, sources, flags=glob.NEGATE | glob.GLOBSTAR | glob.SPLIT) + + if matched: + exit(0) + else: + exit(1) diff --git a/test/test.bats b/test/test.bats new file mode 100644 index 00000000..dc4ddd30 --- /dev/null +++ b/test/test.bats @@ -0,0 +1,41 @@ +@test "can do basic run using Docker image with two input files" { + docker run -e INPUT_SOURCE_FILES="README.md CHANGELOG.md" \ + -e INPUT_TASK_NAME=Markdown -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image with unignored and ignored input files" { + docker run -e INPUT_SOURCE_FILES="README.md venv/lib/python3.13/site-packages/pyspelling-2.10.dist-info/licenses/LICENSE.md" \ + -e INPUT_TASK_NAME=Markdown -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image with just ignored input file" { + docker run -e INPUT_SOURCE_FILES="venv/lib/python3.13/site-packages/pyspelling-2.10.dist-info/licenses/LICENSE.md" \ + -e INPUT_TASK_NAME=Markdown -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image without any input files" { + docker run \ + -e INPUT_TASK_NAME=Markdown -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image without task parameter" { + docker run \ + -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image with two input files but not task parameter" { + ! docker run -e INPUT_SOURCE_FILES="README.md CHANGELOG.md" \ + -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +} + +@test "can do basic run using Docker image with two non-existing input files" { + ! docker run -e INPUT_SOURCE_FILES="DONOTREADME.md LOGCHANGE.md" \ + -e INPUT_TASK_NAME=Markdown -it -v $PWD:/tmp \ + jonasbn/github-action-spellcheck:local +}