Skip to content

Conversation

DeamonDev
Copy link
Contributor

@DeamonDev DeamonDev commented Oct 6, 2025

Description

I added new flags related to other kind of retrievers. Based on them the new retriever is being spawned (but see #4024).
There is also new --check-mode flag which when present would only dump the configuration of retriever being used to perform evaluate call. It also served me while testing some multi-flags (like http's --header) because there is some kind of parsing logic at evaluate_cmd layer.

The redis retriever is not supported because of #4023. We may of course hack it and provide empty output when -kind=redis but I think the refactor of RetrieverConf struct would benefit more.

Closes issue(s)

Resolve #3876

Checklist

  • I have tested this code
  • I have added unit test to cover this code
  • I have updated the documentation (README.md and /website/docs)
  • I have followed the contributing guide

Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Signed-off-by: deamondev <[email protected]>
Copy link

netlify bot commented Oct 6, 2025

Deploy Preview for go-feature-flag-doc-preview canceled.

Name Link
🔨 Latest commit fcf358d
🔍 Latest deploy log https://app.netlify.com/projects/go-feature-flag-doc-preview/deploys/68e36d81b4b40f0008b3224f

@DeamonDev DeamonDev changed the title Feature add support for all retrievers in cli feature: add support for all retrievers in cli Oct 6, 2025
Copy link

sonarqubecloud bot commented Oct 6, 2025

Copy link

codecov bot commented Oct 6, 2025

Codecov Report

❌ Patch coverage is 89.37500% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.04%. Comparing base (4c730fb) to head (fcf358d).
⚠️ Report is 24 commits behind head on main.

Files with missing lines Patch % Lines
cmd/cli/evaluate/evaluate_cmd.go 91.61% 8 Missing and 5 partials ⚠️
retriever/gcstorageretriever/retriever.go 0.00% 2 Missing ⚠️
retriever/s3retrieverv2/retriever.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4025      +/-   ##
==========================================
+ Coverage   83.92%   84.04%   +0.11%     
==========================================
  Files         137      137              
  Lines        6813     6968     +155     
==========================================
+ Hits         5718     5856     +138     
- Misses        884      897      +13     
- Partials      211      215       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DeamonDev DeamonDev changed the title feature: add support for all retrievers in cli feat: add support for all retrievers in cli Oct 6, 2025
Comment on lines +100 to +103

func (s *Retriever) SetDownloader(downloader DownloaderAPI) {
s.downloader = downloader
}
Copy link
Owner

Choose a reason for hiding this comment

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

Just to be sure, why do you need this function?
You can probably set the downloader directly in the struct?

@thomaspoignant
Copy link
Owner

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly enhances the CLI by adding support for all retrievers, which is a great feature. The implementation introduces a --check-mode for inspecting retriever configurations, which is very useful for debugging.

My review focuses on improving documentation clarity, fixing a parsing bug, and some minor code cleanup. I've identified a few issues in the README.md that could confuse users, a bug in the HTTP header parsing logic, and some opportunities for code refinement in the tests and command implementation.

Overall, this is a solid contribution. Addressing the feedback will make the new CLI features more robust and easier to use.

Comment on lines +263 to +278
func parseHTTPHeaders() map[string][]string {
result := make(map[string][]string)
for _, h := range headers {
parts := strings.SplitN(h, "=", 2)
if len(parts) != 2 {
parts = strings.SplitN(h, ":", 2)
}
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
val := strings.TrimSpace(parts[1])
result[key] = append(result[key], val)
}
return result
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The current parsing logic for HTTP headers can lead to incorrect key-value pairs if a header value contains an = character. The logic attempts to split by = before splitting by :. It should be the other way around, as : is the standard separator for HTTP headers. For example, a header like Some-Header: key=value would be incorrectly parsed. Swapping the order of checks will fix this.

Suggested change
func parseHTTPHeaders() map[string][]string {
result := make(map[string][]string)
for _, h := range headers {
parts := strings.SplitN(h, "=", 2)
if len(parts) != 2 {
parts = strings.SplitN(h, ":", 2)
}
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
val := strings.TrimSpace(parts[1])
result[key] = append(result[key], val)
}
return result
}
func parseHTTPHeaders() map[string][]string {
result := make(map[string][]string)
for _, h := range headers {
parts := strings.SplitN(h, ":", 2)
if len(parts) != 2 {
parts = strings.SplitN(h, "=", 2)
}
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
val := strings.TrimSpace(parts[1])
result[key] = append(result[key], val)
}
return result
}

|------------|---------------------------------------------------------------------|---------|
| `--url` | URL of the remote flag configuration file | "" |
| `--method` | HTTP method to access your configuration file on HTTP | "" |
| `--body` | Http body to access your configuration file on HTTP | GET |
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The default value for --body is documented as GET, which is incorrect. GET is the default for the --method flag. The default for --body should be an empty string ("").

Suggested change
| `--body` | Http body to access your configuration file on HTTP | GET |
| `--body` | Http body to access your configuration file on HTTP | "" |

Comment on lines +97 to +119
| `--repository-slug` | | "" |
| `--branch` | Name of the repository | "" |
| `--auth-token` | Authentication token to access your configuration file | "" |
| `--github-token` | Authentication token to access your configuration file on GitHub<br/> (⚠️ deprecated, use `--auth-token` instead) | "" |
| `--path` | Path to the remote flag configuration file inside github repository | "" |

#### GitLab

| Flag | Description | Default |
|---------------------|---------------------------------------------------------------------|---------|
| `--base-url` | Base URL of your configuration file on Gitlab | "" |
| `--repository-slug` | Name of the repository | "" |
| `--branch` | Name of the repository | "" |
| `--path` | Path to the remote flag configuration file inside gitlab repository | "" |

#### BitBucket

| Flag | Description | Default |
|---------------------|------------------------------------------------------------------------|---------|
| `--base-url` | Base URL of your configuration file on BitBucket | "" |
| `--repository-slug` | Name of the repository | "" |
| `--branch` | Name of the repository | "" |
| `--path` | Path to the remote flag configuration file inside bitbucket repository | "" |
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

There are several documentation issues in the tables for Git-based retrievers (GitHub, GitLab, BitBucket):

  • GitHub (--repository-slug): The description is missing.
  • GitHub, GitLab, BitBucket (--branch): The description is incorrectly 'Name of the repository'. It should describe the branch.
  • GitLab, BitBucket (--repository-slug): The description is incorrectly 'Name of the repository'. It should describe the repository slug.

Please update these descriptions for clarity. For example, you could use 'Repository slug (e.g., owner/repo)' and 'Git branch name'.

"column", nil, "Postgres column mapping of your configuration file on Postgres (may be repeated)")
_ = evaluateCmd.Flags().MarkDeprecated("github-token", "Use auth-token instead")
_ = evaluateCmd.Flags().MarkDeprecated("config", "Use path instead")
_ = evaluateCmd.Flags()
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This line of code has no effect and can be safely removed.

expectedResult: "testdata/res/check-gcs.json",
},
{
name: "should return configuration of GCS retriever when using check-mode",
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This test case has an incorrect name. It's named for the GCS retriever but is testing the configmap retriever.

Suggested change
name: "should return configuration of GCS retriever when using check-mode",
name: "should return configuration of configmap retriever when using check-mode",

func Test_evaluate_Evaluate(t *testing.T) {
tests := []struct {
name string
evaluate evaluate
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The evaluate field in this test struct is no longer used since the introduction of initEvaluate. It can be removed to improve code clarity.

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.

(feature) Allow cli tool to use retriever other than fileretriever

2 participants