bazel-gazelle icon indicating copy to clipboard operation
bazel-gazelle copied to clipboard

Gazelle strips data files used in go:embed

Open iangudger opened this issue 1 year ago • 10 comments

What version of gazelle are you using?

v0.26.0

What version of rules_go are you using?

v0.34.0

What version of Bazel are you using?

5.2.0

Does this issue reproduce with the latest releases of all the above?

These are the latest versions at the time of writing.

What operating system and processor architecture are you using?

Linux 5.15.0-1013-gcp

Intel(R) Xeon(R) CPU @ 2.20GHz

AMD64/EM64T

What did you do?

I added a dependency on github.com/go-ego/gse. I used the recommended workflow where the dependency is first added to go.mod and then imported with bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=deps.bzl%go_dependencies.

What did you expect to see?

Build success.

What did you see instead?

# bazel build //third_party/zinclabs/zinc/routes 
INFO: Analyzed target //third_party/zinclabs/zinc/routes:routes (530 packages loaded, 12782 targets configured).
INFO: Found 1 target...
ERROR: /root/.cache/bazel/_bazel_root/01314bf940876cada24aeb02ece50b59/external/com_github_go_ego_gse/BUILD.bazel:3:11: GoCompilePkg external/com_github_go_ego_gse/gse.a failed: (Exit 1): builder failed: error executing command bazel-out/k8-opt-exec-2B5CBBC6/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src external/com_github_go_ego_gse/dag.go -src ... (remaining 45 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
compilepkg: /root/.cache/bazel/_bazel_root/01314bf940876cada24aeb02ece50b59/sandbox/processwrapper-sandbox/68/execroot/__main__/external/com_github_go_ego_gse/dict_embed.go:11:13: could not embed data/dict/jp/dict.txt: no matching files found
Target //third_party/zinclabs/zinc/routes:routes failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 28.170s, Critical Path: 10.34s
INFO: 75 processes: 16 internal, 59 processwrapper-sandbox.
FAILED: Build did NOT complete successfully

It seems that Gazelle is removing the data directory of github.com/go-ego/gse when it copies source files. The go:embed then fails to find the files. I believe the problem is that the embedded files are in a subdirectory. go mod vendor preserves this directory, so I think it is a Gazelle specific issue.

I was able to work around the issue by using the github.com/go-ego/gse project's ne build tag.

iangudger avatar Aug 13 '22 20:08 iangudger

Hey @iangudger, good to see you!

Another possible problem is that the embed_srcs implementation in rules_go can't cross build package boundaries (so far as I know). Do you have a sample repo I could use to poke at this a little bit?

achew22 avatar Aug 13 '22 21:08 achew22

https://github.com/iangudger/zinc_demo

iangudger avatar Aug 14 '22 19:08 iangudger

Thanks for the repo link. Looks like it's just not finding the file for ... some reason?

➜  gse git:(master) gazelle -repo_root . .
gazelle: /private/tmp/gse/crf: go prefix is not set, so importpath can't be determined for rules. Set a prefix with a '# gazelle:prefix' comment or with -go_prefix on the command line
gazelle: /private/tmp/gse/dict_embed.go:11:3: pattern data/dict/jp/dict.txt: matched no files
gazelle: /private/tmp/gse/dict_embed.go:14:3: pattern data/dict/zh/t_1.txt: matched no files
gazelle: /private/tmp/gse/dict_embed.go:16:3: pattern data/dict/zh/s_1.txt: matched no files
gazelle: /private/tmp/gse/dict_embed.go:20:2: pattern data/dict/zh/stop_tokens.txt: matched no files
➜  gse git:(master) ls data/dict/jp/dict.txt
data/dict/jp/dict.txt

Why wouldn't it be in that dir? Well, it turns out it's getting excluded from consideration because there is a .go file in the path between the embedding target and the file to be embedded.

➜  gse git:(master) ls data/main.go
data/main.go

I'm not sure what can be done about that. Bazel doesn't allow anything to traverse a package boundary without having an entry in the BUILD file that governs it. We can't omit the BUILD file, or the data/main.go file wouldn't be able to be invoked. Even if we couldn't right now it's not possible in rules_go to embed from another package. I'm happy to leave this issue around as a tombstone feature request, but I don't really know how one would go about fixing it.

WDYT @iangudger?

achew22 avatar Aug 21 '22 03:08 achew22

@achew22, thanks for looking into it! How is this different from https://github.com/bazelbuild/bazel-gazelle/issues/1192 which was supposedly fixed?

iangudger avatar Aug 21 '22 06:08 iangudger

I think that PR covers the case of A (parent) embedding a buildable subdir (B). This case is A (parent) embedding a buildable subdir (B) which then has embedded data inside of it (C).

achew22 avatar Aug 21 '22 18:08 achew22

fwiw I am also seeing this. It's impossible to build k8s.io/kubectl because of this.

https://github.com/kubernetes/kubectl/blob/5ef32b94c02dc1206f4b5a3f00728363bb62e8dc/pkg/explain/v2/template.go#L25-L26

ERROR: /home/thomas/.cache/bazel/_bazel_thomas/5ced9b658c4071801666548792308eaf/external/io_k8s_kubectl/pkg/explain/v2/BUILD.bazel:3:11: GoCompilePkg external/io_k8s_kubectl/pkg/explain/v2/explain.a failed: (Exit 1): builder failed: error executing command (from target @io_k8s_kubectl//pkg/explain/v2:explain) bazel-out/k8-opt-exec-2B5CBBC6/bin/external/go_sdk/builder_reset/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src external/io_k8s_kubectl/pkg/explain/v2/explain.go -src ... (remaining 37 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
compilepkg: /home/thomas/.cache/bazel/_bazel_thomas/5ced9b658c4071801666548792308eaf/sandbox/linux-sandbox/777/execroot/com_github_uhthomas_automata/external/io_k8s_kubectl/pkg/explain/v2/template.go:25:12: could not embed templates/*.tmpl: no matching files found
Target //k8s/unwind:object.apply failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 38.172s, Critical Path: 26.75s
INFO: 932 processes: 156 internal, 776 linux-sandbox.
FAILED: Build did NOT complete successfully
ERROR: Build failed. Not running target

uhthomas avatar May 04 '23 13:05 uhthomas

I'm also facing this problem with the Docker CLI, because it embeds files in a data directory (https://github.com/docker/cli/blob/v23.0.1/cli/compose/schema/schema.go#L62):

compilepkg: [...]/external/com_github_docker_cli/cli/compose/schema/schema.go:62:12: could not embed data/config_schema_v*.json: no matching files found

zakcutner avatar Aug 02 '23 13:08 zakcutner

Same Problem as @zakcutner Are there any workarounds ?

dvelop-jkas avatar Nov 17 '23 23:11 dvelop-jkas

Just confirming I'm seeing the same problem. With the docker CLI.

loganasherjones avatar Mar 30 '24 01:03 loganasherjones

Finally getting around to documenting my workaround. I ended up having to use the patches portion of the go_repository. So I manually deleted the doc.go that is causing trouble and created the following patch:

diff --git a/cli/compose/schema/BUILD.bazel b/cli/compose/schema/BUILD.bazel
index e8a4e79..0ae1114 100644
--- a/cli/compose/schema/BUILD.bazel
+++ b/cli/compose/schema/BUILD.bazel
@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
 go_library(
     name = "schema",
     srcs = ["schema.go"],
+    embedsrcs = glob(["data/config_schema_v*.json"]),
     importpath = "github.com/docker/cli/cli/compose/schema",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/cli/compose/schema/data/BUILD.bazel b/cli/compose/schema/data/BUILD.bazel
deleted file mode 100644
index 444c30a..0000000
--- a/cli/compose/schema/data/BUILD.bazel
+++ /dev/null
@@ -1,14 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "data",
-    srcs = ["doc.go"],
-    importpath = "github.com/docker/cli/cli/compose/schema/data",
-    visibility = ["//visibility:public"],
-)
-
-alias(
-    name = "go_default_library",
-    actual = ":data",
-    visibility = ["//visibility:public"],
-)
diff --git a/cli/compose/schema/data/doc.go b/cli/compose/schema/data/doc.go
deleted file mode 100644
index f8ddd00..0000000
--- a/cli/compose/schema/data/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
-       Package data contains all the Compose file JSON schemas, starting from v3.0.
-*/
-
-//
-// +domain=docker.com
-
-package data

Then I modified the go_repository to say:

    go_repository(
        name = "com_github_docker_cli",
        build_file_proto_mode = "disable_global",
        importpath = "github.com/docker/cli",
        patch_args = ["-p1"],
        patches = [
            "//third_party/docker_cli:patch.txt",
        ],
        sum = "h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg=",
        version = "v24.0.7+incompatible",
    )

loganasherjones avatar Apr 12 '24 12:04 loganasherjones