From 695dd6185654cc07a448e06981604043a07d1bb3 Mon Sep 17 00:00:00 2001 From: Sahid Velji Date: Sat, 6 Dec 2025 22:37:23 -0500 Subject: [PATCH 1/3] chore: add lint config file and fix findings Signed-off-by: Sahid Velji --- .golangci.yml | 51 ++++++++++++++++++++ docs/generate-commands.go | 2 +- internal/api/sync/client.go | 2 - internal/api/sync/retry_test.go | 65 +++++++++++++------------ internal/cmd/config_test.go | 61 +++++------------------ internal/cmd/generate_test.go | 8 ++-- internal/cmd/init.go | 4 +- internal/cmd/manifest_add.go | 8 ++-- internal/cmd/manifest_add_test.go | 70 +++++++++++++-------------- internal/cmd/manifest_list.go | 4 +- internal/cmd/manifest_list_test.go | 10 ++-- internal/cmd/pull.go | 2 +- internal/cmd/pull_test.go | 26 +++++----- internal/cmd/push.go | 4 +- internal/cmd/push_test.go | 72 ++++++++++++++-------------- internal/cmd/root.go | 1 - internal/config/flags.go | 22 ++++----- internal/filesystem/filesystem.go | 2 +- internal/generators/csharp/csharp.go | 2 +- internal/generators/java/java.go | 4 +- internal/generators/nestjs/nestjs.go | 5 +- internal/generators/nodejs/nodejs.go | 5 +- internal/generators/python/python.go | 6 +-- internal/generators/react/react.go | 5 +- internal/manifest/compare.go | 12 ++--- internal/manifest/validate_test.go | 2 +- test/integration/cmd/nodejs/run.go | 8 +++- test/integration/cmd/run.go | 3 +- 28 files changed, 231 insertions(+), 235 deletions(-) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..373b300 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,51 @@ +--- +version: "2" + +formatters: + enable: + - gofumpt + - gci + +linters: + default: none + enable: + - copyloopvar + - dupword + - errcheck + - govet + - ineffassign + - intrange + - misspell + - modernize + - staticcheck + - unused + - usetesting + settings: + staticcheck: + checks: + - all + usetesting: + context-background: true + context-todo: true + os-chdir: true + os-mkdir-temp: true + os-setenv: true + os-temp-dir: true + os-create-temp: true + exclusions: + generated: lax + presets: + - comments + - std-error-handling + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 + +run: + timeout: 3m + modules-download-mode: readonly + +output: + sort-order: + - file diff --git a/docs/generate-commands.go b/docs/generate-commands.go index 40e1cdc..8a11d25 100644 --- a/docs/generate-commands.go +++ b/docs/generate-commands.go @@ -109,7 +109,7 @@ func processCommandFile(cmd *cobra.Command, filePath string) { // Only write the file if content was modified if modifiedContent != string(content) { - err = os.WriteFile(filePath, []byte(modifiedContent), 0644) + err = os.WriteFile(filePath, []byte(modifiedContent), 0o644) if err != nil { fmt.Fprintf(os.Stderr, "error writing file %s: %v\n", filePath, err) } diff --git a/internal/api/sync/client.go b/internal/api/sync/client.go index 965bcad..8d591d7 100644 --- a/internal/api/sync/client.go +++ b/internal/api/sync/client.go @@ -238,7 +238,6 @@ func (c *Client) PushFlags(ctx context.Context, localFlags *flagset.Flagset, rem return c.handleFlagResponse(resp.HTTPResponse, resp.Body, flagKey, "create") }, goretry.WithTransientErrorFunc(isTransientHTTPError)) - if err != nil { return nil, err } @@ -272,7 +271,6 @@ func (c *Client) PushFlags(ctx context.Context, localFlags *flagset.Flagset, rem return c.handleFlagResponse(resp.HTTPResponse, resp.Body, flagKey, "update") }, goretry.WithTransientErrorFunc(isTransientHTTPError)) - if err != nil { return nil, err } diff --git a/internal/api/sync/retry_test.go b/internal/api/sync/retry_test.go index 36302a5..b817536 100644 --- a/internal/api/sync/retry_test.go +++ b/internal/api/sync/retry_test.go @@ -1,7 +1,6 @@ package sync import ( - "context" "encoding/json" "net/http" "testing" @@ -20,8 +19,8 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). Reply(500). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Internal Server Error", "status": 500, }, @@ -31,8 +30,8 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). Reply(500). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Internal Server Error", "status": 500, }, @@ -42,8 +41,8 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": "test-flag", }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -52,7 +51,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "test-flag", Type: flagset.BoolType, DefaultValue: true}, @@ -79,8 +78,8 @@ func TestRetryLogic(t *testing.T) { return true, nil }). Reply(400). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Bad Request", "status": 400, }, @@ -89,7 +88,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "test-flag", Type: flagset.BoolType, DefaultValue: true}, @@ -118,8 +117,8 @@ func TestRetryLogic(t *testing.T) { return true, nil }). Reply(503). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Service Unavailable", "status": 503, }, @@ -128,7 +127,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "test-flag", Type: flagset.BoolType, DefaultValue: true}, @@ -149,8 +148,8 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Put("/openfeature/v0/manifest/flags/existing-flag"). Reply(502). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Bad Gateway", "status": 502, }, @@ -160,8 +159,8 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Put("/openfeature/v0/manifest/flags/existing-flag"). Reply(200). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": "existing-flag", }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -170,7 +169,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "existing-flag", Type: flagset.BoolType, DefaultValue: true}, @@ -201,8 +200,8 @@ func TestRetryLogic(t *testing.T) { return true, nil }). Reply(404). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Flag not found", "status": 404, }, @@ -211,7 +210,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "nonexistent-flag", Type: flagset.BoolType, DefaultValue: true}, @@ -236,13 +235,13 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). AddMatcher(func(req *http.Request, _ *gock.Request) (bool, error) { - var body map[string]interface{} + var body map[string]any _ = json.NewDecoder(req.Body).Decode(&body) return body["key"] == "flag1", nil }). Reply(500). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Internal Server Error", "status": 500, }, @@ -251,13 +250,13 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). AddMatcher(func(req *http.Request, _ *gock.Request) (bool, error) { - var body map[string]interface{} + var body map[string]any _ = json.NewDecoder(req.Body).Decode(&body) return body["key"] == "flag1", nil }). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": "flag1", }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -267,13 +266,13 @@ func TestRetryLogic(t *testing.T) { gock.New("https://api.example.com"). Post("/openfeature/v0/manifest/flags"). AddMatcher(func(req *http.Request, _ *gock.Request) (bool, error) { - var body map[string]interface{} + var body map[string]any _ = json.NewDecoder(req.Body).Decode(&body) return body["key"] == "flag2", nil }). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": "flag2", }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -282,7 +281,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "flag1", Type: flagset.BoolType, DefaultValue: true}, @@ -302,7 +301,7 @@ func TestRetryLogic(t *testing.T) { client, err := NewClient("https://api.example.com", "") require.NoError(t, err) - ctx := context.Background() + ctx := t.Context() localFlags := &flagset.Flagset{ Flags: []flagset.Flag{ {Key: "new-flag", Type: flagset.BoolType, DefaultValue: true, Description: "New flag"}, diff --git a/internal/cmd/config_test.go b/internal/cmd/config_test.go index 6920a0a..3cc8313 100644 --- a/internal/cmd/config_test.go +++ b/internal/cmd/config_test.go @@ -23,28 +23,18 @@ func setupTestCommand() *cobra.Command { // setupConfigFileForTest creates a temporary directory with a config file // and changes the working directory to it. -// Returns the original working directory and temp directory path for cleanup. -func setupConfigFileForTest(t *testing.T, configContent string) (string, string) { +func setupConfigFileForTest(t *testing.T, configContent string) { // Create a temporary config file - tmpDir, err := os.MkdirTemp("", "config-test") - if err != nil { - t.Fatal(err) - } + tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, ".openfeature.yaml") - err = os.WriteFile(configPath, []byte(configContent), 0644) + err := os.WriteFile(configPath, []byte(configContent), 0o644) if err != nil { t.Fatal(err) } // Change to the temporary directory so the config file can be found - originalDir, _ := os.Getwd() - err = os.Chdir(tmpDir) - if err != nil { - t.Fatal(err) - } - - return originalDir, tmpDir + t.Chdir(tmpDir) } func TestRootCommandIgnoresUnrelatedConfig(t *testing.T) { @@ -52,11 +42,7 @@ func TestRootCommandIgnoresUnrelatedConfig(t *testing.T) { generate: output: output-from-generate ` - originalDir, tmpDir := setupConfigFileForTest(t, configContent) - defer func() { - _ = os.Chdir(originalDir) - _ = os.RemoveAll(tmpDir) - }() + setupConfigFileForTest(t, configContent) rootCmd := setupTestCommand() err := initializeConfig(rootCmd, "") @@ -71,11 +57,7 @@ func TestGenerateCommandGetsGenerateConfig(t *testing.T) { generate: output: output-from-generate ` - originalDir, tmpDir := setupConfigFileForTest(t, configContent) - defer func() { - _ = os.Chdir(originalDir) - _ = os.RemoveAll(tmpDir) - }() + setupConfigFileForTest(t, configContent) generateCmd := setupTestCommand() err := initializeConfig(generateCmd, "generate") @@ -93,11 +75,7 @@ generate: output: output-from-go package-name: fromconfig ` - originalDir, tmpDir := setupConfigFileForTest(t, configContent) - defer func() { - _ = os.Chdir(originalDir) - _ = os.RemoveAll(tmpDir) - }() + setupConfigFileForTest(t, configContent) goCmd := setupTestCommand() err := initializeConfig(goCmd, "generate.go") @@ -114,11 +92,7 @@ func TestSubcommandInheritsFromParent(t *testing.T) { generate: output: output-from-generate ` - originalDir, tmpDir := setupConfigFileForTest(t, configContent) - defer func() { - _ = os.Chdir(originalDir) - _ = os.RemoveAll(tmpDir) - }() + setupConfigFileForTest(t, configContent) otherCmd := setupTestCommand() err := initializeConfig(otherCmd, "generate.other") @@ -130,33 +104,20 @@ generate: func TestCommandLineOverridesConfig(t *testing.T) { // Create a temporary config file - tmpDir, err := os.MkdirTemp("", "config-test") - if err != nil { - t.Fatal(err) - } - defer func() { - _ = os.RemoveAll(tmpDir) - }() + tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, ".openfeature.yaml") configContent := ` generate: output: output-from-config ` - err = os.WriteFile(configPath, []byte(configContent), 0644) + err := os.WriteFile(configPath, []byte(configContent), 0o644) if err != nil { t.Fatal(err) } // Change to the temporary directory so the config file can be found - originalDir, _ := os.Getwd() - err = os.Chdir(tmpDir) - if err != nil { - t.Fatal(err) - } - defer func() { - _ = os.Chdir(originalDir) - }() + t.Chdir(tmpDir) // Set up a command with a flag value already set via command line cmd := setupTestCommand() diff --git a/internal/cmd/generate_test.go b/internal/cmd/generate_test.go index ee34f2c..b9179e1 100644 --- a/internal/cmd/generate_test.go +++ b/internal/cmd/generate_test.go @@ -9,7 +9,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/open-feature/cli/internal/config" "github.com/open-feature/cli/internal/filesystem" - "github.com/spf13/afero" ) @@ -111,11 +110,12 @@ func TestGenerate(t *testing.T) { // Add parameters specific to each generator if tc.packageName != "" { - if tc.command == "csharp" { + switch tc.command { + case "csharp": args = append(args, "--namespace", tc.packageName) - } else if tc.command == "go" { + case "go": args = append(args, "--package-name", tc.packageName) - } else if tc.command == "java" { + case "java": args = append(args, "--package-name", tc.packageName) } } diff --git a/internal/cmd/init.go b/internal/cmd/init.go index ce0e3d0..83e4d48 100644 --- a/internal/cmd/init.go +++ b/internal/cmd/init.go @@ -24,13 +24,13 @@ func GetInitCmd() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { manifestPath := config.GetManifestPath(cmd) override := config.GetOverride(cmd) - providerUrl := config.GetFlagSourceUrl(cmd) + providerURL := config.GetFlagSourceURL(cmd) if err := handleManifestCreation(manifestPath, override); err != nil { return err } - if err := handleConfigFile(providerUrl, override); err != nil { + if err := handleConfigFile(providerURL, override); err != nil { return err } diff --git a/internal/cmd/manifest_add.go b/internal/cmd/manifest_add.go index 469da6d..f96eedd 100644 --- a/internal/cmd/manifest_add.go +++ b/internal/cmd/manifest_add.go @@ -110,7 +110,7 @@ Examples: } // Handle default-value: prompt if missing and not --no-input - var defaultValue interface{} + var defaultValue any if !cmd.Flags().Changed("default-value") { if noInput { return errors.New("--default-value is required") @@ -144,7 +144,6 @@ Examples: // Load existing manifest var fs *flagset.Flagset exists, err := afero.Exists(filesystem.FileSystem(), manifestPath) - if err != nil { return fmt.Errorf("failed to check manifest existence: %w", err) } @@ -217,7 +216,7 @@ func parseFlagTypeString(typeStr string) (flagset.FlagType, error) { } // parseDefaultValue parses and validates the default value based on flag type -func parseDefaultValue(value string, flagType flagset.FlagType) (interface{}, error) { +func parseDefaultValue(value string, flagType flagset.FlagType) (any, error) { switch flagType { case flagset.BoolType: switch strings.ToLower(value) { @@ -243,7 +242,7 @@ func parseDefaultValue(value string, flagType flagset.FlagType) (interface{}, er } return floatVal, nil case flagset.ObjectType: - var jsonObj interface{} + var jsonObj any if err := json.Unmarshal([]byte(value), &jsonObj); err != nil { return nil, fmt.Errorf("invalid JSON object: %s", err.Error()) } @@ -263,7 +262,6 @@ func promptForFlagType(flagName string) (string, error) { WithDefaultOption("boolean"). WithFilter(false). Show(prompt) - if err != nil { return "", fmt.Errorf("failed to prompt for flag type: %w", err) } diff --git a/internal/cmd/manifest_add_test.go b/internal/cmd/manifest_add_test.go index 3140120..c437098 100644 --- a/internal/cmd/manifest_add_test.go +++ b/internal/cmd/manifest_add_test.go @@ -36,14 +36,14 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Contains(t, flags, "new-feature") - flag := flags["new-feature"].(map[string]interface{}) + flag := flags["new-feature"].(map[string]any) assert.Equal(t, "boolean", flag["flagType"]) assert.Equal(t, true, flag["defaultValue"]) assert.Equal(t, "A new feature flag", flag["description"]) @@ -64,12 +64,12 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) - flag := flags["welcome-message"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) + flag := flags["welcome-message"].(map[string]any) assert.Equal(t, "string", flag["flagType"]) assert.Equal(t, "Hello World", flag["defaultValue"]) }, @@ -89,12 +89,12 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) - flag := flags["max-retries"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) + flag := flags["max-retries"].(map[string]any) assert.Equal(t, "integer", flag["flagType"]) // JSON unmarshaling converts numbers to float64 assert.Equal(t, float64(5), flag["defaultValue"]) @@ -115,12 +115,12 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) - flag := flags["discount-rate"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) + flag := flags["discount-rate"].(map[string]any) assert.Equal(t, "float", flag["flagType"]) assert.Equal(t, 0.15, flag["defaultValue"]) }, @@ -140,17 +140,17 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) - flag := flags["config"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) + flag := flags["config"].(map[string]any) assert.Equal(t, "object", flag["flagType"]) - defaultVal := flag["defaultValue"].(map[string]interface{}) + defaultVal := flag["defaultValue"].(map[string]any) assert.Equal(t, "value", defaultVal["key"]) - nested := defaultVal["nested"].(map[string]interface{}) + nested := defaultVal["nested"].(map[string]any) assert.Equal(t, float64(123), nested["prop"]) }, }, @@ -269,11 +269,11 @@ func TestManifestAddCmd(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Len(t, flags, 2) assert.Contains(t, flags, "existing-flag") assert.Contains(t, flags, "new-flag") @@ -289,7 +289,7 @@ func TestManifestAddCmd(t *testing.T) { // Create existing manifest if provided if tt.existingManifest != "" { - err := afero.WriteFile(fs, "flags.json", []byte(tt.existingManifest), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(tt.existingManifest), 0o644) require.NoError(t, err) } @@ -348,7 +348,7 @@ func TestManifestAddCmd_CreateNewManifest(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) @@ -356,10 +356,10 @@ func TestManifestAddCmd_CreateNewManifest(t *testing.T) { assert.Contains(t, manifest, "$schema") // Check flag was added - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Contains(t, flags, "first-flag") - flag := flags["first-flag"].(map[string]interface{}) + flag := flags["first-flag"].(map[string]any) assert.Equal(t, "boolean", flag["flagType"]) assert.Equal(t, true, flag["defaultValue"]) assert.Equal(t, "The first flag in a new manifest", flag["description"]) @@ -381,7 +381,7 @@ func TestManifestAddCmd_DisplaysSuccessMessage(t *testing.T) { } } }` - err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0o644) require.NoError(t, err) // Enable pterm output and capture it @@ -414,11 +414,11 @@ func TestManifestAddCmd_DisplaysSuccessMessage(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Len(t, flags, 2, "Should have 2 flags total") assert.Contains(t, flags, "existing-flag", "Should still contain existing flag") assert.Contains(t, flags, "new-flag", "Should contain newly added flag") @@ -449,14 +449,14 @@ func TestManifestAddCmd_NoInputFlag(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Contains(t, flags, "test-flag") - flag := flags["test-flag"].(map[string]interface{}) + flag := flags["test-flag"].(map[string]any) assert.Equal(t, "boolean", flag["flagType"]) assert.Equal(t, true, flag["defaultValue"]) assert.Equal(t, "Test flag", flag["description"]) @@ -481,14 +481,14 @@ func TestManifestAddCmd_NoInputFlag(t *testing.T) { content, err := afero.ReadFile(fs, "flags.json") require.NoError(t, err) - var manifest map[string]interface{} + var manifest map[string]any err = json.Unmarshal(content, &manifest) require.NoError(t, err) - flags := manifest["flags"].(map[string]interface{}) + flags := manifest["flags"].(map[string]any) assert.Contains(t, flags, "test-flag") - flag := flags["test-flag"].(map[string]interface{}) + flag := flags["test-flag"].(map[string]any) assert.Equal(t, "boolean", flag["flagType"]) assert.Equal(t, false, flag["defaultValue"]) // Description should be empty when not provided with --no-input @@ -511,7 +511,7 @@ func TestManifestAddCmd_NoInputFlag(t *testing.T) { "$schema": "https://raw.githubusercontent.com/open-feature/cli/refs/heads/main/schema/v0/flag-manifest.json", "flags": {} }` - err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0o644) require.NoError(t, err) // Create command and execute @@ -552,7 +552,7 @@ func TestManifestAddCmd_AutoDetectNonInteractive(t *testing.T) { "$schema": "https://raw.githubusercontent.com/open-feature/cli/refs/heads/main/schema/v0/flag-manifest.json", "flags": {} }` - err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0o644) require.NoError(t, err) // Create command and execute @@ -584,7 +584,7 @@ func TestManifestAddCmd_NoFlagKeyArgument(t *testing.T) { "$schema": "https://raw.githubusercontent.com/open-feature/cli/refs/heads/main/schema/v0/flag-manifest.json", "flags": {} }` - err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(existingManifest), 0o644) require.NoError(t, err) // Create command and execute diff --git a/internal/cmd/manifest_list.go b/internal/cmd/manifest_list.go index c0d4504..79aedb5 100644 --- a/internal/cmd/manifest_list.go +++ b/internal/cmd/manifest_list.go @@ -81,7 +81,7 @@ func displayFlagList(fs *flagset.Flagset, manifestPath string) { } // formatValue converts a value to a string representation suitable for display -func formatValue(value interface{}) string { +func formatValue(value any) string { switch v := value.(type) { case string: if len(v) > 30 { @@ -90,7 +90,7 @@ func formatValue(value interface{}) string { return fmt.Sprintf("\"%s\"", v) case bool, int, float64: return fmt.Sprintf("%v", v) - case map[string]interface{}, []interface{}: + case map[string]any, []any: jsonBytes, err := json.Marshal(v) if err != nil { return fmt.Sprintf("%v", v) diff --git a/internal/cmd/manifest_list_test.go b/internal/cmd/manifest_list_test.go index 27e6eee..9ce72b8 100644 --- a/internal/cmd/manifest_list_test.go +++ b/internal/cmd/manifest_list_test.go @@ -126,7 +126,7 @@ func TestManifestListCmd(t *testing.T) { // Create manifest if provided if tt.manifestContent != "" { - err := afero.WriteFile(fs, "flags.json", []byte(tt.manifestContent), 0644) + err := afero.WriteFile(fs, "flags.json", []byte(tt.manifestContent), 0o644) require.NoError(t, err) } @@ -293,7 +293,7 @@ func TestDisplayFlagList(t *testing.T) { func TestFormatValue(t *testing.T) { tests := []struct { name string - value interface{} + value any expected string }{ { @@ -328,17 +328,17 @@ func TestFormatValue(t *testing.T) { }, { name: "format object", - value: map[string]interface{}{"key": "value"}, + value: map[string]any{"key": "value"}, expected: `{"key":"value"}`, }, { name: "format large object", - value: map[string]interface{}{"key1": "value1", "key2": "value2", "key3": "value3"}, + value: map[string]any{"key1": "value1", "key2": "value2", "key3": "value3"}, expected: "...", }, { name: "format array", - value: []interface{}{"a", "b", "c"}, + value: []any{"a", "b", "c"}, expected: `["a","b","c"]`, }, } diff --git a/internal/cmd/pull.go b/internal/cmd/pull.go index c15f85e..745f499 100644 --- a/internal/cmd/pull.go +++ b/internal/cmd/pull.go @@ -42,7 +42,7 @@ Why pull from a remote source: return initializeConfig(cmd, "pull") }, RunE: func(cmd *cobra.Command, args []string) error { - providerURL := config.GetFlagSourceUrl(cmd) + providerURL := config.GetFlagSourceURL(cmd) manifestPath := config.GetManifestPath(cmd) authToken := config.GetAuthToken(cmd) noPrompt := config.GetNoPrompt(cmd) diff --git a/internal/cmd/pull_test.go b/internal/cmd/pull_test.go index 8495f8a..32646a4 100644 --- a/internal/cmd/pull_test.go +++ b/internal/cmd/pull_test.go @@ -7,9 +7,7 @@ import ( "github.com/h2non/gock" "github.com/open-feature/cli/internal/config" "github.com/open-feature/cli/internal/filesystem" - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" ) @@ -88,7 +86,7 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) @@ -96,7 +94,7 @@ func TestPull(t *testing.T) { flags := manifestResponse["flags"].([]map[string]any) for _, flag := range flags { flagKey := flag["key"].(string) - _, exists := manifestFlags["flags"].(map[string]interface{})[flagKey] + _, exists := manifestFlags["flags"].(map[string]any)[flagKey] assert.True(t, exists, "Flag %s should exist in manifest", flagKey) } }) @@ -179,12 +177,12 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) // Verify the flag exists in the manifest - flags := manifestFlags["flags"].(map[string]interface{}) + flags := manifestFlags["flags"].(map[string]any) _, exists := flags["jsonFileFlag"] assert.True(t, exists, "Flag jsonFileFlag should exist in manifest") }) @@ -232,12 +230,12 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) // Verify the flag exists in the manifest - flags := manifestFlags["flags"].(map[string]interface{}) + flags := manifestFlags["flags"].(map[string]any) _, exists := flags["yamlFileFlag"] assert.True(t, exists, "Flag yamlFileFlag should exist in manifest") }) @@ -285,12 +283,12 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) // Verify the flag exists in the manifest - flags := manifestFlags["flags"].(map[string]interface{}) + flags := manifestFlags["flags"].(map[string]any) _, exists := flags["ymlFileFlag"] assert.True(t, exists, "Flag ymlFileFlag should exist in manifest") }) @@ -339,12 +337,12 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) // Verify the flag exists in the manifest - flags := manifestFlags["flags"].(map[string]interface{}) + flags := manifestFlags["flags"].(map[string]any) _, exists := flags["syncApiFlag"] assert.True(t, exists, "Flag syncApiFlag should exist in manifest") }) @@ -393,12 +391,12 @@ func TestPull(t *testing.T) { content, err := afero.ReadFile(fs, "manifest/path.json") assert.NoError(t, err) - var manifestFlags map[string]interface{} + var manifestFlags map[string]any err = json.Unmarshal(content, &manifestFlags) assert.NoError(t, err) // Verify the flag exists in the manifest - flags := manifestFlags["flags"].(map[string]interface{}) + flags := manifestFlags["flags"].(map[string]any) _, exists := flags["backwardCompatFlag"] assert.True(t, exists, "Flag backwardCompatFlag should exist in manifest") }) diff --git a/internal/cmd/push.go b/internal/cmd/push.go index bfa30e4..d9957d4 100644 --- a/internal/cmd/push.go +++ b/internal/cmd/push.go @@ -55,7 +55,7 @@ For local file operations, use standard shell commands like cp or mv.`, }, RunE: func(cmd *cobra.Command, args []string) error { // Get configuration values - providerURL := config.GetFlagSourceUrl(cmd) + providerURL := config.GetFlagSourceURL(cmd) manifestPath := config.GetManifestPath(cmd) authToken := config.GetAuthToken(cmd) dryRun := config.GetDryRun(cmd) @@ -159,7 +159,7 @@ func displayPushResults(result *sync.PushResult, destination string, dryRun bool fmt.Println() // Show flag details - flagJSON, _ := json.MarshalIndent(map[string]interface{}{ + flagJSON, _ := json.MarshalIndent(map[string]any{ "type": flag.Type.String(), "defaultValue": flag.DefaultValue, }, " ", " ") diff --git a/internal/cmd/push_test.go b/internal/cmd/push_test.go index 44831c0..7b142c9 100644 --- a/internal/cmd/push_test.go +++ b/internal/cmd/push_test.go @@ -8,9 +8,7 @@ import ( "github.com/h2non/gock" "github.com/open-feature/cli/internal/filesystem" - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" ) @@ -42,11 +40,11 @@ func TestPush(t *testing.T) { defer gock.Off() // Mock GET request to fetch remote flags (returns empty list) - emptyFlags := []map[string]interface{}{} + emptyFlags := []map[string]any{} gock.New("http://localhost:8080"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": emptyFlags, }) @@ -59,8 +57,8 @@ func TestPush(t *testing.T) { MatchType("application/json"). MatchHeader("Content-Type", "application/json"). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": flagKey, }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -88,9 +86,9 @@ func TestPush(t *testing.T) { // Mock GET request to fetch remote flags (all flags already exist) flagKeys := []string{"enableFeatureA", "usernameMaxLength", "greetingMessage", "discountPercentage", "themeCustomization"} - remoteFlags := make([]map[string]interface{}, 0) + remoteFlags := make([]map[string]any, 0) for _, flagKey := range flagKeys { - remoteFlags = append(remoteFlags, map[string]interface{}{ + remoteFlags = append(remoteFlags, map[string]any{ "key": flagKey, "type": "boolean", "defaultValue": false, @@ -99,7 +97,7 @@ func TestPush(t *testing.T) { gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": remoteFlags, }) @@ -110,8 +108,8 @@ func TestPush(t *testing.T) { MatchType("application/json"). MatchHeader("Content-Type", "application/json"). Reply(200). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": flagKey, }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -140,8 +138,8 @@ func TestPush(t *testing.T) { gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ - "flags": []map[string]interface{}{ + JSON(map[string]any{ + "flags": []map[string]any{ { "key": "enableFeatureA", "type": "boolean", @@ -162,8 +160,8 @@ func TestPush(t *testing.T) { Put("/openfeature/v0/manifest/flags/" + flagKey). MatchType("application/json"). Reply(200). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": flagKey, }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -177,8 +175,8 @@ func TestPush(t *testing.T) { Post("/openfeature/v0/manifest/flags"). MatchType("application/json"). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": flagKey, }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -204,12 +202,12 @@ func TestPush(t *testing.T) { defer gock.Off() // Mock GET request with auth header - emptyFlags := []map[string]interface{}{} + emptyFlags := []map[string]any{} gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). MatchHeader("Authorization", "Bearer secret-token"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": emptyFlags, }) @@ -221,8 +219,8 @@ func TestPush(t *testing.T) { MatchType("application/json"). MatchHeader("Authorization", "Bearer secret-token"). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": flagKey, }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -331,8 +329,8 @@ func TestPush(t *testing.T) { gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(404). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Not Found", "status": 404, }, @@ -356,11 +354,11 @@ func TestPush(t *testing.T) { defer gock.Off() // Mock GET request (empty flags) - emptyFlags := []map[string]interface{}{} + emptyFlags := []map[string]any{} gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": emptyFlags, }) @@ -369,8 +367,8 @@ func TestPush(t *testing.T) { Post("/openfeature/v0/manifest/flags"). Persist(). // Apply to all requests Reply(404). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Not Found", "status": 404, }, @@ -395,11 +393,11 @@ func TestPush(t *testing.T) { defer gock.Off() // Mock GET request (empty flags) - emptyFlags := []map[string]interface{}{} + emptyFlags := []map[string]any{} gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": emptyFlags, }) @@ -408,8 +406,8 @@ func TestPush(t *testing.T) { Post("/openfeature/v0/manifest/flags"). Persist(). // Apply to all requests Reply(500). - JSON(map[string]interface{}{ - "error": map[string]interface{}{ + JSON(map[string]any{ + "error": map[string]any{ "message": "Internal Server Error", "status": 500, }, @@ -434,11 +432,11 @@ func TestPush(t *testing.T) { defer gock.Off() // Mock GET request (empty flags) - emptyFlags := []map[string]interface{}{} + emptyFlags := []map[string]any{} gock.New("https://api.example.com"). Get("/openfeature/v0/manifest"). Reply(200). - JSON(map[string]interface{}{ + JSON(map[string]any{ "flags": emptyFlags, }) @@ -451,7 +449,7 @@ func TestPush(t *testing.T) { SetMatcher(gock.NewMatcher()). AddMatcher(func(req *http.Request, ereq *gock.Request) (bool, error) { // Verify the request has the required fields: key, type, defaultValue - var body map[string]interface{} + var body map[string]any decoder := json.NewDecoder(req.Body) if err := decoder.Decode(&body); err != nil { return false, err @@ -471,8 +469,8 @@ func TestPush(t *testing.T) { }). Persist(). Reply(201). - JSON(map[string]interface{}{ - "flag": map[string]interface{}{ + JSON(map[string]any{ + "flag": map[string]any{ "key": "test", }, "updatedAt": "2024-03-02T09:45:03.000Z", @@ -520,7 +518,7 @@ func TestPush(t *testing.T) { } } }` - err := afero.WriteFile(fs, "invalid.json", []byte(invalidManifest), 0644) + err := afero.WriteFile(fs, "invalid.json", []byte(invalidManifest), 0o644) assert.NoError(t, err) cmd := GetPushCmd() diff --git a/internal/cmd/root.go b/internal/cmd/root.go index f4091e2..5b62017 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -6,7 +6,6 @@ import ( "github.com/open-feature/cli/internal/config" "github.com/open-feature/cli/internal/logger" - "github.com/spf13/cobra" ) diff --git a/internal/config/flags.go b/internal/config/flags.go index 2449422..61b24c9 100644 --- a/internal/config/flags.go +++ b/internal/config/flags.go @@ -19,7 +19,7 @@ const ( OverrideFlagName = "override" JavaPackageFlagName = "package-name" ProviderURLFlagName = "provider-url" - FlagSourceUrlFlagName = "flag-source-url" // Deprecated: use ProviderFlagName instead + FlagSourceURLFlagName = "flag-source-url" // Deprecated: use ProviderFlagName instead AuthTokenFlagName = "auth-token" NoPromptFlagName = "no-prompt" DryRunFlagName = "dry-run" @@ -68,15 +68,15 @@ func AddJavaGenerateFlags(cmd *cobra.Command) { func AddInitFlags(cmd *cobra.Command) { cmd.Flags().Bool(OverrideFlagName, false, "Override an existing configuration") cmd.Flags().String(ProviderURLFlagName, "", "The URL of the flag provider") - cmd.Flags().String(FlagSourceUrlFlagName, "", "The URL of the flag source (deprecated: use --provider-url instead)") - _ = cmd.Flags().MarkDeprecated(FlagSourceUrlFlagName, "use --provider-url instead") + cmd.Flags().String(FlagSourceURLFlagName, "", "The URL of the flag source (deprecated: use --provider-url instead)") + _ = cmd.Flags().MarkDeprecated(FlagSourceURLFlagName, "use --provider-url instead") } // AddPullFlags adds the pull command specific flags func AddPullFlags(cmd *cobra.Command) { cmd.Flags().String(ProviderURLFlagName, "", "The URL of the flag provider") - cmd.Flags().String(FlagSourceUrlFlagName, "", "The URL of the flag source (deprecated: use --provider-url instead)") - _ = cmd.Flags().MarkDeprecated(FlagSourceUrlFlagName, "use --provider-url instead") + cmd.Flags().String(FlagSourceURLFlagName, "", "The URL of the flag source (deprecated: use --provider-url instead)") + _ = cmd.Flags().MarkDeprecated(FlagSourceURLFlagName, "use --provider-url instead") cmd.Flags().String(AuthTokenFlagName, "", "The auth token for the flag provider") cmd.Flags().Bool(NoPromptFlagName, false, "Disable interactive prompts for missing default values") } @@ -84,8 +84,8 @@ func AddPullFlags(cmd *cobra.Command) { // AddPushFlags adds the push command specific flags func AddPushFlags(cmd *cobra.Command) { cmd.Flags().String(ProviderURLFlagName, "", "The URL of the flag provider") - cmd.Flags().String(FlagSourceUrlFlagName, "", "The URL of the flag destination (deprecated: use --provider-url instead)") - _ = cmd.Flags().MarkDeprecated(FlagSourceUrlFlagName, "use --provider-url instead") + cmd.Flags().String(FlagSourceURLFlagName, "", "The URL of the flag destination (deprecated: use --provider-url instead)") + _ = cmd.Flags().MarkDeprecated(FlagSourceURLFlagName, "use --provider-url instead") cmd.Flags().String(AuthTokenFlagName, "", "The auth token for the flag provider") cmd.Flags().Bool(DryRunFlagName, false, "Preview changes without pushing") } @@ -147,10 +147,10 @@ func getConfigValueWithFallback(value string, newConfigKey string, legacyConfigK return viper.GetString(legacyConfigKey) } -// GetFlagSourceUrl gets the flag source URL from the given command +// GetFlagSourceURL gets the flag source URL from the given command // It checks the new --provider-url flag first, then falls back to the deprecated --flag-source-url flag // for backward compatibility. Finally, it checks the config file for both keys. -func GetFlagSourceUrl(cmd *cobra.Command) string { +func GetFlagSourceURL(cmd *cobra.Command) string { // Check new flag first provider, _ := cmd.Flags().GetString(ProviderURLFlagName) if provider != "" { @@ -158,10 +158,10 @@ func GetFlagSourceUrl(cmd *cobra.Command) string { } // Fall back to deprecated flag for backward compatibility - flagSourceUrl, _ := cmd.Flags().GetString(FlagSourceUrlFlagName) + flagSourceURL, _ := cmd.Flags().GetString(FlagSourceURLFlagName) // Use the fallback helper which checks both config keys - return getConfigValueWithFallback(flagSourceUrl, "provider", "flagSourceUrl") + return getConfigValueWithFallback(flagSourceURL, "provider", "flagSourceUrl") } // GetAuthToken gets the auth token from the given command diff --git a/internal/filesystem/filesystem.go b/internal/filesystem/filesystem.go index 4d6a14b..e3fc2b1 100644 --- a/internal/filesystem/filesystem.go +++ b/internal/filesystem/filesystem.go @@ -13,7 +13,7 @@ import ( var viperKey = "filesystem" type Config struct { - FlagSourceUrl string `yaml:"flagSourceUrl"` + FlagSourceURL string `yaml:"flagSourceUrl"` } // Get the filesystem interface from the viper configuration. diff --git a/internal/generators/csharp/csharp.go b/internal/generators/csharp/csharp.go index 7860e42..5db7bf2 100644 --- a/internal/generators/csharp/csharp.go +++ b/internal/generators/csharp/csharp.go @@ -133,7 +133,7 @@ func (g *CsharpGenerator) Generate(params *generators.Params[Params]) error { Custom: params.Custom, } - return g.CommonGenerator.GenerateFile(funcs, csharpTmpl, newParams, "OpenFeature.g.cs") + return g.GenerateFile(funcs, csharpTmpl, newParams, "OpenFeature.g.cs") } // NewGenerator creates a generator for C#. diff --git a/internal/generators/java/java.go b/internal/generators/java/java.go index d628ac9..fb5616a 100644 --- a/internal/generators/java/java.go +++ b/internal/generators/java/java.go @@ -30,7 +30,7 @@ func openFeatureType(t flagset.FlagType) string { case flagset.IntType: return "Integer" case flagset.FloatType: - return "Double" //using Double as per openfeature Java-SDK + return "Double" // using Double as per openfeature Java-SDK case flagset.BoolType: return "Boolean" case flagset.StringType: @@ -141,7 +141,7 @@ func (g *JavaGenerator) Generate(params *generators.Params[Params]) error { Custom: params.Custom, } - return g.CommonGenerator.GenerateFile(funcs, javaTmpl, newParams, "OpenFeature.java") + return g.GenerateFile(funcs, javaTmpl, newParams, "OpenFeature.java") } // NewGenerator creates a generator for Java. diff --git a/internal/generators/nestjs/nestjs.go b/internal/generators/nestjs/nestjs.go index 1d2b41a..2e27e3a 100644 --- a/internal/generators/nestjs/nestjs.go +++ b/internal/generators/nestjs/nestjs.go @@ -13,8 +13,7 @@ type NestJsGenerator struct { generators.CommonGenerator } -type Params struct { -} +type Params struct{} //go:embed nestjs.tmpl var nestJsTmpl string @@ -55,7 +54,7 @@ func (g *NestJsGenerator) Generate(params *generators.Params[Params]) error { Custom: Params{}, } - return g.CommonGenerator.GenerateFile(funcs, nestJsTmpl, newParams, "openfeature-decorators.ts") + return g.GenerateFile(funcs, nestJsTmpl, newParams, "openfeature-decorators.ts") } // NewGenerator creates a generator for NestJS. diff --git a/internal/generators/nodejs/nodejs.go b/internal/generators/nodejs/nodejs.go index 68e2964..2f1572b 100644 --- a/internal/generators/nodejs/nodejs.go +++ b/internal/generators/nodejs/nodejs.go @@ -13,8 +13,7 @@ type NodejsGenerator struct { generators.CommonGenerator } -type Params struct { -} +type Params struct{} //go:embed nodejs.tmpl var nodejsTmpl string @@ -55,7 +54,7 @@ func (g *NodejsGenerator) Generate(params *generators.Params[Params]) error { Custom: Params{}, } - return g.CommonGenerator.GenerateFile(funcs, nodejsTmpl, newParams, "openfeature.ts") + return g.GenerateFile(funcs, nodejsTmpl, newParams, "openfeature.ts") } // NewGenerator creates a generator for NodeJS. diff --git a/internal/generators/python/python.go b/internal/generators/python/python.go index 7d2e7d9..9f09fd9 100644 --- a/internal/generators/python/python.go +++ b/internal/generators/python/python.go @@ -17,8 +17,7 @@ type PythonGenerator struct { generators.CommonGenerator } -type Params struct { -} +type Params struct{} //go:embed python.tmpl var pythonTmpl string @@ -135,7 +134,6 @@ func formatNestedValue(value any) string { } return strings.ReplaceAll(string(jsonBytes), "null", "None") } - } func (g *PythonGenerator) Generate(params *generators.Params[Params]) error { @@ -154,7 +152,7 @@ func (g *PythonGenerator) Generate(params *generators.Params[Params]) error { Custom: Params{}, } - return g.CommonGenerator.GenerateFile(funcs, pythonTmpl, newParams, "openfeature.py") + return g.GenerateFile(funcs, pythonTmpl, newParams, "openfeature.py") } // NewGenerator creates a generator for Python. diff --git a/internal/generators/react/react.go b/internal/generators/react/react.go index 2548d8f..a8e14c8 100644 --- a/internal/generators/react/react.go +++ b/internal/generators/react/react.go @@ -13,8 +13,7 @@ type ReactGenerator struct { generators.CommonGenerator } -type Params struct { -} +type Params struct{} //go:embed react.tmpl var reactTmpl string @@ -55,7 +54,7 @@ func (g *ReactGenerator) Generate(params *generators.Params[Params]) error { Custom: Params{}, } - return g.CommonGenerator.GenerateFile(funcs, reactTmpl, newParams, "openfeature.ts") + return g.GenerateFile(funcs, reactTmpl, newParams, "openfeature.ts") } // NewGenerator creates a generator for React. diff --git a/internal/manifest/compare.go b/internal/manifest/compare.go index fe0fa38..31173ba 100644 --- a/internal/manifest/compare.go +++ b/internal/manifest/compare.go @@ -4,6 +4,7 @@ import ( "fmt" "maps" "reflect" + "slices" "strings" ) @@ -66,8 +67,8 @@ func getKnownFlagProperties() map[string]bool { props := make(map[string]bool) // Extract fields from BaseFlag struct - t := reflect.TypeOf(BaseFlag{}) - for i := 0; i < t.NumField(); i++ { + t := reflect.TypeFor[BaseFlag]() + for i := range t.NumField() { field := t.Field(i) jsonTag := field.Tag.Get("json") if jsonTag != "" { @@ -294,12 +295,7 @@ func matchesPattern(path, pattern string) bool { } else { // Shorthand pattern - matches field anywhere in path // E.g., "description" matches "flags.myFlag.description" - pathParts := strings.Split(path, ".") - for _, part := range pathParts { - if part == pattern { - return true - } - } + return slices.Contains(strings.Split(path, "."), pattern) } return false diff --git a/internal/manifest/validate_test.go b/internal/manifest/validate_test.go index 1789b8d..eaafd4b 100644 --- a/internal/manifest/validate_test.go +++ b/internal/manifest/validate_test.go @@ -20,7 +20,7 @@ func TestFormatValidationError_SortsByPath(t *testing.T) { betaIdx := strings.Index(output, "flagPath: beta.flag") zetaIdx := strings.Index(output, "flagPath: zeta.flag") - if !(alphaIdx < betaIdx && betaIdx < zetaIdx) { + if alphaIdx >= betaIdx || betaIdx >= zetaIdx { t.Errorf("flag paths are not sorted: alphaIdx=%d, betaIdx=%d, zetaIdx=%d\nOutput:\n%s", alphaIdx, betaIdx, zetaIdx, output) } diff --git a/test/integration/cmd/nodejs/run.go b/test/integration/cmd/nodejs/run.go index a15ad57..78bab4d 100644 --- a/test/integration/cmd/nodejs/run.go +++ b/test/integration/cmd/nodejs/run.go @@ -2,11 +2,12 @@ package main import ( "context" - "dagger.io/dagger" "fmt" - "github.com/open-feature/cli/test/integration" "os" "path/filepath" + + "dagger.io/dagger" + "github.com/open-feature/cli/test/integration" ) type Test struct { @@ -20,6 +21,7 @@ func New(projectDir, testDir string) *Test { TestDir: testDir, } } + func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) { source := client.Host().Directory(t.ProjectDir) testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{ @@ -51,9 +53,11 @@ func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Containe return nodeContainer, nil } + func (t *Test) Name() string { return "nodejs" } + func main() { ctx := context.Background() diff --git a/test/integration/cmd/run.go b/test/integration/cmd/run.go index 4380f97..9d68b8e 100644 --- a/test/integration/cmd/run.go +++ b/test/integration/cmd/run.go @@ -7,7 +7,6 @@ import ( ) func main() { - // Run the language-specific tests fmt.Println("=== Running all integration tests ===") @@ -28,7 +27,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error running Go integration test: %v\n", err) os.Exit(1) } - //Run the nodejs test + // Run the nodejs test nodeCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/nodejs") nodeCmd.Stdout = os.Stdout nodeCmd.Stderr = os.Stderr From 317ea73ad1d98ece80666a01156e069b5f85a59e Mon Sep 17 00:00:00 2001 From: Sahid Velji Date: Sat, 6 Dec 2025 22:43:32 -0500 Subject: [PATCH 2/3] chore: upgrade deps Signed-off-by: Sahid Velji --- go.mod | 60 +++++++++++++-------------- go.sum | 129 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 97 insertions(+), 92 deletions(-) diff --git a/go.mod b/go.mod index f780bb7..0ec2f11 100644 --- a/go.mod +++ b/go.mod @@ -5,23 +5,23 @@ go 1.24.0 toolchain go1.24.1 require ( - dagger.io/dagger v0.19.0 + dagger.io/dagger v0.19.8 github.com/google/go-cmp v0.7.0 github.com/h2non/gock v1.2.0 github.com/iancoleman/strcase v0.3.0 github.com/invopop/jsonschema v0.13.0 github.com/kriscoleman/GoRetry v0.0.1 github.com/oapi-codegen/runtime v1.1.2 - github.com/pterm/pterm v0.12.81 - github.com/spf13/afero v1.14.0 - github.com/spf13/cobra v1.9.1 - github.com/spf13/pflag v1.0.6 - github.com/spf13/viper v1.20.1 + github.com/pterm/pterm v0.12.82 + github.com/spf13/afero v1.15.0 + github.com/spf13/cobra v1.10.2 + github.com/spf13/pflag v1.0.10 + github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/term v0.35.0 - golang.org/x/text v0.29.0 - golang.org/x/tools v0.37.0 + golang.org/x/term v0.37.0 + golang.org/x/text v0.31.0 + golang.org/x/tools v0.39.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -29,13 +29,15 @@ require ( atomicgo.dev/cursor v0.2.0 // indirect atomicgo.dev/keyboard v0.2.9 // indirect atomicgo.dev/schedule v0.1.0 // indirect - github.com/99designs/gqlgen v0.17.80 // indirect + github.com/99designs/gqlgen v0.17.84 // indirect github.com/Khan/genqlient v0.8.1 // indirect github.com/adrg/xdg v0.5.3 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/containerd/console v1.0.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -44,29 +46,27 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gookit/color v1.5.4 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect + github.com/gookit/color v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect - github.com/mailru/easyjson v0.9.0 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.9.0 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/sosodev/duration v1.3.1 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/cast v1.8.0 // indirect + github.com/spf13/cast v1.10.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/vektah/gqlparser/v2 v2.5.30 // indirect + github.com/vektah/gqlparser/v2 v2.5.31 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect @@ -81,15 +81,15 @@ require ( go.opentelemetry.io/otel/sdk/log v0.14.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect - go.opentelemetry.io/proto/otlp v1.8.0 // indirect - go.uber.org/multierr v1.11.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/exp v0.0.0-20250530174510-65e920069ea6 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.36.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.9 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.77.0 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/go.sum b/go.sum index b9b8105..57be6e8 100644 --- a/go.sum +++ b/go.sum @@ -6,10 +6,10 @@ atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= -dagger.io/dagger v0.19.0 h1:Lr7UJ+/PocmigoEzMc57os1x8N/38hqIi2lSBQUoKBw= -dagger.io/dagger v0.19.0/go.mod h1:eTvzKtx7BfkIvmkoSxycd2jOAu9Esg0UrmsTAlDi+Rk= -github.com/99designs/gqlgen v0.17.80 h1:S64VF9SK+q3JjQbilgdrM0o4iFQgB54mVQ3QvXEO4Ek= -github.com/99designs/gqlgen v0.17.80/go.mod h1:vgNcZlLwemsUhYim4dC1pvFP5FX0pr2Y+uYUoHFb1ig= +dagger.io/dagger v0.19.8 h1:per+AnYnBzyTb9Z2g5Pg79ygkFyW7ijf18n8OcuPh7o= +dagger.io/dagger v0.19.8/go.mod h1:BjAJWl4Lx7XRW7nooNjBi0ZAC5Ici2pkthkdBIZdbTI= +github.com/99designs/gqlgen v0.17.84 h1:iVMdiStgUVx/BFkMb0J5GAXlqfqtQ7bqMCYK6v52kQ0= +github.com/99designs/gqlgen v0.17.84/go.mod h1:qjoUqzTeiejdo+bwUg8unqSpeYG42XrcrQboGIezmFA= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= @@ -24,6 +24,8 @@ github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= +github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= +github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= @@ -36,6 +38,10 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= @@ -63,12 +69,14 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= +github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= +github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= +github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE= github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= @@ -96,11 +104,11 @@ github.com/kriscoleman/GoRetry v0.0.1 h1:mcslWckaAhHGplF0RyPPkcZx0sb6cJ6A+r5HIxs github.com/kriscoleman/GoRetry v0.0.1/go.mod h1:G0FMRSlXtHuY4c7BK3KE5EEa3BANwPu/1Ye31q06+wE= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= @@ -119,34 +127,31 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.81 h1:ju+j5I2++FO1jBKMmscgh5h5DPFDFMB7epEjSoKehKA= -github.com/pterm/pterm v0.12.81/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= +github.com/pterm/pterm v0.12.82 h1:+D9wYhCaeaK0FIQoZtqbNQuNpe2lB2tajKKsTd5paVQ= +github.com/pterm/pterm v0.12.82/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= -github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= +github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= +github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= -github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= -github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= -github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= -github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -157,8 +162,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE= -github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= +github.com/vektah/gqlparser/v2 v2.5.31 h1:YhWGA1mfTjID7qJhd1+Vxhpk5HTgydrGU9IgkWBTJ7k= +github.com/vektah/gqlparser/v2 v2.5.31/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -172,8 +177,8 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1z github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= @@ -204,31 +209,31 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/otlp v1.8.0 h1:fRAZQDcAFHySxpJ1TwlA1cJ4tvcrw7nXl9xWWC8N5CE= -go.opentelemetry.io/proto/otlp v1.8.0/go.mod h1:tIeYOeNBU4cvmPqpaji1P+KbB4Oloai8wN4rWzRrFF0= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20250530174510-65e920069ea6 h1:gllJVKwONftmCc4KlNbN8o/LvmbxotqQy6zzi6yDQOQ= golang.org/x/exp v0.0.0-20250530174510-65e920069ea6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -240,39 +245,39 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From 3f6ea8c8d2a760bbe721c13ee92da3449ed7e54f Mon Sep 17 00:00:00 2001 From: Sahid Velji Date: Sat, 6 Dec 2025 22:43:45 -0500 Subject: [PATCH 3/3] chore: upgrade golangci-lint version Signed-off-by: Sahid Velji --- .github/workflows/pr-lint.yml | 7 +++---- CONTRIBUTING.md | 2 +- Makefile | 14 +++++++------- lefthook.yml | 4 ++-- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml index cee415f..09edaa2 100644 --- a/.github/workflows/pr-lint.yml +++ b/.github/workflows/pr-lint.yml @@ -24,9 +24,8 @@ jobs: fetch-depth: 0 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: "go.mod" - name: golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v9 with: - version: v1.64 - only-new-issues: true + version: v2.7.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ed8726..7128f22 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,7 +86,7 @@ This tool is particularly helpful for new contributors or those returning to the The pre-commit hook is configured to run the following check: -1. **Code Formatting**: Ensures all files are properly formatted using `go fmt`. Any changes made by `go fmt` will be automatically staged. +1. **Code Formatting**: Ensures all files are properly formatted using `golangci-lint fmt`. Any changes made by `golangci-lint fmt` will be automatically staged. ### Pre-Push Hook diff --git a/Makefile b/Makefile index 47902d9..31fb51d 100644 --- a/Makefile +++ b/Makefile @@ -85,8 +85,8 @@ generate: generate-api generate-docs generate-schema .PHONY: fmt fmt: - @echo "Running go fmt..." - @go fmt ./... + @echo "Running golangci-lint fmt..." + @golangci-lint fmt @echo "Code formatted successfully!" .PHONY: lint @@ -94,9 +94,9 @@ lint: @echo "Running golangci-lint..." @if ! command -v golangci-lint &> /dev/null; then \ echo "Installing golangci-lint..."; \ - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.0; \ + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.1; \ fi - @golangci-lint run ./... + @golangci-lint run @echo "Linting completed successfully!" .PHONY: lint-fix @@ -104,9 +104,9 @@ lint-fix: @echo "Running golangci-lint with auto-fix..." @if ! command -v golangci-lint &> /dev/null; then \ echo "Installing golangci-lint..."; \ - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.0; \ + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.1; \ fi - @golangci-lint run --fix ./... + @golangci-lint run --fix @echo "Linting with auto-fix completed successfully!" .PHONY: verify-generate @@ -121,4 +121,4 @@ verify-generate: generate .PHONY: ci ci: lint test verify-generate - @echo "All CI checks passed successfully!" \ No newline at end of file + @echo "All CI checks passed successfully!" diff --git a/lefthook.yml b/lefthook.yml index 758bdac..d2744c5 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -3,8 +3,8 @@ # please refer to the relevant section in the contributing documentation (CONTRIBUTING.md). pre-commit: commands: - go-fmt: - run: go fmt ./... + golangci-lint-fmt: + run: golangci-lint fmt stage_fixed: true pre-push: commands: