Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
86 lines
2 KiB
Go
86 lines
2 KiB
Go
// Package exec provides easy access to command execution for basic uses.
|
|
package exec
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner"
|
|
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
|
|
"github.com/ignite/cli/v29/ignite/pkg/errors"
|
|
)
|
|
|
|
// ExitError is an alias to exec.ExitError.
|
|
type ExitError = exec.ExitError
|
|
|
|
type execConfig struct {
|
|
stepOptions []step.Option
|
|
includeStdLogsToError bool
|
|
}
|
|
|
|
type Option func(*execConfig)
|
|
|
|
func StepOption(o step.Option) Option {
|
|
return func(c *execConfig) {
|
|
c.stepOptions = append(c.stepOptions, o)
|
|
}
|
|
}
|
|
|
|
func IncludeStdLogsToError() Option {
|
|
return func(c *execConfig) {
|
|
c.includeStdLogsToError = true
|
|
}
|
|
}
|
|
|
|
// Exec executes a command with args, it's a shortcut func for basic command executions.
|
|
func Exec(ctx context.Context, fullCommand []string, options ...Option) error {
|
|
errb := &bytes.Buffer{}
|
|
logs := &bytes.Buffer{}
|
|
|
|
c := &execConfig{
|
|
stepOptions: []step.Option{
|
|
step.Exec(fullCommand[0], fullCommand[1:]...),
|
|
step.Stdout(logs),
|
|
step.Stderr(errb),
|
|
},
|
|
}
|
|
|
|
for _, apply := range options {
|
|
apply(c)
|
|
}
|
|
|
|
err := cmdrunner.New().Run(ctx, step.New(c.stepOptions...))
|
|
if err != nil {
|
|
return &Error{
|
|
Err: errors.Wrap(err, errb.String()),
|
|
Command: strings.Join(fullCommand, " "),
|
|
StdLogs: logs.String(),
|
|
includeStdLogsToError: c.includeStdLogsToError,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Error provides detailed errors from the executed program.
|
|
type Error struct {
|
|
Err error
|
|
Command string
|
|
StdLogs string // collected logs from code generation tools.
|
|
includeStdLogsToError bool
|
|
}
|
|
|
|
func (e *Error) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
message := fmt.Sprintf("error while running command %s: %s", e.Command, e.Err.Error())
|
|
if e.includeStdLogsToError && strings.TrimSpace(e.StdLogs) != "" {
|
|
return fmt.Sprintf("%s\n\n%s", message, e.StdLogs)
|
|
}
|
|
return message
|
|
}
|