This commit is contained in:
Shreyas Goenka 2025-03-03 19:19:39 +01:00
parent 05cd18c0be
commit a2748d531b
No known key found for this signature in database
GPG Key ID: 92A07DF49CCB0622
3 changed files with 35 additions and 10 deletions

View File

@ -12,3 +12,6 @@ hello, world
Error: Running "bash -c exit 5" failed with exit code: 5 Error: Running "bash -c exit 5" failed with exit code: 5
Exit code: 1 Exit code: 1
>>> [CLI] bundle exec -- bash -c echo hello > /dev/stderr
hello

View File

@ -6,4 +6,7 @@ trace $CLI bundle exec -- pwd
trace $CLI bundle exec -- echo --help trace $CLI bundle exec -- echo --help
# The error message should include the exit code. # The error message should include the exit code.
trace $CLI bundle exec -- bash -c "exit 5" errcode trace $CLI bundle exec -- bash -c "exit 5"
# stderr should also be shown in the output.
trace $CLI bundle exec -- bash -c "echo hello > /dev/stderr"

View File

@ -27,11 +27,12 @@ func newExecCommand() *cobra.Command {
Use: "exec", Use: "exec",
Short: "Execute a command using the same authentication context as the bundle", Short: "Execute a command using the same authentication context as the bundle",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
// TODO: format once we have all the documentation here. Long: `Execute a command using the same authentication context as the bundle
Long: `
Note: This command executes scripts
Examples: The current working directory of the provided command will be set to the root
of the bundle.
Example usage:
1. databricks bundle exec -- echo hello 1. databricks bundle exec -- echo hello
2. databricks bundle exec -- /bin/bash -c "echo hello"" 2. databricks bundle exec -- /bin/bash -c "echo hello""
3. databricks bundle exec -- uv run pytest"`, 3. databricks bundle exec -- uv run pytest"`,
@ -81,8 +82,8 @@ Examples:
// adding support for the scripts section. // adding support for the scripts section.
childCmd.Dir = b.BundleRootPath childCmd.Dir = b.BundleRootPath
// Create pipes for stdout and stderr. // Create pipes to stream the stdout and stderr output from the child
// TODO: Test streaming of this? Is there a way? // process.
stdout, err := childCmd.StdoutPipe() stdout, err := childCmd.StdoutPipe()
if err != nil { if err != nil {
return fmt.Errorf("Error creating stdout pipe: %w", err) return fmt.Errorf("Error creating stdout pipe: %w", err)
@ -98,15 +99,21 @@ Examples:
return fmt.Errorf("Error starting command: %s\n", err) return fmt.Errorf("Error starting command: %s\n", err)
} }
// Stream both stdout and stderr to the user. // Stream both stdout and stderr to the user. We do this so that the user
// does not have to wait for the command to finish before seeing the output.
var wg sync.WaitGroup var wg sync.WaitGroup
var stdoutErr, stderrErr error
wg.Add(2) wg.Add(2)
go func() { go func() {
defer wg.Done() defer wg.Done()
scanner := bufio.NewScanner(stdout) scanner := bufio.NewScanner(stdout)
for scanner.Scan() { for scanner.Scan() {
fmt.Println(scanner.Text()) _, err = cmd.OutOrStdout().Write([]byte(scanner.Text() + "\n"))
if err != nil {
stdoutErr = fmt.Errorf("Error writing to stdout: %w", err)
return
}
} }
}() }()
@ -114,10 +121,22 @@ Examples:
defer wg.Done() defer wg.Done()
scanner := bufio.NewScanner(stderr) scanner := bufio.NewScanner(stderr)
for scanner.Scan() { for scanner.Scan() {
fmt.Println(scanner.Text()) _, err := cmd.ErrOrStderr().Write([]byte(scanner.Text() + "\n"))
if err != nil {
stderrErr = fmt.Errorf("Error writing to stderr: %w", err)
return
}
} }
}() }()
if stdoutErr != nil {
return stdoutErr
}
if stderrErr != nil {
return stderrErr
}
// Wait for the command to finish. // Wait for the command to finish.
err = childCmd.Wait() err = childCmd.Wait()
if exitErr, ok := err.(*exec.ExitError); ok { if exitErr, ok := err.(*exec.ExitError); ok {