diff --git a/cmd/build.go b/cmd/build.go index 9d1d773f2..c32ed969c 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -22,8 +22,7 @@ func newLocalExecuteCommand(config *settings.Config) *cobra.Command { } local.AddFlagsForDocumentation(buildCommand.Flags()) - buildAgentVersionUsage := `The version of the build agent image you want to use. This can be configured by writing in $HOME/.circleci/build_agent_settings.json: '{"LatestSha256":""}'` - buildCommand.Flags().String("build-agent-version", "", buildAgentVersionUsage) + buildCommand.Flags().String("build-agent-version", "", `The version of the build agent image you want to use. This can be configured by writing in $HOME/.circleci/build_agent_settings.json: '{"LatestSha256":""}'`) buildCommand.Flags().StringP("org-slug", "o", "", "organization slug (for example: github/example-org), used when a config depends on private orbs belonging to that org") buildCommand.Flags().String("org-id", "", "organization id, used when a config depends on private orbs belonging to that org") diff --git a/cmd/config.go b/cmd/config.go index 44e18b1a4..f20b9add1 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -162,8 +162,15 @@ func migrateConfig(args []string) error { } func generateConfig(args []string) error { - path := "." - if len(args) == 1 { + var err error + var path string + if len(args) == 0 { + // use working directory as default + path, err = os.Getwd() + if err != nil { + return fmt.Errorf("couldn't get working directory") + } + } else { path = args[0] } diff --git a/cmd/config_test.go b/cmd/config_test.go index 6bd041cff..3b1fb3089 100644 --- a/cmd/config_test.go +++ b/cmd/config_test.go @@ -2,6 +2,7 @@ package cmd_test import ( "fmt" + "os" "os/exec" "path/filepath" @@ -245,22 +246,35 @@ var _ = Describe("Config", func() { }) }) }) + Describe("generate", func() { It("works without a path", func() { command := exec.Command(pathCLI, "config", "generate") + command.Dir = "testdata/node" session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) - session.Wait() Expect(err).ShouldNot(HaveOccurred()) + + session.Wait() + Eventually(session.Err.Contents()).Should(BeEmpty()) - Eventually(session.Out.Contents()).Should(MatchRegexp("#.*")) + Eventually(session.Out.Contents()).Should(MatchRegexp("npm run test")) + Eventually(session).Should(gexec.Exit(0)) }) + It("works with a path", func() { - command := exec.Command(pathCLI, "config", "generate", "..") + wd, err := os.Getwd() + Expect(err).ShouldNot(HaveOccurred()) + + command := exec.Command(pathCLI, "config", "generate", "node") + command.Dir = filepath.Join(wd, "testdata") session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) - session.Wait() Expect(err).ShouldNot(HaveOccurred()) + + session.Wait() + Eventually(session.Err.Contents()).Should(BeEmpty()) - Eventually(session.Out.Contents()).Should(MatchRegexp("#.*")) + Eventually(session.Out.Contents()).Should(MatchRegexp("npm run test")) + Eventually(session).Should(gexec.Exit(0)) }) }) }) diff --git a/cmd/testdata/node/package.json b/cmd/testdata/node/package.json new file mode 100644 index 000000000..00e66575a --- /dev/null +++ b/cmd/testdata/node/package.json @@ -0,0 +1,10 @@ +{ + "name": "circleci-cli-node-test", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "webpack", + "lint": "eslint .", + "test": "jest ." + } +} diff --git a/local/local.go b/local/local.go index 32e55320c..39272c91a 100644 --- a/local/local.go +++ b/local/local.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "path" - "regexp" "strings" "syscall" @@ -75,7 +74,6 @@ func Execute(flags *pflag.FlagSet, cfg *settings.Config, args []string) error { picardVersion, _ := flags.GetString("build-agent-version") image, err := picardImage(os.Stdout, picardVersion) - if err != nil { return errors.Wrap(err, "Could not find picard image") } @@ -146,7 +144,6 @@ func buildAgentArguments(flags *pflag.FlagSet) ([]string, string) { } func picardImage(output io.Writer, picardVersion string) (string, error) { - fmt.Fprintf(output, "Fetching latest build environment...\n") sha, err := getPicardSha(output, picardVersion) @@ -176,11 +173,9 @@ func getPicardSha(output io.Writer, picardVersion string) (string, error) { fmt.Fprintf(output, "Falling back to latest build-agent version\n") } - sha, err = findLatestPicardSha() - if err != nil { - return "", err - } - return sha, nil + // We are freezing build-agent cli as we would like to deprecate this path + fixedSha := "sha256:008ba7f4223f1e26c11df9575283491b620074fa96da6961e0dcde47fb757014" + return fixedSha, nil } func ensureDockerIsAvailable() (string, error) { @@ -200,60 +195,6 @@ func ensureDockerIsAvailable() (string, error) { return dockerPath, nil } -// Still depends on a function in cmd/build.go -func findLatestPicardSha() (string, error) { - - if _, err := ensureDockerIsAvailable(); err != nil { - return "", err - } - - outputBytes, err := exec.Command("docker", "pull", picardRepo).CombinedOutput() // #nosec - - if err != nil { - return "", errors.Wrap(err, "failed to pull latest docker image") - } - - output := string(outputBytes) - sha256 := regexp.MustCompile("(?m)sha256:[0-9a-f]+") - latest := sha256.FindString(output) - - if latest == "" { - return "", fmt.Errorf("failed to parse sha256 from docker pull output") - } - - return latest, nil -} - -type buildAgentSettings struct { - LatestSha256 string -} - -func loadBuildAgentShaFromConfig() (string, error) { - if _, err := os.Stat(buildAgentSettingsPath()); os.IsNotExist(err) { - // Settings file does not exist. - return "", nil - } - - file, err := os.Open(buildAgentSettingsPath()) - if err != nil { - return "", errors.Wrap(err, "Could not open build settings config") - } - defer file.Close() - - var settings buildAgentSettings - - if err := json.NewDecoder(file).Decode(&settings); err != nil { - - return "", errors.Wrap(err, "Could not parse build settings config") - } - - return settings.LatestSha256, nil -} - -func buildAgentSettingsPath() string { - return path.Join(settings.SettingsPath(), "build_agent_settings.json") -} - // Write data to a temp file, and return the path to that file. func writeStringToTempFile(data string) (string, error) { // It's important to specify `/tmp` here as the location of the temp file. @@ -305,3 +246,37 @@ func unparseFlag(flags *pflag.FlagSet, flag *pflag.Flag) []string { } return result } + +type buildAgentSettings struct { + LatestSha256 string +} + +func loadBuildAgentShaFromConfig() (string, error) { + if _, err := os.Stat(buildAgentSettingsPath()); os.IsNotExist(err) { + // Settings file does not exist. + return "", nil + } + + file, err := os.Open(buildAgentSettingsPath()) + if err != nil { + return "", errors.Wrap(err, "Could not open build settings config") + } + defer file.Close() + + var settings buildAgentSettings + + buf, err := io.ReadAll(file) + if err != nil { + return "", errors.Wrap(err, "Couldn't read from build settings file") + } + + if err = json.Unmarshal(buf, &settings); err != nil { + return "", errors.Wrap(err, "Could not parse build settings config") + } + + return settings.LatestSha256, nil +} + +func buildAgentSettingsPath() string { + return path.Join(settings.SettingsPath(), "build_agent_settings.json") +}