From 2f0ac20566d3037c714fa54f6dd47926d12ae0a1 Mon Sep 17 00:00:00 2001 From: Marco Ferrari Date: Wed, 14 Aug 2024 22:20:56 +0200 Subject: [PATCH] fix: avoid concurrent edits to the same file (#6027) Reduce the number of processes to 1 if at least one FIX_xxxx variable is set to true. This avoids that Parallel runs multiple processes that might edit the same file at the same time. --- lib/functions/validation.sh | 16 ++++++++++++++++ lib/linter.sh | 15 ++++++++++++++- test/lib/validationTest.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/functions/validation.sh b/lib/functions/validation.sh index 72c3fa17..12845580 100755 --- a/lib/functions/validation.sh +++ b/lib/functions/validation.sh @@ -7,6 +7,7 @@ function ValidateBooleanConfigurationVariables() { ValidateBooleanVariable "DISABLE_ERRORS" "${DISABLE_ERRORS}" ValidateBooleanVariable "ENABLE_GITHUB_ACTIONS_GROUP_TITLE" "${ENABLE_GITHUB_ACTIONS_GROUP_TITLE}" ValidateBooleanVariable "ENABLE_GITHUB_ACTIONS_STEP_SUMMARY" "${ENABLE_GITHUB_ACTIONS_STEP_SUMMARY}" + ValidateBooleanVariable "FIX_MODE_ENABLED" "${FIX_MODE_ENABLED}" ValidateBooleanVariable "FIX_MODE_TEST_CASE_RUN" "${FIX_MODE_TEST_CASE_RUN}" ValidateBooleanVariable "IGNORE_GENERATED_FILES" "${IGNORE_GENERATED_FILES}" ValidateBooleanVariable "IGNORE_GITIGNORED_FILES" "${IGNORE_GITIGNORED_FILES}" @@ -186,6 +187,21 @@ function ValidateCheckModeAndFixModeVariables() { done } +function CheckIfFixModeIsEnabled() { + for LANGUAGE in "${LANGUAGE_ARRAY[@]}"; do + local FIX_MODE_VARIABLE_NAME="FIX_${LANGUAGE}" + local -n FIX_MODE_REF="${FIX_MODE_VARIABLE_NAME}" + + if [[ -v "${FIX_MODE_VARIABLE_NAME}" ]] && + [[ "${FIX_MODE_REF:-"false"}" == "true" ]]; then + FIX_MODE_ENABLED="true" + debug "Fix mode for ${LANGUAGE} is ${FIX_MODE_REF}. Set FIX_MODE_ENABLED to ${FIX_MODE_ENABLED}" + fi + unset -n FIX_MODE_REF + done + ValidateBooleanVariable "FIX_MODE_ENABLED" "${FIX_MODE_ENABLED}" +} + function CheckIfGitBranchExists() { local BRANCH_NAME="${1}" debug "Check if the ${BRANCH_NAME} branch exists in ${GITHUB_WORKSPACE}" diff --git a/lib/linter.sh b/lib/linter.sh index a1674f31..a05e99c3 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -144,6 +144,8 @@ export SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH debug "Super-linter private output directory path: ${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}" mkdir -p "${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}" +FIX_MODE_ENABLED="false" + ValidateBooleanConfigurationVariables ########### @@ -819,8 +821,19 @@ declare PARALLEL_RESULTS_FILE_PATH PARALLEL_RESULTS_FILE_PATH="${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}/super-linter-results.json" debug "PARALLEL_RESULTS_FILE_PATH: ${PARALLEL_RESULTS_FILE_PATH}" +declare -i LINTING_MAX_PROCS +LINTING_MAX_PROCS=$(nproc) + +CheckIfFixModeIsEnabled +if [[ "${FIX_MODE_ENABLED}" == "true" ]]; then + # This slows down the fix process, but avoids that linters that work on the same + # types of files try opening the same file at the same time + LINTING_MAX_PROCS=1 + debug "Set LINTING_MAX_PROCS to ${LINTING_MAX_PROCS} to avoid that linters and formatters edit the same file at the same time." +fi + declare -a PARALLEL_COMMAND -PARALLEL_COMMAND=(parallel --will-cite --keep-order --max-procs "$(($(nproc) * 1))" --xargs --results "${PARALLEL_RESULTS_FILE_PATH}") +PARALLEL_COMMAND=(parallel --will-cite --keep-order --max-procs "$((LINTING_MAX_PROCS))" --xargs --results "${PARALLEL_RESULTS_FILE_PATH}") # Run one LANGUAGE per process. Each of these processes will run more processees in parellel if supported PARALLEL_COMMAND+=(--max-lines 1) diff --git a/test/lib/validationTest.sh b/test/lib/validationTest.sh index 0c30e2bd..6f5bfc97 100755 --- a/test/lib/validationTest.sh +++ b/test/lib/validationTest.sh @@ -499,6 +499,32 @@ function ValidateCheckModeAndFixModeVariablesTest() { notice "${FUNCTION_NAME} PASS" } +CheckIfFixModeIsEnabledTest() { + # shellcheck disable=SC2034 + LANGUAGE_ARRAY=('A') + + FIX_MODE_ENABLED="false" + FIX_A="true" + CheckIfFixModeIsEnabled + EXPECTED_FIX_MODE_ENABLED="true" + if [[ "${FIX_MODE_ENABLED}" == "${EXPECTED_FIX_MODE_ENABLED}" ]]; then + debug "FIX_MODE_ENABLED variable has the expected value: ${FIX_MODE_ENABLED}" + else + fatal "FIX_MODE_ENABLED (${FIX_MODE_ENABLED}) doesn't match with the expected value: ${EXPECTED_FIX_MODE_ENABLED}" + fi + + FIX_MODE_ENABLED="false" + FIX_A="false" + CheckIfFixModeIsEnabled + EXPECTED_FIX_MODE_ENABLED="false" + if [[ "${FIX_MODE_ENABLED}" == "${EXPECTED_FIX_MODE_ENABLED}" ]]; then + debug "FIX_MODE_ENABLED variable has the expected value: ${FIX_MODE_ENABLED}" + else + fatal "FIX_MODE_ENABLED (${FIX_MODE_ENABLED}) doesn't match with the expected value: ${EXPECTED_FIX_MODE_ENABLED}" + fi + +} + IsUnsignedIntegerSuccessTest IsUnsignedIntegerFailureTest ValidateDeprecatedVariablesTest @@ -509,3 +535,4 @@ ValidateAnsibleDirectoryTest ValidateValidationVariablesTest ValidationVariablesExportTest ValidateCheckModeAndFixModeVariablesTest +CheckIfFixModeIsEnabledTest