add --skip-lexical-errors for pmd cpd

report error on api generator run failure
add bootstrap scripts for code lint
This commit is contained in:
Ivan Smolin 2023-12-21 19:41:56 +03:00
parent 4dfed1b2a8
commit f8865b3232
6 changed files with 148 additions and 41 deletions

View File

@ -0,0 +1,25 @@
#!/bin/sh
# Description:
# Runs full linting and copy-paste-detection for project
#
# Required environment variables:
# SRCROOT - project directory.
# SCRIPT_DIR - directory of current script.
#
# Optional environment variables:
# See swiftlint.sh and copy_paste_detection.sh for complete list of available variables
#
# Example of usage:
# ./full_code_lint.sh
#
if [ -z "${SCRIPT_DIR}" ]; then
SCRIPT_DIR=${SRCROOT}/build-scripts/xcode/build_phases
fi
. ${SRCROOT}/build-scripts/xcode/aux_scripts/install_env.sh swiftlint
FORCE_LINT=true; . ${SCRIPT_DIR}/swiftlint.sh
. ${SRCROOT}/build-scripts/xcode/aux_scripts/install_env.sh cpd
. ${SCRIPT_DIR}/copy_paste_detection.sh Localization Generated Pods

View File

@ -0,0 +1,22 @@
#!/bin/sh
# Description:
# Runs incremental linting for project
#
# Required environment variables:
# SRCROOT - project directory.
# SCRIPT_DIR - directory of current script.
#
# Optional environment variables:
# See swiftlint.sh for complete list of available variables
#
# Example of usage:
# ./incremetal_code_lint.sh
#
if [ -z "${SCRIPT_DIR}" ]; then
SCRIPT_DIR=${SRCROOT}/build-scripts/xcode/build_phases
fi
. ${SRCROOT}/build-scripts/xcode/aux_scripts/install_env.sh swiftlint
. ${SCRIPT_DIR}/swiftlint.sh

View File

@ -24,36 +24,50 @@
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly TRUE=0
readonly FALSE=1
readonly TRUE=1
readonly FALSE=0
readonly LOG_TAG="API-GENERATOR"
notice()
{
echo "${LOG_TAG}:NOTICE: ${1}"
echo "${LOG_TAG}:NOTICE: ${1}" >&2
}
debug()
{
if [ ! -z "${VERBOSE}" ]; then
echo "${LOG_TAG}:DEBUG: ${1}"
echo "${LOG_TAG}:DEBUG: ${1}" >&2
fi
}
exit_on_failure()
{
eval ${1}
local -r EXIT_CODE=$?
if [ ${EXIT_CODE} -ne 0 ]; then
echo "Recent command: \`${1}\` failed with code ${EXIT_CODE}"
exit ${EXIT_CODE}
fi
}
is_force_run()
{
if [ -z "${FORCE_RUN}" ]; then
return ${FALSE}
echo ${FALSE}
return
fi
local -r STR_MODE=`tr "[:upper:]" "[:lower:]" <<< ${FORCE_RUN}`
if [ ${STR_MODE} == "yes" ] || [ ${STR_MODE} == "true" ] || [ ${STR_MODE} == "1" ]; then
return ${TRUE}
echo ${TRUE}
else
echo ${FALSE}
fi
return ${FALSE}
}
is_single_file()
@ -85,6 +99,19 @@ get_api_spec_current_commit()
fi
}
get_api_spec_status()
{
if [ -z "${API_SPEC_DIR}" ]; then
if [ ! -z "${1}" ]; then
echo `git -C ${1} status -s`
else
echo `git status -s`
fi
else
echo `git -C ${API_SPEC_DIR} status -s`
fi
}
is_api_spec_under_source_control()
{
local IS_UNDER_SOURCE_CONTROL_CHECK
@ -99,14 +126,33 @@ is_api_spec_under_source_control()
IS_UNDER_SOURCE_CONTROL_CHECK=`git -C ${API_SPEC_DIR} rev-parse --is-inside-work-tree 2>/dev/null`
fi
[ ${IS_UNDER_SOURCE_CONTROL_CHECK} = "true" ]
if [ ${IS_UNDER_SOURCE_CONTROL_CHECK} = "true" ]; then
echo ${TRUE}
else
echo ${FALSE}
fi
}
is_api_spec_has_uncommited_changes()
{
if [ `is_api_spec_under_source_control` -eq ${TRUE} ]; then
local -r API_SPEC_STATUS=`get_api_spec_status`
if [ -z "${API_SPEC_STATUS}" ]; then
echo ${FALSE}
else
echo ${TRUE}
fi
else
echo ${FALSE}
fi
}
is_nothing_changed_since_last_check()
{
if is_force_run; then
if [ `is_force_run` -eq ${TRUE} ]; then
notice "Force run detected. Skipping commits comparison."
return ${EXIT_FAILURE}
echo ${TRUE}
fi
if [ -z "${COMMIT_FILE_PATH}" ]; then
@ -114,28 +160,33 @@ is_nothing_changed_since_last_check()
local -r COMMIT_FILE_PATH=${1}
else
debug "COMMIT_FILE_PATH should be defined or passed as first argument!"
return ${EXIT_FAILURE}
echo ${FALSE}
fi
fi
if is_api_spec_under_source_control; then
if [ `is_api_spec_under_source_control` -eq ${TRUE} ]; then
local -r CURRENT_COMMIT=`get_api_spec_current_commit`
local -r LAST_CHECKED_COMMIT=`cat ${COMMIT_FILE_PATH} 2> /dev/null || echo ""`
if [ ${CURRENT_COMMIT} = "${LAST_CHECKED_COMMIT}" ]; then
return ${EXIT_SUCCESS}
if [ `is_api_spec_has_uncommited_changes` -eq ${TRUE} ]; then
notice "API spec has uncomitted changes."
echo ${FALSE}
else
echo ${TRUE}
fi
else
return ${EXIT_FAILURE}
echo ${FALSE}
fi
else
return ${EXIT_SUCCESS}
echo ${FALSE}
fi
}
record_current_commit()
{
if is_force_run; then
if [ `is_force_run` -eq ${TRUE} ]; then
notice "Force run detected. Commit won't be recorder."
exit ${EXIT_SUCCESS}
fi
@ -204,7 +255,9 @@ openapi_codegen()
rm -rf ${OUTPUT_PATH}/${API_NAME} # remove previously generated API (if exists)
java -cp "Downloads/${CODEGEN_FILE_NAME}:Downloads/${TINETWORKING_CODEGEN_FILE_NAME}" io.swagger.codegen.v3.cli.SwaggerCodegen generate -l TINetworking -i ${OPEN_API_SPEC_PATH} -o ${OUTPUT_PATH} --additional-properties projectName=${API_NAME}
local -r OPENAPI_COMMAND="java -cp "Downloads/${CODEGEN_FILE_NAME}:Downloads/${TINETWORKING_CODEGEN_FILE_NAME}" io.swagger.codegen.v3.cli.SwaggerCodegen generate -l TINetworking -i ${OPEN_API_SPEC_PATH} -o ${OUTPUT_PATH} --additional-properties projectName=${API_NAME}"
exit_on_failure "${OPENAPI_COMMAND}"
# flatten folders hierarchy
@ -249,7 +302,9 @@ api_generator_codegen()
. build-scripts/xcode/aux_scripts/download_file.sh ${FILE_NAME} ${DOWNLOAD_URL}
java -Xmx12g -jar "Downloads/${FILE_NAME}" generate-client-code --output-language SWIFT --specification-path ${API_SPEC_DIR} --output-path ${OUTPUT_PATH} --single-file $(is_single_file)
local -r API_GENERATOR_COMMAND="java -Xmx12g -jar Downloads/${FILE_NAME} generate-client-code --output-language SWIFT --specification-path ${API_SPEC_DIR} --output-path ${OUTPUT_PATH} --single-file $(is_single_file)"
exit_on_failure "${API_GENERATOR_COMMAND}"
}
readonly BUILD_PHASES_DIR=${SRCROOT}/build_phases
@ -258,7 +313,7 @@ mkdir -p ${BUILD_PHASES_DIR}
readonly COMMIT_FILE_PATH=${BUILD_PHASES_DIR}/api-generator-commit
if is_nothing_changed_since_last_check; then
if [ `is_nothing_changed_since_last_check` -eq ${TRUE} ]; then
notice "Nothing was changed. API generation skipped."
exit ${EXIT_SUCCESS}
fi

View File

@ -61,13 +61,12 @@ if has_input_files && \
SCRIPT_INPUT_FILE_VARIABLE_NAME="SCRIPT_INPUT_FILE_${i}"
SHELL_VARIABLE="\${${SCRIPT_INPUT_FILE_VARIABLE_NAME}}"
RESOLVED_FILE_NAME=`envsubst <<< ${SHELL_VARIABLE}`
INPUT_FILE_NAMES=${INPUT_FILE_NAMES}${FILE_NAMES_SEPARATOR}${RESOLVED_FILE_NAME}
if [ ! -z ${INPUT_FILE_NAMES} ]; then
INPUT_FILE_NAMES=${INPUT_FILE_NAMES}${FILE_NAMES_SEPARATOR}
else
INPUT_FILE_NAMES=${INPUT_FILE_NAMES}${FILE_NAMES_SEPARATOR}${RESOLVED_FILE_NAME}
fi
INPUT_FILE_NAMES=${INPUT_FILE_NAMES}${RESOLVED_FILE_NAME}
done
elif has_input_file_lists; then
for i in `seq 0 $((${SCRIPT_INPUT_FILE_LIST_COUNT}-1))`

View File

@ -7,7 +7,7 @@
# $1 $2 $3 $n - folders to exclude from code checking.
#
# Required environment variables:
# PROJECT_DIR - project directory.
# SRCROOT - project directory.
# SCRIPT_DIR - directory of current script.
#
# Optional environment variables:
@ -15,43 +15,47 @@
# SCRIPT_INPUT_FILE_{N} - file path to directory that should be checked.
#
# Modified files:
# ${PROJECT_DIR}/code-quality-reports/CPDLog.txt - check report.
# ${SRCROOT}/code-quality-reports/CPDLog.txt - check report.
#
# Example of usage:
# runner.sh copy_paste_detection.sh Generated Localization Pods
# copy_paste_detection.sh Generated Localization Pods
#
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
. ${SCRIPT_DIR}/../aux_scripts/install_env.sh pmd
EXIT_SUCCESS=0
EXIT_FAILURE=1
if which pmd >/dev/null; then
readonly REPORTS_DIR="${PROJECT_DIR}/code-quality-reports"
REPORTS_DIR="${SRCROOT}/code-quality-reports"
readonly SOURCES_DIRS=`. ${SCRIPT_DIR}/common/read_input_file_names.sh " " ${PROJECT_DIR}`
SOURCES_DIRS=`. ${SCRIPT_DIR}/common/read_input_file_names.sh " " ${SRCROOT}`
readonly COMMAND_LINE_ARGUMENTS=$@
COMMAND_LINE_ARGUMENTS=$@
FOLDERS_TO_EXLUDE=""
FOLDERS_TO_EXCLUDE=""
for argument in ${COMMAND_LINE_ARGUMENTS}
do
FOLDERS_TO_EXLUDE=${FOLDERS_TO_EXLUDE}"-or -name ${argument} "
FOLDERS_TO_EXCLUDE=${FOLDERS_TO_EXCLUDE}"-or -name ${argument} "
done
FOLDERS_TO_EXLUDE=`echo ${FOLDERS_TO_EXLUDE} | cut -c5-` # remove first "-or"
FOLDERS_TO_EXCLUDE=`echo ${FOLDERS_TO_EXCLUDE} | cut -c5-` # remove first "-or"
readonly FILES_TO_EXCLUDE=`find ${PROJECT_DIR} -type d ${FOLDERS_TO_EXLUDE} | paste -sd " " -`
FILES_TO_EXCLUDE=`find ${SRCROOT} -type d ${FOLDERS_TO_EXCLUDE} | paste -sd " " -`
mkdir -p ${REPORTS_DIR}
pmd cpd --files ${SOURCES_DIRS} --exclude ${FILES_TO_EXCLUDE} --minimum-tokens 50 --language swift --encoding UTF-8 --format net.sourceforge.pmd.cpd.XMLRenderer --failOnViolation true > ${REPORTS_DIR}/cpd-output.xml
DIRS_ARGUMENTS=""
for SOURCE_DIR in ${SOURCES_DIRS}; do
DIRS_ARGUMENTS=${DIRS_ARGUMENTS}" --dir "${SOURCE_DIR}
done
pmd cpd ${DIRS_ARGUMENTS} --exclude ${FILES_TO_EXCLUDE} --minimum-tokens 50 --language swift --encoding UTF-8 --format net.sourceforge.pmd.cpd.XMLRenderer --skip-lexical-errors true > ${REPORTS_DIR}/cpd-output.xml
php ${SCRIPT_DIR}/../aux_scripts/cpd_script.php ${REPORTS_DIR}/cpd-output.xml | tee ${REPORTS_DIR}/CPDLog.txt
# Make paths relative to PROJECT_DIR, so different developers won't rewrite entire file
readonly SED_REPLACEMENT_STRING=$(echo ${PROJECT_DIR} | sed "s/\//\\\\\//g")
# Make paths relative to SRCROOT, so different developers won't rewrite entire file
SED_REPLACEMENT_STRING=$(echo ${SRCROOT} | sed "s/\//\\\\\//g")
sed -i '' "s/${SED_REPLACEMENT_STRING}//g" "${REPORTS_DIR}/CPDLog.txt"
else

View File

@ -32,8 +32,10 @@ readonly SOURCES_DIRS=`. ${SCRIPT_DIR}/common/read_input_file_names.sh "\n" ${SR
if [ -z "${SWIFTLINT_EXECUTABLE}" ]; then
if [ ! -z "${1}" ]; then
readonly SWIFTLINT_EXECUTABLE=${1}
else
elif [ ! -z "${PODS_ROOT}" ];
readonly SWIFTLINT_EXECUTABLE=${PODS_ROOT}/SwiftLint/swiftlint
else
readonly SWIFTLINT_EXECUTABLE=${SRCROOT}/Pods/SwiftLint/swiftlint
fi
fi