Skip to content

refactor: simplify validation script - #3310

Merged
kariy merged 1 commit into
mainfrom
fix/validate-script
Aug 19, 2025
Merged

refactor: simplify validation script#3310
kariy merged 1 commit into
mainfrom
fix/validate-script

Conversation

@kariy

@kariy kariy commented Aug 19, 2025

Copy link
Copy Markdown
Member

related #3308

simplify the bash script for better readability.

Summary by CodeRabbit

  • New Features
    • Clear, per-version headers are always shown with improved formatting.
    • Color-coded status indicators (✓/✗) for each component version.
    • Inline display of the associated repository for each component.
    • End-of-run summary listing any missing component versions; confirms when all exist.
  • Bug Fixes
    • Unknown components now produce a clear error and stop the run, preventing silent skips.
    • More consistent validation by iterating all versions and their components.

@coderabbitai

coderabbitai Bot commented Aug 19, 2025

Copy link
Copy Markdown
Contributor

ohayo, sensei!

Walkthrough

The script validate_version.sh was refactored to iterate registry versions directly, resolve component repos with stricter error handling, check both v{version} and {version} tags per component using cached lookups, print uniform per-version headers and colorized statuses, collect missing tags, and exit on unknown components.

Changes

Cohort / File(s) Summary of Changes
Validation script flow and output
scripts/validate_version.sh
- get_repo now errors and exits on unknown components
- Replaced line-based reading with nested for-loops over versions/components via jq keys_unsorted[]
- check_tag_exists used with caching for v{comp_version} and {comp_version}
- Always print per-version headers; inline repo display; colorized ✓/✗
- Accumulate and report missing tags; fail-fast on unknown components

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Script as validate_version.sh
  participant Registry as registry.json (jq)
  participant Repo as git remote(s)

  User->>Script: Run validation
  Script->>Registry: Enumerate versions (keys_unsorted[])
  loop For each version
    Script->>Registry: List components for version
    loop For each component
      Script->>Script: get_repo(component)
      alt Unknown component
        Script-->>User: Print error to stderr
        Script->>Script: exit 1
      else Known component
        Script->>Repo: check_tag_exists v{comp_version} (cached)
        Script->>Repo: check_tag_exists {comp_version} (cached)
        Script-->>User: Print status (✓/✗), repo shown inline
        Script->>Script: Track missing tags if any
      end
    end
  end
  alt Missing tags collected
    Script-->>User: Report missing component versions
    Script->>Script: exit non-zero
  else All exist
    Script-->>User: Confirm all component versions exist
    Script->>Script: exit 0
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/validate-script

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/validate_version.sh (1)

111-116: Fix cache lookup: unescaped regex (|) can corrupt matches; use awk or escape the key. Ohayo, sensei!

The grep checks treat “|” in "${repo}|${tag}" as regex alternation, so keys like owner/repo|v1.2.3 can mis-match. This leads to false cache hits/misses.

Apply this diff to make the lookup exact and regex-safe:

-	# Check cache to avoid redundant lookups
-	if grep -q "^${key}=" "$CACHE_FILE" 2>/dev/null; then
-		local result=$(grep "^${key}=" "$CACHE_FILE" | cut -d= -f2)
-		return "$result"
-	fi
+	# Check cache to avoid redundant lookups (exact match on key before '=')
+	local result
+	if result=$(awk -F= -v k="$key" '$1==k{print $2; exit 0} END{exit 1}' "$CACHE_FILE"); then
+		return "$result"
+	fi
🧹 Nitpick comments (9)
scripts/validate_version.sh (9)

88-88: Quote cache path in trap to handle spaces.

Minor, but robust: quote the path inside trap so it’s safe even if mktemp returns a path with spaces.

-trap "rm -f $CACHE_FILE" EXIT
+trap 'rm -f "$CACHE_FILE"' EXIT

149-151: Quote the registry filename in jq invocation.

Avoid word-splitting/globbing issues if the filename contains spaces.

-all_versions=$(jq -r 'keys_unsorted[]' $VERSION_REGISTRY_FILE)
+all_versions=$(jq -r 'keys_unsorted[]' "$VERSION_REGISTRY_FILE")

146-148: Remove unused variable current_version.

It’s defined but never used after the refactor.

-# We need to track the current version being validated
-current_version=""
-

166-181: Harden jq lookups and quote filename; handle missing arrays gracefully.

If a component key exists but is null/empty, jq will error on [] without default. Also quote the filename.

-		# iterate over the current component's versions
-		comp_versions=$(jq -r ".\"${version}\".${comp}[]" $VERSION_REGISTRY_FILE)
+		# iterate over the current component's versions (default to [] if missing)
+		comp_versions=$(jq -r ".\"${version}\".${comp} // [] | .[]" "$VERSION_REGISTRY_FILE")

Optionally, make interpolation safer and avoid shell quoting pitfalls:

-		comp_versions=$(jq -r ".\"${version}\".${comp} // [] | .[]" "$VERSION_REGISTRY_FILE")
+		comp_versions=$(jq -r --arg v "$version" --arg c "$comp" '.[$v][$c] // [] | .[]' "$VERSION_REGISTRY_FILE")

65-84: Remove legacy ‘pairs’ scan; it’s unused post-refactor and parses JSON twice.

This block only serves an emptiness check and hardcodes component names, which is redundant now. Prefer checking all_versions instead.

-# Parse versions.json which has the format:
-#   { "<version>": { "katana": [...], "torii": [...] }, ... }
-# Each key is a version, and the value contains arrays of compatible component versions
-pairs=$(
-  jq -r '
-    # Iterate through each version entry
-    to_entries[]
-    | .key as $version
-    | .value
-    | ["katana","torii"][] as $component
-    | (.[$component] // empty)[]
-    | [$component, .] | @tsv
-  ' "$VERSION_REGISTRY_FILE"
-)
-
-if [[ -z "$pairs" ]]; then
-  echo "error: no katana/torii versions found in $VERSION_REGISTRY_FILE" >&2
-  exit 1
-fi
+:

Then, right after computing all_versions, add an emptiness check:

 all_versions=$(jq -r 'keys_unsorted[]' "$VERSION_REGISTRY_FILE")
 
+# nothing to validate?
+if [[ -z "$all_versions" ]]; then
+  echo "error: no versions found in $VERSION_REGISTRY_FILE" >&2
+  exit 1
+fi

40-41: Confirm desired fail-fast on unknown components; consider a non-strict mode.

Exiting on unknown keys is a behavior change. If the registry might include metadata keys now or later, this will break validations unexpectedly. Consider honoring an env flag:

  • VALIDATE_STRICT=1 (default): exit 1
  • otherwise: warn and skip.

Example tweak:

-			echo "error: unknown component '$component'" >&2
-			exit 1
+			if [[ "${VALIDATE_STRICT:-1}" == "1" ]]; then
+				echo "error: unknown component '$component'" >&2
+				exit 1
+			else
+				echo "warn: skipping unknown component '$component'" >&2
+				return 1
+			fi

If you adopt non-strict mode, update the call site to skip components when get_repo returns non-zero:

repo=$(get_repo "$comp") || continue

132-137: Micro-optimization: ls-remote + grep is redundant.

ls-remote with a specific ref returns nothing if missing; piping to grep is unnecessary. Not critical, just tidier.

-	if git ls-remote --tags "https://github.com/$repo" "refs/tags/$tag" \
-		| grep -qE 'refs/tags/' ; then
+	if git ls-remote --tags "https://github.com/$repo" "refs/tags/$tag" >/dev/null 2>&1; then
 		echo "${key}=0" >> "$CACHE_FILE"
 		return 0
 	fi

120-129: Nit: remove unnecessary -q . in gh api when discarding output.

You’re already redirecting to /dev/null, so the jq filter is superfluous.

-		if gh api -q . "repos/$repo/releases/tags/$tag" >/dev/null 2>&1; then
+		if gh api "repos/$repo/releases/tags/$tag" >/dev/null 2>&1; then
 			echo "${key}=0" >> "$CACHE_FILE"
 			return 0
 		fi
@@
-		if gh api -q . "repos/$repo/git/ref/tags/$tag" >/dev/null 2>&1; then
+		if gh api "repos/$repo/git/ref/tags/$tag" >/dev/null 2>&1; then
 			echo "${key}=0" >> "$CACHE_FILE"
 			return 0
 		fi

158-164: ohayo sensei! Validation clean – no unknown keys found in versions.json.

The jq scan confirmed that each version only contains “katana” and “torii”, so the current loop won’t encounter extra metadata keys. That said, filtering to the known set remains a useful optional safeguard against future stray entries:

-	# get the components for the current version
-	comps=$(jq -r ".[\"${version}\"] | keys_unsorted[]" "$VERSION_REGISTRY_FILE")
+	# get only known components for the current version
+	comps=$(jq -r ".[\"${version}\"] | keys_unsorted[] | select(.==\"katana\" or .==\"torii\")" "$VERSION_REGISTRY_FILE")
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 23dc33f and d09deaa.

📒 Files selected for processing (1)
  • scripts/validate_version.sh (3 hunks)

@kariy
kariy merged commit e5367fa into main Aug 19, 2025
2 checks passed
@kariy
kariy deleted the fix/validate-script branch August 19, 2025 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant