diff --git a/internal/captain/command.go b/internal/captain/command.go index 2bf59ee8a6..60ed7c1555 100644 --- a/internal/captain/command.go +++ b/internal/captain/command.go @@ -699,7 +699,7 @@ func (c *Command) cobraExecHandler(cobraCmd *cobra.Command, args []string) (rerr } if err := c.execute(c, args); err != nil { - if !locale.IsError(err) { + if !locale.HasError(err) { return locale.WrapError(err, "unexpected_error", "Command failed due to unexpected error. For your convenience, this is the error chain:\n{{.V0}}", errs.JoinMessage(err)) } return errs.Wrap(err, "execute failed") diff --git a/internal/constraints/constraints.go b/internal/constraints/constraints.go index d3ea9394e6..503f8331f5 100644 --- a/internal/constraints/constraints.go +++ b/internal/constraints/constraints.go @@ -123,7 +123,7 @@ func (c *Conditional) RegisterParam(name string, value interface{}) { } func (c *Conditional) Eval(conditional string) (bool, error) { - tpl, err := template.New("letter").Funcs(c.funcs).Parse(fmt.Sprintf(`{{if %s}}1{{end}}`, conditional)) + tpl, err := template.New("").Funcs(c.funcs).Parse(fmt.Sprintf(`{{if %s}}1{{end}}`, conditional)) if err != nil { return false, locale.WrapInputError(err, "err_conditional", "Invalid 'if' condition: '{{.V0}}', error: '{{.V1}}'.", conditional, err.Error()) } @@ -154,7 +154,7 @@ func FilterUnconstrained(conditional *Conditional, items []projectfile.Constrain if conditional != nil && item.ConditionalFilter() != "" { isTrue, err := conditional.Eval(string(item.ConditionalFilter())) if err != nil { - return nil, err + return nil, locale.WrapInputError(err, "err_conditional_eval", "There was an error with the conditional in your activestate.yaml's '{{.V0}}' script", item.ID()) } if isTrue { diff --git a/internal/events/cmdcall/cmdcall.go b/internal/events/cmdcall/cmdcall.go index 1c27f7f04c..bea194ac0d 100644 --- a/internal/events/cmdcall/cmdcall.go +++ b/internal/events/cmdcall/cmdcall.go @@ -3,6 +3,7 @@ package cmdcall import ( "strings" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" @@ -100,7 +101,11 @@ func (cc *CmdCall) Run(eventType project.EventType) error { } scriptName, scriptArgs := ss[0], ss[1:] - if err := cc.scriptrun.Run(cc.proj.ScriptByName(scriptName), scriptArgs); err != nil { + script, err := cc.proj.ScriptByName(scriptName) + if err != nil { + return errs.Wrap(err, "Could not get script") + } + if err := cc.scriptrun.Run(script, scriptArgs); err != nil { return locale.WrapError( err, "cmdcall_event_err_script_run", "Failure running defined script '[NOTICE]{{.V0}}[/RESET]' for event '[NOTICE]{{.V1}}[/RESET]'", diff --git a/internal/runners/export/ghactions/ghactions.go b/internal/runners/export/ghactions/ghactions.go index 379f6b15b9..5fafa10013 100644 --- a/internal/runners/export/ghactions/ghactions.go +++ b/internal/runners/export/ghactions/ghactions.go @@ -3,6 +3,7 @@ package ghactions import ( "gopkg.in/yaml.v2" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/primer" @@ -61,7 +62,11 @@ func (g *GithubActions) Run(p *Params) error { } workflowJob.Env[constant.Name()] = v } - for _, script := range job.Scripts() { + scripts, err := job.Scripts() + if err != nil { + return errs.Wrap(err, "Could not get scripts") + } + for _, script := range scripts { workflowJob.Steps = append(workflowJob.Steps, WorkflowStep{ Name: script.Name(), Run: "state run " + script.Name(), diff --git a/internal/runners/run/run.go b/internal/runners/run/run.go index 1ab8fa949f..5444b1824b 100644 --- a/internal/runners/run/run.go +++ b/internal/runners/run/run.go @@ -5,6 +5,7 @@ import ( "github.com/ActiveState/cli/internal/analytics" "github.com/ActiveState/cli/internal/config" + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/language" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" @@ -73,7 +74,10 @@ func (r *Run) Run(name string, args []string) error { checker.RunCommitsBehindNotifier(r.proj, r.out, r.auth) } - script := r.proj.ScriptByName(name) + script, err := r.proj.ScriptByName(name) + if err != nil { + return errs.Wrap(err, "Could not get script") + } if script == nil { return locale.NewInputError("error_state_run_unknown_name", "", name) } diff --git a/internal/runners/scripts/edit.go b/internal/runners/scripts/edit.go index 7777de43e0..fa34bc2ce6 100644 --- a/internal/runners/scripts/edit.go +++ b/internal/runners/scripts/edit.go @@ -57,12 +57,15 @@ func (e *Edit) Run(params *EditParams) error { return rationalize.ErrNoProject } - script := e.project.ScriptByName(params.Name) + script, err := e.project.ScriptByName(params.Name) + if err != nil { + return errs.Wrap(err, "Could not get script") + } if script == nil { return locale.NewInputError("edit_scripts_no_name", "Could not find script with the given name {{.V0}}", params.Name) } - err := e.editScript(script, params) + err = e.editScript(script, params) if err != nil { return locale.WrapError(err, "error_edit_script", "Failed to edit script.") } @@ -259,7 +262,10 @@ func updateProjectFile(cfg projectfile.ConfigGetter, pj *project.Project, script } pjf := pj.Source() - script := pj.ScriptByName(name) + script, err := pj.ScriptByName(name) + if err != nil { + return errs.Wrap(err, "Could not get script") + } if script == nil { return locale.NewError("err_update_script_cannot_find", "Could not find the source script to update.") } diff --git a/internal/runners/scripts/edit_test.go b/internal/runners/scripts/edit_test.go index 1b4683984c..f55f8f6b3d 100644 --- a/internal/runners/scripts/edit_test.go +++ b/internal/runners/scripts/edit_test.go @@ -76,17 +76,17 @@ func (suite *EditTestSuite) AfterTest(suiteName, testName string) { } func (suite *EditTestSuite) TestCreateScriptFile() { - script := suite.project.ScriptByName("hello") + script, err := suite.project.ScriptByName("hello") + suite.Require().NoError(err) - var err error suite.scriptFile, err = createScriptFile(script, false) suite.Require().NoError(err, "should create file") } func (suite *EditTestSuite) TestCreateScriptFile_Expand() { - script := suite.project.ScriptByName("hello-constant") + script, err := suite.project.ScriptByName("hello-constant") + suite.Require().NoError(err) - var err error suite.scriptFile, err = createScriptFile(script, true) suite.Require().NoError(err, "should create file") @@ -98,9 +98,9 @@ func (suite *EditTestSuite) TestCreateScriptFile_Expand() { } func (suite *EditTestSuite) TestNewScriptWatcher() { - script := suite.project.ScriptByName("hello") + script, err := suite.project.ScriptByName("hello") + suite.Require().NoError(err) - var err error suite.scriptFile, err = createScriptFile(script, false) suite.Require().NoError(err, "should create file") @@ -123,9 +123,9 @@ func (suite *EditTestSuite) TestNewScriptWatcher() { } func (suite *EditTestSuite) TestUpdateProjectFile() { - replace := suite.project.ScriptByName("replace") + replace, err := suite.project.ScriptByName("replace") + suite.Require().NoError(err) - var err error suite.scriptFile, err = createScriptFile(replace, false) suite.Require().NoError(err, "unexpected error creating script file") @@ -138,7 +138,9 @@ func (suite *EditTestSuite) TestUpdateProjectFile() { suite.Require().NoError(err, "unexpected error getting project") v1, err := replace.Value() suite.Require().NoError(err) - v2, err := updatedProject.ScriptByName("replace").Value() + script, err := updatedProject.ScriptByName("replace") + suite.Require().NoError(err) + v2, err := script.Value() suite.Require().NoError(err) suite.Equal(v1, v2) } diff --git a/internal/runners/scripts/scripts.go b/internal/runners/scripts/scripts.go index 08b3e44fc9..48efc8e9e2 100644 --- a/internal/runners/scripts/scripts.go +++ b/internal/runners/scripts/scripts.go @@ -1,6 +1,7 @@ package scripts import ( + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/locale" "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/output" @@ -44,8 +45,12 @@ func (s *Scripts) Run() error { name, owner := s.project.Name(), s.project.Owner() logging.Debug("listing scripts for org=%s, project=%s", owner, name) - scripts := make([]scriptLine, len(s.project.Scripts())) - for i, s := range s.project.Scripts() { + projectScripts, err := s.project.Scripts() + if err != nil { + return errs.Wrap(err, "Could not get scripts") + } + scripts := make([]scriptLine, len(projectScripts)) + for i, s := range projectScripts { scripts[i] = scriptLine{s.Name(), s.Description()} } diff --git a/internal/scriptrun/test/integration/scriptrun_test.go b/internal/scriptrun/test/integration/scriptrun_test.go index bb3f9051b6..468e72cebe 100644 --- a/internal/scriptrun/test/integration/scriptrun_test.go +++ b/internal/scriptrun/test/integration/scriptrun_test.go @@ -77,7 +77,9 @@ scripts: require.NoError(t, err) defer func() { require.NoError(t, cfg.Close()) }() scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) - err = scriptRun.Run(proj.ScriptByName("run"), []string{}) + script, err := proj.ScriptByName("run") + require.NoError(t, err) + err = scriptRun.Run(script, []string{}) assert.NoError(t, err, "No error occurred") } @@ -119,7 +121,9 @@ func (suite *ScriptRunSuite) TestEnvIsSet() { out := capturer.CaptureOutput(func() { scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) - err = scriptRun.Run(proj.ScriptByName("run"), nil) + script, err := proj.ScriptByName("run") + require.NoError(t, err, "Error: "+errs.JoinMessage(err)) + err = scriptRun.Run(script, nil) assert.NoError(t, err, "Error: "+errs.JoinMessage(err)) }) @@ -166,8 +170,10 @@ scripts: out := outputhelper.NewCatcher() scriptRun := scriptrun.New(auth, out, subshell.New(cfg), proj, cfg, blackhole.New(), nil) - fmt.Println(proj.ScriptByName("run")) - err = scriptRun.Run(proj.ScriptByName("run"), nil) + script, err := proj.ScriptByName("run") + fmt.Println(script) + require.NoError(t, err) + err = scriptRun.Run(script, nil) assert.NoError(t, err, "No error occurred") } @@ -198,7 +204,7 @@ scripts: scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) err = scriptRun.Run(nil, nil) - assert.Error(t, err, "Error occurred") + assert.Error(t, err, "No error occurred") } func (suite *ScriptRunSuite) TestRunUnknownCommand() { @@ -228,8 +234,10 @@ scripts: defer func() { require.NoError(t, cfg.Close()) }() scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) - err = scriptRun.Run(proj.ScriptByName("run"), nil) - assert.Error(t, err, "Error occurred") + script, err := proj.ScriptByName("run") + require.NoError(t, err) + err = scriptRun.Run(script, nil) + assert.Error(t, err, "No error occurred") } func (suite *ScriptRunSuite) TestRunActivatedCommand() { @@ -282,7 +290,9 @@ scripts: // Run the command. scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) - err = scriptRun.Run(proj.ScriptByName("run"), nil) + script, err := proj.ScriptByName("run") + require.NoError(t, err) + err = scriptRun.Run(script, nil) assert.NoError(t, err, "No error occurred") // Reset. @@ -378,7 +388,10 @@ func captureExecCommand(t *testing.T, tmplCmdName, cmdName string, cmdArgs []str outStr, outErr := osutil.CaptureStdout(func() { scriptRun := scriptrun.New(auth, outputhelper.NewCatcher(), subshell.New(cfg), proj, cfg, blackhole.New(), nil) - err = scriptRun.Run(proj.ScriptByName(cmdName), cmdArgs) + var script *project.Script + if script, err = proj.ScriptByName(cmdName); err == nil { + err = scriptRun.Run(script, cmdArgs) + } }) require.NoError(t, outErr, "error capturing stdout") diff --git a/internal/subshell/sscommon/rcfile.go b/internal/subshell/sscommon/rcfile.go index b357175365..14c2c1eef0 100644 --- a/internal/subshell/sscommon/rcfile.go +++ b/internal/subshell/sscommon/rcfile.go @@ -286,7 +286,11 @@ func SetupProjectRcFile(prj *project.Project, templateName, ext string, env map[ globalBinDir := filepath.Clean(storage.GlobalBinDir()) // Prepare script map to be parsed by template - for _, cmd := range prj.Scripts() { + projectScripts, err := prj.Scripts() + if err != nil { + return nil, errs.Wrap(err, "Could not get project scripts") + } + for _, cmd := range projectScripts { explicitName = fmt.Sprintf("%s_%s", prj.NormalizedName(), cmd.Name()) path, err := exec.LookPath(cmd.Name()) diff --git a/pkg/project/expander.go b/pkg/project/expander.go index 848abc6145..49218e912b 100644 --- a/pkg/project/expander.go +++ b/pkg/project/expander.go @@ -126,7 +126,10 @@ func EventExpander(_ string, name string, meta string, isFunction bool, ctx *Exp // ScriptExpander expands scripts defined in the project-file. func ScriptExpander(_ string, name string, meta string, isFunction bool, ctx *Expansion) (string, error) { - script := ctx.Project.ScriptByName(name) + script, err := ctx.Project.ScriptByName(name) + if err != nil { + return "", errs.Wrap(err, "Could not get script") + } if script == nil { return "", nil } diff --git a/pkg/project/expander_test.go b/pkg/project/expander_test.go index 63d2323670..2c0d5a3401 100644 --- a/pkg/project/expander_test.go +++ b/pkg/project/expander_test.go @@ -230,7 +230,8 @@ func TestExpandScriptPathRecursive(t *testing.T) { func TestExpandBashScriptPath(t *testing.T) { prj := loadProject(t) - script := prj.ScriptByName("bashScriptPath") + script, err := prj.ScriptByName("bashScriptPath") + require.NoError(t, err) require.NotNil(t, script, "bashScriptPath script does not exist") value, err := script.Value() require.NoError(t, err) diff --git a/pkg/project/project.go b/pkg/project/project.go index 3c0b1c0b90..850718295c 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -141,27 +141,31 @@ func (p *Project) EventByName(name string, bashifyPaths bool) *Event { } // Scripts returns a reference to projectfile.Scripts -func (p *Project) Scripts() []*Script { +func (p *Project) Scripts() ([]*Script, error) { constrained, err := constraints.FilterUnconstrained(pConditional, p.projectfile.Scripts.AsConstrainedEntities()) if err != nil { - logging.Warning("Could not filter unconstrained scripts: %v", err) + return nil, errs.Wrap(err, "Could not filter unconstrained scripts") } scs := projectfile.MakeScriptsFromConstrainedEntities(constrained) scripts := make([]*Script, 0, len(scs)) for _, s := range scs { scripts = append(scripts, &Script{s, p}) } - return scripts + return scripts, nil } // ScriptByName returns a reference to a projectfile.Script with a given name. -func (p *Project) ScriptByName(name string) *Script { - for _, script := range p.Scripts() { +func (p *Project) ScriptByName(name string) (*Script, error) { + scripts, err := p.Scripts() + if err != nil { + return nil, errs.Wrap(err, "Could not get scripts") + } + for _, script := range scripts { if script.Name() == name { - return script + return script, nil } } - return nil + return nil, nil } // Jobs returns a reference to projectfile.Jobs @@ -589,12 +593,16 @@ func (j *Job) Constants() []*Constant { return constants } -func (j *Job) Scripts() []*Script { +func (j *Job) Scripts() ([]*Script, error) { scripts := []*Script{} for _, scriptName := range j.job.Scripts { - if script := j.project.ScriptByName(scriptName); script != nil { + script, err := j.project.ScriptByName(scriptName) + if err != nil { + return nil, errs.Wrap(err, "Could not get script") + } + if script != nil { scripts = append(scripts, script) } } - return scripts + return scripts, nil } diff --git a/pkg/project/project_test.go b/pkg/project/project_test.go index 1bb167469a..6755eb3314 100644 --- a/pkg/project/project_test.go +++ b/pkg/project/project_test.go @@ -123,7 +123,8 @@ func (suite *ProjectTestSuite) TestEventByName() { } func (suite *ProjectTestSuite) TestScripts() { - scripts := suite.project.Scripts() + scripts, err := suite.project.Scripts() + suite.Require().NoError(err) var name string switch runtime.GOOS { case "linux": @@ -153,11 +154,13 @@ func (suite *ProjectTestSuite) TestScripts() { } func (suite *ProjectTestSuite) TestScriptByName() { - script := suite.project.ScriptByName("noop") + script, err := suite.project.ScriptByName("noop") + suite.Require().NoError(err) suite.Nil(script) if runtime.GOOS == "linux" { - script = suite.project.ScriptByName("foo") + script, err = suite.project.ScriptByName("foo") + suite.Require().NoError(err) suite.Require().NotNil(script) suite.Equal("foo", script.Name(), "Names should match (Linux)") v, err := script.Value() @@ -165,7 +168,8 @@ func (suite *ProjectTestSuite) TestScriptByName() { suite.Equal("foo project", v, "Value should match (Linux)") suite.True(script.Standalone(), "Standalone value should match (Linux)") } else if runtime.GOOS == "windows" { - script = suite.project.ScriptByName("bar") + script, err = suite.project.ScriptByName("bar") + suite.Require().NoError(err) suite.Require().NotNil(script) suite.Equal("bar", script.Name(), "Name should match (Windows)") v, err := script.Value() @@ -173,7 +177,8 @@ func (suite *ProjectTestSuite) TestScriptByName() { suite.Equal("bar project", v, "Value should match (Windows)") suite.True(script.Standalone(), "Standalone value should match (Windows)") } else if runtime.GOOS == "darwin" { - script = suite.project.ScriptByName("baz") + script, err = suite.project.ScriptByName("baz") + suite.Require().NoError(err) suite.Require().NotNil(script) suite.Equal("baz", script.Name(), "Names should match (OSX)") v, err := script.Value() diff --git a/test/integration/edit_int_test.go b/test/integration/edit_int_test.go index edf2990fd6..f07252b4c8 100644 --- a/test/integration/edit_int_test.go +++ b/test/integration/edit_int_test.go @@ -112,7 +112,8 @@ func (suite *EditIntegrationTestSuite) TestEdit_UpdateCorrectPlatform() { pj, err := project.FromPath(ts.Dirs.Work) suite.Require().NoError(err) - s := pj.ScriptByName("test-script") + s, err := pj.ScriptByName("test-script") + suite.Require().NoError(err) suite.Require().NotNil(s, "test-script should not be empty") v, err := s.Value() suite.Require().NoError(err)