Skip to content

Commit

Permalink
Delete failed checkouts unless --force is provided.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchell-as committed Dec 18, 2023
1 parent 3c19ee1 commit b21ed06
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cmd/state/internal/cmdtree/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ func newCheckoutCommand(prime *primer.Values) *captain.Command {
Description: locale.Tl("flag_state_checkout_no_clone_description", "Do not clone the github repository associated with this project (if any)"),
Value: &params.NoClone,
},
{
Name: "force",
Shorthand: "f",
Description: locale.Tl("flag_state_checkout_force", "Leave a failed project checkout on disk; do not delete it"),
Value: &params.Force,
},
},
[]*captain.Argument{
{
Expand Down
28 changes: 28 additions & 0 deletions internal/runners/checkout/checkout.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package checkout

import (
"os"
"path/filepath"

"github.com/ActiveState/cli/internal/analytics"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/locale"
"github.com/ActiveState/cli/internal/logging"
"github.com/ActiveState/cli/internal/multilog"
"github.com/ActiveState/cli/internal/osutils"
"github.com/ActiveState/cli/internal/output"
"github.com/ActiveState/cli/internal/primer"
"github.com/ActiveState/cli/internal/runbits/checker"
Expand All @@ -26,6 +31,7 @@ type Params struct {
Branch string
RuntimePath string
NoClone bool
Force bool
}

type primeable interface {
Expand Down Expand Up @@ -77,6 +83,28 @@ func (u *Checkout) Run(params *Params) (rerr error) {
return locale.WrapError(err, "err_project_frompath")
}

// If an error occurs, remove the created activestate.yaml file and/or directory.
if !params.Force {
defer func() {
if rerr == nil {
return
}
err := os.Remove(proj.Path())
if err != nil {
multilog.Error("Failed to remove activestate.yaml after `state checkout` error: %v", err)
return
}
if cwd, err := osutils.Getwd(); err == nil {
if createdDir := filepath.Dir(proj.Path()); createdDir != cwd {
err2 := os.RemoveAll(createdDir)
if err2 != nil {
multilog.Error("Failed to remove created directory after `state checkout` error: %v", err2)
}
}
}
}()
}

rti, err := runtime.NewFromProject(proj, target.TriggerCheckout, u.analytics, u.svcModel, u.out, u.auth)
if err != nil {
return locale.WrapError(err, "err_checkout_runtime_new", "Could not checkout this project.")
Expand Down
30 changes: 30 additions & 0 deletions test/integration/checkout_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,36 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutBuildtimeClosure() {
cp.ExpectExitCode(0)
}

func (suite *CheckoutIntegrationTestSuite) TestFail() {
suite.OnlyRunForTags(tagsuite.Checkout)
ts := e2e.New(suite.T(), false)
defer ts.Close()

cp := ts.SpawnWithOpts(
e2e.OptArgs("checkout", "ActiveState-CLI/fail"),
e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
)
cp.Expect("Something went wrong")
cp.ExpectNotExitCode(0)
suite.Assert().NoDirExists(filepath.Join(ts.Dirs.Work, "fail"), "state checkout fail did not remove created directory")

cp = ts.SpawnWithOpts(
e2e.OptArgs("checkout", "ActiveState-CLI/fail", "."),
e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
)
cp.Expect("Something went wrong")
cp.ExpectNotExitCode(0)
suite.Assert().NoFileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName), "state checkout fail did not remove created activestate.yaml")

cp = ts.SpawnWithOpts(
e2e.OptArgs("checkout", "ActiveState-CLI/fail", "--force"),
e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
)
cp.Expect("Something went wrong")
cp.ExpectNotExitCode(0)
suite.Assert().DirExists(filepath.Join(ts.Dirs.Work, "fail"), "state checkout fail did not leave created directory there despite --force flag override")
}

func TestCheckoutIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(CheckoutIntegrationTestSuite))
}

0 comments on commit b21ed06

Please sign in to comment.