diff --git a/.golangci.yml b/.golangci.yml index 49e5801dc3..434b92875d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,6 +7,7 @@ linters: - deadcode - depguard - errcheck + - gocritic - gocyclo - gofmt - goimports @@ -32,6 +33,17 @@ linters-settings: # The io/ioutil package has been deprecated. # https://go.dev/doc/go1.16#ioutil - io/ioutil + gocritic: + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + enabled-tags: + - diagnostic + - opinionated + - style + disabled-checks: + - paramTypeCombine + - unnamedResult + - whyNoLint gocyclo: min-complexity: 16 lll: diff --git a/Dockerfile b/Dockerfile index a3f58f0fe8..45d2cc2132 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,9 +16,11 @@ # limitations under the License. ARG GO_VERSION=1.18.4-alpine -ARG GOLANGCI_LINT_VERSION=v1.40.1-alpine +ARG GOLANGCI_LINT_VERSION=v1.46.2-alpine ARG PROTOC_GEN_GO_VERSION=v1.4.3 +FROM --platform=${BUILDPLATFORM} golangci/golangci-lint:${GOLANGCI_LINT_VERSION} AS local-golangci-lint + FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION} AS base WORKDIR /compose-cli RUN apk add --no-cache -vv \ @@ -34,7 +36,7 @@ RUN --mount=type=cache,target=/go/pkg/mod \ FROM base AS lint ENV CGO_ENABLED=0 -COPY --from=golangci/golangci-lint /usr/bin/golangci-lint /usr/bin/golangci-lint +COPY --from=local-golangci-lint /usr/bin/golangci-lint /usr/bin/golangci-lint ARG BUILD_TAGS ARG GIT_TAG RUN --mount=target=. \ diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index 84f24d8bfc..c247bef156 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -239,11 +239,11 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { verbose bool version bool ) - command := &cobra.Command{ + c := &cobra.Command{ Short: "Docker Compose", Use: PluginName, TraverseChildren: true, - // By default (no Run/RunE in parent command) for typos in subcommands, cobra displays the help of parent command but exit(0) ! + // By default (no Run/RunE in parent c) for typos in subcommands, cobra displays the help of parent c but exit(0) ! RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return cmd.Help() @@ -300,7 +300,7 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { }, } - command.AddCommand( + c.AddCommand( upCommand(&opts, backend), downCommand(&opts, backend), startCommand(&opts, backend), @@ -327,16 +327,16 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { createCommand(&opts, backend), copyCommand(&opts, backend), ) - command.Flags().SetInterspersed(false) - opts.addProjectFlags(command.Flags()) - command.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`) - command.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information") - command.Flags().MarkHidden("version") //nolint:errcheck - command.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`) - command.Flags().MarkHidden("no-ansi") //nolint:errcheck - command.Flags().BoolVar(&verbose, "verbose", false, "Show more output") - command.Flags().MarkHidden("verbose") //nolint:errcheck - return command + c.Flags().SetInterspersed(false) + opts.addProjectFlags(c.Flags()) + c.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`) + c.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information") + c.Flags().MarkHidden("version") //nolint:errcheck + c.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`) + c.Flags().MarkHidden("no-ansi") //nolint:errcheck + c.Flags().BoolVar(&verbose, "verbose", false, "Show more output") + c.Flags().MarkHidden("verbose") //nolint:errcheck + return c } func setEnvWithDotEnv(prjOpts *projectOptions) error { @@ -355,7 +355,7 @@ func setEnvWithDotEnv(prjOpts *projectOptions) error { } for k, v := range envFromFile { if _, ok := os.LookupEnv(k); !ok { - if err = os.Setenv(k, v); err != nil { + if err := os.Setenv(k, v); err != nil { return err } } diff --git a/cmd/compose/down.go b/cmd/compose/down.go index e94aec1f55..56a40ac763 100644 --- a/cmd/compose/down.go +++ b/cmd/compose/down.go @@ -69,8 +69,7 @@ func downCommand(p *projectOptions, backend api.Service) *cobra.Command { flags.BoolVarP(&opts.volumes, "volumes", "v", false, " Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.") flags.StringVar(&opts.images, "rmi", "", `Remove images used by services. "local" remove only images that don't have a custom tag ("local"|"all")`) flags.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName { - switch name { - case "volume": + if name == "volume" { name = "volumes" logrus.Warn("--volume is deprecated, please use --volumes") } diff --git a/cmd/compose/list.go b/cmd/compose/list.go index ac05dc1d12..618ad03c76 100644 --- a/cmd/compose/list.go +++ b/cmd/compose/list.go @@ -39,19 +39,19 @@ type lsOptions struct { } func listCommand(backend api.Service) *cobra.Command { - opts := lsOptions{Filter: opts.NewFilterOpt()} + lsOpts := lsOptions{Filter: opts.NewFilterOpt()} lsCmd := &cobra.Command{ Use: "ls", Short: "List running compose projects", RunE: Adapt(func(ctx context.Context, args []string) error { - return runList(ctx, backend, opts) + return runList(ctx, backend, lsOpts) }), ValidArgsFunction: noCompletion(), } - lsCmd.Flags().StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json].") - lsCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs.") - lsCmd.Flags().Var(&opts.Filter, "filter", "Filter output based on conditions provided.") - lsCmd.Flags().BoolVarP(&opts.All, "all", "a", false, "Show all stopped Compose projects") + lsCmd.Flags().StringVar(&lsOpts.Format, "format", "pretty", "Format the output. Values: [pretty | json].") + lsCmd.Flags().BoolVarP(&lsOpts.Quiet, "quiet", "q", false, "Only display IDs.") + lsCmd.Flags().Var(&lsOpts.Filter, "filter", "Filter output based on conditions provided.") + lsCmd.Flags().BoolVarP(&lsOpts.All, "all", "a", false, "Show all stopped Compose projects") return lsCmd } @@ -60,18 +60,18 @@ var acceptedListFilters = map[string]bool{ "name": true, } -func runList(ctx context.Context, backend api.Service, opts lsOptions) error { - filters := opts.Filter.Value() +func runList(ctx context.Context, backend api.Service, lsOpts lsOptions) error { + filters := lsOpts.Filter.Value() err := filters.Validate(acceptedListFilters) if err != nil { return err } - stackList, err := backend.List(ctx, api.ListOptions{All: opts.All}) + stackList, err := backend.List(ctx, api.ListOptions{All: lsOpts.All}) if err != nil { return err } - if opts.Quiet { + if lsOpts.Quiet { for _, s := range stackList { fmt.Println(s.Name) } @@ -90,7 +90,7 @@ func runList(ctx context.Context, backend api.Service, opts lsOptions) error { } view := viewFromStackList(stackList) - return formatter.Print(view, opts.Format, os.Stdout, func(w io.Writer) { + return formatter.Print(view, lsOpts.Format, os.Stdout, func(w io.Writer) { for _, stack := range view { _, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", stack.Name, stack.Status, stack.ConfigFiles) } diff --git a/cmd/compose/up.go b/cmd/compose/up.go index 7a89e1dd07..145bb7cea3 100644 --- a/cmd/compose/up.go +++ b/cmd/compose/up.go @@ -219,18 +219,20 @@ func runUp(ctx context.Context, backend api.Service, createOptions createOptions func setServiceScale(project *types.Project, name string, replicas uint64) error { for i, s := range project.Services { - if s.Name == name { - service, err := project.GetService(name) - if err != nil { - return err - } - if service.Deploy == nil { - service.Deploy = &types.DeployConfig{} - } - service.Deploy.Replicas = &replicas - project.Services[i] = service - return nil + if s.Name != name { + continue + } + + service, err := project.GetService(name) + if err != nil { + return err + } + if service.Deploy == nil { + service.Deploy = &types.DeployConfig{} } + service.Deploy.Replicas = &replicas + project.Services[i] = service + return nil } return fmt.Errorf("unknown service %q", name) } diff --git a/cmd/formatter/logs.go b/cmd/formatter/logs.go index 2cc9c84e5a..b5bc37361d 100644 --- a/cmd/formatter/logs.go +++ b/cmd/formatter/logs.go @@ -27,6 +27,16 @@ import ( "github.com/docker/compose/v2/pkg/api" ) +// LogConsumer consume logs from services and format them +type logConsumer struct { + ctx context.Context + presenters sync.Map // map[string]*presenter + width int + writer io.Writer + color bool + prefix bool +} + // NewLogConsumer creates a new LogConsumer func NewLogConsumer(ctx context.Context, w io.Writer, color bool, prefix bool) api.LogConsumer { return &logConsumer{ @@ -79,14 +89,14 @@ func (l *logConsumer) Log(container, service, message string) { } p := l.getPresenter(container) for _, line := range strings.Split(message, "\n") { - fmt.Fprintf(l.writer, "%s%s\n", p.prefix, line) // nolint:errcheck + fmt.Fprintf(l.writer, "%s%s\n", p.prefix, line) //nolint:errcheck } } func (l *logConsumer) Status(container, msg string) { p := l.getPresenter(container) s := p.colors(fmt.Sprintf("%s %s\n", container, msg)) - l.writer.Write([]byte(s)) // nolint:errcheck + l.writer.Write([]byte(s)) //nolint:errcheck } func (l *logConsumer) computeWidth() { @@ -101,16 +111,6 @@ func (l *logConsumer) computeWidth() { l.width = width + 1 } -// LogConsumer consume logs from services and format them -type logConsumer struct { - ctx context.Context - presenters sync.Map // map[string]*presenter - width int - writer io.Writer - color bool - prefix bool -} - type presenter struct { colors colorFunc name string diff --git a/pkg/api/errors.go b/pkg/api/errors.go index 4cdcd80094..e7820168e3 100644 --- a/pkg/api/errors.go +++ b/pkg/api/errors.go @@ -21,7 +21,7 @@ import ( ) const ( - //ExitCodeLoginRequired exit code when command cannot execute because it requires cloud login + // ExitCodeLoginRequired exit code when command cannot execute because it requires cloud login // This will be used by VSCode to detect when creating context if the user needs to login first ExitCodeLoginRequired = 5 ) diff --git a/pkg/compose/attach.go b/pkg/compose/attach.go index 42b815f3f3..52e9051935 100644 --- a/pkg/compose/attach.go +++ b/pkg/compose/attach.go @@ -127,9 +127,9 @@ func (s *composeService) attachContainerStreams(ctx context.Context, container s if stdout != nil { go func() { if tty { - io.Copy(stdout, streamOut) // nolint:errcheck + io.Copy(stdout, streamOut) //nolint:errcheck } else { - stdcopy.StdCopy(stdout, stderr, streamOut) // nolint:errcheck + stdcopy.StdCopy(stdout, stderr, streamOut) //nolint:errcheck } }() } diff --git a/pkg/compose/build.go b/pkg/compose/build.go index 54104c465d..e2e60720f7 100644 --- a/pkg/compose/build.go +++ b/pkg/compose/build.go @@ -61,29 +61,30 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti } for _, service := range services { - if service.Build != nil { - imageName := getImageName(service, project.Name) - imagesToBuild = append(imagesToBuild, imageName) - buildOptions, err := s.toBuildOptions(project, service, imageName, options.SSHs) - if err != nil { - return err - } - buildOptions.Pull = options.Pull - buildOptions.BuildArgs = mergeArgs(buildOptions.BuildArgs, args) - buildOptions.NoCache = options.NoCache - buildOptions.CacheFrom, err = buildflags.ParseCacheEntry(service.Build.CacheFrom) - if err != nil { - return err - } + if service.Build == nil { + continue + } + imageName := getImageName(service, project.Name) + imagesToBuild = append(imagesToBuild, imageName) + buildOptions, err := s.toBuildOptions(project, service, imageName, options.SSHs) + if err != nil { + return err + } + buildOptions.Pull = options.Pull + buildOptions.BuildArgs = mergeArgs(buildOptions.BuildArgs, args) + buildOptions.NoCache = options.NoCache + buildOptions.CacheFrom, err = buildflags.ParseCacheEntry(service.Build.CacheFrom) + if err != nil { + return err + } - for _, image := range service.Build.CacheFrom { - buildOptions.CacheFrom = append(buildOptions.CacheFrom, bclient.CacheOptionsEntry{ - Type: "registry", - Attrs: map[string]string{"ref": image}, - }) - } - opts[imageName] = buildOptions + for _, image := range service.Build.CacheFrom { + buildOptions.CacheFrom = append(buildOptions.CacheFrom, bclient.CacheOptionsEntry{ + Type: "registry", + Attrs: map[string]string{"ref": image}, + }) } + opts[imageName] = buildOptions } _, err = s.doBuild(ctx, project, opts, options.Progress) @@ -312,11 +313,11 @@ func mergeArgs(m ...types.Mapping) types.Mapping { return merged } -func dockerFilePath(context string, dockerfile string) string { - if urlutil.IsGitURL(context) || filepath.IsAbs(dockerfile) { +func dockerFilePath(ctxName string, dockerfile string) string { + if urlutil.IsGitURL(ctxName) || filepath.IsAbs(dockerfile) { return dockerfile } - return filepath.Join(context, dockerfile) + return filepath.Join(ctxName, dockerfile) } func sshAgentProvider(sshKeys types.SSHConfig) (session.Attachable, error) { diff --git a/pkg/compose/build_classic.go b/pkg/compose/build_classic.go index 3c6487be85..db5d948e32 100644 --- a/pkg/compose/build_classic.go +++ b/pkg/compose/build_classic.go @@ -64,7 +64,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj return nameDigests, errs } -// nolint: gocyclo +//nolint: gocyclo func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options buildx.Options) (string, error) { var ( buildCtx io.ReadCloser @@ -96,7 +96,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options if err != nil { return "", errors.Errorf("unable to open Dockerfile: %v", err) } - defer dockerfileCtx.Close() // nolint:errcheck + defer dockerfileCtx.Close() //nolint:errcheck } case urlutil.IsGitURL(specifiedContext): tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName) @@ -111,7 +111,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options } if tempDir != "" { - defer os.RemoveAll(tempDir) // nolint:errcheck + defer os.RemoveAll(tempDir) //nolint:errcheck contextDir = tempDir } @@ -175,7 +175,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options if err != nil { return "", err } - defer response.Body.Close() // nolint:errcheck + defer response.Body.Close() //nolint:errcheck imageID := "" aux := func(msg jsonmessage.JSONMessage) { @@ -214,7 +214,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options if imageID == "" { return "", errors.Errorf("Server did not provide an image ID. Cannot write %s", options.ImageIDFile) } - if err := os.WriteFile(options.ImageIDFile, []byte(imageID), 0666); err != nil { + if err := os.WriteFile(options.ImageIDFile, []byte(imageID), 0o666); err != nil { return "", err } } diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 1db3bc3dbb..25b021cd84 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -553,7 +553,7 @@ func (s composeService) getLinks(ctx context.Context, projectName string, servic containerName := getCanonicalContainerName(c) links = append(links, format(containerName, linkName), - format(containerName, strings.Join([]string{linkServiceName, strconv.Itoa(number)}, Separator)), + format(containerName, linkServiceName+Separator+strconv.Itoa(number)), format(containerName, strings.Join([]string{projectName, linkServiceName, strconv.Itoa(number)}, Separator)), ) } diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index 558de13e27..d7fcd89e5a 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -263,7 +263,7 @@ func (s *composeService) copyFromContainer(ctx context.Context, containerID, src } preArchive := content - if len(srcInfo.RebaseName) != 0 { + if srcInfo.RebaseName != "" { _, srcBase := archive.SplitPathDirEntry(srcInfo.Path) preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName) } diff --git a/pkg/compose/create.go b/pkg/compose/create.go index 8069520a63..d132d65349 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -893,7 +893,7 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount continue } - mount, err := buildMount(p, types.ServiceVolumeConfig{ + mnt, err := buildMount(p, types.ServiceVolumeConfig{ Type: types.VolumeTypeBind, Source: definedSecret.File, Target: target, @@ -902,7 +902,7 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount if err != nil { return nil, err } - mounts[target] = mount + mounts[target] = mnt } values := make([]mount.Mount, 0, len(mounts)) for _, v := range mounts { @@ -911,8 +911,8 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount return values, nil } -func isUnixAbs(path string) bool { - return strings.HasPrefix(path, "/") +func isUnixAbs(p string) bool { + return strings.HasPrefix(p, "/") } func buildMount(project types.Project, volume types.ServiceVolumeConfig) (mount.Mount, error) { diff --git a/pkg/compose/create_test.go b/pkg/compose/create_test.go index 6c6a4f1980..7a0e95c6ff 100644 --- a/pkg/compose/create_test.go +++ b/pkg/compose/create_test.go @@ -22,7 +22,6 @@ import ( "sort" "testing" - "github.com/compose-spec/compose-go/types" composetypes "github.com/compose-spec/compose-go/types" "github.com/docker/compose/v2/pkg/api" moby "github.com/docker/docker/api/types" @@ -66,17 +65,17 @@ func TestBuildVolumeMount(t *testing.T) { } func TestServiceImageName(t *testing.T) { - assert.Equal(t, getImageName(types.ServiceConfig{Image: "myImage"}, "myProject"), "myImage") - assert.Equal(t, getImageName(types.ServiceConfig{Name: "aService"}, "myProject"), "myProject_aService") + assert.Equal(t, getImageName(composetypes.ServiceConfig{Image: "myImage"}, "myProject"), "myImage") + assert.Equal(t, getImageName(composetypes.ServiceConfig{Name: "aService"}, "myProject"), "myProject_aService") } func TestPrepareNetworkLabels(t *testing.T) { - project := types.Project{ + project := composetypes.Project{ Name: "myProject", - Networks: types.Networks(map[string]types.NetworkConfig{"skynet": {}}), + Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{"skynet": {}}), } prepareNetworks(&project) - assert.DeepEqual(t, project.Networks["skynet"].Labels, types.Labels(map[string]string{ + assert.DeepEqual(t, project.Networks["skynet"].Labels, composetypes.Labels(map[string]string{ "com.docker.compose.network": "skynet", "com.docker.compose.project": "myProject", "com.docker.compose.version": api.ComposeVersion, diff --git a/pkg/compose/logs.go b/pkg/compose/logs.go index 7f25207453..7d26c815a2 100644 --- a/pkg/compose/logs.go +++ b/pkg/compose/logs.go @@ -95,7 +95,7 @@ func (s *composeService) logContainers(ctx context.Context, consumer api.LogCons if err != nil { return err } - defer r.Close() // nolint errcheck + defer r.Close() //nolint errcheck name := getContainerNameWithoutProject(c) w := utils.GetWriter(func(line string) { diff --git a/pkg/compose/ls.go b/pkg/compose/ls.go index 942827ef8a..f7094a321b 100644 --- a/pkg/compose/ls.go +++ b/pkg/compose/ls.go @@ -106,9 +106,9 @@ func combinedStatus(statuses []string) string { for _, status := range keys { nb := nbByStatus[status] if result != "" { - result = result + ", " + result += ", " } - result = result + fmt.Sprintf("%s(%d)", status, nb) + result += fmt.Sprintf("%s(%d)", status, nb) } return result } diff --git a/pkg/compose/metrics.go b/pkg/compose/metrics.go index 2cdc927ea6..7bd9ad698d 100644 --- a/pkg/compose/metrics.go +++ b/pkg/compose/metrics.go @@ -50,13 +50,13 @@ var ( ComposeParseFailure = FailureCategory{MetricsStatus: ComposeParseFailureStatus, ExitCode: 15} // CommandSyntaxFailure failure for command line syntax CommandSyntaxFailure = FailureCategory{MetricsStatus: CommandSyntaxFailureStatus, ExitCode: 16} - //BuildFailure failure while building images. + // BuildFailure failure while building images. BuildFailure = FailureCategory{MetricsStatus: BuildFailureStatus, ExitCode: 17} // PullFailure failure while pulling image PullFailure = FailureCategory{MetricsStatus: PullFailureStatus, ExitCode: 18} ) -//ByExitCode retrieve FailureCategory based on command exit code +// ByExitCode retrieve FailureCategory based on command exit code func ByExitCode(exitCode int) FailureCategory { switch exitCode { case 0: diff --git a/pkg/compose/printer.go b/pkg/compose/printer.go index 7942c56411..cb1507759c 100644 --- a/pkg/compose/printer.go +++ b/pkg/compose/printer.go @@ -32,6 +32,11 @@ type logPrinter interface { Cancel() } +type printer struct { + queue chan api.ContainerEvent + consumer api.LogConsumer +} + // newLogPrinter builds a LogPrinter passing containers logs to LogConsumer func newLogPrinter(consumer api.LogConsumer) logPrinter { queue := make(chan api.ContainerEvent) @@ -48,11 +53,6 @@ func (p *printer) Cancel() { } } -type printer struct { - queue chan api.ContainerEvent - consumer api.LogConsumer -} - func (p *printer) HandleEvent(event api.ContainerEvent) { p.queue <- event } diff --git a/pkg/compose/secrets.go b/pkg/compose/secrets.go index a7114cbb3c..30815c3f10 100644 --- a/pkg/compose/secrets.go +++ b/pkg/compose/secrets.go @@ -57,7 +57,7 @@ func createTar(env string, config types.ServiceSecretConfig) (bytes.Buffer, erro value := []byte(env) b := bytes.Buffer{} tarWriter := tar.NewWriter(&b) - mode := uint32(0400) + mode := uint32(0o400) if config.Mode != nil { mode = *config.Mode } diff --git a/pkg/compose/up.go b/pkg/compose/up.go index a20591b1fd..b94c01f618 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -60,7 +60,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options return progress.Run(ctx, func(ctx context.Context) error { go func() { <-signalChan - s.Kill(ctx, project.Name, api.KillOptions{ // nolint:errcheck + s.Kill(ctx, project.Name, api.KillOptions{ //nolint:errcheck Services: project.ServiceNames(), }) }() @@ -74,7 +74,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options <-signalChan printer.Cancel() fmt.Println("Gracefully stopping... (press Ctrl+C again to force)") - stopFunc() // nolint:errcheck + stopFunc() //nolint:errcheck }() var exitCode int diff --git a/pkg/e2e/compose_test.go b/pkg/e2e/compose_test.go index f2ac2ad183..fd430488d5 100644 --- a/pkg/e2e/compose_test.go +++ b/pkg/e2e/compose_test.go @@ -134,7 +134,7 @@ func TestDownComposefileInParentFolder(t *testing.T) { tmpFolder, err := os.MkdirTemp("fixtures/simple-composefile", "test-tmp") assert.NilError(t, err) - defer os.Remove(tmpFolder) // nolint: errcheck + defer os.Remove(tmpFolder) //nolint: errcheck projectName := filepath.Base(tmpFolder) res := c.RunDockerComposeCmd(t, "--project-directory", tmpFolder, "up", "-d") diff --git a/pkg/e2e/framework.go b/pkg/e2e/framework.go index 15eed45549..66a6233a75 100644 --- a/pkg/e2e/framework.go +++ b/pkg/e2e/framework.go @@ -46,13 +46,16 @@ var ( // DockerScanExecutableName is the OS dependent Docker CLI binary name DockerScanExecutableName = "docker-scan" + + // WindowsExecutableSuffix is the Windows executable suffix + WindowsExecutableSuffix = ".exe" ) func init() { if runtime.GOOS == "windows" { - DockerExecutableName = DockerExecutableName + ".exe" - DockerComposeExecutableName = DockerComposeExecutableName + ".exe" - DockerScanExecutableName = DockerScanExecutableName + ".exe" + DockerExecutableName += WindowsExecutableSuffix + DockerComposeExecutableName += WindowsExecutableSuffix + DockerScanExecutableName += WindowsExecutableSuffix } } @@ -124,7 +127,7 @@ func initializePlugins(t testing.TB, configDir string) { } }) - require.NoError(t, os.MkdirAll(filepath.Join(configDir, "cli-plugins"), 0755), + require.NoError(t, os.MkdirAll(filepath.Join(configDir, "cli-plugins"), 0o755), "Failed to create cli-plugins directory") composePlugin, err := findExecutable(DockerComposeExecutableName, []string{"../../bin", "../../../bin"}) if os.IsNotExist(err) { @@ -169,12 +172,12 @@ func CopyFile(t testing.TB, sourceFile string, destinationFile string) { src, err := os.Open(sourceFile) require.NoError(t, err, "Failed to open source file: %s") - // nolint: errcheck + //nolint: errcheck defer src.Close() - dst, err := os.OpenFile(destinationFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + dst, err := os.OpenFile(destinationFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o755) require.NoError(t, err, "Failed to open destination file: %s", destinationFile) - // nolint: errcheck + //nolint: errcheck defer dst.Close() _, err = io.Copy(dst, src) @@ -213,7 +216,7 @@ func (c *CLI) NewCmdWithEnv(envvars []string, command string, args ...string) ic // MetricsSocket get the path where test metrics will be sent func (c *CLI) MetricsSocket() string { - return filepath.Join(c.ConfigDir, "./docker-cli.sock") + return filepath.Join(c.ConfigDir, "docker-cli.sock") } // NewDockerCmd creates a docker cmd without running it diff --git a/pkg/e2e/scan_message_test.go b/pkg/e2e/scan_message_test.go index 1515efd0f4..4204ef3d23 100644 --- a/pkg/e2e/scan_message_test.go +++ b/pkg/e2e/scan_message_test.go @@ -71,9 +71,9 @@ func TestDisplayScanMessageAfterBuild(t *testing.T) { }) t.Run("do not display if scan already invoked", func(t *testing.T) { - _ = os.MkdirAll(filepath.Join(c.ConfigDir, "scan"), 0755) + _ = os.MkdirAll(filepath.Join(c.ConfigDir, "scan"), 0o755) scanConfigFile := filepath.Join(c.ConfigDir, "scan", "config.json") - err := os.WriteFile(scanConfigFile, []byte(`{"optin":true}`), 0644) + err := os.WriteFile(scanConfigFile, []byte(`{"optin":true}`), 0o644) assert.NilError(t, err) res := c.RunDockerCmd(t, "build", "-t", "test-image-scan-msg", "fixtures/simple-build-test/nginx-build") diff --git a/pkg/e2e/volumes_test.go b/pkg/e2e/volumes_test.go index ecce19e13a..c07bfaadb3 100644 --- a/pkg/e2e/volumes_test.go +++ b/pkg/e2e/volumes_test.go @@ -50,7 +50,7 @@ func TestLocalComposeVolume(t *testing.T) { t.Run("check container volume specs", func(t *testing.T) { res := c.RunDockerCmd(t, "inspect", "compose-e2e-volume-nginx2-1", "--format", "{{ json .Mounts }}") output := res.Stdout() - // nolint + //nolint assert.Assert(t, strings.Contains(output, `"Destination":"/usr/src/app/node_modules","Driver":"local","Mode":"z","RW":true,"Propagation":""`), output) assert.Assert(t, strings.Contains(output, `"Destination":"/myconfig","Mode":"","RW":false,"Propagation":"rprivate"`), output) }) @@ -68,7 +68,7 @@ func TestLocalComposeVolume(t *testing.T) { t.Run("check container bind-mounts specs", func(t *testing.T) { res := c.RunDockerCmd(t, "inspect", "compose-e2e-volume-nginx-1", "--format", "{{ json .Mounts }}") output := res.Stdout() - // nolint + //nolint assert.Assert(t, strings.Contains(output, `"Type":"bind"`)) assert.Assert(t, strings.Contains(output, `"Destination":"/usr/share/nginx/html"`)) }) @@ -103,7 +103,7 @@ func TestProjectVolumeBind(t *testing.T) { t.Run("up on project volume with bind specification", func(t *testing.T) { tmpDir, err := os.MkdirTemp("", projectName) assert.NilError(t, err) - defer os.RemoveAll(tmpDir) // nolint + defer os.RemoveAll(tmpDir) //nolint c.RunDockerComposeCmd(t, "--project-name", projectName, "down") diff --git a/pkg/progress/event.go b/pkg/progress/event.go index 5a013a8b16..0ead54dd41 100644 --- a/pkg/progress/event.go +++ b/pkg/progress/event.go @@ -44,99 +44,99 @@ type Event struct { } // ErrorMessageEvent creates a new Error Event with message -func ErrorMessageEvent(ID string, msg string) Event { - return NewEvent(ID, Error, msg) +func ErrorMessageEvent(id string, msg string) Event { + return NewEvent(id, Error, msg) } // ErrorEvent creates a new Error Event -func ErrorEvent(ID string) Event { - return NewEvent(ID, Error, "Error") +func ErrorEvent(id string) Event { + return NewEvent(id, Error, "Error") } // CreatingEvent creates a new Create in progress Event -func CreatingEvent(ID string) Event { - return NewEvent(ID, Working, "Creating") +func CreatingEvent(id string) Event { + return NewEvent(id, Working, "Creating") } // StartingEvent creates a new Starting in progress Event -func StartingEvent(ID string) Event { - return NewEvent(ID, Working, "Starting") +func StartingEvent(id string) Event { + return NewEvent(id, Working, "Starting") } // StartedEvent creates a new Started in progress Event -func StartedEvent(ID string) Event { - return NewEvent(ID, Done, "Started") +func StartedEvent(id string) Event { + return NewEvent(id, Done, "Started") } // Waiting creates a new waiting event -func Waiting(ID string) Event { - return NewEvent(ID, Working, "Waiting") +func Waiting(id string) Event { + return NewEvent(id, Working, "Waiting") } // Healthy creates a new healthy event -func Healthy(ID string) Event { - return NewEvent(ID, Done, "Healthy") +func Healthy(id string) Event { + return NewEvent(id, Done, "Healthy") } // Exited creates a new exited event -func Exited(ID string) Event { - return NewEvent(ID, Done, "Exited") +func Exited(id string) Event { + return NewEvent(id, Done, "Exited") } // RestartingEvent creates a new Restarting in progress Event -func RestartingEvent(ID string) Event { - return NewEvent(ID, Working, "Restarting") +func RestartingEvent(id string) Event { + return NewEvent(id, Working, "Restarting") } // RestartedEvent creates a new Restarted in progress Event -func RestartedEvent(ID string) Event { - return NewEvent(ID, Done, "Restarted") +func RestartedEvent(id string) Event { + return NewEvent(id, Done, "Restarted") } // RunningEvent creates a new Running in progress Event -func RunningEvent(ID string) Event { - return NewEvent(ID, Done, "Running") +func RunningEvent(id string) Event { + return NewEvent(id, Done, "Running") } // CreatedEvent creates a new Created (done) Event -func CreatedEvent(ID string) Event { - return NewEvent(ID, Done, "Created") +func CreatedEvent(id string) Event { + return NewEvent(id, Done, "Created") } // StoppingEvent creates a new Stopping in progress Event -func StoppingEvent(ID string) Event { - return NewEvent(ID, Working, "Stopping") +func StoppingEvent(id string) Event { + return NewEvent(id, Working, "Stopping") } // StoppedEvent creates a new Stopping in progress Event -func StoppedEvent(ID string) Event { - return NewEvent(ID, Done, "Stopped") +func StoppedEvent(id string) Event { + return NewEvent(id, Done, "Stopped") } // KillingEvent creates a new Killing in progress Event -func KillingEvent(ID string) Event { - return NewEvent(ID, Working, "Killing") +func KillingEvent(id string) Event { + return NewEvent(id, Working, "Killing") } // KilledEvent creates a new Killed in progress Event -func KilledEvent(ID string) Event { - return NewEvent(ID, Done, "Killed") +func KilledEvent(id string) Event { + return NewEvent(id, Done, "Killed") } // RemovingEvent creates a new Removing in progress Event -func RemovingEvent(ID string) Event { - return NewEvent(ID, Working, "Removing") +func RemovingEvent(id string) Event { + return NewEvent(id, Working, "Removing") } // RemovedEvent creates a new removed (done) Event -func RemovedEvent(ID string) Event { - return NewEvent(ID, Done, "Removed") +func RemovedEvent(id string) Event { + return NewEvent(id, Done, "Removed") } // NewEvent new event -func NewEvent(ID string, status EventStatus, statusText string) Event { +func NewEvent(id string, status EventStatus, statusText string) Event { return Event{ - ID: ID, + ID: id, Status: status, StatusText: statusText, } diff --git a/pkg/progress/tty.go b/pkg/progress/tty.go index a94d659dde..0dc95b906e 100644 --- a/pkg/progress/tty.go +++ b/pkg/progress/tty.go @@ -164,14 +164,14 @@ func (w *ttyWriter) print() { continue } line := lineText(event, "", terminalWidth, statusPadding, runtime.GOOS != "windows") - // nolint: errcheck + //nolint: errcheck fmt.Fprint(w.out, line) numLines++ for _, v := range w.eventIDs { ev := w.events[v] if ev.ParentID == event.ID { line := lineText(ev, " ", terminalWidth, statusPadding, runtime.GOOS != "windows") - // nolint: errcheck + //nolint: errcheck fmt.Fprint(w.out, line) numLines++ }