package command import ( "context" "io" "gitlab.com/gitlab-org/gitaly/v16/internal/cgroups" ) type config struct { stdin io.Reader stdout io.Writer stderr io.Writer dir string environment []string finalizers []func(context.Context, *Command) commandName string subcommandName string gitVersion string cgroupsManager cgroups.Manager cgroupsAddCommandOpts []cgroups.AddCommandOption } // Option is an option that can be passed to `New()` for controlling how the command is being // created. type Option func(cfg *config) // WithStdin sets up the command to read from the given reader. func WithStdin(stdin io.Reader) Option { return func(cfg *config) { cfg.stdin = stdin } } // WithSetupStdin instructs New() to configure the stdin pipe of the command it is creating. This // allows you call Write() on the command as if it is an ordinary io.Writer, sending data directly // to the stdin of the process. func WithSetupStdin() Option { return func(cfg *config) { cfg.stdin = stdinSentinel{} } } // WithStdout sets up the command to write standard output to the given writer. func WithStdout(stdout io.Writer) Option { return func(cfg *config) { cfg.stdout = stdout } } // WithStderr sets up the command to write standard error to the given writer. func WithStderr(stderr io.Writer) Option { return func(cfg *config) { cfg.stderr = stderr } } // WithDir will set up the command to be ran in the specific directory. func WithDir(dir string) Option { return func(cfg *config) { cfg.dir = dir } } // WithEnvironment sets up environment variables that shall be set for the command. func WithEnvironment(environment []string) Option { return func(cfg *config) { cfg.environment = environment } } // WithCommandName overrides the "cmd" and "subcmd" label used in metrics. func WithCommandName(commandName, subcommandName string) Option { return func(cfg *config) { cfg.commandName = commandName cfg.subcommandName = subcommandName } } // WithCommandGitVersion overrides the "git_version" label used in metrics. func WithCommandGitVersion(gitCmdVersion string) Option { return func(cfg *config) { cfg.gitVersion = gitCmdVersion } } // WithCgroup adds the spawned command to a Cgroup. The bucket used will be derived from the // command's arguments and/or from the repository. func WithCgroup(cgroupsManager cgroups.Manager, opts ...cgroups.AddCommandOption) Option { return func(cfg *config) { cfg.cgroupsManager = cgroupsManager cfg.cgroupsAddCommandOpts = opts } } // WithFinalizer sets up the finalizer to be run when the command is being wrapped up. It will be // called after `Wait()` has returned. func WithFinalizer(finalizer func(context.Context, *Command)) Option { return func(cfg *config) { cfg.finalizers = append(cfg.finalizers, finalizer) } }