diff --git a/pkg/commands/compute/init.go b/pkg/commands/compute/init.go index 46d4f054f..d52a82cef 100644 --- a/pkg/commands/compute/init.go +++ b/pkg/commands/compute/init.go @@ -476,8 +476,7 @@ func (c *InitCommand) Exec(in io.Reader, out io.Writer) (err error) { } spinner.Message(msg + "...") spinner.StopFailMessage(msg) - spinErr = spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } } @@ -848,8 +847,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A if fi, err := os.Stat(c.CloneFrom); err == nil && fi.IsDir() { if err := cp.Copy(c.CloneFrom, c.dir); err != nil { spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -863,8 +861,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A u, err := url.Parse(c.CloneFrom) if err != nil { spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return fmt.Errorf("could not read --from URL: %w", err) @@ -874,8 +871,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A // empty and the string ends up in u.Path. if u.Host == "" && u.Scheme == "" { spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return fmt.Errorf("--from url seems invalid: %s", c.CloneFrom) @@ -889,8 +885,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A if gitRepositoryRegEx.MatchString(c.CloneFrom) { if err := c.ClonePackageFromEndpoint(c.CloneFrom, branch, tag); err != nil { spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -900,8 +895,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A } spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -925,8 +919,7 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A err = fmt.Errorf("failed to get package '%s': %w", req.URL.String(), err) c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -937,14 +930,28 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A err := fmt.Errorf("failed to get package '%s': %s", req.URL.String(), res.Status) c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { + return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) + } + return err + } + + tempdir, err := tempDir("package-init-download") + if err != nil { + err = fmt.Errorf("error creating temporary path for package template download: %w", err) + c.Globals.ErrLog.Add(err) + spinner.StopFailMessage(msg) + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err } + defer os.RemoveAll(tempdir) - filename := filepath.Base(c.CloneFrom) + filename := filepath.Join( + tempdir, + filepath.Base(c.CloneFrom), + ) ext := filepath.Ext(filename) // gosec flagged this: @@ -957,30 +964,18 @@ func (c *InitCommand) FetchPackageTemplate(branch, tag string, archives []file.A err = fmt.Errorf("failed to create local %s archive: %w", filename, err) c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err } - defer func() { - // NOTE: Later on we rename the file to include an extension and the - // following call to os.Remove works still because the `filename` variable - // that is still in scope is also updated to include the extension. - err := os.Remove(filename) - if err != nil { - c.Globals.ErrLog.Add(err) - text.Info(out, "We were unable to clean-up the local %s file (it can be safely removed)", filename) - } - }() _, err = io.Copy(f, res.Body) if err != nil { err = fmt.Errorf("failed to write %s archive to disk: %w", filename, err) c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -1028,8 +1023,7 @@ mimes: if err != nil { c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -1045,8 +1039,7 @@ mimes: err = fmt.Errorf("failed to extract %s archive content: %w", filename, err) c.Globals.ErrLog.Add(err) spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err @@ -1058,8 +1051,7 @@ mimes: if err := c.ClonePackageFromEndpoint(c.CloneFrom, branch, tag); err != nil { spinner.StopFailMessage(msg) - spinErr := spinner.StopFail() - if spinErr != nil { + if spinErr := spinner.StopFail(); spinErr != nil { return fmt.Errorf(text.SpinnerErrWrapper, spinErr, err) } return err diff --git a/pkg/commands/compute/init_test.go b/pkg/commands/compute/init_test.go index 5ed37bcd0..4de22aaa4 100644 --- a/pkg/commands/compute/init_test.go +++ b/pkg/commands/compute/init_test.go @@ -57,6 +57,7 @@ func TestInit(t *testing.T) { manifestIncludes string manifestPath string stdin string + setupSteps func() error }{ { name: "broken endpoint", @@ -149,6 +150,28 @@ func TestInit(t *testing.T) { "SUCCESS: Initialized package", }, }, + { + name: "with --from set to starter kit repository when dir with same name exists in pwd", + args: args("compute init --auto-yes --from https://github.com/fastly/compute-starter-kit-rust-default"), + configFile: config.File{ + StarterKits: config.StarterKitLanguages{ + Rust: []config.StarterKit{ + { + Name: "Default", + Path: "https://github.com/fastly/compute-starter-kit-rust-default.git", + }, + }, + }, + }, + wantOutput: []string{ + "Fetching package template", + "Reading fastly.toml", + "SUCCESS: Initialized package", + }, + setupSteps: func() error { + return os.MkdirAll("compute-starter-kit-rust-default", 0755) + }, + }, { name: "with --from set to starter kit repository with .git extension and branch", args: args("compute init --from https://github.com/fastly/compute-starter-kit-rust-default.git --branch main"), @@ -168,6 +191,28 @@ func TestInit(t *testing.T) { "SUCCESS: Initialized package", }, }, + { + name: "with --from set to starter kit repository with .git extension and branch when dir with same name exists in pwd", + args: args("compute init --auto-yes --from https://github.com/fastly/compute-starter-kit-rust-default.git --branch main"), + configFile: config.File{ + StarterKits: config.StarterKitLanguages{ + Rust: []config.StarterKit{ + { + Name: "Default", + Path: "https://github.com/fastly/compute-starter-kit-rust-default.git", + }, + }, + }, + }, + wantOutput: []string{ + "Fetching package template", + "Reading fastly.toml", + "SUCCESS: Initialized package", + }, + setupSteps: func() error { + return os.MkdirAll("compute-starter-kit-rust-default.git", 0755) + }, + }, { name: "with --from set to zip archive", args: args("compute init --from https://github.com/fastly/compute-starter-kit-rust-default/archive/refs/heads/main.zip"), @@ -187,6 +232,32 @@ func TestInit(t *testing.T) { "SUCCESS: Initialized package", }, }, + { + name: "with --from set to zip archive when file with same name exists in pwd", + args: args("compute init --auto-yes --from https://github.com/fastly/compute-starter-kit-rust-default/archive/refs/heads/main.zip"), + configFile: config.File{ + StarterKits: config.StarterKitLanguages{ + Rust: []config.StarterKit{ + { + Name: "Default", + Path: "https://github.com/fastly/compute-starter-kit-rust-default.git", + }, + }, + }, + }, + wantOutput: []string{ + "Fetching package template", + "Reading fastly.toml", + "SUCCESS: Initialized package", + }, + setupSteps: func() error { + file, err := os.Create("main.zip") + if file != nil { + defer file.Close() + } + return err + }, + }, { name: "with --from set to tar.gz archive", args: args("compute init --from https://github.com/Integralist/devnull/files/7339887/compute-starter-kit-rust-default-main.tar.gz"), @@ -375,6 +446,13 @@ func TestInit(t *testing.T) { _ = os.Chdir(pwd) }() + // Before running the test, run some steps to initialize the environment. + if testcase.setupSteps != nil { + if err := testcase.setupSteps(); err != nil { + t.Fatal(err) + } + } + var stdout bytes.Buffer app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { opts := testutil.MockGlobalData(testcase.args, &stdout)