Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 119 additions & 33 deletions scripts/check-spring-ai-version.sh
Original file line number Diff line number Diff line change
@@ -1,64 +1,150 @@
#!/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

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 "<spring-ai.version>" "$pom_file"; then
version=$(grep "<spring-ai.version>" "$pom_file" | sed 's/.*<spring-ai.version>\(.*\)<\/spring-ai.version>.*/\1/')
perl -0777 -ne '
my $xml = $_;

# Ignore declarations inside XML comments.
$xml =~ s/<!--.*?-->//sg;

while (
$xml =~
/<spring-ai\.version>\s*([^<]+?)\s*<\/spring-ai\.version>/sg
) {
print "$1\n";
}

while ($xml =~ /<dependency>\s*(.*?)\s*<\/dependency>/sg) {
my $dependency = $1;

next unless $dependency =~
/<groupId>\s*org\.springframework\.ai\s*<\/groupId>/s;

next unless $dependency =~
/<artifactId>\s*spring-ai-bom\s*<\/artifactId>/s;

if (
$dependency =~
/<version>\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 <desired-version>"
else
echo ""
echo "✅ All files use the same Spring AI version"
fi
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 <version>" \
>&2
exit 1
;;
esac
77 changes: 77 additions & 0 deletions scripts/tests/check-spring-ai-version-tests.sh
Original file line number Diff line number Diff line change
@@ -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'
<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>commented-version-test</artifactId>
<version>1.0.0</version>

<properties>
<!-- <spring-ai.version>1.1.3-SNAPSHOT</spring-ai.version> -->
<spring-ai.version>2.0.0-SNAPSHOT</spring-ai.version>
</properties>
</project>
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"