Bazel ignore subdirectory on full build - bazel

In my repository I have some files with the name "build" (automatically generated and/or imported, spread around elsewhere from where I have my bazel build files). These seem to be interpreted by Bazel as its BUILD files, and fail the full build I try to run with bazel build //...
Is there some way I can tell Bazel in a settings configuration file to ignore certain directories altogether? Or perhaps specify the build file names as something other than BUILD, like BUILD.bazel?
Or are my options:
To banish the name build from the entire repository.
To add a gigantic --deleted_packages=<...> to every run of build.
To not use full builds, instead specifying explicit targets.

I think this is a duplicate of the two questions you linked, but to expand on what you asked about in your comment:
You don't have to rename them BUILD.bazel, my suggestion is to add an empty BUILD.bazel to those directories. So you'd end up with:
my-project/
BUILD
src/
build/
stuff-bazel-shouldn't-mess-with
BUILD.bazel # Empty
Then Bazel will check for targets in BUILD.bazel, see that there are none, and won't try to parse the build/ directory.
And there is a distressing lack of documentation about BUILD vs. BUILD.bazel, at least that I could find.

Related

When to prefix a BUILD file (*.BUILD) in Bazel

In its C++ unit testing tutorial, Bazel suggests adding a root level gtest.BUILD file to the workspace root in order to properly integrate Google Test into the test project.
https://docs.bazel.build/versions/master/cpp-use-cases.html
Why would one create a new BUILD file and add gtest prefix to it rather than adding a new build rule to an existing BUILD file in the workspace? Is it just a minor style preference?
Because if you added a BUILD file somewhere in the workspace (e.g. under //third_party/gtest/BUILD) then that file would create a package there.
Then, if you had targets declared in that BUILD file, would their files exist under //third_party/gtest, or would they exist in the zip file that the http_archive downloads? If the former, then there's no need for a http_archive because the files are already in the source tree; if the latter, then the BUILD file references non-existent files in its own package. Both scenarios are flawed.
Better to call gtest's BUILD-file-to-be something that doesn't create a package, but that's descriptive of its purpose.
The build_file attribute of http_archive can reference any file, there's no requirement of the name. The name gtest.BUILD is mostly stylistic, yes, but it also avoids creating a package where it shouldn't. You could say it's an "inactive" BUILD file that will be "active" when Bazel downloads the http_archive, extracts it somewhere, and creates in that directory a symlink called BUILD which points to gtest.BUILD.
Another advantage of having such "inactive" BUILD files is that you can have multiple of them within one package, for multiple http_archives.

How to avoid deleting cached files after build in Bazel

I have a genrule in Bazel that is supposed to manipulate some files. I think I'm not accessing these files by the correct path, so I want to look at the directory structure that Bazel is creating so I can debug.
I added some echo statements to my genrule and I can see that Bazel is working in the directory /home/lyft/.cache/bazel/_bazel_lyft/8de0a1069de8d166c668173ca21c04ae/sandbox/linux-sandbox/1/execroot/. However, after Bazel finishes running, this directory is gone, so I can't look at the directory structure.
How can I prevent Bazel from deleting its temporary files so that I can debug what's happening?
Since this question is a top result for "keep sandbox files after build bazel" Google search and it wasn't obvious for me from the accepted answer, I feel the need to write this answer.
Short answer
Use --sandbox_debug. If this flag is passed, Bazel will not delete the files inside the sandbox folder after the build finishes.
Longer answer
Run bazel build with --sandbox_debug option:
$ bazel build mypackage:mytarget --sandbox_debug
Then you can inspect the contents of the sandbox folder for the project.
To get the location of the sandbox folder for current project, navigate to project and then run:
$ bazel info output_base
/home/johnsmith/.cache/bazel/_bazel_johnsmith/d949417420413f64a0b619cb69f1db69 # output will be something like this
Inside that directory there will be sandbox folder.
Possible caveat: (I'm NOT sure about this but) It's possible that some of the files are missing in sandbox folder, if you previously ran a build without --sandbox_debug flag and it partially succeeded. The reason is Bazel won't rerun parts of the build that already succeeded, and consequently the files corresponding to the successful build parts might not end up in the sandbox.
If you want to make sure all the sandbox files are there, clean the project first using either bazel clean or bazel clean --expunge.
You can use --spawn_strategy=standalone.
You can also use --sandbox_debug to see which directories are mounted to the sandbox.
You can also set the genrule's cmd to find . > $# to debug what's available to the genrule.
Important: declare all srcs/outs/tools that the genrule will read/write/use, and use $(location //label/of:target) to look up their path. Example:
genrule(
name = "x1",
srcs = ["//foo:input1.txt", "//bar:generated_file"],
outs = ["x1out.txt", "x1err.txt"],
tools = ["//util:bin1"],
cmd = "$(location //util:bin1) --input1=$(location //foo:input1.txt) --input2=$(location //bar:generated_file) --some_flag --other_flag >$(location x1out.txt) 2>$(location x1err.txt)",
)

Can I ignore some folder (containing bazel configuration) while building the project recursively?

For some reasons, practical or not, rxjs npm package stores BAZEL.build configuration in the package, so when I'm trying to build my project (which has node_modules folder) bazel tries automatically to build something that it's not supposed to build at all.
My question would be - what is canonical way of ignoring some specific folder while building bazel project recursively?
The only way to achieve what I'm looking for that I know of is to point to it explicitly in the command line
bazel build //... --deleted_packages=node_modules/rxjs/src (see user manual)
But I don't want to type this every time.
Bazel recently added a feature for ignoring folders (similar to gitignore).
Simply add node_modules to the .bazelignore file in the root of your project.
Yes, this is expressible as a bazel target pattern:
bazel build -- //... -//node_modules/rxjs/src/...
Full documentation is available at https://docs.bazel.build/versions/master/user-manual.html#target-patterns

Bazel- How to recursively glob deleted_packages to ignore maven outputs?

I have a mutli-module project which I'm migrating from Maven to Bazel. During this migration people will need to be able to work on both build systems.
After an mvn clean install Maven copies some of the BUILD files into the target folder.
When I later try to run bazel build //... it thinks the BUILD files under the various target folders are valid packages and fails due to some mismatch.
I've seen deleted_packages but AFAICT it requires I specify the list of folders to "delete" while I can't do that for 200+ modules.
I'm looking for the ability to say bazel build //... --deleted_packages=**/target.
Is this supported? (my experimentation says it's not but I might be wrong). If it's not supported is there an existing hack for it?
Can you use your shell to find the list of packages to ignore?
deleted=$(find . -name target -type d)
bazel build //... --deleted_packages="$deleted"
#Laurent's answer gave me the lead but Bazel didn't accept relative paths and required I add both classes and test-classes folders under target to delete the package so I decided to answer with the complete solution:
#!/bin/bash
#find all the target folders under the current working dir
target_folders=$(find . -name target -type d)
#find the repo root (currently assuming it's git based)
repo_root=$(git rev-parse --show-toplevel)
repo_root_length=${#repo_root}
#the current bazel package prefix is the PWD minus the repo root and adding a slash
current_bazel_package="/${PWD:repo_root_length}"
deleted_packages=""
for target in $target_folders
do
#cannonicalize the package path
full_package_path="$current_bazel_package${target:1}"
classes_full="${full_package_path}/classes"
test_classes_full="${full_package_path}/test-classes"
deleted_packages="$deleted_packages,$classes_full,$test_classes_full"
done
#remove the leading comma and call bazel-real with the other args
bazel-real "$#" --deleted_packages=${deleted_packages:1}
This script was checked in under tools/bazel which is why it calls bazel-real at the end.
I'm sorry I don't think this is supported. Some brainstorming:
Is it an option to point maven outputs somewhere else?
Is is an option not to use //... but explicit target(s)?
Maybe just remove the bad BUILD files before running bazel?

TFS copy and deploy: exclude files using minimatch

According to many different SO-questions, it should be possible to exclude files being copied/deployed using the Task "Copy and Publish Build Artifacts" in the new TFS build system.
However it doesn't work for me (it is not excluding anything). What could I be doing wrong:
This should work (I know the question is old but I needed an answer myself)
**\!(System.Windows.Interactivity.resources.dll|*.dll.config|*fluentassertions*)
This is a known issue of the build task “Copy and Publish Build Artifacts”,bitbonk.
Q: This step didn't produce the outcome I was expecting. How can I fix it?
This step has a couple of known issues:
Some minimatch patterns don't work.
It eliminates the most common root path for all paths matched.
Source Link: Utility: Copy and Publish Build Artifacts
Well, it's nothing business with your settings of minimatch. It's just not work for that build task. Certainly, you can also doulbe check your minimatch with Copy Files task to verify this.
For now, you can avoid these issues by instead using the Copy Files step and the Publish Build Artifacts step.
Note: If it's still not working on copy files step, you should pay attention to the architecture of file when using minimatch. There must be something wrong on it.
The task copies the files base on the contents you entered one line by one line and the "!" only exclude the files during the copy, it does not delete the files that already been copied. So with the "**\*" you entered in the first line, all the files have already been copied and published. You need to remove the first line in "Contents". And for the excluded files, if there are in the same folded, you need to exclude them in one line. For example: using
!?(1.txt|2.txt)
to exclude both 1.txt and 2.txt file instead of using
!1.txt
!2.txt

Resources