diff --git a/internal/cmd/stack/flags.go b/internal/cmd/stack/flags.go index 1f99bf5..2575a8c 100644 --- a/internal/cmd/stack/flags.go +++ b/internal/cmd/stack/flags.go @@ -13,6 +13,12 @@ var flagCommitSHA = &cli.StringFlag{ Usage: "Commit SHA for the newly created run", } +var flagNoFindRepositoryRoot = &cli.BoolFlag{ + Name: "no-find-repository-root", + Usage: "Indicate whether spacectl should avoid finding the repository root (containing a .git directory) before packaging it.", + Value: false, +} + var flagRequiredCommitSHA = &cli.StringFlag{ Name: "sha", Usage: "SHA of the commit to set as canonical for the stack", diff --git a/internal/cmd/stack/local_preview.go b/internal/cmd/stack/local_preview.go index 33e5090..4a00339 100644 --- a/internal/cmd/stack/local_preview.go +++ b/internal/cmd/stack/local_preview.go @@ -20,6 +20,12 @@ func localPreview() cli.ActionFunc { return func(cliCtx *cli.Context) error { ctx := context.Background() + if !cliCtx.Bool(flagNoFindRepositoryRoot.Name) { + if err := moveToRepositoryRoot(); err != nil { + return fmt.Errorf("couldn't move to repository root: %w", err) + } + } + fmt.Println("Uploading local workspace...") var uploadMutation struct { @@ -97,6 +103,39 @@ func localPreview() cli.ActionFunc { } } +func moveToRepositoryRoot() error { + startCwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("couldn't get current working directory: %w", err) + } + for { + if _, err := os.Stat(".git"); err == nil { + return nil + } else if !os.IsNotExist(err) { + return fmt.Errorf("couldn't stat .git directory: %w", err) + } + + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("couldn't get current working directory: %w", err) + } + + parent := filepath.Dir(cwd) + + if parent == cwd { + fmt.Println("Couldn't find repository root, using current directory.") + if err := os.Chdir(startCwd); err != nil { + return fmt.Errorf("couldn't set current working directory: %w", err) + } + return nil + } + + if err := os.Chdir(parent); err != nil { + return fmt.Errorf("couldn't set current working directory: %w", err) + } + } +} + func getIgnoreMatcherFn(ctx context.Context) (func(filePath string) bool, error) { gitignore, err := ignore.CompileIgnoreFile(".gitignore") if err != nil && !os.IsNotExist(err) { diff --git a/internal/cmd/stack/stack.go b/internal/cmd/stack/stack.go index 66ad1c2..87dcd46 100644 --- a/internal/cmd/stack/stack.go +++ b/internal/cmd/stack/stack.go @@ -42,8 +42,9 @@ func Command() *cli.Command { { Category: "Run local preview", Name: "local-preview", - Usage: "Start a preview (proposed run) based on the current directory. Respects .gitignore and .terraformignore.", + Usage: "Start a preview (proposed run) based on the current project. Respects .gitignore and .terraformignore.", Flags: []cli.Flag{ + flagNoFindRepositoryRoot, flagRunMetadata, flagNoTail, },