diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2042e817..5bedfebe 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +* Fix detection of changed files that might cause failure on paths with special characters. * Drop support for `shell-scripts` input * Drop support for `ignored-codes` input diff --git a/src/functions.sh b/src/functions.sh index b7fe1652..976a1f58 100644 --- a/src/functions.sh +++ b/src/functions.sh @@ -83,7 +83,7 @@ get_scripts_for_scanning () { # Find modified shell scripts local list_of_changes=() - file_to_array "${1}" "list_of_changes" 0 + file_to_array "${1}" "list_of_changes" # Create a list of scripts for testing local scripts_for_scanning=() @@ -212,17 +212,21 @@ is_matched_by_path () { return 2 } -# Function to get rid of comments represented by '#' +# Function that reads a file of paths and stores them in an array +# https://stackoverflow.com/a/28109890/10221282 # $1 - file path # $2 - name of a variable where the result array will be stored -# $3 - value 1|0 - does the file contain inline comments? # $? - return value - 0 on success file_to_array () { - [[ $# -le 2 ]] && return 1 + [[ $# -le 1 ]] && return 1 local output=() - [[ "$3" -eq 0 ]] && readarray output < <(grep -v "^#.*" "$1") # fetch the array with lines from the file while excluding '#' comments - [[ "$3" -eq 1 ]] && readarray output < <(cut -d ' ' -f 1 < <(grep -v "^#.*" "$1")) # fetch the array with lines from the file while excluding '#' comments + while IFS= read -r -d '' file; do + output+=("${file}") + done < "${1}" + + [[ ${UNIT_TESTS:-1} -eq 0 ]] && echo "${output[@]}" + clean_array "$2" "${output[@]}" && return 0 } @@ -250,7 +254,7 @@ clean_array () { local cleaned_item="" cleaned_item=$(printf '%s' "${i##+([[:space:]])}") \ && cleaned_item=$(printf '%s' "${cleaned_item%%+([[:space:]])}") - eval $output+=\("$(printf '%q' "${cleaned_item}")"\) + eval "${output}"+=\("$(printf '%q' "${cleaned_item}")"\) done [[ ${extglob_state} -ne 0 ]] && shopt -u extglob diff --git a/src/index.sh b/src/index.sh index 6beb56a5..f8949169 100755 --- a/src/index.sh +++ b/src/index.sh @@ -27,7 +27,7 @@ is_full_scan_demanded FULL_SCAN=$? if [[ ${FULL_SCAN} -eq 0 ]]; then - git ls-tree -r --name-only "${GITHUB_REF_NAME-"main"}" > ../files.txt + git ls-tree -r --name-only -z "${GITHUB_REF_NAME-"main"}" > ../files.txt all_scripts=() get_scripts_for_scanning "../files.txt" "all_scripts" @@ -37,7 +37,7 @@ if ! [[ ${FULL_SCAN} -eq 0 ]] || ! is_strict_check_on_push_demanded; then # https://github.com/actions/runner/issues/342 # Get the names of files from range of commits (excluding deleted files) # BASE and HEAD are always set, it is checked inside pick_base_and_head_hash function - git diff --name-only --diff-filter=db "${BASE}".."${HEAD}" > ../changed-files.txt + git diff --name-only -z --diff-filter=db "${BASE}".."${HEAD}" > ../changed-files.txt only_changed_scripts=() get_scripts_for_scanning "../changed-files.txt" "only_changed_scripts" diff --git a/test/file_to_array.bats b/test/file_to_array.bats index 6fff23ac..4d215880 100644 --- a/test/file_to_array.bats +++ b/test/file_to_array.bats @@ -16,7 +16,7 @@ setup () { touch file.txt file_array=() - run file_to_array "file.txt" "file_array" + run file_to_array "file.txt" assert_failure 1 assert_equal "${file_array[*]}" "" } @@ -28,43 +28,20 @@ setup () { touch file.txt file_array=() - run file_to_array "file.txt" "file_array" 0 + run file_to_array "file.txt" "file_array" # assert_success assert_equal "${file_array[*]}" "" } -@test "file_to_array() - in-line comments" { - source "${PROJECT_ROOT}/src/functions.sh" - - echo -e "\ -# comment -#comment -Something1\t # comment -# comment -\rSomething2\r #comment -Something3" > file.txt - - local file_array=() - file_to_array "file.txt" "file_array" 1 - assert_equal "${file_array[*]}" "Something1 Something2 Something3" -} - -@test "file_to_array() - no in-line comments" { +@test "file_to_array() - general" { source "${PROJECT_ROOT}/src/functions.sh" - echo -e "\ -# comment -#comment -Something1\t -# comment -\rSomething2\r -Something3 -Something 4 \r -\r Something5&Something6 conf \r" > file.txt + UNIT_TESTS=0 - local file_array=() - file_to_array "file.txt" "file_array" 0 - assert_equal "${file_array[*]}" "Something1 Something2 Something3 Something 4 Something5&Something6 conf" + file_array=() + run file_to_array "./test/fixtures/file_to_array/files.txt" "file_array" + assert_success + assert_output "test/fixtures/get_scripts_for_scanning/files.txt test/fixtures/get_scripts_for_scanning/non-script.md test/fixtures/get_scripts_for_scanning/script1.sh test/fixtures/get_scripts_for_scanning/script2 test/fixtures/get_scripts_for_scanning/script 2.sh test/fixtures/get_scripts_for_scanning/script&3.sh test/fixtures/get_scripts_for_scanning/\$script4.sh test/fixtures/get_scripts_for_scanning/dm-back\\x2dslash.swap" } teardown () { diff --git a/test/fixtures/file_to_array/files.txt b/test/fixtures/file_to_array/files.txt new file mode 100644 index 00000000..c1ae50b8 Binary files /dev/null and b/test/fixtures/file_to_array/files.txt differ diff --git "a/test/fixtures/get_scripts_for_scanning/dm-back\\x2dslash.swap" "b/test/fixtures/get_scripts_for_scanning/dm-back\\x2dslash.swap" new file mode 100644 index 00000000..2886021b --- /dev/null +++ "b/test/fixtures/get_scripts_for_scanning/dm-back\\x2dslash.swap" @@ -0,0 +1,10 @@ +swap +[Unit] +SourcePath=/etc/fstab +Documentation=man:fstab(5) man:systemd-fstab-generator(8) + +[Swap] +What=/dev/mapper/fedora_krowka-swap +Options=defaults,x-systemd.device-timeout=0 +Priority=11 +TimeoutSec=123h 5min 2y diff --git a/test/fixtures/get_scripts_for_scanning/files.txt b/test/fixtures/get_scripts_for_scanning/files.txt index 0a3d2145..c1ae50b8 100644 Binary files a/test/fixtures/get_scripts_for_scanning/files.txt and b/test/fixtures/get_scripts_for_scanning/files.txt differ diff --git a/test/get_scripts_for_scanning.bats b/test/get_scripts_for_scanning.bats index c219ff76..1b69c0a2 100644 --- a/test/get_scripts_for_scanning.bats +++ b/test/get_scripts_for_scanning.bats @@ -10,7 +10,7 @@ setup () { load 'test_helper/bats-support/load' } -@test "get_scripts_for_scanning()" { +@test "get_scripts_for_scanning() - general" { source "${PROJECT_ROOT}/src/functions.sh" UNIT_TESTS=0 @@ -24,7 +24,7 @@ setup () { shell_scripts=() run get_scripts_for_scanning "./test/fixtures/get_scripts_for_scanning/files.txt" "shell_scripts" assert_success - assert_output "'./test/fixtures/get_scripts_for_scanning/script1.sh' './test/fixtures/get_scripts_for_scanning/script2' './test/fixtures/get_scripts_for_scanning/script 2.sh' './test/fixtures/get_scripts_for_scanning/script&3.sh' './test/fixtures/get_scripts_for_scanning/\$script4.sh'" + assert_output --partial "'./test/fixtures/get_scripts_for_scanning/script1.sh' './test/fixtures/get_scripts_for_scanning/script2' './test/fixtures/get_scripts_for_scanning/script 2.sh' './test/fixtures/get_scripts_for_scanning/script&3.sh' './test/fixtures/get_scripts_for_scanning/\$script4.sh'" } teardown () {