Grep with subpackages

This commit is contained in:
Phani Teja Marupaka
2020-09-08 16:59:23 -07:00
parent d2f23a4b8b
commit 8e4c8464e7
2 changed files with 202 additions and 26 deletions

View File

@@ -5,10 +5,12 @@ package commands
import (
"fmt"
"io"
"strings"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/resource"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/filters"
@@ -18,13 +20,13 @@ import (
func GetGrepRunner(name string) *GrepRunner {
r := &GrepRunner{}
c := &cobra.Command{
Use: "grep QUERY [DIR]...",
Use: "grep QUERY [DIR]",
Short: commands.GrepShort,
Long: commands.GrepLong,
Example: commands.GrepExamples,
PreRunE: r.preRunE,
RunE: r.runE,
Args: cobra.MinimumNArgs(1),
Args: cobra.MaximumNArgs(2),
}
fixDocs(name, c)
c.Flags().BoolVar(&r.IncludeSubpackages, "include-subpackages", true,
@@ -33,7 +35,8 @@ func GetGrepRunner(name string) *GrepRunner {
"annotate resources with their file origins.")
c.Flags().BoolVarP(&r.InvertMatch, "invert-match", "", false,
"Selected Resources are those not matching any of the specified patterns..")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", true,
"also print resources recursively in all the nested subpackages")
r.Command = c
return r
}
@@ -48,7 +51,8 @@ type GrepRunner struct {
KeepAnnotations bool
Command *cobra.Command
filters.GrepFilter
Format bool
Format bool
RecurseSubPackages bool
}
func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
@@ -101,25 +105,56 @@ func (r *GrepRunner) preRunE(c *cobra.Command, args []string) error {
}
func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
var filters = []kio.Filter{r.GrepFilter}
var inputs []kio.Reader
for _, a := range args[1:] {
inputs = append(inputs, kio.LocalPackageReader{
PackagePath: a,
IncludeSubpackages: r.IncludeSubpackages,
})
}
if len(inputs) == 0 {
inputs = append(inputs, &kio.ByteReader{Reader: c.InOrStdin()})
if len(args) == 1 {
input := &kio.ByteReader{Reader: c.InOrStdin()}
return handleError(c, kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: []kio.Filter{r.GrepFilter},
Outputs: []kio.Writer{kio.ByteWriter{
Writer: c.OutOrStdout(),
KeepReaderAnnotations: r.KeepAnnotations,
}},
}.Execute())
}
return handleError(c, kio.Pipeline{
Inputs: inputs,
Filters: filters,
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[1],
}
return e.execute()
}
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
fmt.Fprintf(w, "%q:\n", pkgPath)
err = kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: []kio.Filter{r.GrepFilter},
Outputs: []kio.Writer{kio.ByteWriter{
Writer: c.OutOrStdout(),
Writer: w,
KeepReaderAnnotations: r.KeepAnnotations,
}},
}.Execute())
}.Execute()
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s in package %q\n", err.Error(), pkgPath)
}
}
return nil
}

View File

@@ -8,10 +8,12 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
)
// TestGrepCommand_files verifies grep reads the files and filters them
@@ -68,7 +70,7 @@ spec:
return
}
if !assert.Equal(t, `kind: Deployment
if !assert.Contains(t, b.String(), `kind: Deployment
metadata:
labels:
app: nginx2
@@ -90,7 +92,7 @@ metadata:
spec:
selector:
app: nginx
`, b.String()) {
`) {
return
}
}
@@ -136,7 +138,7 @@ spec:
return
}
if !assert.Equal(t, `kind: Deployment
if !assert.Contains(t, b.String(), `kind: Deployment
metadata:
labels:
app: nginx2
@@ -156,7 +158,7 @@ metadata:
spec:
selector:
app: nginx
`, b.String()) {
`) {
return
}
}
@@ -250,7 +252,7 @@ spec:
if !assert.NoError(t, err) {
return
}
if !assert.Equal(t, `kind: Deployment
if !assert.Contains(t, b.String(), `kind: Deployment
metadata:
labels:
app: nginx1.7
@@ -264,7 +266,146 @@ spec:
containers:
- name: nginx
image: nginx:1.7.9
`, b.String()) {
`) {
return
}
}
func TestGrepSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "grep-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"kind=Deployment"},
expected: `
"${baseDir}/mysql":
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: mysql-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9
"${baseDir}/mysql/storage":
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: storage-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7
`,
},
{
name: "grep-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"kind=Deployment", "-R=false"},
packagePath: "mysql",
expected: `
"${baseDir}/mysql":
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: mysql-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 3
template:
spec:
containers:
- name: mysql
image: mysql:1.7.9`,
},
{
name: "grep-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"kind=Deployment", "-R=false"},
expected: `
"${baseDir}/mysql/storage":
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: myspace
name: storage-deployment
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'deployment.yaml'
spec:
replicas: 4
template:
spec:
containers:
- name: storage
image: storage:1.7.7`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := commands.GetGrepRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append(test.args, filepath.Join(baseDir, test.packagePath)))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}