Skip to content

feat: add restore option, map proper component name and purl when replacing a match#148

Merged
eeisegn merged 13 commits intomainfrom
bugfix/mdaloia/SP-4023-Bug-on-component-replacement-in-scanoss.cc-SONY
Mar 10, 2026
Merged

feat: add restore option, map proper component name and purl when replacing a match#148
eeisegn merged 13 commits intomainfrom
bugfix/mdaloia/SP-4023-Bug-on-component-replacement-in-scanoss.cc-SONY

Conversation

@matiasdaloia
Copy link
Collaborator

@matiasdaloia matiasdaloia commented Feb 13, 2026

Summary by CodeRabbit

  • New Features

    • Restore action to undo filtering decisions on completed results (menu, confirmation dialog, keyboard shortcut: U).
    • File-snippet settings and BOM exclude entries in scan settings; component filters may omit PURL.
    • Result DTO exposes detected_name for richer component display.
    • Build-time configurable default API URL.
  • Bug Fixes / Improvements

    • Show original PURL/name when scanner-applied replacements exist; matching now considers replacement PURLs.
    • Sidebar auto-scrolls to last selected item; selection syncing avoids stale selections.

@matiasdaloia matiasdaloia self-assigned this Feb 13, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97f14b21-2a9f-4b2d-bfbf-6461077e7851

📥 Commits

Reviewing files that changed from the base of the PR and between ad2290e and ca964f4.

📒 Files selected for processing (2)
  • frontend/src/modules/results/stores/useResultsStore.ts
  • scanoss.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/modules/results/stores/useResultsStore.ts
  • scanoss.json

📝 Walkthrough

Walkthrough

Adds an end-to-end Restore action (UI, keyboard shortcut, confirmation), backend RemoveBomEntry flow, exposes detected_name in ResultDTO, makes ComponentFilter purl optional and MatchesAnyPurl consider ReplaceWith, adds file_snippet settings and BOM exclude entries, and updates result mapping to prefer original BOM values when replacements were pre-applied.

Changes

Cohort / File(s) Summary
Entities & DTOs
backend/entities/component.go, backend/entities/keyboard.go, backend/entities/result.go, frontend/wailsjs/go/models.ts
Added Restore / RestoreFile action constants and detected_name to ResultDTO; updated Wails/TS model mapping.
Domain & UI State
frontend/src/modules/components/domain/index.ts, frontend/src/modules/results/domain/index.tsx
Added FilterAction.Restore, label mapping, and presentation styling for restored state.
Filter Matching & Settings
backend/entities/scanoss_settings.go, backend/entities/scanoss_settings_test.go, scanoss.json
Made purl optional on ComponentFilter, added FileSnippetSettings and Exclude to BOM, and updated MatchesAnyPurl to consider ReplaceWith; tests updated.
Repository API & Impl
backend/repository/scanoss_settings_repository.go, backend/repository/scanoss_settings_repository_json_impl.go, backend/repository/mocks/mock_ScanossSettingsRepository.go
Added RemoveBomEntry to repository interface, JSON-backed implementation to remove matching BOM entries across lists, and corresponding mock methods.
Service Layer
backend/service/component_service_impl.go
Service now branches on Restore action to call RemoveBomEntry; other actions continue to call AddBomEntry.
Result Mapping & PURL Handling
backend/mappers/result_mapper_impl.go
Reworked mapping to prefer original BOM PURL/name when scanner pre-applied replacements exist; added componentNameFromPurl helper and consolidated PURL→URL mapping/cache.
Frontend - Actions, UI & Shortcuts
frontend/src/components/FilterComponentActions.tsx, frontend/src/lib/shortcuts.ts, frontend/src/components/ComponentDetailTooltip.tsx
Added Restore menu/button and confirmation dialog, keyboard shortcut u wired to RestoreFile, display changes to use detected_name/detected PURL URL and hide VERSION/LICENSE when pre-applied replacement is active.
Frontend - Results & Sidebar
frontend/src/modules/results/stores/useResultsStore.ts, frontend/src/components/Sidebar.tsx
Synchronizes selectedResults with fresh fetches to avoid stale references; auto-scrolls results list to last selected index when applicable.
Versioning & Build
backend/entities/version.go, Makefile, internal/config/config.go, cmd/root.go
Expanded UpdateInfo fields; replaced compile-time DEFAULT_API_URL with build-time-overridable DefaultAPIURL (Makefile ldflags + config + CLI default).
Changelog
CHANGELOG.md
Added 0.12.0 release notes covering Restore action, keyboard shortcut, file_snippet support, exclude entries, and UI/scroll/display fixes.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Frontend (FilterComponentActions)
    participant Service as Backend (ComponentService)
    participant Repo as Backend (ScanossSettingsRepository)
    participant Store as In-Memory BOM Lists

    UI->>Service: ApplyFilters(filter, Action=Restore)
    Service->>Repo: RemoveBomEntry(filter)
    Repo->>Store: Remove matching entries from Include/Remove/Replace lists
    Repo-->>Service: nil / error
    Service-->>UI: return result / error
Loading
sequenceDiagram
    participant Mapper as ResultMapper
    participant Component as ComponentDetailTooltip
    participant Display as Rendered UI

    Mapper->>Mapper: MapToResultDTO(result)
    Mapper->>Mapper: Detect scanner pre-applied replacement
    Mapper-->>Component: ResultDTO (includes detected_name, detected_purl_url, concluded_purl)
    Component->>Component: compute isPreAppliedReplacement
    alt Pre-applied replacement
        Component->>Display: displayName = detected_name, displayUrl = detected_purl_url (hide VERSION/LICENSE)
    else No replacement
        Component->>Display: displayName = original name, displayUrl = original URL (show VERSION/LICENSE)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I found a patch and gave a chew,
Restore hops back what once we knew,
Detected names peek bright and new,
Press "u" to undo the verdict true,
A nibble, a hop — the file’s like new.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add restore option, map proper component name and purl when replacing a match' accurately captures the main changes: introducing a restore/undo feature and fixing PURL/name mapping for component replacements.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/mdaloia/SP-4023-Bug-on-component-replacement-in-scanoss.cc-SONY

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.

@matiasdaloia matiasdaloia added the enhancement New feature or request label Feb 13, 2026
@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 146
  • Detected files undeclared: 0
  • Detected files declared: 146
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 147
  • Detected files undeclared: 0
  • Detected files declared: 147
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 148
  • Detected files undeclared: 0
  • Detected files declared: 148
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 148
  • Detected files undeclared: 0
  • Detected files declared: 148
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 148
  • Detected files undeclared: 0
  • Detected files declared: 148
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link

@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

🤖 Fix all issues with AI agents
In `@frontend/src/modules/results/stores/useResultsStore.ts`:
- Around line 104-113: The sync code for selectedResults can leave stale
selections when updatedSelected is empty; change the logic in the block that
computes updatedSelected (using pendingResults and completedResults) to always
call set({ selectedResults: updatedSelected }) even when updatedSelected.length
=== 0 so the store is cleared, and then re-read the current selectedResults via
get() before executing the subsequent fallback selection logic so the fallback
uses the freshly-synced value; update references to selectedResults,
pendingResults, completedResults, updatedSelected, set(), and get() accordingly.
🧹 Nitpick comments (1)
frontend/src/components/FilterComponentActions.tsx (1)

354-367: Restore button uses a plain <button> outside the Menubar pattern.

All other actions use MenubarMenu/MenubarTrigger for consistent styling and accessibility (keyboard navigation, ARIA roles). The restore button is a raw <button>, which won't participate in the menubar's roving tabindex or receive the same ARIA attributes. Consider wrapping it in a MenubarMenu/MenubarTrigger for consistency, even though it has no dropdown.

@github-actions
Copy link

github-actions bot commented Mar 9, 2026

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link

@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.

Caution

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

⚠️ Outside diff range comments (1)
scanoss.json (1)

94-97: ⚠️ Potential issue | 🟡 Minor

Remove duplicate replace entry.

This entry for pkg:github/genesysgo/shadow-nft-standard is a duplicate of the one at lines 78-81. The duplicate should be removed to avoid confusion.

🧹 Proposed fix to remove duplicate
       {
-        "purl": "pkg:github/genesysgo/shadow-nft-standard",
-        "replace_with": "pkg:github/shadcn-ui/ui"
-      },
-      {
         "purl": "pkg:github/yournextstore/yournextstore",
         "replace_with": "pkg:github/shadcn-ui/ui"
       },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scanoss.json` around lines 94 - 97, Remove the duplicate replacement entry
for the purl "pkg:github/genesysgo/shadow-nft-standard" by deleting the second
object that contains "purl": "pkg:github/genesysgo/shadow-nft-standard" and
"replace_with": "pkg:github/shadcn-ui/ui" (the duplicate shown in the diff);
keep the original entry already present earlier so there is only one replacement
mapping for that purl.
🧹 Nitpick comments (2)
Makefile (1)

9-9: Consider removing quotes from the variable value.

The quotes around the URL become part of the Makefile variable value and are passed to ldflags. While this works, it's more conventional to define the value without quotes:

♻️ Suggested simplification
-DEFAULT_API_URL = "https://api.osskb.org"
+DEFAULT_API_URL = https://api.osskb.org

Without special characters or spaces in the URL, quotes aren't necessary. This makes it slightly easier to reason about shell expansion and avoids potential edge cases if the value is used in other contexts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` at line 9, The DEFAULT_API_URL Makefile variable currently includes
surrounding quotes which become part of its value and get propagated into
ldflags; remove the surrounding quotes from the DEFAULT_API_URL assignment so
the value is defined as https://api.osskb.org (update any uses that expect the
quoted form if necessary) to avoid embedding literal quotes in build flags and
to follow Makefile conventions.
backend/entities/scanoss_settings.go (1)

74-82: Consider using pointer types for boolean fields if explicit false needs to be serialized.

Boolean fields with omitempty will be omitted from JSON output when false. This means callers cannot distinguish between "not explicitly configured" and "explicitly disabled".

If the server/consumer needs to differentiate between these states (e.g., a feature enabled by default that users can explicitly disable), consider using *bool pointers like you did for RankingThreshold.

If false is the intended default and omitting it is acceptable, this is fine as-is.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/entities/scanoss_settings.go` around lines 74 - 82, The boolean
fields on FileSnippetSettings (RankingEnabled, HonourFileExts, SkipHeaders) use
plain bool with `omitempty`, so explicit false can’t be distinguished from
unset; change those fields to pointer types (*bool) so nil == unset and &false
== explicitly disabled (keep `omitempty` so nil is omitted); update any code
that constructs or reads FileSnippetSettings (creators, unmarshallers, defaults)
to allocate bool pointers or check for nil accordingly and preserve behavior for
RankingThreshold which is already a pointer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@scanoss.json`:
- Around line 94-97: Remove the duplicate replacement entry for the purl
"pkg:github/genesysgo/shadow-nft-standard" by deleting the second object that
contains "purl": "pkg:github/genesysgo/shadow-nft-standard" and "replace_with":
"pkg:github/shadcn-ui/ui" (the duplicate shown in the diff); keep the original
entry already present earlier so there is only one replacement mapping for that
purl.

---

Nitpick comments:
In `@backend/entities/scanoss_settings.go`:
- Around line 74-82: The boolean fields on FileSnippetSettings (RankingEnabled,
HonourFileExts, SkipHeaders) use plain bool with `omitempty`, so explicit false
can’t be distinguished from unset; change those fields to pointer types (*bool)
so nil == unset and &false == explicitly disabled (keep `omitempty` so nil is
omitted); update any code that constructs or reads FileSnippetSettings
(creators, unmarshallers, defaults) to allocate bool pointers or check for nil
accordingly and preserve behavior for RankingThreshold which is already a
pointer.

In `@Makefile`:
- Line 9: The DEFAULT_API_URL Makefile variable currently includes surrounding
quotes which become part of its value and get propagated into ldflags; remove
the surrounding quotes from the DEFAULT_API_URL assignment so the value is
defined as https://api.osskb.org (update any uses that expect the quoted form if
necessary) to avoid embedding literal quotes in build flags and to follow
Makefile conventions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9f1c6d36-abba-416a-a47b-27f13e792129

📥 Commits

Reviewing files that changed from the base of the PR and between 9a10090 and cdcb955.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • Makefile
  • backend/entities/scanoss_settings.go
  • backend/entities/version.go
  • cmd/root.go
  • internal/config/config.go
  • scanoss.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

Copy link

@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 (1)
scanoss.json (1)

3-7: Remove unused file_snippet settings or wire them through to the scanner.

The file_snippet fields (ranking_enabled, skip_headers, skip_headers_limit) are deserialized from the JSON configuration into the FileSnippetSettings struct (backend/entities/scanoss_settings.go:74-82), but they are never accessed or used anywhere in the codebase. Adding configuration that has no effect provides no functional benefit and adds maintenance burden.

Either remove these fields from the configuration file, or implement the logic to actually use them in the scanning process.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scanoss.json` around lines 3 - 7, The FileSnippetSettings fields are unused;
either remove them from the JSON and code or wire them into the scanner: Option
A — delete the file_snippet keys from scanoss.json and remove the
FileSnippetSettings struct and its deserialization in
backend/entities/scanoss_settings.go (and any references) so config matches
behavior; Option B — propagate FileSnippetSettings from ScanOSSSettings into the
scanning pipeline (e.g., pass it into NewScanOSSScanner / ScanRepository /
ScanFile implementation) and apply ranking_enabled, skip_headers and
skip_headers_limit inside the snippet extraction routine (e.g.,
ExtractFileSnippets or equivalent) to control snippet ranking and header
skipping. Ensure the chosen approach updates config parsing and tests
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scanoss.json`:
- Line 133: Add a trailing newline to scanoss.json so the file ends with a POSIX
newline; this aligns with the JSONSerialize behavior in
internal/utils/file_utils_default_impl.go (JSONSerialize appends a newline) and
avoids inconsistencies between manually-maintained and generated files—open
scanoss.json, ensure the final character is a newline, save the file.

---

Nitpick comments:
In `@scanoss.json`:
- Around line 3-7: The FileSnippetSettings fields are unused; either remove them
from the JSON and code or wire them into the scanner: Option A — delete the
file_snippet keys from scanoss.json and remove the FileSnippetSettings struct
and its deserialization in backend/entities/scanoss_settings.go (and any
references) so config matches behavior; Option B — propagate FileSnippetSettings
from ScanOSSSettings into the scanning pipeline (e.g., pass it into
NewScanOSSScanner / ScanRepository / ScanFile implementation) and apply
ranking_enabled, skip_headers and skip_headers_limit inside the snippet
extraction routine (e.g., ExtractFileSnippets or equivalent) to control snippet
ranking and header skipping. Ensure the chosen approach updates config parsing
and tests accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57e13e0f-3151-4f9e-8c0b-a57a30cc09f3

📥 Commits

Reviewing files that changed from the base of the PR and between cdcb955 and ad2290e.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • scanoss.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@github-actions
Copy link

SCANOSS SCAN Completed 🚀

  • Detected components: 3
  • Undeclared components: 0
  • Declared components: 3
  • Detected files: 190
  • Detected files undeclared: 0
  • Detected files declared: 190
  • Licenses detected: 2
  • Licenses detected with copyleft: 1
  • Policies: ✅ 1 pass (1 total)

View more details on SCANOSS Action Summary

@eeisegn eeisegn merged commit 3ee9dbd into main Mar 10, 2026
6 checks passed
@eeisegn eeisegn deleted the bugfix/mdaloia/SP-4023-Bug-on-component-replacement-in-scanoss.cc-SONY branch March 10, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants