You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@yetus.apache.org by aw...@apache.org on 2018/11/11 22:19:25 UTC
[09/17] yetus git commit: YETUS-15. build environment
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/maven.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/maven.sh b/precommit/src/main/shell/test-patch.d/maven.sh
new file mode 100755
index 0000000..12fb239
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/maven.sh
@@ -0,0 +1,761 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare -a MAVEN_ARGS
+
+if [[ -z "${MAVEN_HOME:-}" ]]; then
+ MAVEN=mvn
+else
+ MAVEN=${MAVEN_HOME}/bin/mvn
+fi
+
+MAVEN_CUSTOM_REPOS=false
+MAVEN_CUSTOM_REPOS_DIR="@@@WORKSPACE@@@/yetus-m2"
+MAVEN_DEPENDENCY_ORDER=true
+
+add_test_type mvnsite
+add_build_tool maven
+
+## @description Add the given test type as requiring a mvn install during the branch phase
+## @audience public
+## @stability stable
+## @replaceable yes
+## @param test
+function maven_add_install
+{
+ yetus_add_entry MAVEN_NEED_INSTALL "${1}"
+}
+
+## @description Remove the given test type as requiring a mvn install
+## @audience public
+## @stability stable
+## @replaceable yes
+## @param test
+function maven_delete_install
+{
+ yetus_delete_entry MAVEN_NEED_INSTALL "${1}"
+}
+
+## @description replace the custom repo with either home or workspace if jenkins.
+## @description is configured. this gets called in a few places since different
+## @description circumstances dictate a few places where it may be needed.
+## @audience private
+## @stability evolving
+function maven_ws_replace
+{
+ declare previous=${MAVEN_CUSTOM_REPOS_DIR}
+
+ if [[ ${JENKINS} == true ]] && [[ -n "${WORKSPACE}" ]]; then
+ MAVEN_CUSTOM_REPOS_DIR=$(echo "${MAVEN_CUSTOM_REPOS_DIR}" | "${SED}" -e "s,@@@WORKSPACE@@@,${WORKSPACE},g" )
+ else
+ MAVEN_CUSTOM_REPOS_DIR=$(echo "${MAVEN_CUSTOM_REPOS_DIR}" | "${SED}" -e "s,@@@WORKSPACE@@@,${HOME},g" )
+ fi
+ if [[ "${previous}" != "${MAVEN_CUSTOM_REPOS_DIR}" ]]; then
+ # put this in the array so that if docker is run, this is already resolved
+ USER_PARAMS=("${USER_PARAMS[@]}" "--mvn-custom-repos-dir=${MAVEN_CUSTOM_REPOS_DIR}")
+ fi
+}
+
+function maven_usage
+{
+ maven_ws_replace
+ yetus_add_option "--mvn-cmd=<cmd>" "The 'mvn' command to use (default \${MAVEN_HOME}/bin/mvn, or 'mvn')"
+ yetus_add_option "--mvn-custom-repos" "Use per-project maven repos"
+ yetus_add_option "--mvn-custom-repos-dir=dir" "Location of repos, default is '${MAVEN_CUSTOM_REPOS_DIR}'"
+ yetus_add_option "--mvn-deps-order=<bool>" "Disable maven's auto-dependency module ordering (Default: '${MAVEN_DEPENDENCY_ORDER}')"
+ yetus_add_option "--mvn-settings=file" "File to use for settings.xml"
+}
+
+## @description parse maven build tool args
+## @replaceable yes
+## @audience public
+## @stability stable
+function maven_parse_args
+{
+ local i
+
+ for i in "$@"; do
+ case ${i} in
+ --mvn-cmd=*)
+ MAVEN=${i#*=}
+ ;;
+ --mvn-custom-repos)
+ MAVEN_CUSTOM_REPOS=true
+ ;;
+ --mvn-custom-repos-dir=*)
+ MAVEN_CUSTOM_REPOS_DIR=${i#*=}
+ ;;
+ --mvn-deps-order=*)
+ MAVEN_DEPENDENCY_ORDER=${i#*=}
+ ;;
+ --mvn-settings=*)
+ MAVEN_SETTINGS=${i#*=}
+ if [[ -f ${MAVEN_SETTINGS} ]]; then
+ MAVEN_ARGS=("${MAVEN_ARGS[@]}" "--settings=${MAVEN_SETTINGS}")
+ else
+ yetus_error "WARNING: ${MAVEN_SETTINGS} not found. Ignoring."
+ fi
+ ;;
+ esac
+ done
+
+ if [[ ${OFFLINE} == "true" ]]; then
+ MAVEN_ARGS=("${MAVEN_ARGS[@]}" --offline)
+ fi
+
+ maven_ws_replace
+}
+
+## @description initialize the maven build tool
+## @replaceable yes
+## @audience public
+## @stability stable
+function maven_initialize
+{
+ # we need to do this before docker does it as root
+
+ maven_add_install compile
+ maven_add_install mvnsite
+ maven_add_install unit
+
+ # Tell the reaper about the maven surefire plugin
+ reaper_add_name surefirebooter
+
+ # we need to do this before docker does it as root
+ maven_ws_replace
+
+ if [[ ! ${MAVEN_CUSTOM_REPOS_DIR} =~ ^/ ]]; then
+ yetus_error "ERROR: --mvn-custom-repos-dir must be an absolute path."
+ return 1
+ fi
+
+ if [[ ${MAVEN_CUSTOM_REPOS} = true ]]; then
+ MAVEN_LOCAL_REPO="${MAVEN_CUSTOM_REPOS_DIR}"
+ if [[ -e "${MAVEN_CUSTOM_REPOS_DIR}"
+ && ! -d "${MAVEN_CUSTOM_REPOS_DIR}" ]]; then
+ yetus_error "ERROR: ${MAVEN_CUSTOM_REPOS_DIR} is not a directory."
+ return 1
+ elif [[ ! -d "${MAVEN_CUSTOM_REPOS_DIR}" ]]; then
+ yetus_debug "Creating ${MAVEN_CUSTOM_REPOS_DIR}"
+ mkdir -p "${MAVEN_CUSTOM_REPOS_DIR}"
+ fi
+ fi
+
+ if [[ -e "${HOME}/.m2"
+ && ! -d "${HOME}/.m2" ]]; then
+ yetus_error "ERROR: ${HOME}/.m2 is not a directory."
+ return 1
+ elif [[ ! -e "${HOME}/.m2" ]]; then
+ yetus_debug "Creating ${HOME}/.m2"
+ mkdir -p "${HOME}/.m2"
+ fi
+}
+
+## @audience private
+## @stability stable
+function mvnsite_precheck
+{
+ if ! verify_plugin_enabled 'maven'; then
+ yetus_error "ERROR: to run the mvnsite test you must ensure the 'maven' plugin is enabled."
+ return 1
+ fi
+}
+
+## @audience private
+## @stability stable
+function maven_precheck
+{
+ declare logfile="${PATCH_DIR}/mvnrepoclean.log"
+ declare line
+ declare maven_version
+
+ if ! verify_plugin_enabled 'maven'; then
+ yetus_error "ERROR: you can't specify maven as the buildtool if you don't enable the plugin."
+ return 1
+ fi
+
+ if ! verify_command maven "${MAVEN}"; then
+ add_vote_table -1 maven "ERROR: maven was not available."
+ return 1
+ fi
+
+ if [[ ! ${MAVEN_CUSTOM_REPOS_DIR} =~ ^/ ]]; then
+ yetus_error "ERROR: --mvn-custom-repos-dir must be an absolute path."
+ return 1
+ fi
+
+ MAVEN_ARGS=("${MAVEN_ARGS[@]}" "--batch-mode")
+
+ if [[ ${MAVEN_CUSTOM_REPOS} = true ]]; then
+ MAVEN_LOCAL_REPO="${MAVEN_CUSTOM_REPOS_DIR}/${PROJECT_NAME}-${PATCH_BRANCH}-${BUILDMODE}-${INSTANCE}"
+ if [[ -e "${MAVEN_LOCAL_REPO}"
+ && ! -d "${MAVEN_LOCAL_REPO}" ]]; then
+ yetus_error "ERROR: ${MAVEN_LOCAL_REPO} is not a directory."
+ return 1
+ fi
+
+ if [[ ! -d "${MAVEN_LOCAL_REPO}" ]]; then
+ yetus_debug "Creating ${MAVEN_LOCAL_REPO}"
+ mkdir -p "${MAVEN_LOCAL_REPO}"
+ if [[ $? -ne 0 ]]; then
+ yetus_error "ERROR: Unable to create ${MAVEN_LOCAL_REPO}"
+ return 1
+ fi
+ fi
+ touch "${MAVEN_LOCAL_REPO}"
+
+ # if we have a local settings.xml file, we copy it.
+ if [[ -f "${HOME}/.m2/settings.xml" ]]; then
+ cp -p "${HOME}/.m2/settings.xml" "${MAVEN_LOCAL_REPO}"
+ fi
+ MAVEN_ARGS=("${MAVEN_ARGS[@]}" "-Dmaven.repo.local=${MAVEN_LOCAL_REPO}")
+
+ # let's do some cleanup while we're here
+
+ find "${MAVEN_CUSTOM_REPOS_DIR}" \
+ -name '*-*-*' \
+ -type d \
+ -mtime +30 \
+ -maxdepth 1 \
+ -print \
+ > "${logfile}"
+
+ while read -r line; do
+ echo "Removing old maven repo ${line}"
+ rm -rf "${line}"
+ done < "${logfile}"
+ fi
+
+ # finally let folks know what version they'll be dealing with.
+ maven_version=$(${MAVEN} --offline --version 2>/dev/null | head -n 1 2>/dev/null)
+ add_footer_table maven "version: ${maven_version}"
+}
+
+function maven_filefilter
+{
+ declare filename=$1
+
+ if [[ ${filename} =~ pom\.xml$ ]]; then
+ yetus_debug "tests/compile: ${filename}"
+ add_test compile
+ fi
+}
+
+function maven_buildfile
+{
+ echo "pom.xml"
+}
+
+function maven_executor
+{
+ echo "${MAVEN}" "${MAVEN_ARGS[@]}"
+}
+
+function mvnsite_filefilter
+{
+ local filename=$1
+
+ if [[ ${BUILDTOOL} = maven ]]; then
+ if [[ ${filename} =~ src/site ]]; then
+ yetus_debug "tests/mvnsite: ${filename}"
+ add_test mvnsite
+ fi
+ fi
+}
+
+## @description maven version of the modules_worker routine
+## @audience public
+## @stability stable
+function maven_modules_worker
+{
+ declare repostatus=$1
+ declare tst=$2
+ declare maven_unit_test_filter
+
+ maven_unit_test_filter="$(maven_unit_test_filter)"
+ # shellcheck disable=SC2034
+ UNSUPPORTED_TEST=false
+
+ case ${tst} in
+ findbugs)
+ modules_workers "${repostatus}" findbugs test-compile findbugs:findbugs -DskipTests=true
+ ;;
+ compile)
+ modules_workers "${repostatus}" compile clean test-compile -DskipTests=true
+ ;;
+ distclean)
+ modules_workers "${repostatus}" distclean clean -DskipTests=true
+ ;;
+ javadoc)
+ modules_workers "${repostatus}" javadoc clean javadoc:javadoc -DskipTests=true
+ ;;
+ scaladoc)
+ modules_workers "${repostatus}" scaladoc clean scala:doc -DskipTests=true
+ ;;
+ unit)
+ if [[ -n "${maven_unit_test_filter}" ]]; then
+ modules_workers "${repostatus}" unit clean test -fae "${maven_unit_test_filter}"
+ else
+ modules_workers "${repostatus}" unit clean test -fae
+ fi
+ ;;
+ *)
+ # shellcheck disable=SC2034
+ UNSUPPORTED_TEST=true
+ if [[ ${repostatus} = patch ]]; then
+ add_footer_table "${tst}" "not supported by the ${BUILDTOOL} plugin"
+ fi
+ yetus_error "WARNING: ${tst} is unsupported by ${BUILDTOOL}"
+ return 1
+ ;;
+ esac
+}
+
+function maven_javac_logfilter
+{
+ declare input=$1
+ declare output=$2
+
+ ${GREP} -E '\[(ERROR|WARNING)\] /.*\.java:' "${input}" > "${output}"
+}
+
+## @description Helper for check_patch_javadoc
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function maven_javadoc_logfilter
+{
+ declare input=$1
+ declare output=$2
+
+ ${GREP} -E '\[(ERROR|WARNING)\] /.*\.java:' "${input}" > "${output}"
+}
+
+## @description handle diffing maven javac errors
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function maven_javac_calcdiffs
+{
+ declare orig=$1
+ declare new=$2
+ declare tmp=${PATCH_DIR}/pl.$$.${RANDOM}
+ declare j
+
+ # first, strip :[line
+ # this keeps file,column in an attempt to increase
+ # accuracy in case of multiple, repeated errors
+ # since the column number shouldn't change
+ # if the line of code hasn't been touched
+ # shellcheck disable=SC2016
+ ${SED} -e 's#:\[[0-9]*,#:#' "${orig}" > "${tmp}.branch"
+ # shellcheck disable=SC2016
+ ${SED} -e 's#:\[[0-9]*,#:#' "${new}" > "${tmp}.patch"
+
+ # compare the errors, generating a string of line
+ # numbers. Sorry portability: GNU diff makes this too easy
+ ${DIFF} --unchanged-line-format="" \
+ --old-line-format="" \
+ --new-line-format="%dn " \
+ "${tmp}.branch" \
+ "${tmp}.patch" > "${tmp}.lined"
+
+ # now, pull out those lines of the raw output
+ # shellcheck disable=SC2013
+ for j in $(cat "${tmp}.lined"); do
+ # shellcheck disable=SC2086
+ head -${j} "${new}" | tail -1
+ done
+
+ rm "${tmp}.branch" "${tmp}.patch" "${tmp}.lined" 2>/dev/null
+}
+
+## @description handle diffing maven javadoc errors
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function maven_javadoc_calcdiffs
+{
+ declare orig=$1
+ declare new=$2
+ declare tmp=${PATCH_DIR}/pl.$$.${RANDOM}
+ declare j
+
+ # can't use the generic handler for this because of the
+ # [WARNING], etc headers.
+ # strip :linenum from the output, keeping the filename
+ # shellcheck disable=SC2016
+ ${SED} -e 's#:[0-9]*:#:#' "${orig}" > "${tmp}.branch"
+ # shellcheck disable=SC2016
+ ${SED} -e 's#:[0-9]*:#:#' "${new}" > "${tmp}.patch"
+
+ # compare the errors, generating a string of line
+ # numbers. Sorry portability: GNU diff makes this too easy
+ ${DIFF} --unchanged-line-format="" \
+ --old-line-format="" \
+ --new-line-format="%dn " \
+ "${tmp}.branch" \
+ "${tmp}.patch" > "${tmp}.lined"
+
+ # now, pull out those lines of the raw output
+ # shellcheck disable=SC2013
+ for j in $(cat "${tmp}.lined"); do
+ # shellcheck disable=SC2086
+ head -${j} "${new}" | tail -1
+ done
+
+ rm "${tmp}.branch" "${tmp}.patch" "${tmp}.lined" 2>/dev/null
+}
+
+function maven_builtin_personality_modules
+{
+ declare repostatus=$1
+ declare testtype=$2
+
+ declare module
+
+ yetus_debug "Using builtin personality_modules"
+ yetus_debug "Personality: ${repostatus} ${testtype}"
+
+ clear_personality_queue
+
+ # this always makes sure the local repo has a fresh
+ # copy of everything per pom rules.
+ if [[ ${repostatus} == branch
+ && ${testtype} == mvninstall ]] ||
+ [[ "${BUILDMODE}" = full ]];then
+ personality_enqueue_module "${CHANGED_UNION_MODULES}"
+ return
+ fi
+
+ for module in "${CHANGED_MODULES[@]}"; do
+ personality_enqueue_module "${module}"
+ done
+}
+
+function maven_builtin_personality_file_tests
+{
+ local filename=$1
+
+ yetus_debug "Using builtin mvn personality_file_tests"
+
+ if [[ ${filename} =~ src/main/webapp ]]; then
+ yetus_debug "tests/webapp: ${filename}"
+ elif [[ ${filename} =~ \.sh
+ || ${filename} =~ \.cmd
+ || ${filename} =~ src/main/scripts
+ || ${filename} =~ src/test/scripts
+ ]]; then
+ yetus_debug "tests/shell: ${filename}"
+ elif [[ ${filename} =~ \.c$
+ || ${filename} =~ \.cc$
+ || ${filename} =~ \.h$
+ || ${filename} =~ \.hh$
+ || ${filename} =~ \.proto$
+ || ${filename} =~ \.cmake$
+ || ${filename} =~ CMakeLists.txt
+ ]]; then
+ yetus_debug "tests/units: ${filename}"
+ add_test cc
+ add_test unit
+ elif [[ ${filename} =~ \.scala$
+ || ${filename} =~ src/scala ]]; then
+ add_test scalac
+ add_test scaladoc
+ add_test unit
+ elif [[ ${filename} =~ build.xml$
+ || ${filename} =~ pom.xml$
+ || ${filename} =~ \.java$
+ || ${filename} =~ src/main
+ ]]; then
+ yetus_debug "tests/javadoc+units: ${filename}"
+ add_test javac
+ add_test javadoc
+ add_test unit
+ fi
+
+ if [[ ${filename} =~ src/test ]]; then
+ yetus_debug "tests"
+ add_test unit
+ fi
+
+ if [[ ${filename} =~ \.java$ ]]; then
+ add_test findbugs
+ fi
+}
+
+## @description Maven unit test filter file string
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return string
+function maven_unit_test_filter()
+{
+ declare filtered
+
+ if [[ ! -z "${UNIT_TEST_FILTER_FILE}" ]]; then
+ while read -r line || [[ -n "${line}" ]]; do
+ if [[ -z $line ]]; then
+ continue
+ fi
+
+ filtered="${filtered}${line},"
+ done < "${UNIT_TEST_FILTER_FILE}"
+ fi
+
+ if [[ -z "${filtered}" ]]; then
+ printf "%s" ""
+ else
+ printf "%s" "-Dtest=${filtered%,}"
+ fi
+}
+
+## @description Confirm site pre-patch
+## @audience private
+## @stability stable
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function mvnsite_postcompile
+{
+ declare repostatus=$1
+ declare result=0
+
+ if [[ ${BUILDTOOL} != maven ]]; then
+ return 0
+ fi
+
+ if ! verify_needed_test mvnsite; then
+ return 0
+ fi
+
+ if [[ "${repostatus}" = branch ]]; then
+ big_console_header "maven site verification: ${PATCH_BRANCH}"
+ else
+ big_console_header "maven site verification: ${BUILDMODE}"
+ fi
+
+ personality_modules "${repostatus}" mvnsite
+ modules_workers "${repostatus}" mvnsite clean site site:stage
+ result=$?
+ modules_messages "${repostatus}" mvnsite true
+ if [[ ${result} != 0 ]]; then
+ return 1
+ fi
+ return 0
+}
+
+## @description maven precompile phase
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function maven_precompile
+{
+ declare repostatus=$1
+ declare result=0
+ declare need=false
+
+ if [[ ${BUILDTOOL} != maven ]]; then
+ return 0
+ fi
+
+ # not everything needs a maven install
+ # but quite a few do ...
+ # shellcheck disable=SC2086
+ for index in ${MAVEN_NEED_INSTALL}; do
+ if verify_needed_test "${index}"; then
+ need=true
+ fi
+ done
+
+ if [[ "${need}" = false ]]; then
+ return 0
+ fi
+
+ if [[ "${repostatus}" = branch ]]; then
+ big_console_header "maven install: ${PATCH_BRANCH}"
+ else
+ big_console_header "maven install: ${BUILDMODE}"
+ fi
+
+ personality_modules "${repostatus}" mvninstall
+ modules_workers "${repostatus}" mvninstall -fae \
+ clean install \
+ -DskipTests=true -Dmaven.javadoc.skip=true \
+ -Dcheckstyle.skip=true -Dfindbugs.skip=true
+ result=$?
+ modules_messages "${repostatus}" mvninstall true
+ if [[ ${result} != 0 ]]; then
+ return 1
+ fi
+ return 0
+}
+
+function maven_docker_support
+{
+ DOCKER_EXTRAARGS=("${DOCKER_EXTRAARGS[@]}" "-v" "${HOME}/.m2:/home/${USER_NAME}/.m2")
+
+ if [[ ${MAVEN_CUSTOM_REPOS} = true ]]; then
+ DOCKER_EXTRAARGS=("${DOCKER_EXTRAARGS[@]}" "-v" "${MAVEN_CUSTOM_REPOS_DIR}:${MAVEN_CUSTOM_REPOS_DIR}")
+ fi
+}
+
+## @description worker for maven reordering. MAVEN_DEP_LOG is set to the log file name
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param repostatus
+## @return 0 = success
+## @return 1 = failure
+function maven_reorder_module_process
+{
+ declare repostatus=$1
+ declare module
+ declare line
+ declare indexm
+ declare indexn
+ declare -a newlist
+ declare fn
+ declare needroot=false
+ declare found
+ declare ret
+
+ for module in "${CHANGED_MODULES[@]}"; do
+ if [[ "${module}" = \. ]]; then
+ needroot=true
+ fi
+ done
+
+ fn=$(module_file_fragment "${CHANGED_UNION_MODULES}")
+ pushd "${BASEDIR}/${CHANGED_UNION_MODULES}" >/dev/null
+
+ # get the module directory list in the correct order based on maven dependencies
+ # shellcheck disable=SC2046
+ echo_and_redirect "${PATCH_DIR}/maven-${repostatus}-dirlist-${fn}.txt" \
+ $("${BUILDTOOL}_executor") "-fae" "-q" "exec:exec" "-Dexec.executable=pwd" "-Dexec.args=''"
+ MAVEN_DEP_LOG="maven-${repostatus}-dirlist-${fn}.txt"
+ ret=$?
+
+ while read -r line; do
+ for indexm in "${CHANGED_MODULES[@]}"; do
+ if [[ ${line} == "${BASEDIR}/${indexm}" ]]; then
+ yetus_debug "mrm: placing ${indexm} from dir: ${line}"
+ newlist=("${newlist[@]}" "${indexm}")
+ break
+ fi
+ done
+ done < "${PATCH_DIR}/maven-${repostatus}-dirlist-${fn}.txt"
+ popd >/dev/null
+
+ if [[ "${needroot}" = true ]]; then
+ newlist=("${newlist[@]}" ".")
+ fi
+
+ indexm="${#CHANGED_MODULES[@]}"
+ indexn="${#newlist[@]}"
+
+ if [[ ${indexm} -ne ${indexn} ]]; then
+ yetus_debug "mrm: Missed a module"
+ for indexm in "${CHANGED_MODULES[@]}"; do
+ found=false
+ for indexn in "${newlist[@]}"; do
+ if [[ "${indexn}" = "${indexm}" ]]; then
+ found=true
+ break
+ fi
+ done
+ if [[ ${found} = false ]]; then
+ yetus_debug "mrm: missed ${indexm}"
+ newlist=("${newlist[@]}" "${indexm}")
+ fi
+ done
+ fi
+
+ CHANGED_MODULES=("${newlist[@]}")
+ return "${ret}"
+}
+
+## @description take a stab at reordering modules based upon
+## @description maven dependency order
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param repostatus
+## @param module
+function maven_reorder_modules
+{
+ declare repostatus=$1
+ declare index
+ declare ret
+
+ if [[ "${MAVEN_DEPENDENCY_ORDER}" != "true" ]]; then
+ return
+ fi
+
+ # don't bother if there is only one
+ index="${#CHANGED_MODULES[@]}"
+ if [[ ${index} -eq 1 ]]; then
+ return
+ fi
+
+ big_console_header "Determining Maven Dependency Order (downloading dependencies in the process)"
+
+ start_clock
+
+ maven_reorder_module_process "${repostatus}"
+ ret=$?
+
+ yetus_debug "Maven: finish re-ordering modules"
+ yetus_debug "Finished list: ${CHANGED_MODULES[*]}"
+
+ # build some utility module lists for maven modules
+ for index in "${CHANGED_MODULES[@]}"; do
+ if [[ -d "${index}/src" ]]; then
+ MAVEN_SRC_MODULES=("${MAVEN_SRC_MODULES[@]}" "${index}")
+ if [[ -d "${index}/src/test" ]]; then
+ MAVEN_SRCTEST_MODULES=("${MAVEN_SRCTEST_MODULES[@]}" "${index}")
+ fi
+ fi
+ done
+
+ if [[ "${BUILDMODE}" = patch ]]; then
+ if [[ ${ret} == 0 ]]; then
+ add_vote_table 0 mvndep "Maven dependency ordering for ${repostatus}"
+ else
+ add_vote_table -1 mvndep "Maven dependency ordering for ${repostatus}"
+ add_footer_table mvndep "${MAVEN_DEP_LOG}"
+ fi
+ else
+ if [[ ${ret} == 0 ]]; then
+ add_vote_table 0 mvndep "Maven dependency ordering"
+ else
+ add_vote_table -1 mvndep "Maven dependency ordering"
+ add_footer_table mvndep "${MAVEN_DEP_LOG}"
+ fi
+ fi
+
+ echo "Elapsed: $(clock_display $(stop_clock))"
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/nobuild.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/nobuild.sh b/precommit/src/main/shell/test-patch.d/nobuild.sh
new file mode 100755
index 0000000..cf5a2ad
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/nobuild.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_build_tool nobuild
+
+function nobuild_buildfile
+{
+ echo
+}
+
+function nobuild_executor
+{
+ echo "true"
+}
+
+function nobuild_modules_worker
+{
+ local status=$1
+ local testtype=$2
+ modules_workers "${status}" "${testtype}"
+}
+
+function nobuild_builtin_personality_modules
+{
+ local status=$1
+ local testtype=$2
+ yetus_debug "built-in personality for no build system: ${status} ${testtype}"
+
+ clear_personality_queue
+ for module in "${CHANGED_MODULES[@]}"; do
+ personality_enqueue_module "${module}"
+ done
+}
+
+function nobuild_builtin_personality_file_tests
+{
+ local filename=$1
+
+ yetus_debug "Using built-in no build system personality_file_tests."
+ yetus_debug " given file ${filename}"
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/pathlen.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/pathlen.sh b/precommit/src/main/shell/test-patch.d/pathlen.sh
new file mode 100755
index 0000000..a013adb
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/pathlen.sh
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type pathlen
+
+PATHLEN_SIZE=240
+
+## @description pathlen usage hook
+## @audience private
+## @stability evolving
+## @replaceable no
+function pathlen_usage
+{
+ yetus_add_option "--pathlen-size=<int>" "reject patches with this size of paths (default: ${PATHLEN_SIZE}"
+
+}
+
+## @description pathlen parse args hook
+## @audience private
+## @stability evolving
+## @replaceable no
+function pathlen_parse_args
+{
+ declare i
+
+ for i in "$@"; do
+ case ${i} in
+ --pathlen-size=*)
+ PATHLEN_SIZE="${i#*=}"
+ ;;
+ esac
+ done
+}
+
+## @description helper function to count long pathnames
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function pathlen_generic
+{
+ declare size
+ declare i
+ declare msg
+ declare counter
+
+ counter=0
+
+ if [[ "${BUILDMODE}" = full ]]; then
+ msg="source tree"
+ else
+ msg="patch"
+ fi
+
+ for i in "${CHANGED_FILES[@]}"; do
+ size=${#i}
+ if [[ ${size} -gt ${PATHLEN_SIZE} ]]; then
+ ((counter = counter + 1 ))
+ echo "${i}" >> "${PATCH_DIR}/pathlen.txt"
+ fi
+ done
+
+ # shellcheck disable=SC2016
+ echo "${counter} files in the ${msg} with paths longer that ${PATHLEN_SIZE}."
+ if [[ ${counter} -gt 0 ]] ; then
+ add_vote_table -1 pathlen \
+ "${BUILDMODEMSG} appears to contain ${counter} files with names longer than ${PATHLEN_SIZE}"
+ add_footer_table pathlen "@@BASE@@/pathlen.txt"
+ return 1
+ fi
+ return 0
+}
+
+## @description Check the current patchfile for @pathlen tags
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+## @param patchfile
+function pathlen_patchfile
+{
+ if [[ "${BUILDMODE}" != patch ]]; then
+ return
+ fi
+
+ big_console_header "Checking for long paths: ${BUILDMODE}"
+
+ start_clock
+
+ pathlen_generic
+}
+
+
+## @description Check the current directory for @pathlen tags
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function pathlen_postcompile
+{
+ if [[ "${BUILDMODE}" != full ]]; then
+ return
+ fi
+
+ big_console_header "Checking for long paths: ${BUILDMODE}"
+
+ start_clock
+
+ pathlen_generic
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/perlcritic.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/perlcritic.sh b/precommit/src/main/shell/test-patch.d/perlcritic.sh
new file mode 100755
index 0000000..291e94e
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/perlcritic.sh
@@ -0,0 +1,171 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type perlcritic
+
+PERLCRITIC_TIMER=0
+
+PERLCRITIC=${PERLCRITIC:-$(which perlcritic 2>/dev/null)}
+
+function perlcritic_usage
+{
+ yetus_add_option "--perlcritic=<path>" "path to perlcritic executable"
+}
+
+function perlcritic_parse_args
+{
+ local i
+
+ for i in "$@"; do
+ case ${i} in
+ --perlcritic=*)
+ PERLCRITIC=${i#*=}
+ ;;
+ esac
+ done
+}
+
+function perlcritic_filefilter
+{
+ local filename=$1
+
+ if [[ ${filename} =~ \.p[lm]$ ]]; then
+ add_test perlcritic
+ fi
+}
+
+function perlcritic_precheck
+{
+ if ! verify_command "Perl::Critic" "${PERLCRITIC}"; then
+ add_vote_table 0 perlcritic "Perl::Critic was not available."
+ delete_test perlcritic
+ fi
+}
+
+
+function perlcritic_preapply
+{
+ local i
+
+ if ! verify_needed_test perlcritic; then
+ return 0
+ fi
+
+ big_console_header "Perl::Critic plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ echo "Running perlcritic against identified perl scripts/modules."
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.p[lm]$ && -f ${i} ]]; then
+ ${PERLCRITIC} -1 --verbose 1 "${i}" 2>/dev/null >> "${PATCH_DIR}/branch-perlcritic-result.txt"
+ fi
+ done
+ popd >/dev/null
+ # keep track of how much as elapsed for us already
+ PERLCRITIC_TIMER=$(stop_clock)
+ return 0
+}
+
+## @description Wrapper to call column_calcdiffs
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function perlcritic_calcdiffs
+{
+ column_calcdiffs "$@"
+}
+
+function perlcritic_postapply
+{
+ declare i
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test perlcritic; then
+ return 0
+ fi
+
+ big_console_header "Perl::Critic plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${PERLCRITIC_TIMER}"
+
+ echo "Running perlcritic against identified perl scripts/modules."
+ # we re-check this in case one has been added
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.p[lm]$ && -f ${i} ]]; then
+ ${PERLCRITIC} -1 --verbose 1 "${i}" 2>/dev/null >> "${PATCH_DIR}/patch-perlcritic-result.txt"
+ fi
+ done
+ popd >/dev/null
+
+ PERLCRITIC_VERSION=$(${PERLCRITIC} --version 2>/dev/null)
+ add_footer_table perlcritic "v${PERLCRITIC_VERSION}"
+
+ calcdiffs \
+ "${PATCH_DIR}/branch-perlcritic-result.txt" \
+ "${PATCH_DIR}/patch-perlcritic-result.txt" \
+ perlcritic \
+ > "${PATCH_DIR}/diff-patch-perlcritic.txt"
+
+ # shellcheck disable=SC2016
+ numPrepatch=$(wc -l "${PATCH_DIR}/branch-perlcritic-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ numPostpatch=$(wc -l "${PATCH_DIR}/patch-perlcritic-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ diffPostpatch=$(wc -l "${PATCH_DIR}/diff-patch-perlcritic.txt" | ${AWK} '{print $1}')
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]]; then
+ add_vote_table -1 perlcritic "${BUILDMODEMSG} ${statstring}"
+ add_footer_table perlcritic "@@BASE@@/diff-patch-perlcritic.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 perlcritic "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 perlcritic "There were no new perlcritic issues."
+ return 0
+}
+
+function perlcritic_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ perlcritic_preapply
+ else
+ perlcritic_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/pylint.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/pylint.sh b/precommit/src/main/shell/test-patch.d/pylint.sh
new file mode 100755
index 0000000..facba6c
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/pylint.sh
@@ -0,0 +1,183 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type pylint
+
+PYLINT_TIMER=0
+
+PYLINT=${PYLINT:-$(which pylint 2>/dev/null)}
+PYLINT_OPTIONS=${PYLINT_OPTIONS:-}
+
+function pylint_usage
+{
+ yetus_add_option "--pylint=<path>" "path to pylint executable"
+ yetus_add_option "--pylint-options=<path>" "pylint options other than output-format and reports"
+}
+
+function pylint_parse_args
+{
+ local i
+
+ for i in "$@"; do
+ case ${i} in
+ --pylint=*)
+ PYLINT=${i#*=}
+ ;;
+ --pylint-options=*)
+ PYLINT_OPTIONS=${i#*=}
+ ;;
+ esac
+ done
+}
+
+function pylint_filefilter
+{
+ local filename=$1
+
+ if [[ ${filename} =~ \.py$ ]]; then
+ add_test pylint
+ fi
+}
+
+function pylint_precheck
+{
+ if ! verify_command "Pylint" "${PYLINT}"; then
+ add_vote_table 0 pylint "Pylint was not available."
+ delete_test pylint
+ fi
+}
+
+
+function pylint_preapply
+{
+ local i
+ local count
+ local pylintStderr=branch-pylint-stderr.txt
+
+ if ! verify_needed_test pylint; then
+ return 0
+ fi
+
+ big_console_header "pylint plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ echo "Running pylint against identified python scripts."
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.py$ && -f ${i} ]]; then
+ # shellcheck disable=SC2086
+ eval "${PYLINT} ${PYLINT_OPTIONS} --msg-template='{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}' --reports=n ${i}" \
+ 2>>${PATCH_DIR}/${pylintStderr} | ${AWK} '1<NR' >> "${PATCH_DIR}/branch-pylint-result.txt"
+ fi
+ done
+ if [[ -f ${PATCH_DIR}/${pylintStderr} ]]; then
+ count=$(${GREP} -Evc "^(No config file found|Using config file)" "${PATCH_DIR}/${pylintStderr}")
+ if [[ ${count} -gt 0 ]]; then
+ add_footer_table pylint "${PATCH_BRANCH} stderr: @@BASE@@/${pylintStderr}"
+ return 1
+ fi
+ fi
+ rm "${PATCH_DIR}/${pylintStderr}" 2>/dev/null
+ popd >/dev/null
+ # keep track of how much as elapsed for us already
+ PYLINT_TIMER=$(stop_clock)
+ return 0
+}
+
+function pylint_postapply
+{
+ declare i
+ declare count
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare pylintStderr=patch-pylint-stderr.txt
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test pylint; then
+ return 0
+ fi
+
+ big_console_header "pylint plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${PYLINT_TIMER}"
+
+ echo "Running pylint against identified python scripts."
+ # we re-check this in case one has been added
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.py$ && -f ${i} ]]; then
+ # shellcheck disable=SC2086
+ eval "${PYLINT} ${PYLINT_OPTIONS} --msg-template='{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}' --reports=n ${i}" \
+ 2>>${PATCH_DIR}/${pylintStderr} | ${AWK} '1<NR' >> "${PATCH_DIR}/patch-pylint-result.txt"
+ fi
+ done
+ if [[ -f ${PATCH_DIR}/${pylintStderr} ]]; then
+ count=$(${GREP} -Evc "^(No config file found|Using config file)" "${PATCH_DIR}/${pylintStderr}")
+ if [[ ${count} -gt 0 ]]; then
+ add_vote_table -1 pylint "Something bad seems to have happened in running pylint. Please check pylint stderr files."
+ add_footer_table pylint "${BUILDMODEMSG} stderr: @@BASE@@/${pylintStderr}"
+ return 1
+ fi
+ fi
+ rm "${PATCH_DIR}/${pylintStderr}" 2>/dev/null
+ popd >/dev/null
+
+ # shellcheck disable=SC2016
+ PYLINT_VERSION=$(${PYLINT} --version 2>/dev/null | ${GREP} pylint | ${AWK} '{print $NF}')
+ add_footer_table pylint "v${PYLINT_VERSION%,}"
+
+ calcdiffs "${PATCH_DIR}/branch-pylint-result.txt" \
+ "${PATCH_DIR}/patch-pylint-result.txt" \
+ pylint > "${PATCH_DIR}/diff-patch-pylint.txt"
+ numPrepatch=$(${GREP} -c "^.*:.*: \[.*\] " "${PATCH_DIR}/branch-pylint-result.txt")
+ numPostpatch=$(${GREP} -c "^.*:.*: \[.*\] " "${PATCH_DIR}/patch-pylint-result.txt")
+ # Exclude Pylint messages from the information category to avoid false positives (see YETUS-309).
+ diffPostpatch=$(${GREP} -c "^.*:.*: \[[^I].*\] " "${PATCH_DIR}/diff-patch-pylint.txt")
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]] ; then
+ add_vote_table -1 pylint "${BUILDMODEMSG} ${statstring}"
+ add_footer_table pylint "@@BASE@@/diff-patch-pylint.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 pylint "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 pylint "There were no new pylint issues."
+ return 0
+}
+
+function pylint_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ pylint_preapply
+ else
+ pylint_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/rubocop.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/rubocop.sh b/precommit/src/main/shell/test-patch.d/rubocop.sh
new file mode 100755
index 0000000..828bea1
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/rubocop.sh
@@ -0,0 +1,170 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type rubocop
+
+RUBOCOP_TIMER=0
+
+RUBOCOP=${RUBOCOP:-$(which rubocop 2>/dev/null)}
+
+function rubocop_usage
+{
+ yetus_add_option "--rubocop=<path>" "path to rubocop executable"
+}
+
+function rubocop_parse_args
+{
+ local i
+
+ for i in "$@"; do
+ case ${i} in
+ --rubocop=*)
+ RUBOCOP=${i#*=}
+ ;;
+ esac
+ done
+}
+
+function rubocop_filefilter
+{
+ local filename=$1
+
+ if [[ ${filename} =~ \.rb$ ]]; then
+ add_test rubocop
+ fi
+}
+
+function rubocop_precheck
+{
+ if ! verify_command rubocop "${RUBOCOP}"; then
+ add_vote_table 0 rubocop "rubocop was not available."
+ delete_test rubocop
+ fi
+}
+
+
+function rubocop_preapply
+{
+ local i
+
+ if ! verify_needed_test rubocop; then
+ return 0
+ fi
+
+ big_console_header "rubocop plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ echo "Running rubocop against identified ruby scripts."
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.rb$ && -f ${i} ]]; then
+ ${RUBOCOP} -f e "${i}" | ${AWK} '!/[0-9]* files? inspected/' >> "${PATCH_DIR}/branch-rubocop-result.txt"
+ fi
+ done
+ popd >/dev/null
+ # keep track of how much as elapsed for us already
+ RUBOCOP_TIMER=$(stop_clock)
+ return 0
+}
+
+## @description Wrapper to call column_calcdiffs
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function rubocop_calcdiffs
+{
+ column_calcdiffs "$@"
+}
+
+function rubocop_postapply
+{
+ declare i
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test rubocop; then
+ return 0
+ fi
+
+ big_console_header "rubocop plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${RUBOCOP_TIMER}"
+
+ echo "Running rubocop against identified ruby scripts."
+ # we re-check this in case one has been added
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.rb$ && -f ${i} ]]; then
+ ${RUBOCOP} -f e "${i}" | ${AWK} '!/[0-9]* files? inspected/' >> "${PATCH_DIR}/patch-rubocop-result.txt"
+ fi
+ done
+ popd >/dev/null
+
+ # shellcheck disable=SC2016
+ RUBOCOP_VERSION=$(${RUBOCOP} -v | ${AWK} '{print $NF}')
+ add_footer_table rubocop "v${RUBOCOP_VERSION}"
+
+ calcdiffs \
+ "${PATCH_DIR}/branch-rubocop-result.txt" \
+ "${PATCH_DIR}/patch-rubocop-result.txt" \
+ rubocop \
+ > "${PATCH_DIR}/diff-patch-rubocop.txt"
+ diffPostpatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/diff-patch-rubocop.txt")
+
+ # shellcheck disable=SC2016
+ numPrepatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/branch-rubocop-result.txt")
+
+ # shellcheck disable=SC2016
+ numPostpatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/patch-rubocop-result.txt")
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]] ; then
+ add_vote_table -1 rubocop "${BUILDMODEMSG} ${statstring}"
+ add_footer_table rubocop "@@BASE@@/diff-patch-rubocop.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 rubocop "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 rubocop "There were no new rubocop issues."
+ return 0
+}
+
+function rubocop_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ rubocop_preapply
+ else
+ rubocop_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/ruby-lint.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/ruby-lint.sh b/precommit/src/main/shell/test-patch.d/ruby-lint.sh
new file mode 100755
index 0000000..78be7b6
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/ruby-lint.sh
@@ -0,0 +1,200 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type ruby_lint
+
+RUBY_LINT_TIMER=0
+
+RUBY_LINT=${RUBY_LINT:-$(which ruby-lint 2>/dev/null)}
+
+function ruby_lint_usage
+{
+ yetus_add_option "--ruby-lint=<path>" "path to ruby-lint executable"
+}
+
+function ruby_lint_parse_args
+{
+ local i
+
+ for i in "$@"; do
+ case ${i} in
+ --ruby-lint=*)
+ RUBY_LINT=${i#*=}
+ ;;
+ esac
+ done
+}
+
+function ruby_lint_filefilter
+{
+ local filename=$1
+
+ if [[ ${filename} =~ \.rb$ ]]; then
+ add_test ruby_lint
+ fi
+}
+
+function ruby_lint_precheck
+{
+ if ! verify_command "Ruby-lint" "${RUBY_LINT}"; then
+ add_vote_table 0 ruby-lint "Ruby-lint was not available."
+ delete_test ruby_lint
+ fi
+}
+
+function ruby_lint_preapply
+{
+ local i
+
+ if ! verify_needed_test ruby_lint; then
+ return 0
+ fi
+
+ big_console_header "ruby-lint plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ echo "Running ruby-lint against identified ruby scripts."
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.rb$ && -f ${i} ]]; then
+ ${RUBY_LINT} -p syntastic "${i}" | sort -t : -k 1,1 -k 3,3n -k 4,4n >> "${PATCH_DIR}/branch-ruby-lint-result.txt"
+ fi
+ done
+ popd >/dev/null
+ # keep track of how much as elapsed for us already
+ RUBY_LINT_TIMER=$(stop_clock)
+ return 0
+}
+
+## @description Calculate the differences between the specified files
+## @description using columns and output it to stdout
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function ruby_lint_calcdiffs
+{
+ declare orig=$1
+ declare new=$2
+ declare tmp=${PATCH_DIR}/pl.$$.${RANDOM}
+ declare j
+
+ # first, strip filenames:line:
+ # this keeps column: in an attempt to increase
+ # accuracy in case of multiple, repeated errors
+ # since the column number shouldn't change
+ # if the line of code hasn't been touched
+ # shellcheck disable=SC2016
+ cut -f4- -d: "${orig}" > "${tmp}.branch"
+ # shellcheck disable=SC2016
+ cut -f4- -d: "${new}" > "${tmp}.patch"
+
+ # compare the errors, generating a string of line
+ # numbers. Sorry portability: GNU diff makes this too easy
+ ${DIFF} --unchanged-line-format="" \
+ --old-line-format="" \
+ --new-line-format="%dn " \
+ "${tmp}.branch" \
+ "${tmp}.patch" > "${tmp}.lined"
+
+ # now, pull out those lines of the raw output
+ # shellcheck disable=SC2013
+ for j in $(cat "${tmp}.lined"); do
+ # shellcheck disable=SC2086
+ head -${j} "${new}" | tail -1
+ done
+
+ rm "${tmp}.branch" "${tmp}.patch" "${tmp}.lined" 2>/dev/null
+}
+
+function ruby_lint_postapply
+{
+ declare i
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test ruby_lint; then
+ return 0
+ fi
+
+ big_console_header "ruby-lint plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${RUBY_LINT_TIMER}"
+
+ echo "Running ruby-lint against identified ruby scripts."
+ # we re-check this in case one has been added
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.rb$ && -f ${i} ]]; then
+ ${RUBY_LINT} -p syntastic "${i}" | sort -t : -k 1,1 -k 3,3n -k 4,4n >> "${PATCH_DIR}/patch-ruby-lint-result.txt"
+ fi
+ done
+ popd >/dev/null
+
+ # shellcheck disable=SC2016
+ RUBY_LINT_VERSION=$(${RUBY_LINT} -v | ${AWK} '{print $2}')
+ add_footer_table ruby-lint "${RUBY_LINT_VERSION}"
+
+ calcdiffs \
+ "${PATCH_DIR}/branch-ruby-lint-result.txt" \
+ "${PATCH_DIR}/patch-ruby-lint-result.txt" \
+ ruby_lint \
+ > "${PATCH_DIR}/diff-patch-ruby-lint.txt"
+ diffPostpatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/diff-patch-ruby-lint.txt")
+
+ # shellcheck disable=SC2016
+ numPrepatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/branch-ruby-lint-result.txt")
+
+ # shellcheck disable=SC2016
+ numPostpatch=$(${AWK} -F: 'BEGIN {sum=0} 4<NF {sum+=1} END {print sum}' "${PATCH_DIR}/patch-ruby-lint-result.txt")
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]] ; then
+ add_vote_table -1 ruby-lint "${BUILDMODEMSG} ${statstring}"
+ add_footer_table ruby-lint "@@BASE@@/diff-patch-ruby-lint.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 ruby-lint "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 ruby-lint "There were no new ruby-lint issues."
+ return 0
+}
+
+function ruby_lint_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ ruby_lint_preapply
+ else
+ ruby_lint_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/scala.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/scala.sh b/precommit/src/main/shell/test-patch.d/scala.sh
new file mode 100755
index 0000000..f2b599a
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/scala.sh
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type scalac
+add_test_type scaladoc
+
+SCALA_INITIALIZED=false
+
+function scalac_filefilter
+{
+ declare filename=$1
+
+ if [[ ${filename} =~ \.scala$ ]]; then
+ yetus_debug "tests/scalac: ${filename}"
+ add_test scalac
+ add_test compile
+ fi
+}
+
+function scaladoc_filefilter
+{
+ local filename=$1
+
+ if [[ ${filename} =~ \.scala$ ]]; then
+ yetus_debug "tests/scaladoc: ${filename}"
+ add_test scaladoc
+ fi
+}
+
+## @description initialize the scala plug-in
+## @audience private
+## @stability evolving
+## @replaceable no
+function scala_initialize
+{
+ if [[ ${SCALA_INITIALIZED} == true ]]; then
+ return
+ else
+ SCALA_INITIALIZED=true
+ fi
+
+ if declare -f maven_add_install >/dev/null 2>&1; then
+ maven_add_install scaladoc
+ maven_add_install scalac
+ fi
+}
+
+## @description initialize the scalac plug-in
+## @audience private
+## @stability evolving
+## @replaceable no
+function scalac_initialize
+{
+ scala_initialize
+}
+
+## @description initialize the scaladoc plug-in
+## @audience private
+## @stability evolving
+## @replaceable no
+function scaladoc_initialize
+{
+ scala_initialize
+}
+
+## @description
+## @audience private
+## @stability stable
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function scalac_compile
+{
+ declare codebase=$1
+ declare multijdkmode=$2
+
+ if ! verify_needed_test scalac; then
+ return 0
+ fi
+
+ if [[ ${codebase} = patch ]]; then
+ generic_postlog_compare compile scalac "${multijdkmode}"
+ fi
+}
+
+## @description Count and compare the number of ScalaDoc warnings pre- and post- patch
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function scaladoc_rebuild
+{
+ declare codebase=$1
+
+ if [[ "${codebase}" = branch ]]; then
+ generic_pre_handler scaladoc false
+ else
+ generic_post_handler scaladoc scaladoc false true
+ fi
+}
+
+## @description Helper for generic_logfilter
+## @audience private
+## @stability evolving
+## @replaceable no
+function scalac_logfilter
+{
+ declare input=$1
+ declare output=$2
+
+ #shellcheck disable=SC2016,SC2046
+ ${GREP} "^/.*.scala:[0-9]*:" "${input}" > "${output}"
+}
+
+## @description Helper for generic_logfilter
+## @audience private
+## @stability evolving
+## @replaceable no
+function scaladoc_logfilter
+{
+ declare input=$1
+ declare output=$2
+
+ #shellcheck disable=SC2016,SC2046
+ ${GREP} "^/.*.scala:[0-9]*:" "${input}" > "${output}"
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/shellcheck.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/shellcheck.sh b/precommit/src/main/shell/test-patch.d/shellcheck.sh
new file mode 100755
index 0000000..f0450f7
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/shellcheck.sh
@@ -0,0 +1,263 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# no public APIs here
+# SHELLDOC-IGNORE
+
+add_test_type shellcheck
+
+SHELLCHECK_TIMER=0
+SHELLCHECK_X=true
+
+SHELLCHECK=${SHELLCHECK:-$(which shellcheck 2>/dev/null)}
+
+# files that are going to get shellcheck'd
+SHELLCHECK_CHECKFILES=()
+
+# files that are going to get shellcheck'd
+SHELLCHECK_FILTERFILES=()
+
+
+function shellcheck_filefilter
+{
+ declare filename=$1
+
+ if [[ ${filename} =~ \.sh$ ]]; then
+ # if it ends in an explicit .sh, then this is shell code.
+ add_test shellcheck
+ yetus_add_array_element SHELLCHECK_FILTERFILES "${filename}"
+ elif [[ ${BUILDTOOL} = maven && ${filename} =~ src/main/shell ]]; then
+ # if it is maven and in src/main/shell, assume it's shell code
+ add_test shellcheck
+ yetus_add_array_element SHELLCHECK_FILTERFILES "${filename}"
+ elif [[ ! ${filename} =~ \. ]]; then
+ # if it doesn't have an extension, then assume it is and
+ # we'll deal with it later
+ add_test shellcheck
+ yetus_add_array_element SHELLCHECK_FILTERFILES "${filename}"
+ fi
+}
+
+function shellcheck_precheck
+{
+ declare langs
+
+ if ! verify_command "shellcheck" "${SHELLCHECK}"; then
+ add_vote_table 0 shellcheck "Shellcheck was not available."
+ delete_test shellcheck
+ else
+ # shellcheck disable=SC2016
+ SHELLCHECK_VERSION=$("${SHELLCHECK}" --version | "${GREP}" version: | "${AWK}" '{print $NF}')
+
+ # versions less than 0.4.1 do not support -x
+ if [[ ${SHELLCHECK_VERSION} =~ 0.[0-3].[0-9] || ${SHELLCHECK_VERSION} = 0.4.0 ]]; then
+ SHELLCHECK_X=false
+ fi
+ fi
+
+ if [[ -z "${LANG}" ]]; then
+ langs=$(locale -a)
+ if [[ ${langs} =~ C.UTF-8 ]]; then
+ yetus_error "WARNING: shellcheck needs UTF-8 locale support. Forcing C.UTF-8."
+ export LANG=C.UTF-8
+ export LC_ALL=C.UTF-8
+ elif [[ ${langs} =~ en_US.UTF-8 ]]; then
+ yetus_error "WARNING: shellcheck needs UTF-8 locale support. Forcing en_US.UTF-8."
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+ else
+ for i in ${langs}; do
+ if [[ "${i}" =~ UTF-8 ]]; then
+ yetus_error "WARNING: shellcheck needs UTF-8 locale support. Forcing ${i}."
+ export LANG="${i}"
+ export LC_ALL="${i}"
+ break
+ fi
+ done
+ fi
+ fi
+
+ if [[ ! "${LANG}" =~ UTF-8 ]]; then
+ yetus_error "WARNING: shellcheck may fail without UTF-8 locale setting."
+ fi
+}
+
+function shellcheck_criteria
+{
+ declare fn=$1
+ declare text
+
+ if [[ ! -f "${fn}" ]]; then
+ yetus_debug "Shellcheck rejected (not exist): ${fn}"
+ return
+ fi
+
+ text=$(head -n 1 "${fn}")
+
+ # shell check requires either a bangpath or a shell check directive
+ # on the first line. so check for a leading comment char
+ # and some sort of reference to 'sh'
+ if echo "${text}" | "${GREP}" -E -q "^#"; then
+ if echo "${text}" | "${GREP}" -q sh; then
+ yetus_add_array_element SHELLCHECK_CHECKFILES "${fn}"
+ yetus_debug "Shellcheck added: ${fn}"
+ fi
+ fi
+}
+
+function shellcheck_findscripts
+{
+ declare fn
+
+ # reset
+ SHELLCHECK_CHECKFILES=()
+
+ # run through the files our filter caught
+ # this will set SHELLCHECK_CHECKFILES elements
+ for fn in "${SHELLCHECK_FILTERFILES[@]}"; do
+ shellcheck_criteria "${fn}"
+ done
+
+ # finally, sort the array
+ yetus_sort_array SHELLCHECK_CHECKFILES
+}
+
+function shellcheck_logic
+{
+ declare repostatus=$1
+ declare i
+
+ echo "Running shellcheck against all suspected shell scripts"
+ pushd "${BASEDIR}" >/dev/null
+
+ # need to run this every time in case patch
+ # add/removed files
+ shellcheck_findscripts
+
+ for i in "${SHELLCHECK_CHECKFILES[@]}"; do
+ if [[ "${SHELLCHECK_X}" = true ]]; then
+ "${SHELLCHECK}" -x -f gcc "${i}" >> "${PATCH_DIR}/${repostatus}-shellcheck-result.txt"
+ else
+ "${SHELLCHECK}" -f gcc "${i}" >> "${PATCH_DIR}/${repostatus}-shellcheck-result.txt"
+ fi
+ done
+ popd > /dev/null
+}
+
+function shellcheck_preapply
+{
+ declare msg
+
+ if ! verify_needed_test shellcheck; then
+ return 0
+ fi
+
+ big_console_header "shellcheck plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ shellcheck_logic branch
+
+ msg="v${SHELLCHECK_VERSION}"
+ if [[ ${SHELLCHECK_VERSION} =~ 0.[0-3].[0-5] ]]; then
+ msg="${msg} (This is an old version that has serious bugs. Consider upgrading.)"
+ fi
+ add_footer_table shellcheck "${msg}"
+
+ # keep track of how much as elapsed for us already
+ SHELLCHECK_TIMER=$(stop_clock)
+ return 0
+}
+
+## @description Wrapper to call column_calcdiffs
+## @audience private
+## @stability evolving
+## @replaceable no
+## @param branchlog
+## @param patchlog
+## @return differences
+function shellcheck_calcdiffs
+{
+ column_calcdiffs "$@"
+}
+
+function shellcheck_postapply
+{
+ declare i
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test shellcheck; then
+ return 0
+ fi
+
+ big_console_header "shellcheck plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${SHELLCHECK_TIMER}"
+
+ shellcheck_logic patch
+
+ calcdiffs \
+ "${PATCH_DIR}/branch-shellcheck-result.txt" \
+ "${PATCH_DIR}/patch-shellcheck-result.txt" \
+ shellcheck \
+ > "${PATCH_DIR}/diff-patch-shellcheck.txt"
+
+ # shellcheck disable=SC2016
+ numPrepatch=$(wc -l "${PATCH_DIR}/branch-shellcheck-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ numPostpatch=$(wc -l "${PATCH_DIR}/patch-shellcheck-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ diffPostpatch=$(wc -l "${PATCH_DIR}/diff-patch-shellcheck.txt" | ${AWK} '{print $1}')
+
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]] ; then
+ add_vote_table -1 shellcheck "${BUILDMODEMSG} ${statstring}"
+ add_footer_table shellcheck "@@BASE@@/diff-patch-shellcheck.txt"
+ bugsystem_linecomments "shellcheck" "${PATCH_DIR}/diff-patch-shellcheck.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 shellcheck "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 shellcheck "There were no new shellcheck issues."
+ return 0
+}
+
+function shellcheck_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ shellcheck_preapply
+ else
+ shellcheck_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/shelldocs.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/shelldocs.sh b/precommit/src/main/shell/test-patch.d/shelldocs.sh
new file mode 100755
index 0000000..d52fa6b
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/shelldocs.sh
@@ -0,0 +1,195 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type shelldocs
+
+SHELLDOCS_TIMER=0
+
+SHELLDOCS=${SHELLDOCS}
+if [[ -z ${SHELLDOCS} ]]; then
+ for shelldocsexec in "${BINDIR}/shelldocs" "${BINDIR}/../shelldocs/shelldocs.py"; do
+ if [[ -f ${shelldocsexec} && -x ${shelldocsexec} ]]; then
+ SHELLDOCS=${shelldocsexec}
+ break
+ fi
+ done
+fi
+
+SHELLDOCS_SPECIFICFILES=""
+
+function shelldocs_usage
+{
+ yetus_add_option "--shelldocs=<path>" "path to shelldocs executable"
+}
+
+function shelldocs_parse_args
+{
+ declare i
+
+ for i in "$@"; do
+ case ${i} in
+ --shelldocs=*)
+ SHELLDOCS=${i#*=}
+ ;;
+ esac
+ done
+}
+
+# if it ends in an explicit .sh, then this is shell code.
+# if it doesn't have an extension, we assume it is shell code too
+function shelldocs_filefilter
+{
+ declare filename=$1
+
+ if [[ ${filename} =~ \.sh$ ]]; then
+ add_test shelldocs
+ SHELLDOCS_SPECIFICFILES="${SHELLDOCS_SPECIFICFILES} ./${filename}"
+ fi
+
+ if [[ ! ${filename} =~ \. ]]; then
+ add_test shelldocs
+ fi
+}
+
+function shelldocs_precheck
+{
+ if ! verify_command "shelldocs" "${SHELLDOCS}"; then
+ add_vote_table 0 shelldocs "Shelldocs was not available."
+ delete_test shelldocs
+ fi
+}
+
+function shelldocs_private_findbash
+{
+ declare i
+ declare value
+ declare list
+
+ while read -r line; do
+ value=$(find "${line}" ! -name '*.cmd' -type f \
+ | ${GREP} -E -v '(.orig$|.rej$)')
+
+ for i in ${value}; do
+ if [[ ! ${i} =~ \.sh(\.|$)
+ && ! $(head -n 1 "${i}") =~ ^#! ]]; then
+ yetus_debug "Shelldocs skipped: ${i}"
+ continue
+ fi
+ list="${list} ${i}"
+ done
+ done < <(find . -type d -name bin -o -type d -name sbin -o -type d -name scripts -o -type d -name libexec -o -type d -name shellprofile.d)
+ # shellcheck disable=SC2086
+ echo ${list} ${SHELLDOCS_SPECIFICFILES} | tr ' ' '\n' | sort -u
+}
+
+function shelldocs_preapply
+{
+ declare i
+
+ if ! verify_needed_test shelldocs; then
+ return 0
+ fi
+
+ big_console_header "shelldocs plugin: ${PATCH_BRANCH}"
+
+ start_clock
+
+ echo "Running shelldocs against all identifiable shell scripts"
+ pushd "${BASEDIR}" >/dev/null
+ for i in $(shelldocs_private_findbash); do
+ if [[ -f ${i} ]]; then
+ ${SHELLDOCS} --input "${i}" --lint >> "${PATCH_DIR}/branch-shelldocs-result.txt"
+ fi
+ done
+ popd > /dev/null
+
+ # keep track of how much as elapsed for us already
+ SHELLDOCS_TIMER=$(stop_clock)
+ return 0
+}
+
+function shelldocs_postapply
+{
+ declare i
+ declare numPrepatch
+ declare numPostpatch
+ declare diffPostpatch
+ declare fixedpatch
+ declare statstring
+
+ if ! verify_needed_test shelldocs; then
+ return 0
+ fi
+
+ big_console_header "shelldocs plugin: ${BUILDMODE}"
+
+ start_clock
+
+ # add our previous elapsed to our new timer
+ # by setting the clock back
+ offset_clock "${SHELLDOCS_TIMER}"
+
+ echo "Running shelldocs against all identifiable shell scripts"
+ # we re-check this in case one has been added
+ for i in $(shelldocs_private_findbash); do
+ if [[ -f ${i} ]]; then
+ ${SHELLDOCS} --input "${i}" --lint >> "${PATCH_DIR}/patch-shelldocs-result.txt"
+ fi
+ done
+
+ calcdiffs \
+ "${PATCH_DIR}/branch-shelldocs-result.txt" \
+ "${PATCH_DIR}/patch-shelldocs-result.txt" \
+ shelldocs \
+ > "${PATCH_DIR}/diff-patch-shelldocs.txt"
+
+ # shellcheck disable=SC2016
+ numPrepatch=$(wc -l "${PATCH_DIR}/branch-shelldocs-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ numPostpatch=$(wc -l "${PATCH_DIR}/patch-shelldocs-result.txt" | ${AWK} '{print $1}')
+
+ # shellcheck disable=SC2016
+ diffPostpatch=$(wc -l "${PATCH_DIR}/diff-patch-shelldocs.txt" | ${AWK} '{print $1}')
+
+ ((fixedpatch=numPrepatch-numPostpatch+diffPostpatch))
+
+ statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
+
+ if [[ ${diffPostpatch} -gt 0 ]] ; then
+ add_vote_table -1 shelldocs "${BUILDMODEMSG} ${statstring}"
+ add_footer_table shelldocs "@@BASE@@/diff-patch-shelldocs.txt"
+ bugsystem_linecomments "shelldocs" "${PATCH_DIR}/diff-patch-shelldocs.txt"
+ return 1
+ elif [[ ${fixedpatch} -gt 0 ]]; then
+ add_vote_table +1 shelldocs "${BUILDMODEMSG} ${statstring}"
+ return 0
+ fi
+
+ add_vote_table +1 shelldocs "There were no new shelldocs issues."
+ return 0
+}
+
+function shelldocs_postcompile
+{
+ declare repostatus=$1
+
+ if [[ "${repostatus}" = branch ]]; then
+ shelldocs_preapply
+ else
+ shelldocs_postapply
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/tap.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/tap.sh b/precommit/src/main/shell/test-patch.d/tap.sh
new file mode 100755
index 0000000..465b7f1
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/tap.sh
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_format tap
+
+TAP_FAILED_TESTS=""
+TAP_LOG_DIR="target/tap"
+
+function tap_parse_args
+{
+ declare i
+
+ for i in "$@"; do
+ case ${i} in
+ --tap-log-dir=*)
+ TAP_LOG_DIR=${i#=*}
+ ;;
+ esac
+ done
+}
+
+function tap_usage
+{
+ yetus_add_option "--tap-log-dir=<dir>" "Directory relative to the module for tap output (default: \"target/tap\")"
+}
+
+function tap_process_tests
+{
+ # shellcheck disable=SC2034
+ declare module=$1
+ # shellcheck disable=SC2034
+ declare buildlogfile=$2
+ declare filefrag=$3
+ declare result=0
+ declare module_failed_tests
+ declare filenames
+
+ if [[ -d "${TAP_LOG_DIR}" ]]; then
+ filenames=$(find "${TAP_LOG_DIR}" -type f -exec "${GREP}" -l -E "^not ok" {} \;)
+ fi
+
+ if [[ -n "${filenames}" ]]; then
+ module_failed_tests=$(echo "${filenames}" \
+ | ${SED} -e "s,${TAP_LOG_DIR},,g" -e s,^/,,g )
+ # shellcheck disable=SC2086
+ cat ${filenames} >> "${PATCH_DIR}/patch-${filefrag}.tap"
+ TAP_LOGS="${TAP_LOGS} @@BASE@@/patch-${filefrag}.tap"
+ TAP_FAILED_TESTS="${TAP_FAILED_TESTS} ${module_failed_tests}"
+ ((result=result+1))
+ fi
+
+ if [[ ${result} -gt 0 ]]; then
+ return 1
+ fi
+ return 0
+}
+
+function tap_finalize_results
+{
+ declare jdk=$1
+
+ if [[ -n "${TAP_FAILED_TESTS}" ]] ; then
+ # shellcheck disable=SC2086
+ populate_test_table "${jdk}Failed TAP tests" ${TAP_FAILED_TESTS}
+ TAP_FAILED_TESTS=""
+ add_footer_table "TAP logs" "${TAP_LOGS}"
+ fi
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/test4tests.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/test4tests.sh b/precommit/src/main/shell/test-patch.d/test4tests.sh
new file mode 100755
index 0000000..6c3230c
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/test4tests.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type test4tests
+
+## @description Check the patch file for changed/new tests
+## @audience private
+## @stability evolving
+## @replaceable no
+## @return 0 on success
+## @return 1 on failure
+function test4tests_patchfile
+{
+ declare testReferences=0
+ declare i
+
+ if [[ "${BUILDMODE}" = full ]]; then
+ return
+ fi
+
+ big_console_header "Checking there are new or changed tests in the patch."
+
+ if ! verify_needed_test unit; then
+ echo "Patch does not appear to need new or modified tests."
+ return 0
+ fi
+
+ start_clock
+
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ (^|/)test/ ]]; then
+ ((testReferences=testReferences + 1))
+ fi
+ done
+
+ echo "There appear to be ${testReferences} test file(s) referenced in the patch."
+ if [[ ${testReferences} == 0 ]] ; then
+ add_vote_table -1 "test4tests" \
+ "The patch doesn't appear to include any new or modified tests. " \
+ "Please justify why no new tests are needed for this patch." \
+ "Also please list what manual steps were performed to verify this patch."
+ return 1
+ fi
+ add_vote_table +1 "test4tests" \
+ "The patch appears to include ${testReferences} new or modified test files."
+ return 0
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/unitveto.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/unitveto.sh b/precommit/src/main/shell/test-patch.d/unitveto.sh
new file mode 100755
index 0000000..e0d348e
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/unitveto.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+add_test_type unitveto
+
+UNITVETO_RE=${UNITVETO_RE:-}
+
+function unitveto_filefilter
+{
+ declare filename=$1
+
+ if [[ -n "${UNITVETO_RE}"
+ && ${filename} =~ ${UNITVETO_RE} ]]; then
+ yetus_debug "unitveto: ${filename} matched"
+ add_test unitveto
+ fi
+}
+
+function unitveto_usage
+{
+ yetus_add_option "--unitveto-re=<regex>" "Regex to automatically -1 due to manual test requirements"
+}
+
+function unitveto_parse_args
+{
+ declare i
+
+ for i in "$@"; do
+ case ${i} in
+ --unitveto-re=*)
+ UNITVETO_RE=${i#*=}
+ ;;
+ esac
+ done
+}
+
+function unitveto_patchfile
+{
+ if ! verify_needed_test unit; then
+ return 0
+ fi
+
+ if ! verify_needed_test unitveto; then
+ return 0
+ fi
+
+ add_vote_table -1 unitveto "Patch requires manual testing."
+ return 1
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/whitespace.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/whitespace.sh b/precommit/src/main/shell/test-patch.d/whitespace.sh
new file mode 100755
index 0000000..390f15f
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/whitespace.sh
@@ -0,0 +1,150 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+WHITESPACE_EOL_IGNORE_LIST=
+WHITESPACE_TABS_IGNORE_LIST=Makefile
+
+add_test_type whitespace
+
+## @description whitespace usage hook
+## @audience private
+## @stability evolving
+## @replaceable no
+function whitespace_usage
+{
+ yetus_add_option "--whitespace-eol-ignore-list=<list>" "comma-separated regex list of filenames to ignore on checking whitespaces at EOL (default '${WHITESPACE_EOL_IGNORE_LIST}')"
+ yetus_add_option "--whitespace-tabs-ignore-list=<list>" "comma-separated regex list of filenames to ignore on checking tabs in a file (default '${WHITESPACE_TABS_IGNORE_LIST}')"
+}
+
+## @description whitespace parse args hook
+## @audience private
+## @stability evolving
+## @replaceable no
+function whitespace_parse_args
+{
+ declare i
+
+ for i in "$@"; do
+ case ${i} in
+ --whitespace-eol-ignore-list=*)
+ yetus_comma_to_array WHITESPACE_EOL_IGNORE_LIST "${i#*=}"
+ ;;
+ --whitespace-tabs-ignore-list=*)
+ yetus_comma_to_array WHITESPACE_TABS_IGNORE_LIST "${i#*=}"
+ ;;
+ esac
+ done
+}
+
+function whitespace_linecomment_reporter
+{
+ declare file=$1
+ shift
+ declare comment=$*
+ declare tmpfile="${PATCH_DIR}/wlr.$$.${RANDOM}"
+
+ while read -r line; do
+ {
+ # shellcheck disable=SC2086
+ printf "%s" "$(echo ${line} | cut -f1-2 -d:)"
+ echo "${comment}"
+ } >> "${tmpfile}"
+ done < "${file}"
+
+ bugsystem_linecomments "whitespace:" "${tmpfile}"
+ rm "${tmpfile}"
+}
+
+function whitespace_postcompile
+{
+ declare repostatus=$1
+ declare count
+ declare result=0
+ declare eolignore
+ declare tabsignore
+
+ if [[ "${repostatus}" = branch ]]; then
+ return 0
+ fi
+
+ big_console_header "Checking for whitespace issues."
+ start_clock
+
+ pushd "${BASEDIR}" >/dev/null
+
+ eolignore=$(printf -- "-e ^%s: " "${WHITESPACE_EOL_IGNORE_LIST[@]}")
+ tabsignore=$(printf -- "-e ^%s: " "${WHITESPACE_TABS_IGNORE_LIST[@]}")
+
+ case "${BUILDMODE}" in
+ patch)
+ # shellcheck disable=SC2016,SC2086
+ ${AWK} '/\t/ {print $0}' \
+ "${GITDIFFCONTENT}" \
+ | ${GREP} -v ${tabsignore} >> "${PATCH_DIR}/whitespace-tabs.txt"
+
+ # shellcheck disable=SC2086
+ ${GREP} -E '[[:blank:]]$' \
+ "${GITDIFFCONTENT}" \
+ | ${GREP} -v ${eolignore} >> "${PATCH_DIR}/whitespace-eol.txt"
+ ;;
+ full)
+ # shellcheck disable=SC2086
+ ${GIT} grep -n -I --extended-regexp '[[:blank:]]$' \
+ | "${GREP}" -v ${eolignore} \
+ >> "${PATCH_DIR}/whitespace-eol.txt"
+ # shellcheck disable=SC2086
+ ${GIT} grep -n -I $'\t' \
+ | "${GREP}" -v ${tabsignore} \
+ >> "${PATCH_DIR}/whitespace-tabs.txt"
+ ;;
+ esac
+
+ # shellcheck disable=SC2016
+ count=$(wc -l "${PATCH_DIR}/whitespace-eol.txt" | ${AWK} '{print $1}')
+
+ if [[ ${count} -gt 0 ]]; then
+ if [[ "${BUILDMODE}" = full ]]; then
+ add_vote_table -1 whitespace "${BUILDMODEMSG} has ${count} line(s) that end in whitespace."
+ else
+ add_vote_table -1 whitespace \
+ "${BUILDMODEMSG} has ${count} line(s) that end in whitespace. Use git apply --whitespace=fix <<patch_file>>. Refer https://git-scm.com/docs/git-apply"
+ fi
+
+ whitespace_linecomment_reporter "${PATCH_DIR}/whitespace-eol.txt" "end of line"
+ add_footer_table whitespace "@@BASE@@/whitespace-eol.txt"
+ ((result=result+1))
+ fi
+
+ # shellcheck disable=SC2016
+ count=$(wc -l "${PATCH_DIR}/whitespace-tabs.txt" | ${AWK} '{print $1}')
+
+ if [[ ${count} -gt 0 ]]; then
+ add_vote_table -1 whitespace "${BUILDMODEMSG} ${count}"\
+ " line(s) with tabs."
+ add_footer_table whitespace "@@BASE@@/whitespace-tabs.txt"
+ whitespace_linecomment_reporter "${PATCH_DIR}/whitespace-tabs.txt" "tabs in line"
+ ((result=result+1))
+ fi
+
+ if [[ ${result} -gt 0 ]]; then
+ popd >/dev/null
+ return 1
+ fi
+
+ popd >/dev/null
+ add_vote_table +1 whitespace "${BUILDMODEMSG} has no whitespace issues."
+ return 0
+}
http://git-wip-us.apache.org/repos/asf/yetus/blob/6ebaa111/precommit/src/main/shell/test-patch.d/xml.sh
----------------------------------------------------------------------
diff --git a/precommit/src/main/shell/test-patch.d/xml.sh b/precommit/src/main/shell/test-patch.d/xml.sh
new file mode 100755
index 0000000..1e56905
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/xml.sh
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare -a XML_FILES
+
+add_test_type xml
+
+function xml_filefilter
+{
+ declare filename=$1
+
+ if [[ ${filename} =~ \.xml$ ]]; then
+ add_test xml
+ fi
+}
+
+function xml_precheck
+{
+ if ! verify_command "jrunscript" "${JAVA_HOME}/bin/jrunscript"; then
+ add_vote_table 0 xml "jrunscript was not available."
+ delete_test xml
+ fi
+}
+
+function xml_postcompile
+{
+ declare repostatus=$1
+ declare js
+ declare i
+ declare count
+
+ if ! verify_needed_test xml; then
+ return 0
+ fi
+
+ if [[ "${repostatus}" = branch ]]; then
+ return 0
+ fi
+
+ big_console_header "XML verification: ${BUILDMODE}"
+
+ js="${JAVA_HOME}/bin/jrunscript"
+
+ start_clock
+
+ pushd "${BASEDIR}" >/dev/null
+ for i in "${CHANGED_FILES[@]}"; do
+ if [[ ${i} =~ \.xml$ && -f ${i} ]]; then
+ if ! "${js}" -e "XMLDocument(arguments[0])" "${i}" > "${PATCH_DIR}/xml.txt.tmp" 2>&1; then
+ {
+ echo ""
+ echo "${i}:"
+ echo ""
+ cat "${PATCH_DIR}/xml.txt.tmp"
+ } >> "${PATCH_DIR}/xml.txt"
+ ((count=count+1))
+ XML_FILES+=("${i}")
+ fi
+ fi
+ done
+
+ popd >/dev/null
+
+ if [[ -f "${PATCH_DIR}/xml.txt.tmp" ]]; then
+ rm "${PATCH_DIR}/xml.txt.tmp"
+ fi
+
+ if [[ ${count} -gt 0 ]]; then
+ add_vote_table -1 xml "${BUILDMODEMSG} has ${count} ill-formed XML file(s)."
+ add_footer_table xml "@@BASE@@/xml.txt"
+ populate_test_table "XML" "Parsing Error(s):" "${XML_FILES[@]}"
+ return 1
+ fi
+
+ add_vote_table +1 xml "${BUILDMODEMSG} has no ill-formed XML file."
+ return 0
+}