Skip to content

Commit

Permalink
Merge pull request #16 from hashicorp/rar-skip-ignore
Browse files Browse the repository at this point in the history
Allow bypassing the .terraformignore rules
  • Loading branch information
Russell Rollins committed Feb 26, 2021
2 parents 699121e + 3fd0a40 commit 447e7f0
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 3 deletions.
66 changes: 63 additions & 3 deletions slug.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,71 @@ func (e *IllegalSlugError) Error() string {
// chain.
func (e *IllegalSlugError) Unwrap() error { return e.Err }

// PackerOption is a functional option that can configure non-default Packers.
type PackerOption func(*Packer) error

// ApplyTerraformIgnore is a PackerOption that will apply the .terraformignore
// rules and skip packing files it specifies.
func ApplyTerraformIgnore() PackerOption {
return func(p *Packer) error {
p.applyTerraformIgnore = true
return nil
}
}

// DereferenceSymlinks is a PackerOption that will allow symlinks that
// reference a target outside of the src directory.
func DereferenceSymlinks() PackerOption {
return func(p *Packer) error {
p.dereference = true
return nil
}
}

// Packer holds options for the Pack function.
type Packer struct {
dereference bool
applyTerraformIgnore bool
}

// NewPacker is a constructor for Packer.
func NewPacker(options ...PackerOption) (*Packer, error) {
p := &Packer{
dereference: false,
applyTerraformIgnore: false,
}

for _, opt := range options {
if err := opt(p); err != nil {
return nil, fmt.Errorf("option failed: %w", err)
}
}

return p, nil
}

// Pack at the package level is used to maintain compatibility with existing
// code that relies on this function signature. New options related to packing
// slugs should be added to the Packer struct instead.
func Pack(src string, w io.Writer, dereference bool) (*Meta, error) {
p := Packer{
dereference: dereference,

// This defaults to false in NewPacker, but is true here. This matches
// the old behavior of Pack, which always used .terraformignore.
applyTerraformIgnore: true,
}
return p.Pack(src, w)
}

// Pack creates a slug from a src directory, and writes the new slug
// to w. Returns metadata about the slug and any errors.
//
// When dereference is set to true, symlinks with a target outside of
// the src directory will be dereferenced. When dereference is set to
// false symlinks with a target outside the src directory are omitted
// from the slug.
func Pack(src string, w io.Writer, dereference bool) (*Meta, error) {
func (p *Packer) Pack(src string, w io.Writer) (*Meta, error) {
// Gzip compress all the output data.
gzipW := gzip.NewWriter(w)

Expand All @@ -50,13 +107,16 @@ func Pack(src string, w io.Writer, dereference bool) (*Meta, error) {

// Load the ignore rule configuration, which will use
// defaults if no .terraformignore is configured
ignoreRules := parseIgnoreFile(src)
var ignoreRules []rule
if p.applyTerraformIgnore {
ignoreRules = parseIgnoreFile(src)
}

// Track the metadata details as we go.
meta := &Meta{}

// Walk the tree of files.
err := filepath.Walk(src, packWalkFn(src, src, src, tarW, meta, dereference, ignoreRules))
err := filepath.Walk(src, packWalkFn(src, src, src, tarW, meta, p.dereference, ignoreRules))
if err != nil {
return nil, err
}
Expand Down
122 changes: 122 additions & 0 deletions slug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,79 @@ func TestPackWithoutDereferencing(t *testing.T) {
}
}

func TestPackWithoutIgnoring(t *testing.T) {
slug := bytes.NewBuffer(nil)

// By default NewPacker() creates a Packer that does not use
// .terraformignore or dereference symlinks.
p, err := NewPacker()
if err != nil {
t.Fatalf("err: %v", err)
}

meta, err := p.Pack("testdata/archive-dir", slug)
if err != nil {
t.Fatalf("err: %v", err)
}

gzipR, err := gzip.NewReader(slug)
if err != nil {
t.Fatalf("err: %v", err)
}

tarR := tar.NewReader(gzipR)
var (
fileList []string
slugSize int64
)

for {
hdr, err := tarR.Next()
if err == io.EOF {
break
}
if err != nil {
t.Fatalf("err: %v", err)
}

fileList = append(fileList, hdr.Name)
if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA {
slugSize += hdr.Size
}
}

// baz.txt would normally be ignored, but should not be
var bazFound bool
for _, file := range fileList {
if file == "baz.txt" {
bazFound = true
}
}
if !bazFound {
t.Fatal("expected file baz.txt to be present, but not found")
}

// .terraform/file.txt would normally be ignored, but should not be
var dotTerraformFileFound bool
for _, file := range fileList {
if file == ".terraform/file.txt" {
dotTerraformFileFound = true
}
}
if !dotTerraformFileFound {
t.Fatal("expected file .terraform/file.txt to be present, but not found")
}

// Check the metadata
expect := &Meta{
Files: fileList,
Size: slugSize,
}
if !reflect.DeepEqual(meta, expect) {
t.Fatalf("\nexpect:\n%#v\n\nactual:\n%#v", expect, meta)
}
}

func TestUnpack(t *testing.T) {
// First create the slug file so we can try to unpack it.
slug := bytes.NewBuffer(nil)
Expand Down Expand Up @@ -647,6 +720,55 @@ func TestCheckFileMode(t *testing.T) {
}
}

func TestNewPacker(t *testing.T) {
for _, tc := range []struct {
desc string
options []PackerOption
expect *Packer
}{
{
desc: "defaults",
expect: &Packer{
dereference: false,
applyTerraformIgnore: false,
},
},
{
desc: "enable dereferencing",
options: []PackerOption{DereferenceSymlinks()},
expect: &Packer{
dereference: true,
},
},
{
desc: "apply .terraformignore",
options: []PackerOption{ApplyTerraformIgnore()},
expect: &Packer{
applyTerraformIgnore: true,
},
},
{
desc: "multiple options",
options: []PackerOption{ApplyTerraformIgnore(), DereferenceSymlinks()},
expect: &Packer{
dereference: true,
applyTerraformIgnore: true,
},
},
} {
t.Run(tc.desc, func(t *testing.T) {
p, err := NewPacker(tc.options...)
if err != nil {
t.Fatalf("err: %v", err)
}

if !reflect.DeepEqual(p, tc.expect) {
t.Fatalf("\nexpect:\n%#v\n\nactual:\n%#v", p, tc.expect)
}
})
}
}

func verifyFile(t *testing.T, path string, mode os.FileMode, expect string) {
fh, err := os.Open(path)
if err != nil {
Expand Down

0 comments on commit 447e7f0

Please sign in to comment.