diff --git a/.golangci.yml b/.golangci.yml index 9abd8e53..846208a4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -34,6 +34,7 @@ linters: - G703 # Path traversal via taint - paths come from admin config or are internal CI/CD pipeline paths, not user input - G705 # XSS via taint - raw-response/static-file steps write admin-configured content by design - G706 # Log injection via taint - step.log and publish steps are designed to log arbitrary admin-configured content + - G710 # Open redirect via taint - OAuth2 redirect URLs come from the authorization server (AuthCodeURL); intentional by design gocritic: enabled-tags: - diagnostic @@ -53,6 +54,15 @@ linters: linters: - staticcheck text: "SA5011" + # ui/node_modules contains third-party Go code that should not be linted + - path: ui/node_modules/ + linters: + - govet + - staticcheck + - unused + - gocritic + - gosec + - errcheck presets: - std-error-handling diff --git a/cmd/iac-codemod/add_validate_plan.go b/cmd/iac-codemod/add_validate_plan.go index 3626d9c5..f2e74366 100644 --- a/cmd/iac-codemod/add_validate_plan.go +++ b/cmd/iac-codemod/add_validate_plan.go @@ -12,7 +12,6 @@ import ( "go/token" "io" "io/fs" - "os" "path/filepath" "sort" "strings" @@ -643,50 +642,6 @@ func qualifierFromProviderMethods(methods []*ast.FuncDecl) string { return "" } -// siblingUsesInterfacesImport returns true if any non-test .go file -// in dir (other than excludePath) imports -// github.com/GoCodeAlone/workflow/interfaces. Used to decide whether -// to inject an interfaces import into a file that doesn't have one -// when emitting a qualified ValidatePlan stub (review round-4 #1). -func siblingUsesInterfacesImport(dir, excludePath string) bool { - const wantPath = "github.com/GoCodeAlone/workflow/interfaces" - entries, err := os.ReadDir(dir) - if err != nil { - return false - } - for _, e := range entries { - if e.IsDir() { - continue - } - name := e.Name() - if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") { - continue - } - fpath := filepath.Join(dir, name) - if fpath == excludePath { - continue - } - src, err := readFile(fpath) - if err != nil { - continue - } - fs := token.NewFileSet() - sib, err := parser.ParseFile(fs, fpath, src, parser.ImportsOnly) - if err != nil { - continue - } - for _, imp := range sib.Imports { - if imp.Path == nil { - continue - } - if strings.Trim(imp.Path.Value, `"`) == wantPath { - return true - } - } - } - return false -} - // interfacesQualifier returns the package alias `file` uses for // github.com/GoCodeAlone/workflow/interfaces. If the import is // renamed (`alias "github.com/.../interfaces"`), the alias name is diff --git a/cmd/iac-codemod/lint.go b/cmd/iac-codemod/lint.go index 9ffb6d88..46e2b4f7 100644 --- a/cmd/iac-codemod/lint.go +++ b/cmd/iac-codemod/lint.go @@ -1039,39 +1039,6 @@ func receiverTypeName(fn *ast.FuncDecl) string { return id.Name } -// bodyCallsSelector reports whether the function body contains a -// CallExpr whose callee is a SelectorExpr with the given X.Name and -// Sel.Name, e.g. `wfctlhelpers.Plan(...)`. -func bodyCallsSelector(body *ast.BlockStmt, pkgIdent, selName string) bool { - if body == nil { - return false - } - found := false - ast.Inspect(body, func(n ast.Node) bool { - if found { - return false - } - call, ok := n.(*ast.CallExpr) - if !ok { - return true - } - sel, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - return true - } - x, ok := sel.X.(*ast.Ident) - if !ok { - return true - } - if x.Name == pkgIdent && sel.Sel.Name == selName { - found = true - return false - } - return true - }) - return found -} - // bodyReferencesField reports whether the function body references any // SelectorExpr with the given Sel.Name, e.g. any `.ForceNew`. func bodyReferencesField(body *ast.BlockStmt, fieldName string) bool { diff --git a/cmd/iac-codemod/refactor_apply.go b/cmd/iac-codemod/refactor_apply.go index 3a1d9301..ad23d38b 100644 --- a/cmd/iac-codemod/refactor_apply.go +++ b/cmd/iac-codemod/refactor_apply.go @@ -22,10 +22,6 @@ func init() { modes["refactor-apply"] = runRefactorApply } -// applyCanonicalCallExpr is the canonical replacement-body expression -// emitted by refactor-apply. -const applyCanonicalCallExpr = "wfctlhelpers.ApplyPlan(ctx, p, plan)" - // applyClassification labels the disposition of a single Apply() // method site. The non-canonical idioms are surfaced as distinct // classes so the report can suggest the right hand-port handling. @@ -123,7 +119,7 @@ func runRefactorApply(args []string, opts *Options, stdout, stderr io.Writer) in if *reportFile != "" { var buf bytes.Buffer report.print(&buf, opts) - if err := os.WriteFile(*reportFile, buf.Bytes(), 0o644); err != nil { + if err := os.WriteFile(*reportFile, buf.Bytes(), 0o600); err != nil { fmt.Fprintf(stderr, "iac-codemod refactor-apply: write report-file %s: %v\n", *reportFile, err) return 1 } @@ -476,7 +472,7 @@ func isCanonicalApplyLoopAssign(a *ast.AssignStmt, recvName string) bool { if !ok { return false } - if !((recvName != "" && x.Name == recvName) || (recvName == "" && x.Name == "p")) { + if (recvName == "" || x.Name != recvName) && (recvName != "" || x.Name != "p") { return false } // Round-12 #7: also verify the lookup KEY is `action.Resource.Type`. @@ -1162,7 +1158,7 @@ func isProviderIDGuard(ifs *ast.IfStmt) bool { if id, ok := be.Y.(*ast.Ident); ok && id.Name == "nil" { yIsNil = true } - if !(xIsCurrent && yIsNil) { + if !xIsCurrent || !yIsNil { // Allow the reverse order too (`nil != action.Current`), // though it's not idiomatic Go. yIsCurrent := false @@ -1173,7 +1169,7 @@ func isProviderIDGuard(ifs *ast.IfStmt) bool { if id, ok := be.X.(*ast.Ident); ok && id.Name == "nil" { xIsNil = true } - if !(yIsCurrent && xIsNil) { + if !yIsCurrent || !xIsNil { return false } } diff --git a/cmd/iac-codemod/refactor_plan.go b/cmd/iac-codemod/refactor_plan.go index 2640ee64..7e1e099f 100644 --- a/cmd/iac-codemod/refactor_plan.go +++ b/cmd/iac-codemod/refactor_plan.go @@ -39,11 +39,6 @@ const helperImportPath = "github.com/GoCodeAlone/workflow/iac/wfctlhelpers" // files would fail to compile". const planHelperImportPath = "github.com/GoCodeAlone/workflow/platform" -// planCanonicalCallExpr is the canonical replacement-body expression -// emitted by refactor-plan. Calls platform.ComputePlan (the real helper); -// see planHelperImportPath above for the review-correction rationale. -const planCanonicalCallExpr = "platform.ComputePlan(ctx, p, desired, current)" - // planClassification labels the disposition of a single Plan() method // site. Each report entry carries one classification; the rewriter // honors only `planCanonical`. @@ -1108,13 +1103,11 @@ func rewritePlanBody(fn *ast.FuncDecl, file *ast.File) { ast.NewIdent(currentName), }, } - // plan, err := platform.ComputePlan(ctx, p, desired, current) planAssign := &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("plan"), ast.NewIdent("err")}, Tok: token.DEFINE, Rhs: []ast.Expr{call}, } - // return &plan, err returnStmt := &ast.ReturnStmt{ Results: []ast.Expr{ &ast.UnaryExpr{Op: token.AND, X: ast.NewIdent("plan")}, diff --git a/cmd/wfctl/infra.go b/cmd/wfctl/infra.go index cc0ac103..9f9625c7 100644 --- a/cmd/wfctl/infra.go +++ b/cmd/wfctl/infra.go @@ -295,7 +295,7 @@ func runInfraPlan(args []string) error { // cmd/wfctl/main.go's top-level wrapper. errors.New (rather than // fmt.Errorf) avoids govet's no-verbs noise and is canonical for // fixed-string error literals per Go convention. - return errors.New("this plan requires JIT resolution; persisted plan.json is not supported. Run 'wfctl infra apply' directly without -o/--plan.") + return errors.New("this plan requires JIT resolution; persisted plan.json is not supported. Run 'wfctl infra apply' directly without -o/--plan") } // Embed a hash of the desired-state inputs so wfctl infra apply --plan // can detect stale plans when the config changes after plan generation. diff --git a/cmd/wfctl/infra_bootstrap.go b/cmd/wfctl/infra_bootstrap.go index 49a11acd..60809cc7 100644 --- a/cmd/wfctl/infra_bootstrap.go +++ b/cmd/wfctl/infra_bootstrap.go @@ -429,13 +429,10 @@ func bootstrapSecrets(ctx context.Context, provider secrets.Provider, cfg *Secre if forceRotate[gen.Key] { deleteKey := gen.Key if delErr := provider.Delete(ctx, deleteKey); delErr != nil { - if errors.Is(delErr, secrets.ErrNotFound) || errors.Is(delErr, secrets.ErrUnsupported) { - // Secret was already absent or provider doesn't support Delete. - // Log a warning and continue — the create path handles this. - fmt.Fprintf(os.Stderr, "warn: rotate-pre-delete %s: %v (continuing)\n", deleteKey, delErr) - } else { - fmt.Fprintf(os.Stderr, "warn: rotate-pre-delete %s: %v (continuing)\n", deleteKey, delErr) - } + // Secret was already absent, provider doesn't support Delete, + // or another error. Log a warning and continue — the create + // path handles this. + fmt.Fprintf(os.Stderr, "warn: rotate-pre-delete %s: %v (continuing)\n", deleteKey, delErr) } // Invalidate the List cache so the existence check below reflects the // deletion. A fresh List call after Delete is the safe path for diff --git a/cmd/wfctl/infra_plan_jit_reject_test.go b/cmd/wfctl/infra_plan_jit_reject_test.go index b6dc21e7..d43117e1 100644 --- a/cmd/wfctl/infra_plan_jit_reject_test.go +++ b/cmd/wfctl/infra_plan_jit_reject_test.go @@ -20,7 +20,7 @@ import ( // prefix from cmd/wfctl/main.go's top-level error wrapper; the value // returned by runInfraPlan (and asserted here) does NOT include that // prefix. -const expectedJITRejectError = "this plan requires JIT resolution; persisted plan.json is not supported. Run 'wfctl infra apply' directly without -o/--plan." +const expectedJITRejectError = "this plan requires JIT resolution; persisted plan.json is not supported. Run 'wfctl infra apply' directly without -o/--plan" // TestInfraPlan_RejectsPersistedJITPlan_WithExactErrorString is the // canonical T5.5 scenario: a config whose env_vars carry a diff --git a/example/go.mod b/example/go.mod index beb95ce1..444edd14 100644 --- a/example/go.mod +++ b/example/go.mod @@ -38,33 +38,32 @@ require ( github.com/Workiva/go-datastructures v1.1.7 // indirect github.com/andybalholm/brotli v1.2.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect - github.com/aws/aws-sdk-go-v2/config v1.32.14 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.16 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.15 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1 // indirect github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.14 // indirect github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.13 // indirect github.com/aws/aws-sdk-go-v2/service/ec2 v1.297.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecs v1.78.0 // indirect github.com/aws/aws-sdk-go-v2/service/eks v1.82.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5 // indirect github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 // indirect - github.com/aws/smithy-go v1.24.3 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 // indirect + github.com/aws/smithy-go v1.25.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.24.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -78,7 +77,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.8.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/digitalocean/godo v1.184.0 // indirect + github.com/digitalocean/godo v1.186.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/docker v28.5.2+incompatible // indirect github.com/docker/go-connections v0.6.0 // indirect diff --git a/example/go.sum b/example/go.sum index ec57d9ad..11cb6f88 100644 --- a/example/go.sum +++ b/example/go.sum @@ -86,24 +86,22 @@ github.com/antithesishq/antithesis-sdk-go v0.7.0 h1:uWDG8BqLD1lI2ps38WDz2vXflrTX github.com/antithesishq/antithesis-sdk-go v0.7.0/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= -github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2 v1.41.6 h1:1AX0AthnBQzMx1vbmir3Y4WsnJgiydmnJjiLu+LvXOg= +github.com/aws/aws-sdk-go-v2 v1.41.6/go.mod h1:dy0UzBIfwSeot4grGvY1AqFWN5zgziMmWGzysDnHFcQ= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI= -github.com/aws/aws-sdk-go-v2/config v1.32.14 h1:opVIRo/ZbbI8OIqSOKmpFaY7IwfFUOCCXBsUpJOwDdI= -github.com/aws/aws-sdk-go-v2/config v1.32.14/go.mod h1:U4/V0uKxh0Tl5sxmCBZ3AecYny4UNlVmObYjKuuaiOo= -github.com/aws/aws-sdk-go-v2/credentials v1.19.14 h1:n+UcGWAIZHkXzYt87uMFBv/l8THYELoX6gVcUvgl6fI= -github.com/aws/aws-sdk-go-v2/credentials v1.19.14/go.mod h1:cJKuyWB59Mqi0jM3nFYQRmnHVQIcgoxjEMAbLkpr62w= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y= +github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2+wze1u3cNeM= +github.com/aws/aws-sdk-go-v2/config v1.32.16/go.mod h1:duCCnJEFqpt2RC6no1iK6q+8HpwOAkiUua0pY507dQc= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTtEVmAVyo+NFLHBhH4= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 h1:GmLa5Kw1ESqtFpXsx5MmC84QWa/ZrLZvlJGa2y+4kcQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22/go.mod h1:6sW9iWm9DK9YRpRGga/qzrzNLgKpT2cIxb7Vo2eNOp0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 h1:dY4kWZiSaXIzxnKlj17nHnBcXXBfac6UlsAx2qL6XrU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22/go.mod h1:KIpEUx0JuRZLO7U6cbV204cWAEco2iC3l061IxlwLtI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U= github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1 h1:KdeMmKNbHOcFsiFe8BhLYE2A8crvEWnetrs8GkF2od8= github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1/go.mod h1:QdVi7bF8U8HE8FWQ77pa4wcAMFnxI/UPx4mmQ4azRQs= github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.14 h1:0aYQ2UaSB1ccXZXUQ4a5XanrHEykKNzMLFgLEDhf8PU= @@ -118,12 +116,12 @@ github.com/aws/aws-sdk-go-v2/service/eks v1.82.0 h1:AvBDUgHffBd4AErnQY6sB9u5vY/9 github.com/aws/aws-sdk-go-v2/service/eks v1.82.0/go.mod h1:xdUh6tdF9A8hc+PE84kmHbF/zsVPNiKnc6oLgulq1Eo= github.com/aws/aws-sdk-go-v2/service/iam v1.53.7 h1:n9YLiWtX3+6pTLZWvRJmtq5JIB9NA/KFelyCg5fOlTU= github.com/aws/aws-sdk-go-v2/service/iam v1.53.7/go.mod h1:sP46Vo6MeJcM4s0ZXcG2PFmfiSyixhIuC/74W52yKuk= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 h1:HtOTYcbVcGABLOVuPYaIihj6IlkqubBwFj10K5fxRek= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8/go.mod h1:VsK9abqQeGlzPgUr+isNWzPlK2vKe9INMLWnY65f5Xs= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 h1:PUmZeJU6Y1Lbvt9WFuJ0ugUK2xn6hIWUBBbKuOWF30s= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22/go.mod h1:nO6egFBoAaoXze24a2C0NjQCvdpk8OueRoYimvEB9jo= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ= github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5 h1:LxgRVyuY+5DEPSX7kmin/V7toE8MWZ9U8n2dqRtX+RE= @@ -132,16 +130,16 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 h1:Z+/OLsb85Kpq7TVLCspskqeP github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5/go.mod h1:TmxGowuBYwjmHFOsEDxaZdsQE62JJzOmtiWafTi/czg= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0 h1:hlSuz394kV0vhv9drL5lhuEFbEOEP1VyQpy15qWh1Pk= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 h1:QKZH0S178gCmFEgst8hN0mCX1KxLgHBKKY/CLqwP8lg= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.9/go.mod h1:7yuQJoT+OoH8aqIxw9vwF+8KpvLZ8AWmvmUWHsGQZvI= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 h1:lFd1+ZSEYJZYvv9d6kXzhkZu07si3f+GQ1AaYwa2LUM= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.15/go.mod h1:WSvS1NLr7JaPunCXqpJnWk1Bjo7IxzZXrZi1QQCkuqM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 h1:dzztQ1YmfPrxdrOiuZRMF6fuOwWlWpD2StNLTceKpys= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw= -github.com/aws/smithy-go v1.24.3 h1:XgOAaUgx+HhVBoP4v8n6HCQoTRDhoMghKqw4LNHsDNg= -github.com/aws/smithy-go v1.24.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 h1:a1Fq/KXn75wSzoJaPQTgZO0wHGqE9mjFnylnqEPTchA= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10/go.mod h1:p6+MXNxW7IA6dMgHfTAzljuwSKD0NCm/4lbS4t6+7vI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 h1:x6bKbmDhsgSZwv6q19wY/u3rLk/3FGjJWyqKcIRufpE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16/go.mod h1:CudnEVKRtLn0+3uMV0yEXZ+YZOKnAtUJ5DmDhilVnIw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3VgHCT64RQKkZwh0DG5j8ak= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20/go.mod h1:JHs8/y1f3zY7U5WcuzoJ/yAYGYtNIVPKLIbp61euvmg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 h1:ks8KBcZPh3PYISr5dAiXCM5/Thcuxk8l+PG4+A0exds= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0/go.mod h1:pFw33T0WLvXU3rw1WBkpMlkgIn54eCB5FYLhjDc9Foo= +github.com/aws/smithy-go v1.25.0 h1:Sz/XJ64rwuiKtB6j98nDIPyYrV1nVNJ4YU74gttcl5U= +github.com/aws/smithy-go v1.25.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -197,8 +195,8 @@ github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+Zlfu github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/digitalocean/godo v1.184.0 h1:2B2CQhxftlf3xa24Nrzn5CBQlaQjyaWqi3XbbnJlG3w= -github.com/digitalocean/godo v1.184.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= +github.com/digitalocean/godo v1.186.0 h1:aEYwSumR47vD1tX5mdPdznHrR72DBfHcmh0v9MxCwCw= +github.com/digitalocean/godo v1.186.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= diff --git a/go.mod b/go.mod index 2e07b392..8fe798a9 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sqs v1.42.21 github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 github.com/cucumber/godog v0.15.1 - github.com/digitalocean/godo v1.178.0 + github.com/digitalocean/godo v1.186.0 github.com/docker/docker v28.5.2+incompatible github.com/expr-lang/expr v1.17.8 github.com/fsnotify/fsnotify v1.9.0 diff --git a/go.sum b/go.sum index be276fd9..5aeb0592 100644 --- a/go.sum +++ b/go.sum @@ -242,8 +242,8 @@ github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+Zlfu github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/digitalocean/godo v1.178.0 h1:+B4xGOaoFwwwpM7TKhoyGHdmFg5eF9zDB1YfOLvNJ2E= -github.com/digitalocean/godo v1.178.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= +github.com/digitalocean/godo v1.186.0 h1:aEYwSumR47vD1tX5mdPdznHrR72DBfHcmh0v9MxCwCw= +github.com/digitalocean/godo v1.186.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= diff --git a/iac/diffcache/cache_filesystem.go b/iac/diffcache/cache_filesystem.go index 52818b71..0035cf6e 100644 --- a/iac/diffcache/cache_filesystem.go +++ b/iac/diffcache/cache_filesystem.go @@ -123,7 +123,7 @@ func (c *filesystemCache) Get(k Key) (interfaces.DiffResult, bool) { // working" signal from elsewhere. The cache-as-amortization framing // in the package godoc sets the expectation. func (c *filesystemCache) Put(k Key, result interfaces.DiffResult) { - if err := os.MkdirAll(c.dir, 0o755); err != nil { + if err := os.MkdirAll(c.dir, 0o750); err != nil { return } env := envelope{SchemaVersion: cacheSchemaVersion, Result: result} diff --git a/iac/wfctlhelpers/apply.go b/iac/wfctlhelpers/apply.go index 7f824b3f..dd26952c 100644 --- a/iac/wfctlhelpers/apply.go +++ b/iac/wfctlhelpers/apply.go @@ -136,7 +136,8 @@ func applyPlanWithEnvProvider( // to later actions in the same plan). syncedOutputs := buildInitialSyncedOutputs(plan.Actions) - for _, action := range plan.Actions { + for i := range plan.Actions { + action := plan.Actions[i] // Honor cancellation at the loop boundary. Drivers should also // check ctx internally for in-flight work, but the loop check // guarantees apply stops between actions even if a driver @@ -205,11 +206,11 @@ func applyPlanWithEnvProvider( // ProviderID). func buildInitialSyncedOutputs(actions []interfaces.PlanAction) map[string]map[string]any { out := make(map[string]map[string]any) - for _, a := range actions { - if a.Current == nil { + for i := range actions { + if actions[i].Current == nil { continue } - out[a.Current.Name] = flattenStateOutputs(a.Current) + out[actions[i].Current.Name] = flattenStateOutputs(actions[i].Current) } return out } diff --git a/iac/wfctlhelpers/apply_create_test.go b/iac/wfctlhelpers/apply_create_test.go index cbb44042..bb03f14f 100644 --- a/iac/wfctlhelpers/apply_create_test.go +++ b/iac/wfctlhelpers/apply_create_test.go @@ -28,7 +28,7 @@ type fakeDriverWithUpsert struct { } func (d *fakeDriverWithUpsert) Create(_ context.Context, _ interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ if d.createErr != nil { return nil, d.createErr } @@ -44,7 +44,7 @@ func (d *fakeDriverWithUpsert) Read(_ context.Context, _ interfaces.ResourceRef) func (d *fakeDriverWithUpsert) Update(_ context.Context, ref interfaces.ResourceRef, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { d.updateCalled = true - d.fakeDriver.updateCount++ + d.updateCount++ if d.updateOut != nil { return d.updateOut, nil } @@ -133,7 +133,7 @@ type alreadyExistsBareDriver struct { } func (d *alreadyExistsBareDriver) Create(_ context.Context, _ interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ return nil, interfaces.ErrResourceAlreadyExists } diff --git a/iac/wfctlhelpers/apply_jit_test.go b/iac/wfctlhelpers/apply_jit_test.go index a81c69c3..8938e0aa 100644 --- a/iac/wfctlhelpers/apply_jit_test.go +++ b/iac/wfctlhelpers/apply_jit_test.go @@ -26,7 +26,7 @@ type jitRecordingDriver struct { } func (d *jitRecordingDriver) Create(_ context.Context, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ d.mu.Lock() if d.seenConfigs == nil { d.seenConfigs = make(map[string]map[string]any) @@ -40,7 +40,7 @@ func (d *jitRecordingDriver) Create(_ context.Context, spec interfaces.ResourceS } func (d *jitRecordingDriver) Update(_ context.Context, ref interfaces.ResourceRef, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.updateCount++ + d.updateCount++ d.mu.Lock() if d.seenUpdateCfgs == nil { d.seenUpdateCfgs = make(map[string]map[string]any) diff --git a/iac/wfctlhelpers/apply_postcondition_test.go b/iac/wfctlhelpers/apply_postcondition_test.go index b7ef765b..e45e3dad 100644 --- a/iac/wfctlhelpers/apply_postcondition_test.go +++ b/iac/wfctlhelpers/apply_postcondition_test.go @@ -232,6 +232,6 @@ type erroringFakeDriver struct { } func (d *erroringFakeDriver) Create(_ context.Context, _ interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ return nil, errFromDispatch } diff --git a/iac/wfctlhelpers/apply_replace_test.go b/iac/wfctlhelpers/apply_replace_test.go index 5e215bb8..aaf12d91 100644 --- a/iac/wfctlhelpers/apply_replace_test.go +++ b/iac/wfctlhelpers/apply_replace_test.go @@ -25,14 +25,14 @@ type orderRecordingDriver struct { } func (d *orderRecordingDriver) Delete(_ context.Context, _ interfaces.ResourceRef) error { - d.fakeDriver.deleteCount++ + d.deleteCount++ d.step++ d.deleteAt = d.step return d.deleteErr } func (d *orderRecordingDriver) Create(_ context.Context, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ d.step++ d.createAt = d.step if d.createErr != nil { @@ -169,12 +169,12 @@ type perResourceReplaceDriver struct { } func (d *perResourceReplaceDriver) Delete(_ context.Context, _ interfaces.ResourceRef) error { - d.fakeDriver.deleteCount++ + d.deleteCount++ return nil } func (d *perResourceReplaceDriver) Create(_ context.Context, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.createCount++ + d.createCount++ id := d.newIDs[spec.Name] if id == "" { id = "fallback-id" @@ -279,7 +279,7 @@ type cancelOnDeleteDriver struct { } func (d *cancelOnDeleteDriver) Delete(_ context.Context, _ interfaces.ResourceRef) error { - d.fakeDriver.deleteCount++ + d.deleteCount++ d.cancel() // ctx is now canceled; Create must not run. return nil } diff --git a/iac/wfctlhelpers/apply_update_delete_test.go b/iac/wfctlhelpers/apply_update_delete_test.go index 44614653..b9c38b50 100644 --- a/iac/wfctlhelpers/apply_update_delete_test.go +++ b/iac/wfctlhelpers/apply_update_delete_test.go @@ -21,7 +21,7 @@ type providerIDCapturingDriver struct { } func (d *providerIDCapturingDriver) Update(_ context.Context, ref interfaces.ResourceRef, spec interfaces.ResourceSpec) (*interfaces.ResourceOutput, error) { - d.fakeDriver.updateCount++ + d.updateCount++ d.updateRef = ref d.updateSpec = spec if d.updateErr != nil { @@ -31,7 +31,7 @@ func (d *providerIDCapturingDriver) Update(_ context.Context, ref interfaces.Res } func (d *providerIDCapturingDriver) Delete(_ context.Context, ref interfaces.ResourceRef) error { - d.fakeDriver.deleteCount++ + d.deleteCount++ d.deleteRef = ref return d.deleteErr } diff --git a/module/scan_provider_test.go b/module/scan_provider_test.go index 187e6d86..2536ae17 100644 --- a/module/scan_provider_test.go +++ b/module/scan_provider_test.go @@ -51,7 +51,7 @@ func (a *scanMockApp) GetService(name string, target any) error { return fmt.Errorf("service %q not found", name) } rv := reflect.ValueOf(target) - if rv.Kind() != reflect.Ptr || rv.IsNil() { + if rv.Kind() != reflect.Pointer || rv.IsNil() { return fmt.Errorf("target must be a non-nil pointer") } rv.Elem().Set(reflect.ValueOf(svc)) diff --git a/schema/reflect.go b/schema/reflect.go index 1bf58b81..f82e6dd7 100644 --- a/schema/reflect.go +++ b/schema/reflect.go @@ -15,7 +15,7 @@ func GenerateConfigFields(configStruct interface{}) []ConfigFieldDef { if t == nil { return nil } - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } if t.Kind() != reflect.Struct {