Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bake: Add a built-in function for running shell commands and scripts. #2776

Open
shaj13 opened this issue Nov 3, 2024 · 1 comment
Open
Assignees
Labels
kind/enhancement New feature or request status/triage

Comments

@shaj13
Copy link

shaj13 commented Nov 3, 2024

Description

Issue

Bake quickly becomes a preferred solution for running CI/CD and local tasks. However, sometimes, we need to run a pre-task, like fetching the current Git commit reference or setting up custom environment variables. Currently, Bake doesn’t offer a built-in way to handle these tasks, making it difficult to gather this information on the fly. As a result, users have to rely on external tools or scripts to complete setup tasks.

Proposal

The goal of this proposal is to add a built-in function to run shell commands and scripts. This feature would let users handle tasks like setting up variables/gathering info without needing extra tools like Makefile and keeping workflows in one place.

To address this, I propose adding a new built-in function to the hclparser stdlib. This function would be similar to other built-ins in stdlib.go and would leverage "github.com/mvdan/sh" to execute shell commands.

func shellFunc() function.Function {
	return function.New(&function.Spec{
		Params: []function.Parameter{
			{
				Name: "script",
				Type: cty.String,
			},
		},
		Type: function.StaticReturnType(cty.String),
		Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
			script := args[0].AsString()

			var buf bytes.Buffer

                        	r, err := interp.New(
                          		interp.Env(expand.ListEnviron(os.Environ()...)),
                          		interp.ExecHandlers(func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc {
                          			return interp.DefaultExecHandler(10 * time.Second)
                          		}),
                          		interp.StdIO(nil, &buf, &buf),
                          		interp.Dir(s.Dir),
                	)
                
                	if err != nil {
                		return err
                	}
                
                	parser := syntax.NewParser()
                       p, err := parser.Parse(strings.NewReader(script), "")
                	if err != nil {
                		return err
                	}

			if err := r.Run(ctx, p); err != nil {
				return cty.NilVal, fmt.Errorf("%w:%s", err, buf.String())
			}

			return cty.StringVal(buf.String()), nil
		},
	})
}
target "default" {
  output = ["type=image,name=foo"]
  annotations = [shell("git log --pretty=format:'%h' -n 1")]
}
@shaj13 shaj13 added kind/enhancement New feature or request status/triage labels Nov 3, 2024
@halvorstein
Copy link

As for today, we are using a Taskfile wrapper in order to achieve the variables settings.
This feature will render a lot of the external tools redundant for us and will improve our codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request status/triage
Projects
None yet
Development

No branches or pull requests

4 participants