From 90b4429b40d247d3ef41b7868a8e1f58a91d0d79 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Fri, 21 Jun 2019 18:29:26 +0200 Subject: [PATCH] Bazel: support sub directories Fix #2070 Signed-off-by: David Gageot --- pkg/skaffold/build/bazel/dependencies.go | 45 ++++++++++++++-- pkg/skaffold/build/bazel/dependencies_test.go | 51 +++++++++++++------ 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/pkg/skaffold/build/bazel/dependencies.go b/pkg/skaffold/build/bazel/dependencies.go index 3bd9c7a3075..2a0c81317d3 100644 --- a/pkg/skaffold/build/bazel/dependencies.go +++ b/pkg/skaffold/build/bazel/dependencies.go @@ -39,7 +39,7 @@ func query(target string) string { // GetDependencies finds the sources dependencies for the given bazel artifact. // All paths are relative to the workspace. -func GetDependencies(ctx context.Context, workspace string, a *latest.BazelArtifact) ([]string, error) { +func GetDependencies(ctx context.Context, dir string, a *latest.BazelArtifact) ([]string, error) { timer := time.NewTimer(1 * time.Second) defer timer.Stop() @@ -48,8 +48,18 @@ func GetDependencies(ctx context.Context, workspace string, a *latest.BazelArtif logrus.Warnln("Retrieving Bazel dependencies can take a long time the first time") }() + topLevelFolder, err := findWorkspace(dir) + if err != nil { + return nil, errors.Wrap(err, "unable to find the WORKSPACE file") + } + + absDir, err := filepath.Abs(dir) + if err != nil { + return nil, errors.Wrapf(err, "unable to find absolute path for %s", dir) + } + cmd := exec.CommandContext(ctx, "bazel", "query", query(a.BuildTarget), "--noimplicit_deps", "--order_output=no") - cmd.Dir = workspace + cmd.Dir = dir stdout, err := util.RunCmdOut(cmd) if err != nil { return nil, errors.Wrap(err, "getting bazel dependencies") @@ -68,12 +78,18 @@ func GetDependencies(ctx context.Context, workspace string, a *latest.BazelArtif continue } - deps = append(deps, depToPath(l)) + rel, err := filepath.Rel(absDir, filepath.Join(topLevelFolder, depToPath(l))) + if err != nil { + return nil, errors.Wrap(err, "unable to find absolute path") + } + deps = append(deps, rel) } - if _, err := os.Stat(filepath.Join(workspace, "WORKSPACE")); err == nil { - deps = append(deps, "WORKSPACE") + rel, err := filepath.Rel(absDir, filepath.Join(topLevelFolder, "WORKSPACE")) + if err != nil { + return nil, errors.Wrap(err, "unable to find absolute path") } + deps = append(deps, rel) logrus.Debugf("Found dependencies for bazel artifact: %v", deps) @@ -83,3 +99,22 @@ func GetDependencies(ctx context.Context, workspace string, a *latest.BazelArtif func depToPath(dep string) string { return strings.TrimPrefix(strings.Replace(strings.TrimPrefix(dep, "//"), ":", "/", 1), "/") } + +func findWorkspace(workingDir string) (string, error) { + dir, err := filepath.Abs(workingDir) + if err != nil { + return "", errors.Wrap(err, "invalid working dir") + } + + for { + if _, err := os.Stat(filepath.Join(dir, "WORKSPACE")); err == nil { + return dir, nil + } + + parent := filepath.Dir(dir) + if parent == dir { + return "", errors.New("no WORKSPACE file found") + } + dir = parent + } +} diff --git a/pkg/skaffold/build/bazel/dependencies_test.go b/pkg/skaffold/build/bazel/dependencies_test.go index 3b7a906c7c3..f91fd4bc208 100644 --- a/pkg/skaffold/build/bazel/dependencies_test.go +++ b/pkg/skaffold/build/bazel/dependencies_test.go @@ -18,6 +18,7 @@ package bazel import ( "context" + "path/filepath" "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" @@ -28,41 +29,61 @@ import ( func TestGetDependencies(t *testing.T) { tests := []struct { description string + workspace string target string files map[string]string expectedQuery string output string expected []string + shouldErr bool }{ { - description: "with workspace", - target: "target", - files: map[string]string{"WORKSPACE": "content is ignored"}, + description: "with WORKSPACE", + workspace: ".", + target: "target", + files: map[string]string{ + "WORKSPACE": "", + "BUILD": "", + "dep1": "", + "dep2": "", + }, expectedQuery: "bazel query kind('source file', deps('target')) union buildfiles('target') --noimplicit_deps --order_output=no", - output: "@ignored\n//external/ignored\n\n//:dep1\n//:dep2\n", - expected: []string{"dep1", "dep2", "WORKSPACE"}, + output: "@ignored\n//:BUILD\n//external/ignored\n\n//:dep1\n//:dep2\n", + expected: []string{"BUILD", "dep1", "dep2", "WORKSPACE"}, }, { - description: "without workspace", - target: "target2", - files: map[string]string{}, + description: "with parent WORKSPACE", + workspace: "./sub/folder", + target: "target2", + files: map[string]string{ + "WORKSPACE": "", + "BUILD": "", + "sub/folder/BUILD": "", + "sub/folder/dep1": "", + "sub/folder/dep2": "", + "sub/folder/baz/dep3": "", + }, expectedQuery: "bazel query kind('source file', deps('target2')) union buildfiles('target2') --noimplicit_deps --order_output=no", - output: "@ignored\n//external/ignored\n\n//:dep3\n", - expected: []string{"dep3"}, + output: "@ignored\n//:BUILD\n//sub/folder:BUILD\n//external/ignored\n\n//sub/folder:dep1\n//sub/folder:dep2\n//sub/folder/baz:dep3\n", + expected: []string{filepath.Join("..", "..", "BUILD"), "BUILD", "dep1", "dep2", filepath.Join("baz", "dep3"), filepath.Join("..", "..", "WORKSPACE")}, + }, + { + description: "without WORKSPACE", + workspace: ".", + target: "target", + shouldErr: true, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { t.Override(&util.DefaultExecCommand, t.FakeRunOut(test.expectedQuery, test.output)) - tmpDir := t.NewTempDir(). - WriteFiles(test.files) + t.NewTempDir().WriteFiles(test.files).Chdir() - deps, err := GetDependencies(context.Background(), tmpDir.Root(), &latest.BazelArtifact{ + deps, err := GetDependencies(context.Background(), test.workspace, &latest.BazelArtifact{ BuildTarget: test.target, }) - t.CheckNoError(err) - t.CheckDeepEqual(test.expected, deps) + t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, deps) }) } }