From 958676156f4b8bfae8390aa0f7425e4fa5bf8176 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Date: Tue, 21 Jul 2026 10:15:50 +0530 Subject: [PATCH] Improve Spring AI version consistency validation Signed-off-by: Vinod Kumar --- scripts/check-spring-ai-version.sh | 152 ++++++++++++++---- .../tests/check-spring-ai-version-tests.sh | 77 +++++++++ 2 files changed, 196 insertions(+), 33 deletions(-) create mode 100755 scripts/tests/check-spring-ai-version-tests.sh diff --git a/scripts/check-spring-ai-version.sh b/scripts/check-spring-ai-version.sh index dd26b1bc..775d8e10 100755 --- a/scripts/check-spring-ai-version.sh +++ b/scripts/check-spring-ai-version.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Check Spring AI versions across all pom.xml files +# Check Spring AI versions across all pom.xml files. # Usage: ./scripts/check-spring-ai-version.sh set -e @@ -8,57 +8,143 @@ set -e echo "Checking Spring AI versions in all pom.xml files..." echo "" -# Find script directory and project root SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" -# Change to project root cd "${PROJECT_ROOT}" -# Track versions found -declare -A VERSION_COUNT +POM_LIST_FILE="$(mktemp "${TMPDIR:-/tmp}/spring-ai-poms.XXXXXX")" +RESULTS_FILE="$(mktemp "${TMPDIR:-/tmp}/spring-ai-versions.XXXXXX")" +POM_VERSIONS_FILE="$(mktemp "${TMPDIR:-/tmp}/spring-ai-pom-versions.XXXXXX")" + +cleanup() { + rm -f \ + "${POM_LIST_FILE}" \ + "${RESULTS_FILE}" \ + "${POM_VERSIONS_FILE}" +} + +trap cleanup EXIT HUP INT TERM + +find . \ + -name "pom.xml" \ + -type f \ + -not -path "./.version-backups/*" \ + | sort > "${POM_LIST_FILE}" + TOTAL_WITH_VERSION=0 TOTAL_WITHOUT_VERSION=0 -# Find and check all pom.xml files (excluding backups) -echo "Files with spring-ai.version property:" -echo "----------------------------------------" +echo "Files with Spring AI version declarations:" +echo "-----------------------------------------" + while IFS= read -r pom_file; do - if grep -q "" "$pom_file"; then - version=$(grep "" "$pom_file" | sed 's/.*\(.*\)<\/spring-ai.version>.*/\1/') + perl -0777 -ne ' + my $xml = $_; + + # Ignore declarations inside XML comments. + $xml =~ s///sg; + + while ( + $xml =~ + /\s*([^<]+?)\s*<\/spring-ai\.version>/sg + ) { + print "$1\n"; + } + + while ($xml =~ /\s*(.*?)\s*<\/dependency>/sg) { + my $dependency = $1; + + next unless $dependency =~ + /\s*org\.springframework\.ai\s*<\/groupId>/s; + + next unless $dependency =~ + /\s*spring-ai-bom\s*<\/artifactId>/s; + + if ( + $dependency =~ + /\s*([^<]+?)\s*<\/version>/s + ) { + my $version = $1; + + # The concrete value is already obtained from the property. + next if $version eq q(${spring-ai.version}); + + print "$version\n"; + } + } + ' "${pom_file}" \ + | sed '/^[[:space:]]*$/d' \ + | sort -u > "${POM_VERSIONS_FILE}" + + if [ -s "${POM_VERSIONS_FILE}" ]; then + TOTAL_WITH_VERSION=$((TOTAL_WITH_VERSION + 1)) relative_path="${pom_file#./}" - echo " $version - $relative_path" - - # Count this version - if [ -n "$version" ]; then - VERSION_COUNT["$version"]=$((${VERSION_COUNT["$version"]:-0} + 1)) - TOTAL_WITH_VERSION=$((TOTAL_WITH_VERSION + 1)) - fi + + while IFS= read -r version; do + printf " %s - %s\n" "${version}" "${relative_path}" + printf "%s\t%s\n" \ + "${version}" \ + "${relative_path}" >> "${RESULTS_FILE}" + done < "${POM_VERSIONS_FILE}" else TOTAL_WITHOUT_VERSION=$((TOTAL_WITHOUT_VERSION + 1)) fi -done < <(find . -name "pom.xml" -type f -not -path "./.version-backups/*" | sort) +done < "${POM_LIST_FILE}" echo "" echo "Version Summary:" echo "----------------" -for version in "${!VERSION_COUNT[@]}"; do - echo " $version: ${VERSION_COUNT[$version]} files" -done + +if [ -s "${RESULTS_FILE}" ]; then + cut -f1 "${RESULTS_FILE}" \ + | sort \ + | uniq -c \ + | while read -r count version; do + echo " ${version}: ${count} files" + done +else + echo " No Spring AI versions detected" +fi echo "" echo "Statistics:" echo "-----------" echo " Total pom.xml files: $((TOTAL_WITH_VERSION + TOTAL_WITHOUT_VERSION))" -echo " Files with spring-ai.version: $TOTAL_WITH_VERSION" -echo " Files without spring-ai.version: $TOTAL_WITHOUT_VERSION" - -# Check for version inconsistencies -if [ ${#VERSION_COUNT[@]} -gt 1 ]; then - echo "" - echo "⚠️ WARNING: Multiple versions detected! Consider running:" - echo " ./scripts/update-spring-ai-version.sh " -else - echo "" - echo "✅ All files use the same Spring AI version" -fi \ No newline at end of file +echo " Files with Spring AI version declarations: ${TOTAL_WITH_VERSION}" +echo " Files without Spring AI version declarations: ${TOTAL_WITHOUT_VERSION}" + +UNIQUE_VERSION_COUNT=0 + +if [ -s "${RESULTS_FILE}" ]; then + UNIQUE_VERSION_COUNT="$( + cut -f1 "${RESULTS_FILE}" \ + | sort -u \ + | wc -l \ + | tr -d '[:space:]' + )" +fi + +case "${UNIQUE_VERSION_COUNT}" in + 0) + echo "" + echo "Error: no Spring AI version declarations were detected." >&2 + exit 2 + ;; + 1) + CONSISTENT_VERSION="$( + cut -f1 "${RESULTS_FILE}" | sort -u + )" + + echo "" + echo "All detected declarations use Spring AI version ${CONSISTENT_VERSION}" + ;; + *) + echo "" + echo "Error: multiple Spring AI versions were detected." >&2 + echo \ + "Consider running: ./scripts/update-spring-ai-version.sh " \ + >&2 + exit 1 + ;; +esac \ No newline at end of file diff --git a/scripts/tests/check-spring-ai-version-tests.sh b/scripts/tests/check-spring-ai-version-tests.sh new file mode 100755 index 00000000..d28dff50 --- /dev/null +++ b/scripts/tests/check-spring-ai-version-tests.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -eu + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CHECKER="$(cd "${SCRIPT_DIR}/.." && pwd)/check-spring-ai-version.sh" + +TEST_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/spring-ai-version-test.XXXXXX")" + +cleanup() { + rm -rf "${TEST_ROOT}" +} + +trap cleanup EXIT HUP INT TERM + +fail() { + echo "FAIL: $1" >&2 + exit 1 +} + +assert_contains() { + output="$1" + expected="$2" + + echo "${output}" | grep -Fq "${expected}" || + fail "Expected output to contain: ${expected}" +} + +assert_not_contains() { + output="$1" + unexpected="$2" + + if echo "${output}" | grep -Fq "${unexpected}"; then + fail "Expected output not to contain: ${unexpected}" + fi +} + +echo "Test: ignores commented Spring AI version declarations" + +mkdir -p "${TEST_ROOT}/scripts" +mkdir -p "${TEST_ROOT}/example" + +cp "${CHECKER}" "${TEST_ROOT}/scripts/check-spring-ai-version.sh" +chmod +x "${TEST_ROOT}/scripts/check-spring-ai-version.sh" + +cat > "${TEST_ROOT}/example/pom.xml" <<'EOF' + + 4.0.0 + + com.example + commented-version-test + 1.0.0 + + + + 2.0.0-SNAPSHOT + + +EOF + +set +e +output="$("${TEST_ROOT}/scripts/check-spring-ai-version.sh" 2>&1)" +exit_code=$? +set -e + +if [ "${exit_code}" -ne 0 ]; then + echo "${output}" >&2 + fail "Expected exit code 0, but received ${exit_code}" +fi + +assert_contains "${output}" "2.0.0-SNAPSHOT" +assert_not_contains "${output}" "1.1.3-SNAPSHOT" +assert_contains \ + "${output}" \ + "All detected declarations use Spring AI version 2.0.0-SNAPSHOT" + +echo "PASS: commented Spring AI version declaration was ignored" \ No newline at end of file