Skip to content

issue-383-asset-picking#421

Closed
Jassem-sendi wants to merge 1 commit intomainfrom
issue-383-asset-picking
Closed

issue-383-asset-picking#421
Jassem-sendi wants to merge 1 commit intomainfrom
issue-383-asset-picking

Conversation

@Jassem-sendi
Copy link
Copy Markdown
Collaborator

@Jassem-sendi Jassem-sendi commented Apr 14, 2026

Summary by CodeRabbit

Release Notes

  • Enhancements
    • Improved asset selection logic during app updates to intelligently prefer previously installed versions when available.
    • Enhanced version matching and fallback handling to provide smarter asset selection across update scenarios.
    • Better tracking of selected app versions for future update operations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

Walkthrough

This PR introduces intelligent asset preference matching by adding a new AssetPreferenceMatcher component that selects preferred assets using fuzzy matching, then integrates this logic throughout the app to enhance asset selection in installed apps management and app linking workflows.

Changes

Cohort / File(s) Summary
Core Domain Model
core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/AssetPreferenceMatcher.kt
New singleton providing choosePreferredAsset() function that matches assets from a list against ordered preferred names using fuzzy matching (family/extension matching, tokenization similarity, and size as tiebreaker).
Core Data Repository
core/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/InstalledAppsRepositoryImpl.kt
Replaced primary asset selection with preference-based selection via AssetPreferenceMatcher.choosePreferredAsset() using app.latestAssetName and app.installedAssetName as preferences, falling back to installer's primary asset choice when no match found.
Apps Domain & Data
feature/apps/domain/src/commonMain/kotlin/zed/rainxch/apps/domain/repository/AppsRepository.kt, feature/apps/data/src/commonMain/kotlin/zed/rainxch/apps/data/repository/AppsRepositoryImpl.kt
Extended linkAppToRepo() signature to accept optional selected asset metadata (selectedAssetName, selectedAssetUrl, selectedAssetSize); updated implementation to populate both installed and latest asset fields from selected asset parameters.
Apps Presentation
feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsViewModel.kt
Integrated AssetPreferenceMatcher for asset selection during single-app updates and updated linkAppToRepo() calls to pass selected asset metadata.
Details Presentation
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt
Reordered asset selection precedence to prioritize primaryAsset first, then fallback to matching by latestAssetName and installedAssetName.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A clever matcher hops through assets, choosing with care,
Fuzzy logic and similarity scoring beyond compare!
From latest to installed names, preferences align,
Each layer now passes the chosen asset fine. ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

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.
Title check ❓ Inconclusive The title 'issue-383-asset-picking' is vague and references only an issue number and a generic term without clearly describing the actual changes or improvements made in the pull request. Consider a more descriptive title that explains the main change, such as 'Add preferred asset selection logic with fallback matching' or 'Implement smart asset preference matching for app updates'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-383-asset-picking
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch issue-383-asset-picking

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.

🧹 Nitpick comments (2)
feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt (1)

690-697: Consider using AssetPreferenceMatcher for consistency with InstalledAppsRepositoryImpl.

The asset selection logic here uses simple exact-name matching via firstOrNull { it.name == ... }, while InstalledAppsRepositoryImpl.checkForUpdates() and AppsViewModel.updateSingleApp() use AssetPreferenceMatcher.choosePreferredAsset() which provides fuzzy matching (family-based, extension-aware, similarity scoring).

This inconsistency could lead to different asset selection behavior during updates initiated from the details screen versus the apps list screen. If the asset name changes slightly between releases (e.g., version number in filename), this simple matching will fail while AssetPreferenceMatcher would still find a match.

♻️ Suggested refactor for consistency
+import zed.rainxch.core.domain.model.AssetPreferenceMatcher
+
 private fun update() {
     val installedApp = _state.value.installedApp
     val selectedRelease = _state.value.selectedRelease

     if (installedApp != null && selectedRelease != null && installedApp.isUpdateAvailable) {
         val latestAsset =
-            _state.value.primaryAsset
-                ?: _state.value.installableAssets.firstOrNull {
-                    it.name == installedApp.latestAssetName
-                }
-                ?: _state.value.installableAssets.firstOrNull {
-                    it.name == installedApp.installedAssetName
-                }
+            _state.value.primaryAsset
+                ?: AssetPreferenceMatcher.choosePreferredAsset(
+                    assets = _state.value.installableAssets,
+                    preferredAssetNames = listOf(installedApp.latestAssetName, installedApp.installedAssetName),
+                )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt`
around lines 690 - 697, DetailsViewModel currently selects latestAsset by exact
name equality which differs from InstalledAppsRepositoryImpl and AppsViewModel
that use AssetPreferenceMatcher; replace the two firstOrNull name-equality
checks in DetailsViewModel.kt (the latestAsset assignment) with a call to
AssetPreferenceMatcher.choosePreferredAsset passing
_state.value.installableAssets and the preferred names
(installedApp.latestAssetName and installedApp.installedAssetName) so matching
uses the same fuzzy/family/extension-aware logic as InstalledAppsRepositoryImpl
and AppsViewModel.
core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/AssetPreferenceMatcher.kt (1)

100-103: Consider extending VERSION_TOKEN_REGEX to cover additional version patterns.

The current regex ^v?\\d+(?:[._-]?\\d+)*[a-z]*$ handles common semver patterns but may miss:

  • Date-based versions: 2024.04.14, 20240414
  • Named pre-releases: rc1, alpha, beta2, preview
  • Build metadata: build123, nightly

These tokens remaining in the family key could cause family mismatches when asset naming changes between releases.

♻️ Optional: Extended version token detection
-    private fun isLikelyVersionToken(token: String): Boolean = VERSION_TOKEN_REGEX.matches(token)
+    private fun isLikelyVersionToken(token: String): Boolean =
+        VERSION_TOKEN_REGEX.matches(token) ||
+            PRERELEASE_TOKEN_REGEX.matches(token) ||
+            DATE_VERSION_REGEX.matches(token)

     private val NON_ALNUM_REGEX = Regex("[^a-z0-9]+")
     private val VERSION_TOKEN_REGEX = Regex("^v?\\d+(?:[._-]?\\d+)*[a-z]*$")
+    private val PRERELEASE_TOKEN_REGEX = Regex("^(alpha|beta|rc|preview|nightly|canary|dev|snapshot)\\d*$")
+    private val DATE_VERSION_REGEX = Regex("^\\d{8}$")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/AssetPreferenceMatcher.kt`
around lines 100 - 103, The VERSION_TOKEN_REGEX used by isLikelyVersionToken is
too narrow and misses date-based, named pre-release, and build-metadata tokens;
update VERSION_TOKEN_REGEX to match additional patterns like YYYY(.MM(.DD)?) and
compact dates (e.g., 20240414), named pre-releases (alpha|beta|rc|preview) with
optional digits, and build metadata prefixes (build|nightly) while preserving
the existing semver handling so isLikelyVersionToken detects these tokens;
locate and modify VERSION_TOKEN_REGEX (and adjust any dependent logic in
isLikelyVersionToken if needed) and ensure NON_ALNUM_REGEX remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/AssetPreferenceMatcher.kt`:
- Around line 100-103: The VERSION_TOKEN_REGEX used by isLikelyVersionToken is
too narrow and misses date-based, named pre-release, and build-metadata tokens;
update VERSION_TOKEN_REGEX to match additional patterns like YYYY(.MM(.DD)?) and
compact dates (e.g., 20240414), named pre-releases (alpha|beta|rc|preview) with
optional digits, and build metadata prefixes (build|nightly) while preserving
the existing semver handling so isLikelyVersionToken detects these tokens;
locate and modify VERSION_TOKEN_REGEX (and adjust any dependent logic in
isLikelyVersionToken if needed) and ensure NON_ALNUM_REGEX remains unchanged.

In
`@feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt`:
- Around line 690-697: DetailsViewModel currently selects latestAsset by exact
name equality which differs from InstalledAppsRepositoryImpl and AppsViewModel
that use AssetPreferenceMatcher; replace the two firstOrNull name-equality
checks in DetailsViewModel.kt (the latestAsset assignment) with a call to
AssetPreferenceMatcher.choosePreferredAsset passing
_state.value.installableAssets and the preferred names
(installedApp.latestAssetName and installedApp.installedAssetName) so matching
uses the same fuzzy/family/extension-aware logic as InstalledAppsRepositoryImpl
and AppsViewModel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 87297cd7-493b-440c-9e6b-7fd8816bd03a

📥 Commits

Reviewing files that changed from the base of the PR and between d66565a and d3e0046.

📒 Files selected for processing (6)
  • core/data/src/commonMain/kotlin/zed/rainxch/core/data/repository/InstalledAppsRepositoryImpl.kt
  • core/domain/src/commonMain/kotlin/zed/rainxch/core/domain/model/AssetPreferenceMatcher.kt
  • feature/apps/data/src/commonMain/kotlin/zed/rainxch/apps/data/repository/AppsRepositoryImpl.kt
  • feature/apps/domain/src/commonMain/kotlin/zed/rainxch/apps/domain/repository/AppsRepository.kt
  • feature/apps/presentation/src/commonMain/kotlin/zed/rainxch/apps/presentation/AppsViewModel.kt
  • feature/details/presentation/src/commonMain/kotlin/zed/rainxch/details/presentation/DetailsViewModel.kt

@Jassem-sendi Jassem-sendi deleted the issue-383-asset-picking branch April 15, 2026 07:24
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