containerd / nerdctl

contaiNERD CTL - Docker-compatible CLI for containerd, with support for Compose, Rootless, eStargz, OCIcrypt, IPFS, ...
Apache License 2.0
7.71k stars 574 forks source link

completion: let `nerdctl build --target <TAB>` show Dockerfile stage names #566

Open AkihiroSuda opened 2 years ago

AkihiroSuda commented 2 years ago

https://github.com/docker/cli/blob/9bc104eff0798097954f5d9bc25ca93f892e63f5/contrib/completion/bash/docker#L2929-L2941

Docker uses sed, but we can probably use real Dockerfile parser package https://pkg.go.dev/github.com/moby/buildkit/frontend/dockerfile/parser#Parse

djdongjin commented 1 year ago

I did a try on this but encountered a wired go mod tidy issue while importing buildkit 🤔 (specifically, "github.com/moby/buildkit/frontend/dockerfile/instructions"

➜  nerdctl git:(build-stage-complete) ✗ go mod tidy
go: finding module for package github.com/docker/libnetwork/ipamutils
go: found github.com/docker/libnetwork/ipamutils in github.com/docker/libnetwork v0.5.6
go: finding module for package github.com/Sirupsen/logrus
go: found github.com/Sirupsen/logrus in github.com/Sirupsen/logrus v1.9.0
go: github.com/containerd/nerdctl/cmd/nerdctl imports
        github.com/moby/buildkit/frontend/dockerfile/instructions imports
        github.com/docker/docker/opts imports
        github.com/docker/libnetwork/ipamutils imports
        github.com/docker/libnetwork/osl imports
        github.com/Sirupsen/logrus: github.com/Sirupsen/logrus@v1.9.0: parsing go.mod:
        module declares its path as: github.com/sirupsen/logrus
                but was required as: github.com/Sirupsen/logrus

The change is not much

// https://github.com/containerd/nerdctl/blob/7dfbaa2122628921febeb097e7a8a86074dc931d/cmd/nerdctl/completion.go
func shellCompleteDockerfile(cmd *cobra.Command) ([]string, cobra.ShellCompDirective) {
    filename := buildkitutil.DefaultDockerfileName
    if df, err := cmd.Flags().GetString("file"); err == nil && df != "" {
        filename = df
    }

    df, err := os.ReadFile(filename)
    if err != nil {
        return nil, cobra.ShellCompDirectiveError
    }
    ast, err := parser.Parse(bytes.NewBuffer(df))
    stages, _, err := instructions.Parse(ast.AST)

    candidates := []string{}
    for _, stage := range stages {
        candidates = append(candidates, stage.Name)
    }

    return nil, cobra.ShellCompDirectiveNoFileComp
}

Will visit this later.

yuchanns commented 1 year ago

I did a try on this but encountered a wired go mod tidy issue while importing buildkit 🤔 (specifically, "github.com/moby/buildkit/frontend/dockerfile/instructions"

FYI https://github.com/sirupsen/logrus/issues/1041