Skip to content

feat: add GitHub repository comparison feature with side-by-side analytics#540

Merged
mehul-m-prajapati merged 3 commits into
GitMetricsLab:mainfrom
PremDhakad07:feature/repo-comparison
May 31, 2026
Merged

feat: add GitHub repository comparison feature with side-by-side analytics#540
mehul-m-prajapati merged 3 commits into
GitMetricsLab:mainfrom
PremDhakad07:feature/repo-comparison

Conversation

@PremDhakad07
Copy link
Copy Markdown
Contributor

@PremDhakad07 PremDhakad07 commented May 26, 2026

Related issue

Closes: #538 🚀 Feature: Add Repository Comparison Feature with side-by-side analytics

📊 GitHub Repository Comparison Feature

This PR introduces a new feature that allows users to compare two GitHub repositories side-by-side with key analytics.


✨ Features Added

  • Compare two GitHub repositories in real time
  • Side-by-side comparison of:
    • Stars ⭐
    • Forks 🍴
    • Open Issues 🐛
    • Watchers 👀
    • Primary language 🧠
    • Last updated date ⏱️
  • Clean and responsive UI for comparison table
  • Error handling for invalid or empty repository input
  • Loading state for better UX during API calls

📁 Changes Made

  • Added RepoCompare.tsx page for comparison feature
  • Updated routing in Routes.tsx to include /compare route
  • Added navigation link in Navbar.tsx

🔧 Tech Used

  • React + TypeScript
  • GitHub REST API
  • Axios for API requests
  • Tailwind CSS for styling

🚀 How to Use

  1. Navigate to /compare
  2. Enter two GitHub repositories (e.g. facebook/react, vuejs/vue)
  3. Click compare to view side-by-side analytics

📌 Notes

  • Fully responsive design
  • Works with valid public GitHub repositories only

Before

Screenshot 2026-05-26 161141

After

Screenshot 2026-05-26 161121

Summary by CodeRabbit

  • New Features

    • Added a repository comparison page accessible from a new "Compare" item in the navigation (desktop + mobile).
    • Comparison shows stars, forks, open issues, watchers, language, last updated, and description for two repos.
  • Improvements

    • Mobile menu now dismisses when navigating to Compare.
    • Graceful loading and user-visible error handling for failed repo lookups.

Review Change Stack

@netlify
Copy link
Copy Markdown

netlify Bot commented May 26, 2026

Deploy Preview for github-spy failed.

Name Link
🔨 Latest commit b926f75
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a1c0a32d9667c00081abaa0

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@mehul-m-prajapati, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 57 minutes and 49 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 879e9288-e0ae-446e-9238-1a8cd1c7c912

📥 Commits

Reviewing files that changed from the base of the PR and between 6e38e68 and b926f75.

📒 Files selected for processing (2)
  • src/Routes/Router.tsx
  • src/components/Navbar.tsx
📝 Walkthrough

Walkthrough

This PR adds a RepoCompare page, GitHub fetch utilities, a /compare route, and a "Compare" navbar link; users can input two owner/repo strings to fetch and view side-by-side repository metadata from the GitHub REST API.

Changes

Repository Comparison Feature

Layer / File(s) Summary
GitHub API utilities
src/utils/github.ts
fetchRepo trims input, fetches https://api.github.com/repos/{owner}/{repo}, throws on non-OK responses, and returns JSON; compareRepos concurrently fetches two repos and returns { a, b }.
RepoCompare page component
src/pages/RepoCompare/RepoCompare.tsx
Adds RepoCompare default export: manages inputs for two repos, concurrent fetching via Promise.all, loading/error state, formatDate helper, inline table styles, and renders a comparison table with stars, forks, open issues, watchers, language, last updated, and description.
Route registration and navigation integration
src/Routes/Router.tsx, src/components/Navbar.tsx
Registers /compare route to render RepoCompare; adds "Compare" NavLink in desktop and mobile nav (mobile links call closeMenu); removes unused Github icon import.

Sequence Diagram

sequenceDiagram
  participant User
  participant Navbar
  participant Router
  participant RepoCompare
  participant GitHub_API

  User->>Navbar: Click "Compare" link
  Navbar->>Router: navigate to /compare
  Router->>RepoCompare: render page
  User->>RepoCompare: Enter repo names, click Compare
  RepoCompare->>GitHub_API: fetchRepo(repo1), fetchRepo(repo2)
  GitHub_API-->>RepoCompare: repo metadata JSON
  RepoCompare->>RepoCompare: update state and render comparison table
  RepoCompare-->>User: display side-by-side metrics
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

type:feature, level:intermediate, quality:clean

Poem

🐰 I hop from repo to repo with glee,
Two names in, two tables I see,
Stars and forks in tidy rows,
Last updated where the timeline goes,
A bunny's glance finds which to choose — whee!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main feature being added: a GitHub repository comparison capability with side-by-side analytics display.
Description check ✅ Passed The PR description covers all required template sections including related issue, comprehensive feature list, changes made, tech stack, usage instructions, and includes before/after screenshots.
Linked Issues check ✅ Passed All core objectives from issue #538 are met: repository comparison UI, side-by-side table layout, all 7 metrics (Stars, Forks, Issues, Watchers, Language, Last Updated, Description), GitHub REST API integration, parallel fetching, error handling, and responsive design.
Out of Scope Changes check ✅ Passed All code changes directly support the comparison feature: RepoCompare.tsx page component, Router.tsx route registration, Navbar.tsx navigation link, and github.ts utility functions for API calls.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/pages/RepoCompare/RepoCompare.tsx (1)

24-32: ⚡ Quick win

Use the shared GitHub utility instead of re-implementing fetch logic here.

This duplicates API behavior and can drift from src/utils/github.ts (it already has the same responsibility). Import and reuse the utility to keep one error-handling contract.

Suggested refactor
-import { useState } from "react";
+import { useState } from "react";
+import { compareRepos } from "../../utils/github";

@@
-  const fetchRepo = async (repo: string): Promise<RepoData> => {
-    const res = await fetch(`https://api.github.com/repos/${repo}`);
-
-    if (!res.ok) {
-      throw new Error(`Repository not found: ${repo}`);
-    }
-
-    return res.json();
-  };
-
   const handleCompare = async () => {
@@
-      const [r1, r2] = await Promise.all([
-        fetchRepo(repo1),
-        fetchRepo(repo2),
-      ]);
+      const { a: r1, b: r2 } = await compareRepos(repo1, repo2);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/RepoCompare/RepoCompare.tsx` around lines 24 - 32, The local
fetchRepo function in RepoCompare.tsx duplicates the repo-fetching logic; remove
this local function and import and call the existing exported GitHub utility
from utils/github (the function that fetches repository data) instead,
preserving the expected RepoData return type and letting the utility's error
handling propagate; update any calls inside the RepoCompare component to use
that imported utility and delete the redundant fetchRepo declaration.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/RepoCompare/RepoCompare.tsx`:
- Around line 40-53: The current compare flow leaves previous results visible
when a new fetch fails; before starting the new request (inside the try before
await Promise.all or immediately prior to setLoading(true)) clear stale results
by calling setData1(null) and setData2(null) (or equivalent empty-state values),
or alternatively clear them in the catch block before calling setError; update
the logic around fetchRepo, setData1 and setData2 so stale data is not shown
when an error occurs.
- Around line 8-9: The repo model and UI currently use GitHub's watchers_count
(which is actually the star count) for the "👀 Watchers" row; update the
type/property and rendering to use subscribers_count instead. Replace
occurrences of watchers_count in the RepoCompare component (the interface/type
declaration near the top and the render row that shows "👀 Watchers" — also at
the referenced lines ~135-137) with subscribers_count, or alternatively relabel
the UI to "Stars" if you intend to keep watchers_count; ensure the displayed
value comes from the subscribers_count field everywhere in RepoCompare.tsx.
- Around line 51-52: The catch block currently uses catch (err: any) which
violates no-explicit-any; change it to catch (err: unknown) and add a type guard
to safely extract a message before calling setError: inside the catch for the
RepoCompare component, check if err is an instance of Error (or has a string
message) and call setError(err.message) otherwise call setError(String(err) ||
"Something went wrong"); update the catch around the async logic where setError
is invoked so no explicit any is used.

In `@src/utils/github.ts`:
- Around line 1-3: fetchRepo currently returns res.json() even for non-2xx
responses, causing callers to receive error payloads as if successful; update
the fetchRepo function to check res.ok after the fetch call (using the existing
fetchRepo(repo: string) function), and if not ok throw an Error or reject with a
clear message that includes the HTTP status and statusText (optionally include
the response body by attempting to await res.text() or res.json() for richer
diagnostics), otherwise return the parsed JSON; ensure the thrown error/message
is descriptive so callers can handle error cases instead of treating them as
valid repo data.

---

Nitpick comments:
In `@src/pages/RepoCompare/RepoCompare.tsx`:
- Around line 24-32: The local fetchRepo function in RepoCompare.tsx duplicates
the repo-fetching logic; remove this local function and import and call the
existing exported GitHub utility from utils/github (the function that fetches
repository data) instead, preserving the expected RepoData return type and
letting the utility's error handling propagate; update any calls inside the
RepoCompare component to use that imported utility and delete the redundant
fetchRepo declaration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 064f40e6-db16-4d18-903b-b3e4d7b6706b

📥 Commits

Reviewing files that changed from the base of the PR and between 6c6bc3e and 4be5644.

📒 Files selected for processing (4)
  • src/Routes/Router.tsx
  • src/components/Navbar.tsx
  • src/pages/RepoCompare/RepoCompare.tsx
  • src/utils/github.ts

Comment on lines +8 to +9
watchers_count: number;
language: string;
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In the GitHub REST API repository response, what is the semantic difference between watchers_count, stargazers_count, and subscribers_count, and which one represents actual watchers?

💡 Result:

In the GitHub REST API response, the semantic difference between these fields is as follows: subscribers_count represents the number of actual watchers—users who are subscribed to receive notifications for activity in a repository [1][2]. watchers, watchers_count, and stargazers_count all represent the number of users who have starred a repository [1][2]. The confusion stems from a historical change made in 2012, where GitHub repurposed the "watching" functionality and introduced "starring" [1]. While the API terminology was maintained for backward compatibility, watchers_count and its related fields currently function as a count of stars, not repository subscribers [1][2]. If you need to identify users who are actively watching (subscribing) to a repository, you should use subscribers_count [3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant sections around the referenced line ranges
sed -n '1,120p' src/pages/RepoCompare/RepoCompare.tsx | nl -ba | sed -n '1,120p'
echo "----"
sed -n '120,220p' src/pages/RepoCompare/RepoCompare.tsx | nl -ba | sed -n '120,220p'
echo "----"
# Specifically extract the likely mapping/transform areas by searching for watchers_count
rg -n "watchers_count|subscribers_count|stargazers_count|watchers" src/pages/RepoCompare/RepoCompare.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== top of file =="
sed -n '1,60p' src/pages/RepoCompare/RepoCompare.tsx | cat -n

echo "== around lines 120-180 =="
sed -n '120,190p' src/pages/RepoCompare/RepoCompare.tsx | cat -n

echo "== occurrences of relevant fields =="
rg -n "watchers_count|subscribers_count|stargazers_count" src/pages/RepoCompare/RepoCompare.tsx || true

echo "== occurrences of string 'Watch' in UI =="
rg -n "Watch|watcher|Star|stargazer|subscriber" src/pages/RepoCompare/RepoCompare.tsx || true

Repository: GitMetricsLab/github_tracker

Length of output: 4843


Fix “Watchers” mapping (GitHub watchers_count ≠ watchers/subscribers)

  watchers_count: number;
  language: string;

The UI label “👀 Watchers” renders watchers_count, but GitHub REST’s watchers_count (like stargazers_count) is effectively the repo’s star count. Actual watchers are subscribers_count. This will duplicate stars and misreport watcher analytics—render subscribers_count for “Watchers” (or relabel the row as Stars-equivalent).

Also applies to: 135-137

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/RepoCompare/RepoCompare.tsx` around lines 8 - 9, The repo model and
UI currently use GitHub's watchers_count (which is actually the star count) for
the "👀 Watchers" row; update the type/property and rendering to use
subscribers_count instead. Replace occurrences of watchers_count in the
RepoCompare component (the interface/type declaration near the top and the
render row that shows "👀 Watchers" — also at the referenced lines ~135-137)
with subscribers_count, or alternatively relabel the UI to "Stars" if you intend
to keep watchers_count; ensure the displayed value comes from the
subscribers_count field everywhere in RepoCompare.tsx.

Comment on lines +40 to +53
try {
setLoading(true);
setError("");

const [r1, r2] = await Promise.all([
fetchRepo(repo1),
fetchRepo(repo2),
]);

setData1(r1);
setData2(r2);
} catch (err: any) {
setError(err.message || "Something went wrong");
} finally {
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear previous comparison data when a new request fails.

If a compare attempt fails, old data1/data2 remain visible under the new error message. Clear previous results before request (or in catch) to avoid stale analytics being shown as current.

Suggested fix
     try {
       setLoading(true);
       setError("");
+      setData1(null);
+      setData2(null);

@@
-    } catch (err: any) {
+    } catch (err: any) {
       setError(err.message || "Something went wrong");
     } finally {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
setLoading(true);
setError("");
const [r1, r2] = await Promise.all([
fetchRepo(repo1),
fetchRepo(repo2),
]);
setData1(r1);
setData2(r2);
} catch (err: any) {
setError(err.message || "Something went wrong");
} finally {
try {
setLoading(true);
setError("");
setData1(null);
setData2(null);
const [r1, r2] = await Promise.all([
fetchRepo(repo1),
fetchRepo(repo2),
]);
setData1(r1);
setData2(r2);
} catch (err: any) {
setError(err.message || "Something went wrong");
} finally {
🧰 Tools
🪛 ESLint

[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/RepoCompare/RepoCompare.tsx` around lines 40 - 53, The current
compare flow leaves previous results visible when a new fetch fails; before
starting the new request (inside the try before await Promise.all or immediately
prior to setLoading(true)) clear stale results by calling setData1(null) and
setData2(null) (or equivalent empty-state values), or alternatively clear them
in the catch block before calling setError; update the logic around fetchRepo,
setData1 and setData2 so stale data is not shown when an error occurs.

Comment on lines +51 to +52
} catch (err: any) {
setError(err.message || "Something went wrong");
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify explicit-any usage and lint rule presence.
rg -n --type=ts --type=tsx 'catch\s*\(\s*[^)]*:\s*any\s*\)'
rg -n '`@typescript-eslint/no-explicit-any`' .

Repository: GitMetricsLab/github_tracker

Length of output: 100


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Inspect the target file around the referenced lines
echo "=== RepoCompare.tsx lines 40-80 ==="
nl -ba src/pages/RepoCompare/RepoCompare.tsx | sed -n '40,80p'

# 2) Find explicit-any in catch clauses (avoid invalid --type=tsx)
echo "=== catch (..: any) occurrences ==="
rg -n "catch\s*\(\s*[^)]*\s:\s*any\s*\)" -S . || true

# 3) Check whether `@typescript-eslint/no-explicit-any` exists in ESLint config
echo "=== `@typescript-eslint/no-explicit-any` occurrences ==="
rg -n "`@typescript-eslint/no-explicit-any`" -S . || true

# 4) List likely ESLint config files to understand whether the rule is enabled
echo "=== ESLint config files ==="
fd -a -t f -e js -e cjs -e mjs -e json -e yaml -e yml -e ts \
  .eslintrc .eslintrc.* eslint.config .eslintignore package.json 2>/dev/null || true

Repository: GitMetricsLab/github_tracker

Length of output: 169


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== command availability ==="
command -v rg >/dev/null && echo "rg: ok" || echo "rg: missing"
command -v fd >/dev/null && echo "fd: ok" || echo "fd: missing"
command -v find >/dev/null && echo "find: ok" || echo "find: missing"
command -v cat >/dev/null && echo "cat: ok" || echo "cat: missing"
command -v sed >/dev/null && echo "sed: ok" || echo "sed: missing"
command -v head >/dev/null && echo "head: ok" || echo "head: missing"

# 1) Inspect the target file around the referenced lines
echo "=== RepoCompare.tsx lines 40-80 ==="
if [ -f "src/pages/RepoCompare/RepoCompare.tsx" ]; then
  cat -n src/pages/RepoCompare/RepoCompare.tsx | sed -n '40,90p'
else
  echo "Missing file: src/pages/RepoCompare/RepoCompare.tsx"
fi

# 2) Find explicit-any in catch clauses (avoid invalid --type=tsx)
echo "=== catch (...: any) occurrences ==="
rg -n "catch\s*\(\s*[^)]*\s:\s*any\s*\)" -S . || true

# 3) Check whether `@typescript-eslint/no-explicit-any` exists in ESLint config
echo "=== `@typescript-eslint/no-explicit-any` occurrences ==="
rg -n "`@typescript-eslint/no-explicit-any`" -S . || true

# 4) List likely ESLint config files to understand whether the rule is enabled
echo "=== ESLint config files ==="
# Prefer fd if available, otherwise fallback to find
if command -v fd >/dev/null; then
  fd -a -t f -e js -e cjs -e mjs -e json -e yaml -e yml -e ts \
    .eslintrc .eslintrc.* eslint.config .eslintignore package.json 2>/dev/null || true
else
  find . -maxdepth 4 -type f \( \
    -name ".eslintrc" -o -name ".eslintrc.*" -o -name "eslint.config.*" -o -name ".eslintignore" \
    -o -name "package.json" \
  \) 2>/dev/null || true
fi

# 5) If we found ESLint config file candidates, print the smallest relevant sections around the rule (if any)
echo "=== Snippets around rule in ESLint configs (if present) ==="
rg -n "`@typescript-eslint/no-explicit-any`" -S . -g'*.js' -g'*.cjs' -g'*.mjs' -g'*.json' -g'*.ts' -g'*.yml' -g'*.yaml' 2>/dev/null || true

Repository: GitMetricsLab/github_tracker

Length of output: 2005


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Files matching eslint config names ==="
fd -a -t f -e js -e cjs -e mjs -e json -e yaml -e yml -e ts \
  '.eslintrc' '.eslintrc.*' 'eslint.config.*' '.eslintignore' -H . 2>/dev/null || true

echo "=== Find eslint / typescript-eslint in package.json ==="
if [ -f package.json ]; then
  cat package.json | head -n 120
  echo "=== grep devDependencies/scripts for eslint ==="
  rg -n '"(eslint|typescript-eslint|`@typescript-eslint`)/' package.json || true
  rg -n 'eslint' package.json || true
else
  echo "Missing package.json"
fi

echo "=== Search for eslint configs and plugin usage ==="
rg -n "eslint\.config|no-explicit-any|`@typescript-eslint`" -S . || true

Repository: GitMetricsLab/github_tracker

Length of output: 2714


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== eslint.config.js ==="
if [ -f eslint.config.js ]; then
  cat -n eslint.config.js | sed -n '1,200p'
else
  echo "Missing eslint.config.js"
fi

echo "=== no-explicit-any references ==="
rg -n "no-explicit-any" -S . || true

echo "=== occurrences of ': any' in ts/tsx ==="
rg -n ":\s*any\b" --glob '*.{ts,tsx}' -S . || true

Repository: GitMetricsLab/github_tracker

Length of output: 1231


🌐 Web query:

typescript-eslint configs.recommended includes no-explicit-any

💡 Result:

No. typescript-eslint’s configs.recommended does include the @typescript-eslint/no-explicit-any rule. The rule is documented as being enabled when you extend plugin:@typescript-eslint/recommended`` [1]. And the actual recommended configuration in the TypeScript ESLint repo sets @typescript-eslint/no-explicit-any: `error` [2]. So if you are seeing “configs.recommended includes no-explicit-any” reported as false/absent, that’s likely due to using a different config (e.g., `recommendedTypeChecked` vs a custom setup) or overriding the rule in your local ESLint config.

Citations:


Replace catch (err: any) with a typed unknown guard.

src/pages/RepoCompare/RepoCompare.tsx uses catch (err: any), which trips @typescript-eslint/no-explicit-any from the repo’s typescript-eslint recommended ESLint config.

Suggested fix
-    } catch (err: any) {
-      setError(err.message || "Something went wrong");
+    } catch (err: unknown) {
+      setError(err instanceof Error ? err.message : "Something went wrong");
     } finally {
🧰 Tools
🪛 ESLint

[error] 51-51: Unexpected any. Specify a different type.

(@typescript-eslint/no-explicit-any)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/RepoCompare/RepoCompare.tsx` around lines 51 - 52, The catch block
currently uses catch (err: any) which violates no-explicit-any; change it to
catch (err: unknown) and add a type guard to safely extract a message before
calling setError: inside the catch for the RepoCompare component, check if err
is an instance of Error (or has a string message) and call setError(err.message)
otherwise call setError(String(err) || "Something went wrong"); update the catch
around the async logic where setError is invoked so no explicit any is used.

Comment thread src/utils/github.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/utils/github.ts (2)

1-8: ⚡ Quick win

Consider adding explicit return type annotation.

The function correctly implements error handling from the previous review. For better type safety and documentation, consider adding an explicit return type annotation.

📝 Optional: Add return type annotation
-export async function fetchRepo(repo: string) {
+export async function fetchRepo(repo: string): Promise<any> {
   const normalizedRepo = repo.trim();
   const res = await fetch(`https://api.github.com/repos/${normalizedRepo}`);
   if (!res.ok) {
     throw new Error(`Repository not found: ${normalizedRepo}`);
   }
   return res.json();
 }

Or, for stronger typing, define a GitHubRepo interface based on the fields used downstream:

interface GitHubRepo {
  full_name: string;
  stargazers_count: number;
  forks_count: number;
  open_issues_count: number;
  watchers_count: number;
  language: string;
  updated_at: string;
  description: string;
}

export async function fetchRepo(repo: string): Promise<GitHubRepo> {
  // ... existing implementation
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/github.ts` around lines 1 - 8, Add an explicit return type to
fetchRepo by defining a GitHubRepo interface (listing the fields used
downstream: full_name, stargazers_count, forks_count, open_issues_count,
watchers_count, language, updated_at, description) and change the function
signature to export async function fetchRepo(repo: string): Promise<GitHubRepo>;
also cast the response when returning (e.g., return res.json() as
Promise<GitHubRepo>) so callers get strong typing.

11-18: Remove or reuse compareRepos (currently unused)

compareRepos is never imported or referenced anywhere in the repo (only its definition in src/utils/github.ts). src/pages/RepoCompare/RepoCompare.tsx instead has its own inline fetchRepo implementation, so this helper looks like dead code unless it’s meant for future refactoring—either remove it, refactor RepoCompare.tsx to use it, or add a clear “reserved for future use” comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/github.ts` around lines 11 - 18, The compareRepos function in
src/utils (compareRepos) is dead code—either delete it or wire it up: remove the
compareRepos export if you won't use it, or refactor RepoCompare.tsx to import
compareRepos and call compareRepos(repoA, repoB) instead of its inline fetchRepo
implementation; if reusing, ensure the fetchRepo implementation signature
matches the utility's fetchRepo used by compareRepos and update imports/exports
accordingly so there are no duplicate fetchRepo definitions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/github.ts`:
- Line 9: Remove the extraneous standalone closing brace (a stray "}") in the
github utility file that causes a syntax error; delete that extra brace so the
module's braces properly balance, run the TypeScript/JS build to confirm
compilation, and verify the module's exported functions remain correctly scoped
after removal.

---

Nitpick comments:
In `@src/utils/github.ts`:
- Around line 1-8: Add an explicit return type to fetchRepo by defining a
GitHubRepo interface (listing the fields used downstream: full_name,
stargazers_count, forks_count, open_issues_count, watchers_count, language,
updated_at, description) and change the function signature to export async
function fetchRepo(repo: string): Promise<GitHubRepo>; also cast the response
when returning (e.g., return res.json() as Promise<GitHubRepo>) so callers get
strong typing.
- Around line 11-18: The compareRepos function in src/utils (compareRepos) is
dead code—either delete it or wire it up: remove the compareRepos export if you
won't use it, or refactor RepoCompare.tsx to import compareRepos and call
compareRepos(repoA, repoB) instead of its inline fetchRepo implementation; if
reusing, ensure the fetchRepo implementation signature matches the utility's
fetchRepo used by compareRepos and update imports/exports accordingly so there
are no duplicate fetchRepo definitions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d31fa372-c92a-4802-943c-7e51a07001bc

📥 Commits

Reviewing files that changed from the base of the PR and between 4be5644 and 6e38e68.

📒 Files selected for processing (1)
  • src/utils/github.ts

Comment thread src/utils/github.ts
}
return res.json();
}
}
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove extra closing brace causing syntax error.

Line 9 contains an extraneous closing brace that will prevent the code from compiling.

🐛 Fix for syntax error
   return res.json();
 }
-}
 
 export async function compareRepos(repo1: string, repo2: string) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
}
return res.json();
}
export async function compareRepos(repo1: string, repo2: string) {
🧰 Tools
🪛 Biome (2.4.15)

[error] 9-9: Expected a statement but instead found '}'.

(parse)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/github.ts` at line 9, Remove the extraneous standalone closing
brace (a stray "}") in the github utility file that causes a syntax error;
delete that extra brace so the module's braces properly balance, run the
TypeScript/JS build to confirm compilation, and verify the module's exported
functions remain correctly scoped after removal.

@mehul-m-prajapati mehul-m-prajapati merged commit 101c7bd into GitMetricsLab:main May 31, 2026
1 of 6 checks passed
@github-actions
Copy link
Copy Markdown

🎉🎉 Thank you for your contribution! Your PR #540 has been merged! 🎉🎉

@PremDhakad07
Copy link
Copy Markdown
Contributor Author

Hi @mehul-m-prajapati , please add GSSOC approved and level, feature label to the PR.

@mehul-m-prajapati
Copy link
Copy Markdown
Collaborator

done @PremDhakad07

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: Add Repository Comparison Feature with side-by-side analytics

2 participants