diff --git a/internal/cmd/module/local_preview.go b/internal/cmd/module/local_preview.go index 89a18e4..915ab9a 100644 --- a/internal/cmd/module/local_preview.go +++ b/internal/cmd/module/local_preview.go @@ -51,7 +51,7 @@ func localPreview() cli.ActionFunc { fp := filepath.Join(os.TempDir(), "spacectl", "local-workspace", fmt.Sprintf("%s.tar.gz", uploadMutation.UploadLocalWorkspace.ID)) - matchFn, err := internal.GetIgnoreMatcherFn(ctx) + matchFn, err := internal.GetIgnoreMatcherFn(ctx, nil) if err != nil { return fmt.Errorf("couldn't analyze .gitignore and .terraformignore files") } diff --git a/internal/cmd/stack/flags.go b/internal/cmd/stack/flags.go index 2c878fe..1fbf9f3 100644 --- a/internal/cmd/stack/flags.go +++ b/internal/cmd/stack/flags.go @@ -32,6 +32,12 @@ var flagNoFindRepositoryRoot = &cli.BoolFlag{ Value: false, } +var flagProjectRootOnly = &cli.BoolFlag{ + Name: "project-root-only", + Usage: "Indicate if spacelift should only package files inside this stacks project_root", + Value: false, +} + var flagRequiredCommitSHA = &cli.StringFlag{ Name: "sha", Usage: "[Required] `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 09f2213..ad545e4 100644 --- a/internal/cmd/stack/local_preview.go +++ b/internal/cmd/stack/local_preview.go @@ -22,13 +22,25 @@ func localPreview() cli.ActionFunc { } ctx := context.Background() + var packagePath *string = nil + if cliCtx.Bool(flagProjectRootOnly.Name) { + root, err := getGitRepositorySubdir() + if err != nil { + return fmt.Errorf("couldn't get the packagePath: %w", err) + } + packagePath = &root + } if !cliCtx.Bool(flagNoFindRepositoryRoot.Name) { if err := internal.MoveToRepositoryRoot(); err != nil { return fmt.Errorf("couldn't move to repository root: %w", err) } } - fmt.Println("Packing local workspace...") + if packagePath == nil { + fmt.Printf("Packing local workspace...\n") + } else { + fmt.Printf("Packing '%s' as local workspace...\n", *packagePath) + } var uploadMutation struct { UploadLocalWorkspace struct { @@ -47,7 +59,7 @@ func localPreview() cli.ActionFunc { fp := filepath.Join(os.TempDir(), "spacectl", "local-workspace", fmt.Sprintf("%s.tar.gz", uploadMutation.UploadLocalWorkspace.ID)) - matchFn, err := internal.GetIgnoreMatcherFn(ctx) + matchFn, err := internal.GetIgnoreMatcherFn(ctx, packagePath) if err != nil { return fmt.Errorf("couldn't analyze .gitignore and .terraformignore files") } diff --git a/internal/cmd/stack/stack.go b/internal/cmd/stack/stack.go index faabcc0..010226c 100644 --- a/internal/cmd/stack/stack.go +++ b/internal/cmd/stack/stack.go @@ -114,6 +114,7 @@ func Command() *cli.Command { Flags: []cli.Flag{ flagStackID, flagNoFindRepositoryRoot, + flagProjectRootOnly, flagRunMetadata, flagNoTail, flagNoUpload, diff --git a/internal/local_preview.go b/internal/local_preview.go index 3ad5dd9..677d3ae 100644 --- a/internal/local_preview.go +++ b/internal/local_preview.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "path/filepath" + "strings" "github.com/cheggaaa/pb/v3" ignore "github.com/sabhiram/go-gitignore" @@ -45,8 +46,10 @@ func MoveToRepositoryRoot() error { } } -// GetIgnoreMatcherFn creates an ignore-matcher for archiving purposes. Respects gitignore and terraformignore. -func GetIgnoreMatcherFn(ctx context.Context) (func(filePath string) bool, error) { +// GetIgnoreMatcherFn creates an ignore-matcher for archiving purposes +// This function respects gitignore and terraformignore, and +// optionally if a projectRoot is provided it only include files from this root +func GetIgnoreMatcherFn(ctx context.Context, projectRoot *string) (func(filePath string) bool, error) { gitignore, err := ignore.CompileIgnoreFile(".gitignore") if err != nil && !os.IsNotExist(err) { return nil, fmt.Errorf("couldn't compile .gitignore file: %w", err) @@ -66,6 +69,15 @@ func GetIgnoreMatcherFn(ctx context.Context) (func(filePath string) bool, error) if terraformignore != nil && terraformignore.MatchesPath(filePath) { return false } + + if projectRoot != nil { + // ensure the root only matches the directory and not all other files + root := strings.TrimSuffix(*projectRoot, "/") + "/" + if !strings.HasPrefix(filePath, root) { + return false + } + } + return true }, nil }