From 06923f7785ab5beedbc80c45f7366152b21dd166 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Wed, 9 Oct 2024 16:48:37 -0600 Subject: [PATCH] feat(lk): use tmp directory while preparing files --- cmd/lk/app.go | 16 ++++++++++++---- cmd/lk/utils.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/cmd/lk/app.go b/cmd/lk/app.go index 754991e7..3cac9237 100644 --- a/cmd/lk/app.go +++ b/cmd/lk/app.go @@ -268,13 +268,18 @@ func setupTemplate(ctx context.Context, cmd *cli.Command) error { func cloneTemplate(_ context.Context, cmd *cli.Command, url, appName string) error { var cmdErr error + + tempName, relocate := useTempPath(appName) + if err := spinner.New(). Title("Cloning template from " + url). Action(func() { - c := exec.Command("git", "clone", "--depth=1", url, appName) + c := exec.Command("git", "clone", "--depth=1", url, tempName) var out []byte - if out, cmdErr = c.CombinedOutput(); len(out) > 0 && cmd.Bool("verbose") { - fmt.Println(string(out)) + if out, cmdErr = c.CombinedOutput(); len(out) > 0 { + if cmdErr != nil || cmd.Bool("verbose") { + fmt.Println(string(out)) + } } os.RemoveAll(path.Join(appName, ".git")) }). @@ -282,7 +287,10 @@ func cloneTemplate(_ context.Context, cmd *cli.Command, url, appName string) err Run(); err != nil { return err } - return cmdErr + if cmdErr != nil { + return cmdErr + } + return relocate() } func instantiateEnv(ctx context.Context, cmd *cli.Command, rootPath string, addlEnv *map[string]string) error { diff --git a/cmd/lk/utils.go b/cmd/lk/utils.go index b1faa244..5415bdfb 100644 --- a/cmd/lk/utils.go +++ b/cmd/lk/utils.go @@ -20,10 +20,13 @@ import ( "encoding/json" "errors" "fmt" + "math/rand" "net/url" "os" + "path" "path/filepath" "strings" + "time" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" @@ -153,6 +156,32 @@ func wrapWith(wrap string) func(string) string { } } +func randomID() string { + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + seed := rand.NewSource(time.Now().UnixNano()) + r := rand.New(seed) + + result := make([]byte, 16) + for i := range result { + result[i] = charset[r.Intn(len(charset))] + } + return string(result) +} + +func useTempPath(permanentPath string) (string, func() error) { + tempPath := path.Join(os.TempDir(), randomID()) + relocate := func() error { + if err := os.Rename(tempPath, permanentPath); err != nil { + // NOTE: on macOS, `os.TempDir()` points to `/var/folders/...`. + // Because this directory is not automatically cleaned up, we need + // to remove it explicitly on a failure to relocate. + return os.RemoveAll(tempPath) + } + return nil + } + return tempPath, relocate +} + func hashString(str string) (string, error) { hash := sha256.New() if _, err := hash.Write([]byte(str)); err != nil {