mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-16 17:33:14 +00:00
Add support for .krmignore file
This commit is contained in:
10
kyaml/ext/ext.go
Normal file
10
kyaml/ext/ext.go
Normal 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"
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ require (
|
|||||||
github.com/go-openapi/spec v0.19.5
|
github.com/go-openapi/spec v0.19.5
|
||||||
github.com/go-openapi/strfmt v0.19.5
|
github.com/go-openapi/strfmt v0.19.5
|
||||||
github.com/go-openapi/validate v0.19.8
|
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/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
|
|||||||
@@ -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 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
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/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/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/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=
|
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
|
||||||
|
|||||||
99
kyaml/kio/ignorefilesmatcher.go
Normal file
99
kyaml/kio/ignorefilesmatcher.go
Normal 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
|
||||||
|
}
|
||||||
203
kyaml/kio/ignorefilesmatcher_test.go
Normal file
203
kyaml/kio/ignorefilesmatcher_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -184,8 +184,13 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
|
|||||||
|
|
||||||
var operand ResourceNodeSlice
|
var operand ResourceNodeSlice
|
||||||
var pathRelativeTo string
|
var pathRelativeTo string
|
||||||
r.PackagePath = filepath.Clean(r.PackagePath)
|
var err error
|
||||||
err := filepath.Walk(r.PackagePath, func(
|
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 {
|
path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
@@ -194,9 +199,10 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) {
|
|||||||
// is this the user specified path?
|
// is this the user specified path?
|
||||||
if path == r.PackagePath {
|
if path == r.PackagePath {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
// skip the root package directory
|
// skip the root package directory, but check for a
|
||||||
|
// .krmignore file first.
|
||||||
pathRelativeTo = r.PackagePath
|
pathRelativeTo = r.PackagePath
|
||||||
return nil
|
return ignoreFilesMatcher.readIgnoreFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// user specified path is a file rather than a directory.
|
// 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
|
// check if we should skip the directory or file
|
||||||
if info.IsDir() {
|
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
|
return err
|
||||||
} else if !match {
|
} else if !match {
|
||||||
// skip this file
|
// 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
|
// 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
|
// check if the files are in scope
|
||||||
for _, g := range r.MatchFilesGlob {
|
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)
|
return false, errors.Wrap(err)
|
||||||
} else if match {
|
} else if match {
|
||||||
return true, nil
|
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
|
// 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 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
|
return nil
|
||||||
}
|
}
|
||||||
// check if this is a subpackage
|
// check if this is a subpackage
|
||||||
_, err := os.Stat(filepath.Join(path, r.PackageFileName))
|
_, err := os.Stat(filepath.Join(path, r.PackageFileName))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
// Skip the folder if it is covered by the .krmignore file.
|
||||||
|
if matcher.matchDir(path) {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
@@ -288,5 +308,9 @@ func (r *LocalPackageReader) ShouldSkipDir(path string) error {
|
|||||||
if !r.IncludeSubpackages {
|
if !r.IncludeSubpackages {
|
||||||
return filepath.SkipDir
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,59 +4,14 @@
|
|||||||
package kio_test
|
package kio_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
. "sigs.k8s.io/kustomize/kyaml/kio"
|
. "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(`---
|
var readFileA = []byte(`---
|
||||||
a: b #first
|
a: b #first
|
||||||
---
|
---
|
||||||
@@ -94,18 +49,18 @@ func TestLocalPackageReader_Read_empty(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_pkg(t *testing.T) {
|
func TestLocalPackageReader_Read_pkg(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("c_test.yaml"), readFileC)
|
s.WriteFile(t, filepath.Join("c_test.yaml"), readFileC)
|
||||||
s.writeFile(t, filepath.Join("d_test.yaml"), readFileD)
|
s.WriteFile(t, filepath.Join("d_test.yaml"), readFileD)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: p.path}
|
rfr := LocalPackageReader{PackagePath: p.path}
|
||||||
@@ -167,13 +122,13 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
|
|
||||||
s.writeFile(t, filepath.Join("a_test.json"), []byte(`{
|
s.WriteFile(t, filepath.Join("a_test.json"), []byte(`{
|
||||||
"a": "b"
|
"a": "b"
|
||||||
}`))
|
}`))
|
||||||
s.writeFile(t, filepath.Join("b_test.json"), []byte(`{
|
s.WriteFile(t, filepath.Join("b_test.json"), []byte(`{
|
||||||
"e": "f",
|
"e": "f",
|
||||||
"g": {
|
"g": {
|
||||||
"h": ["i", "j"]
|
"h": ["i", "j"]
|
||||||
@@ -184,7 +139,7 @@ func TestLocalPackageReader_Read_JSON(t *testing.T) {
|
|||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: p.path, MatchFilesGlob: []string{"*.json"}}
|
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) {
|
func TestLocalPackageReader_Read_file(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
rfr := LocalPackageReader{PackagePath: filepath.Join(p.path, "a_test.yaml")}
|
rfr := LocalPackageReader{PackagePath: filepath.Join(p.path, "a_test.yaml")}
|
||||||
@@ -265,16 +220,16 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_pkgOmitAnnotations(t *testing.T) {
|
func TestLocalPackageReader_Read_pkgOmitAnnotations(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
// empty path
|
// empty path
|
||||||
@@ -313,16 +268,16 @@ g:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_nestedDirs(t *testing.T) {
|
func TestLocalPackageReader_Read_nestedDirs(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
||||||
|
|
||||||
paths := []struct {
|
paths := []struct {
|
||||||
path string
|
path string
|
||||||
}{
|
}{
|
||||||
{path: "./"},
|
{path: "./"},
|
||||||
{path: s.root},
|
{path: s.Root},
|
||||||
}
|
}
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
// empty path
|
// empty path
|
||||||
@@ -374,13 +329,13 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_matchRegex(t *testing.T) {
|
func TestLocalPackageReader_Read_matchRegex(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
s.WriteFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
||||||
s.writeFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
s.WriteFile(t, filepath.Join("a", "b", "b_test.yaml"), readFileB)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, MatchFilesGlob: []string{`a*.yaml`}}
|
rfr := LocalPackageReader{PackagePath: s.Root, MatchFilesGlob: []string{`a*.yaml`}}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
@@ -414,14 +369,14 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_skipSubpackage(t *testing.T) {
|
func TestLocalPackageReader_Read_skipSubpackage(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
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", "c_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, PackageFileName: "pkgFile"}
|
rfr := LocalPackageReader{PackagePath: s.Root, PackageFileName: "pkgFile"}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
@@ -455,14 +410,14 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLocalPackageReader_Read_includeSubpackage(t *testing.T) {
|
func TestLocalPackageReader_Read_includeSubpackage(t *testing.T) {
|
||||||
s := setupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
s := SetupDirectories(t, filepath.Join("a", "b"), filepath.Join("a", "c"))
|
||||||
defer s.clean()
|
defer s.Clean()
|
||||||
s.writeFile(t, filepath.Join("a", "b", "a_test.yaml"), readFileA)
|
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", "c_test.yaml"), readFileB)
|
||||||
s.writeFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
s.WriteFile(t, filepath.Join("a", "c", "pkgFile"), pkgFile)
|
||||||
|
|
||||||
// empty path
|
// empty path
|
||||||
rfr := LocalPackageReader{PackagePath: s.root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
|
rfr := LocalPackageReader{PackagePath: s.Root, IncludeSubpackages: true, PackageFileName: "pkgFile"}
|
||||||
nodes, err := rfr.Read()
|
nodes, err := rfr.Read()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
assert.FailNow(t, err.Error())
|
assert.FailNow(t, err.Error())
|
||||||
|
|||||||
55
kyaml/kio/testing.go
Normal file
55
kyaml/kio/testing.go
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user