Add support for .krmignore file

This commit is contained in:
Morten Torkildsen
2020-08-26 17:40:04 -07:00
parent e39a5adc00
commit 16bbc2d67e
8 changed files with 448 additions and 99 deletions

10
kyaml/ext/ext.go Normal file
View File

@@ -0,0 +1,10 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package ext
// GetIgnoreFileName returns the name for ignore files in
// packages. It can be overridden by tools using this library.
var GetIgnoreFileName = func() string {
return ".krmignore"
}

View File

@@ -8,6 +8,7 @@ require (
github.com/go-openapi/spec v0.19.5
github.com/go-openapi/strfmt v0.19.5
github.com/go-openapi/validate v0.19.8
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d
github.com/sergi/go-diff v1.1.0
github.com/spf13/cobra v1.0.0

View File

@@ -145,6 +145,8 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=

View File

@@ -0,0 +1,99 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package kio
import (
"os"
"path/filepath"
"strings"
"github.com/monochromegane/go-gitignore"
"sigs.k8s.io/kustomize/kyaml/ext"
)
// ignoreFilesMatcher handles `.krmignore` files, which allows for ignoring
// files or folders in a package. The format of this file is a subset of the
// gitignore format, with recursive patterns (like a/**/c) not supported. If a
// file or folder matches any of the patterns in the .krmignore file for the
// package, it will be excluded.
//
// It works as follows:
//
// * It will look for .krmignore file in the top folder and on the top level
// of any subpackages. Subpackages are defined by the presence of a Krmfile
// in the folder.
// * `.krmignore` files only cover files and folders for the package in which
// it is defined. So ignore patterns defined in a parent package does not
// affect which files are ignored from a subpackage.
// * An ignore pattern can not ignore a subpackage. So even if the parent
// package contains a pattern that ignores the directory foo, if foo is a
// subpackage, it will still be included if the IncludeSubpackages property
// is set to true
type ignoreFilesMatcher struct {
matchers []matcher
}
// readIgnoreFile checks whether there is a .krmignore file in the path, and
// if it is, reads it in and turns it into a matcher. If we can't find a file,
// we just add a matcher that match nothing.
func (i *ignoreFilesMatcher) readIgnoreFile(path string) error {
m, err := gitignore.NewGitIgnore(filepath.Join(path, ext.GetIgnoreFileName()))
if err != nil {
if os.IsNotExist(err) {
i.matchers = append(i.matchers, matcher{
matcher: gitignore.DummyIgnoreMatcher(false),
basePath: path,
})
return nil
}
return err
}
i.matchers = append(i.matchers, matcher{
matcher: m,
basePath: path,
})
return nil
}
// verifyPath checks whether the top matcher on the stack
// is correct for the provided filepath. Matchers are removed once
// we encounter a filepath that is not a subpath of the basepath for
// the matcher.
func (i *ignoreFilesMatcher) verifyPath(path string) {
for j := len(i.matchers) - 1; j >= 0; j-- {
matcher := i.matchers[j]
if !strings.HasPrefix(path, matcher.basePath) {
i.matchers = i.matchers[:j]
return
}
}
}
// matchFile checks whether the file given by the provided path matches
// any of the patterns in the .krmignore file for the package.
func (i *ignoreFilesMatcher) matchFile(path string) bool {
if len(i.matchers) == 0 {
return false
}
i.verifyPath(path)
return i.matchers[len(i.matchers)-1].matcher.Match(path, false)
}
// matchFile checks whether the directory given by the provided path matches
// any of the patterns in the .krmignore file for the package.
func (i *ignoreFilesMatcher) matchDir(path string) bool {
if len(i.matchers) == 0 {
return false
}
i.verifyPath(path)
return i.matchers[len(i.matchers)-1].matcher.Match(path, true)
}
// matcher wraps the gitignore matcher and the path to the folder
// where the file was found.
type matcher struct {
matcher gitignore.IgnoreMatcher
basePath string
}

View File

@@ -0,0 +1,203 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package kio
import (
"io/ioutil"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIgnoreFilesMatcher_readIgnoreFile(t *testing.T) {
testCases := []struct {
name string
writeIgnoreFile bool
isMatch bool
}{
{
name: "has .krmignore file",
writeIgnoreFile: true,
isMatch: true,
},
{
name: "no .krmignore file",
writeIgnoreFile: false,
isMatch: false,
},
}
for i := range testCases {
test := testCases[i]
t.Run(test.name, func(t *testing.T) {
dir, err := ioutil.TempDir("", "kyaml-test")
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
if test.writeIgnoreFile {
ignoreFilePath := filepath.Join(dir, ".krmignore")
err = ioutil.WriteFile(ignoreFilePath, []byte(`
testfile.yaml
`), 0600)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
}
testFilePath := filepath.Join(dir, "testfile.yaml")
err = ioutil.WriteFile(testFilePath, []byte{}, 0600)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
ignoreFilesMatcher := ignoreFilesMatcher{}
err = ignoreFilesMatcher.readIgnoreFile(dir)
if !assert.NoError(t, err) {
t.FailNow()
}
assert.Equal(t, test.isMatch, ignoreFilesMatcher.matchFile(testFilePath))
})
}
}
var (
readFileA = []byte(`
a: a
---
c: c
`)
readFileB = []byte(`
b: b
`)
)
func TestLocalPackageReader_Read_ignoreFile(t *testing.T) {
testCases := []struct {
name string
directories []string
files map[string][]byte
expected []string
}{
{
name: "ignore file",
directories: []string{
filepath.Join("a", "b"),
filepath.Join("a", "c"),
},
files: map[string][]byte{
filepath.Join("pkgFile"): {},
filepath.Join("a", "b", "a_test.yaml"): readFileA,
filepath.Join("a", "c", "c_test.yaml"): readFileB,
filepath.Join(".krmignore"): []byte(`
a/c/c_test.yaml
`,
),
},
expected: []string{
`a: a`,
`c: c`,
},
},
{
name: "ignore folder",
directories: []string{
filepath.Join("a", "b"),
filepath.Join("a", "c"),
},
files: map[string][]byte{
filepath.Join("pkgFile"): {},
filepath.Join("a", "b", "a_test.yaml"): readFileA,
filepath.Join("a", "c", "c_test.yaml"): readFileB,
filepath.Join(".krmignore"): []byte(`
a/c
`,
),
},
expected: []string{
`a: a`,
`c: c`,
},
},
{
name: "krmignore file in subpackage",
directories: []string{
filepath.Join("a", "c"),
},
files: map[string][]byte{
filepath.Join("pkgFile"): {},
filepath.Join("a", "c", "a_test.yaml"): readFileA,
filepath.Join("a", "c", "c_test.yaml"): readFileB,
filepath.Join(".krmignore"): []byte(`
d/e/f.yaml
`,
),
filepath.Join("a", "c", "pkgFile"): {},
filepath.Join("a", "c", ".krmignore"): []byte(`
a_test.yaml
`),
},
expected: []string{
`b: b`,
},
},
{
name: "krmignore files does not affect subpackages",
directories: []string{
filepath.Join("a", "c"),
},
files: map[string][]byte{
filepath.Join("pkgFile"): {},
filepath.Join("a", "c", "a_test.yaml"): readFileA,
filepath.Join("a", "c", "c_test.yaml"): readFileB,
filepath.Join(".krmignore"): []byte(`
a/c/c_test.yaml
`,
),
filepath.Join("a", "c", "pkgFile"): {},
filepath.Join("a", "c", ".krmignore"): []byte(`
a_test.yaml
`),
},
expected: []string{
`b: b`,
},
},
}
for i := range testCases {
test := testCases[i]
t.Run(test.name, func(t *testing.T) {
s := SetupDirectories(t, test.directories...)
defer s.Clean()
for path, content := range test.files {
s.WriteFile(t, path, content)
}
// empty path
rfr := LocalPackageReader{
PackagePath: s.Root,
IncludeSubpackages: true,
PackageFileName: "pkgFile",
OmitReaderAnnotations: true,
}
nodes, err := rfr.Read()
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
if !assert.Len(t, nodes, len(test.expected)) {
assert.FailNow(t, "wrong number items")
}
for i, node := range nodes {
val, err := node.String()
assert.NoError(t, err)
want := strings.ReplaceAll(test.expected[i], "${SEP}", string(filepath.Separator))
assert.Equal(t, strings.TrimSpace(want), strings.TrimSpace(val))
}
})
}
}

View File

@@ -184,8 +184,13 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
var operand ResourceNodeSlice
var pathRelativeTo string
r.PackagePath = filepath.Clean(r.PackagePath)
err := filepath.Walk(r.PackagePath, func(
var err error
ignoreFilesMatcher := &ignoreFilesMatcher{}
r.PackagePath, err = filepath.Abs(r.PackagePath)
if err != nil {
return nil, errors.Wrap(err)
}
err = filepath.Walk(r.PackagePath, func(
path string, info os.FileInfo, err error) error {
if err != nil {
return errors.Wrap(err)
@@ -194,9 +199,10 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
// is this the user specified path?
if path == r.PackagePath {
if info.IsDir() {
// skip the root package directory
// skip the root package directory, but check for a
// .krmignore file first.
pathRelativeTo = r.PackagePath
return nil
return ignoreFilesMatcher.readIgnoreFile(path)
}
// user specified path is a file rather than a directory.
@@ -206,9 +212,9 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
// check if we should skip the directory or file
if info.IsDir() {
return r.ShouldSkipDir(path)
return r.ShouldSkipDir(path, ignoreFilesMatcher)
}
if match, err := r.ShouldSkipFile(info); err != nil {
if match, err := r.ShouldSkipFile(path, ignoreFilesMatcher); err != nil {
return err
} else if !match {
// skip this file
@@ -251,10 +257,15 @@ func (r *LocalPackageReader) readFile(path string, _ os.FileInfo) ([]*yaml.RNode
}
// ShouldSkipFile returns true if the file should be skipped
func (r *LocalPackageReader) ShouldSkipFile(info os.FileInfo) (bool, error) {
func (r *LocalPackageReader) ShouldSkipFile(path string, matcher *ignoreFilesMatcher) (bool, error) {
// check if the file is covered by a .krmignore file.
if matcher.matchFile(path) {
return false, nil
}
// check if the files are in scope
for _, g := range r.MatchFilesGlob {
if match, err := filepath.Match(g, info.Name()); err != nil {
if match, err := filepath.Match(g, filepath.Base(path)); err != nil {
return false, errors.Wrap(err)
} else if match {
return true, nil
@@ -274,13 +285,22 @@ func (r *LocalPackageReader) initReaderAnnotations(path string, _ os.FileInfo) {
}
// ShouldSkipDir returns a filepath.SkipDir if the directory should be skipped
func (r *LocalPackageReader) ShouldSkipDir(path string) error {
func (r *LocalPackageReader) ShouldSkipDir(path string, matcher *ignoreFilesMatcher) error {
if r.PackageFileName == "" {
// If the folder is not a package, but covered by the .krmignore file,
// we skip it.
if matcher.matchDir(path) {
return filepath.SkipDir
}
return nil
}
// check if this is a subpackage
_, err := os.Stat(filepath.Join(path, r.PackageFileName))
if os.IsNotExist(err) {
// Skip the folder if it is covered by the .krmignore file.
if matcher.matchDir(path) {
return filepath.SkipDir
}
return nil
} else if err != nil {
return errors.Wrap(err)
@@ -288,5 +308,9 @@ func (r *LocalPackageReader) ShouldSkipDir(path string) error {
if !r.IncludeSubpackages {
return filepath.SkipDir
}
return nil
// We don't allow the .krmignore file in a package cause us to skip
// a subpackage. So if we have found a package file in the folder and
// we should include subpackages, we don't check the .krmignore file. We
// do however check whether the package contains a .krmignore file.
return matcher.readIgnoreFile(path)
}

View File

@@ -4,59 +4,14 @@
package kio_test
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/kyaml/kio"
// "sigs.k8s.io/kustomize/kyaml/testutil"
)
// setup creates directories and files for testing
type setup struct {
// root is the tmp directory
root string
}
// setupDirectories creates directories for reading test configuration from
func setupDirectories(t *testing.T, dirs ...string) setup {
d, err := ioutil.TempDir("", "kyaml-test")
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
err = os.Chdir(d)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
for _, s := range dirs {
err = os.MkdirAll(s, 0700)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
}
return setup{root: d}
}
// writeFile writes a file under the test directory
func (s setup) writeFile(t *testing.T, path string, value []byte) {
err := os.MkdirAll(filepath.Dir(filepath.Join(s.root, path)), 0700)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
err = ioutil.WriteFile(filepath.Join(s.root, path), value, 0600)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
}
// clean deletes the test config
func (s setup) clean() {
os.RemoveAll(s.root)
}
var readFileA = []byte(`---
a: b #first
---
@@ -94,18 +49,18 @@ func TestLocalPackageReader_Read_empty(t *testing.T) {
}
func TestLocalPackageReader_Read_pkg(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
s.writeFile(t, filepath.Join("c_test.yaml"), readFileC)
s.writeFile(t, filepath.Join("d_test.yaml"), readFileD)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
s.WriteFile(t, filepath.Join("c_test.yaml"), readFileC)
s.WriteFile(t, filepath.Join("d_test.yaml"), readFileD)
paths := []struct {
path string
}{
{path: "./"},
{path: s.root},
{path: s.Root},
}
for _, p := range paths {
rfr := LocalPackageReader{PackagePath: p.path}
@@ -167,13 +122,13 @@ metadata:
}
func TestLocalPackageReader_Read_JSON(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.writeFile(t, filepath.Join("a_test.json"), []byte(`{
s.WriteFile(t, filepath.Join("a_test.json"), []byte(`{
"a": "b"
}`))
s.writeFile(t, filepath.Join("b_test.json"), []byte(`{
s.WriteFile(t, filepath.Join("b_test.json"), []byte(`{
"e": "f",
"g": {
"h": ["i", "j"]
@@ -184,7 +139,7 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) {
path string
}{
{path: "./"},
{path: s.root},
{path: s.Root},
}
for _, p := range paths {
rfr := LocalPackageReader{PackagePath: p.path, MatchFilesGlob: []string{"*.json"}}
@@ -217,16 +172,16 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) {
}
func TestLocalPackageReader_Read_file(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
paths := []struct {
path string
}{
{path: "./"},
{path: s.root},
{path: s.Root},
}
for _, p := range paths {
rfr := LocalPackageReader{PackagePath: filepath.Join(p.path, "a_test.yaml")}
@@ -265,16 +220,16 @@ metadata:
}
func TestLocalPackageReader_Read_pkgOmitAnnotations(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
paths := []struct {
path string
}{
{path: "./"},
{path: s.root},
{path: s.Root},
}
for _, p := range paths {
// empty path
@@ -313,16 +268,16 @@ g:
}
func TestLocalPackageReader_Read_nestedDirs(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
paths := []struct {
path string
}{
{path: "./"},
{path: s.root},
{path: s.Root},
}
for _, p := range paths {
// empty path
@@ -374,13 +329,13 @@ metadata:
}
func TestLocalPackageReader_Read_matchRegex(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
// empty path
rfr := LocalPackageReader{PackagePath: s.root, MatchFilesGlob: []string{`a*.yaml`}}
rfr := LocalPackageReader{PackagePath: s.Root, MatchFilesGlob: []string{`a*.yaml`}}
nodes, err := rfr.Read()
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
@@ -414,14 +369,14 @@ metadata:
}
func TestLocalPackageReader_Read_skipSubpackage(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
// empty path
rfr := LocalPackageReader{PackagePath: s.root, PackageFileName: "pkgFile"}
rfr := LocalPackageReader{PackagePath: s.Root, PackageFileName: "pkgFile"}
nodes, err := rfr.Read()
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
@@ -455,14 +410,14 @@ metadata:
}
func TestLocalPackageReader_Read_includeSubpackage(t *testing.T) {
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.clean()
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.writeFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
defer s.Clean()
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
s.WriteFile(t, filepath.Join("a", "c", "c_test.yaml"), readFileB)
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
// empty path
rfr := LocalPackageReader{PackagePath: s.root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
rfr := LocalPackageReader{PackagePath: s.Root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
nodes, err := rfr.Read()
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())

55
kyaml/kio/testing.go Normal file
View File

@@ -0,0 +1,55 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package kio
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
// Setup creates directories and files for testing
type Setup struct {
// root is the tmp directory
Root string
}
// setupDirectories creates directories for reading test configuration from
func SetupDirectories(t *testing.T, dirs ...string) Setup {
d, err := ioutil.TempDir("", "kyaml-test")
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
err = os.Chdir(d)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
for _, s := range dirs {
err = os.MkdirAll(s, 0700)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
}
return Setup{Root: d}
}
// writeFile writes a file under the test directory
func (s Setup) WriteFile(t *testing.T, path string, value []byte) {
err := os.MkdirAll(filepath.Dir(filepath.Join(s.Root, path)), 0700)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
err = ioutil.WriteFile(filepath.Join(s.Root, path), value, 0600)
if !assert.NoError(t, err) {
assert.FailNow(t, err.Error())
}
}
// clean deletes the test config
func (s Setup) Clean() {
os.RemoveAll(s.Root)
}