Skip to content

Commit 8d56bcb

Browse files
balopatdgageot
authored andcommitted
cleanup on analyzers and moving things into a single package (#3538)
1 parent 586da02 commit 8d56bcb

File tree

9 files changed

+113
-112
lines changed

9 files changed

+113
-112
lines changed

pkg/skaffold/initializer/analyze.go

+31-83
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ limitations under the License.
1717
package initializer
1818

1919
import (
20-
"fmt"
2120
"path/filepath"
2221
"sort"
2322

2423
"github.com/karrick/godirwalk"
25-
"github.com/sirupsen/logrus"
2624

27-
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer/kubectl"
2825
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
2926
)
3027

@@ -34,86 +31,9 @@ type analysis struct {
3431
builderAnalyzer *builderAnalyzer
3532
}
3633

37-
// analyzer is a generic Visitor that is called on every file in the directory
38-
// It can manage state and react to walking events assuming a bread first search
39-
type analyzer interface {
40-
enterDir(dir string)
41-
analyzeFile(file string) error
42-
exitDir(dir string)
43-
}
44-
45-
type directoryAnalyzer struct {
46-
currentDir string
47-
}
48-
49-
func (a *directoryAnalyzer) analyzeFile(filePath string) error {
50-
return nil
51-
}
52-
53-
func (a *directoryAnalyzer) enterDir(dir string) {
54-
a.currentDir = dir
55-
}
56-
57-
func (a *directoryAnalyzer) exitDir(dir string) {
58-
//pass
59-
}
60-
61-
type kubectlAnalyzer struct {
62-
directoryAnalyzer
63-
kubernetesManifests []string
64-
}
65-
66-
func (a *kubectlAnalyzer) analyzeFile(filePath string) error {
67-
if kubectl.IsKubernetesManifest(filePath) && !IsSkaffoldConfig(filePath) {
68-
a.kubernetesManifests = append(a.kubernetesManifests, filePath)
69-
}
70-
return nil
71-
}
72-
73-
type skaffoldConfigAnalyzer struct {
74-
directoryAnalyzer
75-
force bool
76-
}
77-
78-
func (a *skaffoldConfigAnalyzer) analyzeFile(filePath string) error {
79-
if !IsSkaffoldConfig(filePath) {
80-
return nil
81-
}
82-
if !a.force {
83-
return fmt.Errorf("pre-existing %s found (you may continue with --force)", filePath)
84-
}
85-
logrus.Debugf("%s is a valid skaffold configuration: continuing since --force=true", filePath)
86-
return nil
87-
}
88-
89-
type builderAnalyzer struct {
90-
directoryAnalyzer
91-
enableJibInit bool
92-
enableBuildpackInit bool
93-
findBuilders bool
94-
foundBuilders []InitBuilder
95-
96-
parentDirToStopFindBuilders string
97-
}
98-
99-
func (a *builderAnalyzer) analyzeFile(filePath string) error {
100-
if a.findBuilders && (a.parentDirToStopFindBuilders == "" || a.parentDirToStopFindBuilders == a.currentDir) {
101-
builderConfigs, continueSearchingBuilders := detectBuilders(a.enableJibInit, a.enableBuildpackInit, filePath)
102-
a.foundBuilders = append(a.foundBuilders, builderConfigs...)
103-
if !continueSearchingBuilders {
104-
a.parentDirToStopFindBuilders = a.currentDir
105-
}
106-
}
107-
return nil
108-
}
109-
110-
func (a *builderAnalyzer) exitDir(dir string) {
111-
if a.parentDirToStopFindBuilders == dir {
112-
a.parentDirToStopFindBuilders = ""
113-
}
114-
}
115-
116-
// analyze recursively walks a directory and returns the k8s configs and builder configs that it finds
34+
// analyze recursively walks a directory and notifies the analyzers of files and enterDir and exitDir events
35+
// at the end of the analyze function the analysis struct's analyzers should contain the state that we can
36+
// use to do further computation.
11737
func (a *analysis) analyze(dir string) error {
11838
for _, analyzer := range a.analyzers() {
11939
analyzer.enterDir(dir)
@@ -168,3 +88,31 @@ func (a *analysis) analyzers() []analyzer {
16888
a.builderAnalyzer,
16989
}
17090
}
91+
92+
// analyzer is following the visitor pattern. It is called on every file
93+
// as the analysis.analyze function walks the directory structure recursively.
94+
// It can manage state and react to walking events assuming a breadth first search.
95+
type analyzer interface {
96+
enterDir(dir string)
97+
analyzeFile(file string) error
98+
exitDir(dir string)
99+
}
100+
101+
// directoryAnalyzer is a base analyzer that can be included in every analyzer as a convenience
102+
// it saves the current directory on enterDir events. Benefits to include this into other analyzers is that
103+
// they can rely on the current directory var, but also they don't have to implement enterDir and exitDir.
104+
type directoryAnalyzer struct {
105+
currentDir string
106+
}
107+
108+
func (a *directoryAnalyzer) analyzeFile(filePath string) error {
109+
return nil
110+
}
111+
112+
func (a *directoryAnalyzer) enterDir(dir string) {
113+
a.currentDir = dir
114+
}
115+
116+
func (a *directoryAnalyzer) exitDir(dir string) {
117+
//pass
118+
}

pkg/skaffold/initializer/builders.go

+27
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,33 @@ import (
3232
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
3333
)
3434

35+
type builderAnalyzer struct {
36+
directoryAnalyzer
37+
enableJibInit bool
38+
enableBuildpackInit bool
39+
findBuilders bool
40+
foundBuilders []InitBuilder
41+
42+
parentDirToStopFindBuilders string
43+
}
44+
45+
func (a *builderAnalyzer) analyzeFile(filePath string) error {
46+
if a.findBuilders && (a.parentDirToStopFindBuilders == "" || a.parentDirToStopFindBuilders == a.currentDir) {
47+
builderConfigs, continueSearchingBuilders := detectBuilders(a.enableJibInit, a.enableBuildpackInit, filePath)
48+
a.foundBuilders = append(a.foundBuilders, builderConfigs...)
49+
if !continueSearchingBuilders {
50+
a.parentDirToStopFindBuilders = a.currentDir
51+
}
52+
}
53+
return nil
54+
}
55+
56+
func (a *builderAnalyzer) exitDir(dir string) {
57+
if a.parentDirToStopFindBuilders == dir {
58+
a.parentDirToStopFindBuilders = ""
59+
}
60+
}
61+
3562
// autoSelectBuilders takes a list of builders and images, checks if any of the builders' configured target
3663
// images match an image in the image list, and returns a list of the matching builder/image pairs. Also
3764
// separately returns the builder configs and images that didn't have any matches.

pkg/skaffold/initializer/config.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package initializer
1818

1919
import (
20+
"fmt"
2021
"os"
2122
"path/filepath"
2223
"regexp"
@@ -33,7 +34,23 @@ var (
3334
getWd = os.Getwd
3435
)
3536

36-
func generateSkaffoldConfig(k DeploymentInitializer, buildConfigPairs []builderImagePair) *latest.SkaffoldConfig {
37+
type skaffoldConfigAnalyzer struct {
38+
directoryAnalyzer
39+
force bool
40+
}
41+
42+
func (a *skaffoldConfigAnalyzer) analyzeFile(filePath string) error {
43+
if !isSkaffoldConfig(filePath) {
44+
return nil
45+
}
46+
if !a.force {
47+
return fmt.Errorf("pre-existing %s found (you may continue with --force)", filePath)
48+
}
49+
logrus.Debugf("%s is a valid skaffold configuration: continuing since --force=true", filePath)
50+
return nil
51+
}
52+
53+
func generateSkaffoldConfig(k deploymentInitializer, buildConfigPairs []builderImagePair) *latest.SkaffoldConfig {
3754
// if we're here, the user has no skaffold yaml so we need to generate one
3855
// if the user doesn't have any k8s yamls, generate one for each dockerfile
3956
logrus.Info("generating skaffold config")
@@ -53,7 +70,7 @@ func generateSkaffoldConfig(k DeploymentInitializer, buildConfigPairs []builderI
5370
Build: latest.BuildConfig{
5471
Artifacts: artifacts(buildConfigPairs),
5572
},
56-
Deploy: k.GenerateDeployConfig(),
73+
Deploy: k.deployConfig(),
5774
},
5875
}
5976
}

pkg/skaffold/initializer/config_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ import (
2828
)
2929

3030
type stubDeploymentInitializer struct {
31-
deployConfig latest.DeployConfig
31+
config latest.DeployConfig
3232
}
3333

34-
func (s stubDeploymentInitializer) GenerateDeployConfig() latest.DeployConfig {
35-
return s.deployConfig
34+
func (s stubDeploymentInitializer) deployConfig() latest.DeployConfig {
35+
return s.config
3636
}
3737

3838
func (s stubDeploymentInitializer) GetImages() []string {

pkg/skaffold/initializer/init.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/tips"
3232
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
3333
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
34-
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer/kubectl"
3534
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
3635
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/warnings"
3736
)
@@ -40,10 +39,10 @@ import (
4039
// an image we parse out from a Kubernetes manifest
4140
const NoBuilder = "None (image not built from these sources)"
4241

43-
// DeploymentInitializer detects a deployment type and is able to extract image names from it
44-
type DeploymentInitializer interface {
45-
// GenerateDeployConfig generates Deploy Config for skaffold configuration.
46-
GenerateDeployConfig() latest.DeployConfig
42+
// deploymentInitializer detects a deployment type and is able to extract image names from it
43+
type deploymentInitializer interface {
44+
// deployConfig generates Deploy Config for skaffold configuration.
45+
deployConfig() latest.DeployConfig
4746
// GetImages fetches all the images defined in the manifest files.
4847
GetImages() []string
4948
}
@@ -108,7 +107,7 @@ func DoInit(ctx context.Context, out io.Writer, c Config) error {
108107
return err
109108
}
110109

111-
k, err := kubectl.New(a.kubectlAnalyzer.kubernetesManifests)
110+
k, err := newKubectlInitializer(a.kubectlAnalyzer.kubernetesManifests)
112111
if err != nil {
113112
return err
114113
}

pkg/skaffold/initializer/kubectl/kubectl.go renamed to pkg/skaffold/initializer/kubectl.go

+22-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package kubectl
17+
package initializer
1818

1919
import (
2020
"bufio"
@@ -32,29 +32,39 @@ import (
3232

3333
var requiredFields = []string{"apiVersion", "kind", "metadata"}
3434

35-
// Kubectl holds parameters to run kubectl.
36-
type Kubectl struct {
35+
// kubectl implements deploymentInitializer for the kubectl deployer.
36+
type kubectl struct {
3737
configs []string
3838
images []string
3939
}
4040

41-
// New returns a Kubectl skaffold generator.
42-
func New(potentialConfigs []string) (*Kubectl, error) {
41+
// kubectlAnalyzer is a Visitor during the directory analysis that collects kubernetes manifests
42+
type kubectlAnalyzer struct {
43+
directoryAnalyzer
44+
kubernetesManifests []string
45+
}
46+
47+
func (a *kubectlAnalyzer) analyzeFile(filePath string) error {
48+
if IsKubernetesManifest(filePath) && !isSkaffoldConfig(filePath) {
49+
a.kubernetesManifests = append(a.kubernetesManifests, filePath)
50+
}
51+
return nil
52+
}
53+
54+
// newKubectlInitializer returns a kubectl skaffold generator.
55+
func newKubectlInitializer(potentialConfigs []string) (*kubectl, error) {
4356
var k8sConfigs, images []string
4457
for _, file := range potentialConfigs {
4558
imgs, err := parseImagesFromKubernetesYaml(file)
4659
if err == nil {
47-
logrus.Infof("found valid k8s yaml: %s", file)
4860
k8sConfigs = append(k8sConfigs, file)
4961
images = append(images, imgs...)
50-
} else {
51-
logrus.Infof("invalid k8s yaml %s: %s", file, err.Error())
5262
}
5363
}
5464
if len(k8sConfigs) == 0 {
5565
return nil, errors.New("one or more valid Kubernetes manifests is required to run skaffold")
5666
}
57-
return &Kubectl{
67+
return &kubectl{
5868
configs: k8sConfigs,
5969
images: images,
6070
}, nil
@@ -70,9 +80,9 @@ func IsKubernetesManifest(file string) bool {
7080
return err == nil
7181
}
7282

73-
// GenerateDeployConfig implements the Initializer interface and generates
83+
// deployConfig implements the Initializer interface and generates
7484
// skaffold kubectl deployment config.
75-
func (k *Kubectl) GenerateDeployConfig() latest.DeployConfig {
85+
func (k *kubectl) deployConfig() latest.DeployConfig {
7686
return latest.DeployConfig{
7787
DeployType: latest.DeployType{
7888
KubectlDeploy: &latest.KubectlDeploy{
@@ -84,7 +94,7 @@ func (k *Kubectl) GenerateDeployConfig() latest.DeployConfig {
8494

8595
// GetImages implements the Initializer interface and lists all the
8696
// images present in the k8 manifest files.
87-
func (k *Kubectl) GetImages() []string {
97+
func (k *kubectl) GetImages() []string {
8898
return k.images
8999
}
90100

pkg/skaffold/initializer/kubectl/kubectl_test.go renamed to pkg/skaffold/initializer/kubectl_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package kubectl
17+
package initializer
1818

1919
import (
2020
"testing"
@@ -38,7 +38,7 @@ spec:
3838
`)
3939
filename := tmpDir.Path("deployment.yaml")
4040

41-
k, err := New([]string{filename})
41+
k, err := newKubectlInitializer([]string{filename})
4242
if err != nil {
4343
t.Fatal("failed to create a pipeline")
4444
}
@@ -50,7 +50,7 @@ spec:
5050
},
5151
},
5252
}
53-
testutil.CheckDeepEqual(t, expectedConfig, k.GenerateDeployConfig())
53+
testutil.CheckDeepEqual(t, expectedConfig, k.deployConfig())
5454
}
5555

5656
func TestParseImagesFromKubernetesYaml(t *testing.T) {

pkg/skaffold/initializer/util.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package initializer
1818

1919
import "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema"
2020

21-
// IsSkaffoldConfig is for determining if a file is skaffold config file.
22-
func IsSkaffoldConfig(file string) bool {
21+
// isSkaffoldConfig is for determining if a file is skaffold config file.
22+
func isSkaffoldConfig(file string) bool {
2323
if config, err := schema.ParseConfig(file, false); err == nil && config != nil {
2424
return true
2525
}

pkg/skaffold/initializer/util_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ deploy:
5555
tmpDir := t.NewTempDir().
5656
Write("skaffold.yaml", test.contents)
5757

58-
isValid := IsSkaffoldConfig(tmpDir.Path("skaffold.yaml"))
58+
isValid := isSkaffoldConfig(tmpDir.Path("skaffold.yaml"))
5959

6060
t.CheckDeepEqual(test.isValid, isValid)
6161
})

0 commit comments

Comments
 (0)