Skip to content

Conversation

jortel
Copy link
Contributor

@jortel jortel commented Aug 19, 2025

closes #880

Summary by CodeRabbit

  • Bug Fixes

    • All slice fields are now correctly detected and included in processing (not just byte slices), improving consistency in sorting and data inspection.
  • Refactor

    • Consolidated internal reflection utilities under a new module, with no impact on public APIs or user-facing behavior.

Copy link

coderabbitai bot commented Aug 19, 2025

Walkthrough

Imports of the internal reflect utilities were updated to github.com/konveyor/tackle2-hub/model/reflect across multiple packages. In model/reflect/fields.go, slice handling was broadened to include all slice types (not just []byte) when reflecting fields. No exported signatures changed.

Changes

Cohort / File(s) Summary
Reflect package relocation
api/base.go, api/sort/sort.go, task/manager.go, task/task.go
Updated import path from .../reflect to .../model/reflect; no functional changes in call sites.
Fields slice handling
model/reflect/fields.go
Modified Fields to include all slice-typed fields (previously only []byte). Arrays still skipped; signature unchanged.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant API as API (Sort)
    participant RF as model/reflect.Fields
    participant Sorter as Sort Logic

    Client->>API: GET /... sort=labels
    API->>RF: Fields(model)
    Note over RF: Now includes all slice fields (e.g., labels []string)
    RF-->>API: Field map incl. slice values
    API->>Sorter: Compare using extracted fields
    Sorter-->>Client: Sorted results
    Note over API,Client: Error "labels not supported by sort" no longer occurs
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Support sorting by JSON slice fields (e.g., labels) in hub sorting (#880)
Eliminate "labels not support by sort" error from sort endpoint (#880)
Ensure UI can sort dependencies by labels without backend rejection (#880) Requires integration/UI verification beyond code changes.

Assessment against linked issues: Out-of-scope changes

(no out-of-scope changes identified)

Poem

I twitch my ears at slices wide,
Labels now join the sorted ride.
No more bumps that made us stop—
Arrays still wait, but lists can hop.
With whiskers bright and code aligned,
The carrots stack in perfect kind. 🥕✨

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

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

Signed-off-by: Jeff Ortel <[email protected]>
switch inst.(type) {
case []byte:
mp[ft.Name] = fv.Interface()
}
Copy link
Contributor Author

@jortel jortel Aug 19, 2025

Choose a reason for hiding this comment

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

hint: In the past json fields stored as []byte. Now json fields are stored as regular Go types (Eg: []string). This changed and the sort package did not get updated.

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: 0

🧹 Nitpick comments (4)
reflect/fields.go (4)

14-15: Doc nit: clarify slice/array handling for sorting

Nice to see sorting called out. Consider making the behavior explicit (slices included; arrays skipped). This helps future readers understand why sorting on labels (JSON slices) is supported now.

Apply this diff to the comment:

-// Fields returns a map of fields.
-// Used for:
-// - db.Updates()
-// - sorting
+// Fields returns a map of exported struct field names to their values.
+// Used for:
+// - db.Updates()
+// - sorting (slice fields are included; array fields are skipped)

16-23: Avoid panic on nil pointers when inspecting

If Fields is called with a nil pointer, mv.Elem() will panic. While call sites likely pass non-nil structs, adding a small guard improves robustness at little cost.

-        if mt.Kind() == reflect.Ptr {
-            mt = mt.Elem()
-            mv = mv.Elem()
-        }
+        if mt.Kind() == reflect.Ptr {
+            if mv.IsNil() {
+                return // nothing to collect from a nil pointer
+            }
+            mt = mt.Elem()
+            mv = mv.Elem()
+        }

65-73: NameOf: mv.IsNil() on non-pointers can panic

reflect.Value.IsNil() panics unless the kind is pointer/map/slice/chan/func/unsafe.Pointer. Guard by checking kind first.

-    mv := reflect.ValueOf(m)
-    if mv.IsNil() {
-        return
-    }
-    if mt.Kind() == reflect.Ptr {
+    mv := reflect.ValueOf(m)
+    if mt.Kind() == reflect.Ptr {
+        if mv.IsNil() {
+            return
+        }
         mt = mt.Elem()
         mv = mv.Elem()
     }

119-126: HasFields: nil embedded pointer structs can panic during recursive inspect

For anonymous pointer fields, inspect(fv.Interface()) will panic when fv.IsNil(). Although the function has a recover, avoiding the panic is cleaner and prevents masking other issues.

-            case reflect.Ptr:
-                if ft.Anonymous {
-                    inspect(fv.Interface())
-                    continue
-                }
-                inst := fv.Interface()
-                mp[ft.Name] = inst
+            case reflect.Ptr:
+                if ft.Anonymous {
+                    if fv.IsNil() {
+                        // Create a zero value of the element type to safely inspect field names.
+                        inspect(reflect.New(ft.Type.Elem()).Interface())
+                    } else {
+                        inspect(fv.Interface())
+                    }
+                    continue
+                }
+                mp[ft.Name] = fv.Interface()
📜 Review details

Configuration used: CodeRabbit UI
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 175d435 and 1ad404f.

📒 Files selected for processing (1)
  • reflect/fields.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: test-unit
🔇 Additional comments (3)
reflect/fields.go (3)

51-55: Including slices via default branch looks correct for restoring label sorting

By keeping arrays skipped and allowing slice kinds through the default path, JSON-backed slice fields (e.g., []string labels) will now be visible to the sorting layer. This aligns with the PR objective.


51-55: No db.Updates(Fields(...)) Usages Found
A search for Updates(Fields( returned no call sites in the codebase, so Fields() isn’t used to build GORM update maps. Slice fields will not leak into any db.Updates() calls—no further action is needed.


30-41: No pointer-to-slice fields found; skipping them poses no risk
Our search for *[] patterns in Go structs returned zero matches, so there are no pointer-to-slice fields in sortable models. No special-case handling is needed.

Signed-off-by: Jeff Ortel <[email protected]>
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: 0

♻️ Duplicate comments (1)
task/manager.go (1)

23-23: LGTM: import path updated to model/reflect

Keeps Manager.Update/next using reflect.Select consistently after the package move.

Same import-path verification script applies as noted in task/task.go.

🧹 Nitpick comments (1)
model/reflect/fields.go (1)

11-15: Fields used for sorting: verify slice coverage meets the labels use-case

Noting the doc update for sorting. With the current implementation, non-pointer slices are included in the map, which should allow api/sort to accept fields like Labels (typically a JSON slice) and avoid returning SortError.

Two follow-ups:

  • Please confirm the model field for labels is a non-pointer slice (e.g., []string or []SomeType). Pointer-to-slice fields remain excluded in the Ptr branch.
  • Add/extend unit tests for Fields to cover:
    • []string and []struct fields are present
    • arrays are skipped
    • pointer-to-slice behavior is as intended

I can draft these tests if helpful.

📜 Review details

Configuration used: CodeRabbit UI
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 1ad404f and 259e74e.

📒 Files selected for processing (5)
  • api/base.go (1 hunks)
  • api/sort/sort.go (1 hunks)
  • model/reflect/fields.go (1 hunks)
  • task/manager.go (1 hunks)
  • task/task.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • api/base.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: vet
  • GitHub Check: build
  • GitHub Check: test-unit
🔇 Additional comments (2)
task/task.go (1)

17-17: ✅ Import path update validated

  • No stale imports of github.com/konveyor/tackle2-hub/reflect remain
  • Select and Fields functions confirmed in model/reflect

All set!

api/sort/sort.go (1)

7-7: LGTM: import path updated; with slice fields now recognized, sort=labels should no longer 400

Sort.inspect relies on reflect.Fields to validate user‐specified sort keys—since reflect.Fields now includes slice fields (e.g. the Labels []string on Dependency), "labels" won’t trigger a SortError, fixing the UI break reported in #880.

Please verify end-to-end that:

  • sort=labels and sort=d:labels are accepted on the dependencies endpoint
  • the database orders results without error for the underlying column type (JSON/JSONB/TEXT)

If your labels are stored via a true many-to-many relation rather than a JSON/TEXT column, you’ll still need to alias a computed/flattened column (e.g. via Sort.Add) to prevent ORDER BY errors—let me know if you’d like help wiring that.

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.

🐛 sort by json slices no longer supported.
2 participants