diff --git a/CHANGELOG.md b/CHANGELOG.md index fe41538e13..a4fecc23b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to `src-cli` are documented in this file. - Error reporting by `src campaign [preview|apply]` has been improved and now includes more information about which step failed in which repository. [#325](https://github.com/sourcegraph/src-cli/pull/325) - The default behaviour of `src campaigns [preview|apply]` has been changed to retain downloaded archives of repositories for better performance across re-runs of the command. To use the old behaviour and delete the archives use the `-clean-archives` flag. Repository archives are also not stored in the directory for temp data (see `-tmp` flag) anymore but in the cache directory, which can be configured with the `-cache` flag. To manually delete archives between runs, delete the `*.zip` files in the `-cache` directory (see `src campaigns -help` for its default location). +- `src campaign [preview|apply]` now check whether `git` and `docker` are available before trying to execute a campaign spec's steps. [#326](https://github.com/sourcegraph/src-cli/pull/326) ### Fixed diff --git a/cmd/src/campaigns_common.go b/cmd/src/campaigns_common.go index 47e7eefaef..9d435db44a 100644 --- a/cmd/src/campaigns_common.go +++ b/cmd/src/campaigns_common.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "os/exec" "path" "runtime" "strings" @@ -148,6 +149,14 @@ func campaignsOpenFileFlag(flag *string) (io.ReadCloser, error) { // to Sourcegraph, including execution as needed. The return values are the // spec ID, spec URL, and error. func campaignsExecute(ctx context.Context, out *output.Output, svc *campaigns.Service, flags *campaignsApplyFlags) (campaigns.CampaignSpecID, string, error) { + if err := checkExecutable("git", "version"); err != nil { + return "", "", err + } + + if err := checkExecutable("docker", "version"); err != nil { + return "", "", err + } + // Parse flags and build up our service options. var errs *multierror.Error @@ -410,3 +419,16 @@ func diffStatDiagram(stat diff.Stat) string { output.StyleLinesDeleted, strings.Repeat("-", int(deleted)), ) } + +func checkExecutable(cmd string, args ...string) error { + if err := exec.Command(cmd, args...).Run(); err != nil { + return fmt.Errorf( + "failed to execute \"%s %s\":\n\t%s\n\n'src campaigns' require %q to be available.", + cmd, + strings.Join(args, " "), + err, + cmd, + ) + } + return nil +}