Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ linters:
alias: "ocispecs"
- pkg: "github.com/opencontainers/go-digest"
alias: "digest"
staticcheck:
# Enable all options, with some exceptions.
# For defaults, see https://golangci-lint.run/usage/linters/#staticcheck
checks:
- all
- -QF1008 # Omit embedded fields from selector expression; https://staticcheck.dev/docs/checks/#QF1008
Comment on lines +77 to +82
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

My bigger concern here is not even -QF1008, it's switching staticcheck from its defaults to checks: [all, -QF1008].

That is a broader policy change than the PR suggests. It doesn't just disable one noisy rule, it also opts this repo into the full staticcheck rule set instead of inheriting upstream defaults. So, we stop following staticcheck's default policy and start owning our own.

It also changes the shape of future golangci-lint bumps. By switching to all, we opt into the full staticcheck rule set, including rules that may be too opinionated or simply not a good fit for this repo, plus any new checks added upstream later. The default set is usually a more deliberate baseline across projects, whereas all pushes us toward a broader policy that may create churn, encourage questionable cleanups, or even move code away from the clearest implementation for this codebase.

I don't see enough benefit here to justify that change imo. If the actual problem is a small number of false positives or overly opinionated reports, I'd rather handle those narrowly than broaden the check set and replace the defaults entirely.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, honestly, these settings kinda suck; the default already is all with some checks removed, but there's no option to specify default, then remove some (or add some); default is;

# Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]

So the all will already change when updating, but yeah, it's possible they add more exclusions as a default as well 🫠

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah I thought default was a minimal set of rules not all of them!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can have a look if there's perhaps better ways to configure it. I agree that it'd be much nicer to do something like;

- default
- -SOMETHING_I_DONT_WANT

Do the other changes look good to you? If so, I could probably move the config changes separate (and can look at options).

testifylint:
disable:
- empty
Expand Down
6 changes: 3 additions & 3 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ func warnOnNoOutput(ctx context.Context, nodes []builder.Node, opts map[string]O
var warnNoOutputBuf bytes.Buffer
warnNoOutputBuf.WriteString("No output specified ")
if len(noOutputTargets) == 1 && noOutputTargets[0] == "default" {
warnNoOutputBuf.WriteString(fmt.Sprintf("with %s driver", noMobyDriver.Factory().Name()))
fmt.Fprintf(&warnNoOutputBuf, "with %s driver", noMobyDriver.Factory().Name())
} else {
warnNoOutputBuf.WriteString(fmt.Sprintf("for %s target(s) with %s driver", strings.Join(noOutputTargets, ", "), noMobyDriver.Factory().Name()))
fmt.Fprintf(&warnNoOutputBuf, "for %s target(s) with %s driver", strings.Join(noOutputTargets, ", "), noMobyDriver.Factory().Name())
}
logrus.Warnf("%s. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load", warnNoOutputBuf.String())
}
Expand Down Expand Up @@ -1287,7 +1287,7 @@ func ReadSourcePolicy() (*spb.Policy, error) {
return nil, nil
}

data, err := os.ReadFile(p)
data, err := os.ReadFile(p) // #nosec G703 -- using user-controlled path by design
if err != nil {
return nil, errors.Wrap(err, "failed to read policy file")
}
Expand Down
1 change: 1 addition & 0 deletions build/opt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
)

// #nosec G101 -- ignoring: Potential hardcoded credentials
func TestCacheOptions_DerivedVars(t *testing.T) {
t.Setenv("ACTIONS_RUNTIME_TOKEN", "sensitive_token")
t.Setenv("ACTIONS_CACHE_URL", "https://cache.github.com")
Expand Down
4 changes: 2 additions & 2 deletions cmd/buildx/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func setupDebugProfiles(ctx context.Context) (stop func()) {

func setupCPUProfile(ctx context.Context) (stop func()) {
if cpuProfile := os.Getenv("BUILDX_CPU_PROFILE"); cpuProfile != "" {
f, err := os.Create(cpuProfile)
f, err := os.Create(cpuProfile) // #nosec G703 -- using user-controlled path by design
if err != nil {
bklog.G(ctx).Warn("could not create cpu profile", logrus.WithError(err))
return nil
Expand All @@ -53,7 +53,7 @@ func setupHeapProfile(ctx context.Context) (stop func()) {
if heapProfile := os.Getenv("BUILDX_MEM_PROFILE"); heapProfile != "" {
// Memory profile is only created on stop.
return func() {
f, err := os.Create(heapProfile)
f, err := os.Create(heapProfile) // #nosec G703 -- using user-controlled path by design
if err != nil {
bklog.G(ctx).Warn("could not create memory profile", logrus.WithError(err))
return
Expand Down
2 changes: 1 addition & 1 deletion commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
if len(drivers.String()) > 0 {
drivers.WriteString(", ")
}
drivers.WriteString(fmt.Sprintf(`"%s"`, d.Name()))
fmt.Fprintf(&drivers, `"%s"`, d.Name())
}

cmd := &cobra.Command{
Expand Down
2 changes: 1 addition & 1 deletion docs/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func generateBakeStdlibDocs(filename string) error {
}

newContent := before + "<!---MARKER_STDLIB_START-->\n\n" + table.String() + "\n" + currentContent[end:]
return os.WriteFile(filename, []byte(newContent), 0644)
return os.WriteFile(filename, []byte(newContent), 0644) // #nosec G703 -- using parameterized path by design.
}

type mdTable struct {
Expand Down
1 change: 1 addition & 0 deletions localstate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func (ls *LocalState) MigrateIfNeeded() error {
}

func (ls *LocalState) migration2() error {
// #nosec G122 -- TODO: consider using os.Root to prevent TOCTOU
return filepath.Walk(ls.GroupDir(), func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (t *Txn) NodeGroupByName(name string) (*NodeGroup, error) {
if err != nil {
return nil, err
}
dt, err := os.ReadFile(filepath.Join(t.s.cfg.Dir(), instanceDir, name))
dt, err := os.ReadFile(filepath.Join(t.s.cfg.Dir(), instanceDir, name)) // #nosec G703 -- name is validated and using user-controlled path by design
if err != nil {
return nil, err
}
Expand Down
42 changes: 21 additions & 21 deletions util/buildflags/attests_cty.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,46 @@ var attestType = sync.OnceValue(func() cty.Type {
return cty.Map(cty.String)
})

func (e *Attests) FromCtyValue(in cty.Value, p cty.Path) error {
func (a *Attests) FromCtyValue(in cty.Value, p cty.Path) error {
got := in.Type()
if got.IsTupleType() || got.IsListType() {
return e.fromCtyValue(in, p)
return a.fromCtyValue(in, p)
}

want := cty.List(attestType())
return p.NewErrorf("%s", convert.MismatchMessage(got, want))
}

func (e *Attests) fromCtyValue(in cty.Value, p cty.Path) (retErr error) {
*e = make([]*Attest, 0, in.LengthInt())
func (a *Attests) fromCtyValue(in cty.Value, p cty.Path) (retErr error) {
*a = make([]*Attest, 0, in.LengthInt())

yield := func(value cty.Value) bool {
entry := &Attest{}
if retErr = entry.FromCtyValue(value, p); retErr != nil {
return false
}
*e = append(*e, entry)
*a = append(*a, entry)
return true
}
eachElement(in)(yield)
return retErr
}

func (e Attests) ToCtyValue() cty.Value {
if len(e) == 0 {
func (a Attests) ToCtyValue() cty.Value {
if len(a) == 0 {
return cty.ListValEmpty(attestType())
}

vals := make([]cty.Value, len(e))
for i, entry := range e {
vals := make([]cty.Value, len(a))
for i, entry := range a {
vals[i] = entry.ToCtyValue()
}
return cty.ListVal(vals)
}

func (e *Attest) FromCtyValue(in cty.Value, p cty.Path) error {
func (a *Attest) FromCtyValue(in cty.Value, p cty.Path) error {
if in.Type() == cty.String {
if err := e.UnmarshalText([]byte(in.AsString())); err != nil {
if err := a.UnmarshalText([]byte(in.AsString())); err != nil {
return p.NewError(err)
}
return nil
Expand All @@ -62,7 +62,7 @@ func (e *Attest) FromCtyValue(in cty.Value, p cty.Path) error {
return err
}

e.Attrs = map[string]string{}
a.Attrs = map[string]string{}
for it := conv.ElementIterator(); it.Next(); {
k, v := it.Element()
if !v.IsKnown() {
Expand All @@ -71,31 +71,31 @@ func (e *Attest) FromCtyValue(in cty.Value, p cty.Path) error {

switch key := k.AsString(); key {
case "type":
e.Type = v.AsString()
a.Type = v.AsString()
case "disabled":
b, err := strconv.ParseBool(v.AsString())
if err != nil {
return err
}
e.Disabled = b
a.Disabled = b
default:
e.Attrs[key] = v.AsString()
a.Attrs[key] = v.AsString()
}
}
return nil
}

func (e *Attest) ToCtyValue() cty.Value {
if e == nil {
func (a *Attest) ToCtyValue() cty.Value {
if a == nil {
return cty.NullVal(cty.Map(cty.String))
}

vals := make(map[string]cty.Value, len(e.Attrs)+2)
for k, v := range e.Attrs {
vals := make(map[string]cty.Value, len(a.Attrs)+2)
for k, v := range a.Attrs {
vals[k] = cty.StringVal(v)
}
vals["type"] = cty.StringVal(e.Type)
if e.Disabled {
vals["type"] = cty.StringVal(a.Type)
if a.Disabled {
vals["disabled"] = cty.StringVal("true")
}
return cty.MapVal(vals)
Expand Down
18 changes: 9 additions & 9 deletions util/buildflags/cache_cty.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,29 +59,29 @@ func (o CacheOptions) ToCtyValue() cty.Value {
return cty.ListVal(vals)
}

func (o *CacheOptionsEntry) FromCtyValue(in cty.Value, p cty.Path) error {
func (e *CacheOptionsEntry) FromCtyValue(in cty.Value, p cty.Path) error {
conv, err := convert.Convert(in, cty.Map(cty.String))
if err != nil {
return err
}

m := conv.AsValueMap()
if err := getAndDelete(m, "type", &o.Type); err != nil {
if err := getAndDelete(m, "type", &e.Type); err != nil {
return err
}
o.Attrs = asMap(m)
return o.validate(in)
e.Attrs = asMap(m)
return e.validate(in)
}

func (o *CacheOptionsEntry) ToCtyValue() cty.Value {
if o == nil {
func (e *CacheOptionsEntry) ToCtyValue() cty.Value {
if e == nil {
return cty.NullVal(cty.Map(cty.String))
}

vals := make(map[string]cty.Value, len(o.Attrs)+1)
for k, v := range o.Attrs {
vals := make(map[string]cty.Value, len(e.Attrs)+1)
for k, v := range e.Attrs {
vals[k] = cty.StringVal(v)
}
vals["type"] = cty.StringVal(o.Type)
vals["type"] = cty.StringVal(e.Type)
return cty.MapVal(vals)
}
20 changes: 10 additions & 10 deletions util/buildflags/secrets_cty.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ func (s Secrets) ToCtyValue() cty.Value {
return cty.ListVal(vals)
}

func (e *Secret) FromCtyValue(in cty.Value, p cty.Path) error {
func (s *Secret) FromCtyValue(in cty.Value, p cty.Path) error {
if in.Type() == cty.String {
if err := e.UnmarshalText([]byte(in.AsString())); err != nil {
if err := s.UnmarshalText([]byte(in.AsString())); err != nil {
return p.NewError(err)
}
return nil
Expand All @@ -69,25 +69,25 @@ func (e *Secret) FromCtyValue(in cty.Value, p cty.Path) error {
}

if id := conv.GetAttr("id"); !id.IsNull() && id.IsKnown() {
e.ID = id.AsString()
s.ID = id.AsString()
}
if src := conv.GetAttr("src"); !src.IsNull() && src.IsKnown() {
e.FilePath = src.AsString()
s.FilePath = src.AsString()
}
if env := conv.GetAttr("env"); !env.IsNull() && env.IsKnown() {
e.Env = env.AsString()
s.Env = env.AsString()
}
return nil
}

func (e *Secret) ToCtyValue() cty.Value {
if e == nil {
func (s *Secret) ToCtyValue() cty.Value {
if s == nil {
return cty.NullVal(secretType())
}

return cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal(e.ID),
"src": cty.StringVal(e.FilePath),
"env": cty.StringVal(e.Env),
"id": cty.StringVal(s.ID),
"src": cty.StringVal(s.FilePath),
"env": cty.StringVal(s.Env),
})
}
20 changes: 10 additions & 10 deletions util/buildflags/ssh_cty.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ func (s SSHKeys) ToCtyValue() cty.Value {
return cty.ListVal(vals)
}

func (e *SSH) FromCtyValue(in cty.Value, p cty.Path) error {
func (s *SSH) FromCtyValue(in cty.Value, p cty.Path) error {
if in.Type() == cty.String {
if err := e.UnmarshalText([]byte(in.AsString())); err != nil {
if err := s.UnmarshalText([]byte(in.AsString())); err != nil {
return p.NewError(err)
}
return nil
Expand All @@ -69,25 +69,25 @@ func (e *SSH) FromCtyValue(in cty.Value, p cty.Path) error {
}

if id := conv.GetAttr("id"); !id.IsNull() && id.IsKnown() {
e.ID = id.AsString()
s.ID = id.AsString()
}
if paths := conv.GetAttr("paths"); !paths.IsNull() && paths.IsKnown() {
if err := gocty.FromCtyValue(paths, &e.Paths); err != nil {
if err := gocty.FromCtyValue(paths, &s.Paths); err != nil {
return err
}
}
return nil
}

func (e *SSH) ToCtyValue() cty.Value {
if e == nil {
func (s *SSH) ToCtyValue() cty.Value {
if s == nil {
return cty.NullVal(sshType())
}

var ctyPaths cty.Value
if len(e.Paths) > 0 {
paths := make([]cty.Value, len(e.Paths))
for i, path := range e.Paths {
if len(s.Paths) > 0 {
paths := make([]cty.Value, len(s.Paths))
for i, path := range s.Paths {
paths[i] = cty.StringVal(path)
}
ctyPaths = cty.ListVal(paths)
Expand All @@ -96,7 +96,7 @@ func (e *SSH) ToCtyValue() cty.Value {
}

return cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal(e.ID),
"id": cty.StringVal(s.ID),
"paths": ctyPaths,
})
}
2 changes: 1 addition & 1 deletion util/desktop/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func BuildDetailsOutput(refs map[string]string, term bool) string {
multiTargets := len(refs) > 1
for target, ref := range refs {
if multiTargets {
out.WriteString(fmt.Sprintf("\n %s: ", target))
fmt.Fprintf(&out, "\n %s: ", target)
}
if term {
url := BuildURL(ref)
Expand Down
2 changes: 1 addition & 1 deletion util/ghutil/ghutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func GithubActionsContext() ([]byte, error) {
// "GITHUB_EVENT_NAME": "push"
// "GITHUB_EVENT_PATH": "/home/runner/work/_temp/_github_workflow/event.json"
m["github_event_name"] = githubEventName
dt, err := os.ReadFile(githubEventPath)
dt, err := os.ReadFile(githubEventPath) // #nosec G703 -- using parameterized path by design
if err != nil {
return nil, errors.Wrapf(err, "failed to read GITHUB_EVENT_PATH %q", githubEventPath)
}
Expand Down
1 change: 1 addition & 0 deletions util/gitutil/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gitutil

import "testing"

// #nosec G101 -- ignoring: Potential hardcoded credentials
func TestStripCredentials(t *testing.T) {
cases := []struct {
name string
Expand Down
2 changes: 1 addition & 1 deletion util/imagetools/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func RegistryAuthForRef(ref string, auth authprovider.AuthConfigProvider) (strin
if err != nil {
return "", err
}
buf, err := json.Marshal(ac)
buf, err := json.Marshal(ac) // #nosec G117 -- Ignore "JSON key "password" matches secret pattern"
if err != nil {
return "", err
}
Expand Down
Loading