princjef / mageutil

Set of utilities to make working with the mage build system more seamless
MIT License
8 stars 3 forks source link

Add option to customize the exec.Cmd #5

Open mszostok opened 3 years ago

mszostok commented 3 years ago

Hi! First of all, thanks for sharing your pkg. The bintool is awesome 👍

I started to use it, and had to adjust it a bit to fit into my use-cases. If you would like to I can contribute my change to your pkg :)

Description

Add option to customize the exec.Cmd

Reason

Currently, it's not possible to easily customize the shellcmd.Command behaviour. Some customization was added here: https://github.com/princjef/mageutil/pull/3 but it's not extensible.

Use cases

Execute command in a different directory with default environment variables, see:

return shellcmd.Command(`go test -v -tags=integration ./integration/...`).Run(
    shellcmd.WithDir("./tests"),
    shellcmd.WithEnv("BINARY_PATH", "./bin/gimme"),
    shellcmd.WithEnv("REPO_PATH", "."),
)

Currently I cannot change the dir at all, as for env variable it's possible but with defaults it's not so readable and always requires fmt.Sprintf if the value is not know upfront:

func getEnvKey(name, def string) string {
    val := os.Getenv(name)
    if val != "" {
        return fmt.Sprintf("%s=%v", name, val)
    }
    return fmt.Sprintf("%s=%v", name, def)
}

func Test() error {
    var (
        binPathEnv  = getEnvKey("BINARY_PATH", "./bin/gimme")
        repoPathEnv = getEnvKey("UPDATE_GOLDEN_FILES", "false")
    )

    return shellcmd.Command(fmt.Sprintf(`%s %s go test -v -tags=integration ./tests/integration/...`, binPathEnv, repoPathEnv)).Run()
}

Proposed solution

Here: https://github.com/princjef/mageutil/pull/6 I submitted draft PR to show how it can be done using the functional options pattern. In that way it's easy to change the behaviour only if necessary.

Unfortunately the shellcmd.Command is string alias, so we cannot attach additional data to it. As a result, I had to do it in Run method.