aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Fradley <joefradley@google.com>2023-11-21 12:53:14 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-21 12:53:14 +0000
commit323c7d29b9bae0171df14138b00a848ef3779792 (patch)
treeff4f2948d51ace255426885412990bc9489474cb
parentf8aadd2ad5a51ac3187333bf589a754c5347d447 (diff)
parent4a69de5007d9c3a9a9dc9a933e4cd5d24e313b97 (diff)
downloadbazel-skylib-323c7d29b9bae0171df14138b00a848ef3779792.tar.gz
Upgrade bazel-skylib to 1.5.0 am: a7ef9ffeaf am: 930baaa099 am: 4a69de5007
Original change: https://android-review.googlesource.com/c/platform/external/bazel-skylib/+/2839138 Change-Id: I8c430b83640d8a69ad5203f326b55e7c9e92e4e5 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.bazelci/presubmit.yml105
-rw-r--r--.bazelignore1
-rw-r--r--BUILD9
-rw-r--r--CHANGELOG.md73
-rw-r--r--METADATA17
-rw-r--r--MODULE.bazel29
-rw-r--r--MODULE.bazel-remove-override.patch16
-rw-r--r--README.md45
-rw-r--r--WORKSPACE60
-rw-r--r--WORKSPACE.bzlmod2
-rw-r--r--bzl_library.bzl11
-rw-r--r--distribution/BUILD81
-rw-r--r--distribution/distribution.bzl32
-rw-r--r--docs/BUILD210
-rwxr-xr-xdocs/analysis_test_doc.md6
-rwxr-xr-xdocs/build_test_doc.md4
-rwxr-xr-xdocs/bzl_library.md88
-rwxr-xr-xdocs/collections_doc.md6
-rwxr-xr-xdocs/common_settings_doc.md52
-rwxr-xr-xdocs/copy_directory_doc.md63
-rwxr-xr-xdocs/copy_file_doc.md2
-rwxr-xr-xdocs/dicts_doc.md48
-rwxr-xr-xdocs/diff_test_doc.md11
-rwxr-xr-xdocs/expand_template_doc.md32
-rw-r--r--docs/maintainers_guide.md121
-rwxr-xr-xdocs/native_binary_doc.md49
-rwxr-xr-xdocs/new_sets_doc.md30
-rwxr-xr-xdocs/partial_doc.md6
-rwxr-xr-xdocs/paths_doc.md16
-rw-r--r--docs/private/BUILD1
-rw-r--r--docs/private/stardoc_with_diff_test.bzl111
-rwxr-xr-xdocs/run_binary_doc.md18
-rwxr-xr-xdocs/select_file_doc.md28
-rwxr-xr-xdocs/selects_doc.md6
-rwxr-xr-xdocs/shell_doc.md4
-rwxr-xr-xdocs/structs_doc.md2
-rwxr-xr-xdocs/subpackages_doc.md96
-rwxr-xr-xdocs/types_doc.md20
-rwxr-xr-xdocs/unittest_doc.md74
-rwxr-xr-xdocs/versions_doc.md19
-rwxr-xr-xdocs/write_file_doc.md4
-rw-r--r--gazelle/BUILD37
-rw-r--r--gazelle/MODULE.bazel21
-rw-r--r--gazelle/WORKSPACE25
-rw-r--r--gazelle/WORKSPACE.bzlmod8
-rw-r--r--gazelle/bzl/BUILD32
-rw-r--r--gazelle/bzl/gazelle.go4
-rw-r--r--gazelle/bzl/gazelle_test.go4
-rw-r--r--gazelle/bzl/testdata/README.md2
-rw-r--r--gazelle/bzl/testdata/empty/BUILD.in2
-rw-r--r--gazelle/setup.bzl32
-rw-r--r--gazelle/workspace.bzl43
-rw-r--r--lib/BUILD5
-rw-r--r--lib/dicts.bzl27
-rw-r--r--lib/subpackages.bzl96
-rw-r--r--lib/unittest.bzl40
-rw-r--r--lib/versions.bzl5
-rw-r--r--rules/BUILD13
-rw-r--r--rules/build_test.bzl21
-rw-r--r--rules/common_settings.bzl53
-rw-r--r--rules/copy_directory.bzl28
-rw-r--r--rules/diff_test.bzl37
-rw-r--r--rules/expand_template.bzl50
-rw-r--r--rules/native_binary.bzl122
-rw-r--r--rules/private/BUILD14
-rw-r--r--rules/private/copy_common.bzl45
-rw-r--r--rules/private/copy_directory_private.bzl157
-rw-r--r--rules/private/copy_file_private.bzl14
-rw-r--r--rules/private/write_file_private.bzl7
-rw-r--r--rules/run_binary.bzl30
-rw-r--r--rules/select_file.bzl5
-rw-r--r--tests/BUILD6
-rwxr-xr-xtests/analysis_test_test.sh19
-rw-r--r--tests/build_test_tests.bzl2
-rw-r--r--tests/common_settings/BUILD25
-rwxr-xr-xtests/common_settings/make_variable_test.sh (renamed from docs/regenerate_docs.sh)14
-rwxr-xr-xtests/common_settings_test.sh4
-rw-r--r--tests/common_settings_tests.bzl167
-rw-r--r--tests/copy_directory/BUILD.bazel43
-rwxr-xr-xtests/copy_directory/copy_directory_tests.sh81
-rw-r--r--tests/copy_directory/dir_with_subdir/a1
-rw-r--r--tests/copy_directory/dir_with_subdir/b1
-rw-r--r--tests/copy_directory/dir_with_subdir/subdir/c1
-rw-r--r--tests/copy_directory/dir_with_symlink/file1
l---------tests/copy_directory/dir_with_symlink/symlink1
-rw-r--r--tests/copy_directory/empty_directory.bzl34
-rwxr-xr-xtests/copy_file/copy_file_tests.sh18
-rw-r--r--tests/dicts_tests.bzl68
-rwxr-xr-xtests/diff_test/diff_test_tests.sh86
-rw-r--r--tests/expand_template/BUILD57
-rwxr-xr-xtests/expand_template/template_test.sh37
-rw-r--r--tests/expand_template/test.cc27
-rw-r--r--tests/expand_template/test.tpl.yaml2
-rw-r--r--tests/expand_template/version.h.in1
-rw-r--r--tests/native_binary/BUILD26
-rw-r--r--tests/native_binary/assertarg.cc7
-rw-r--r--tests/native_binary/assertdata.cc25
-rw-r--r--tests/run_binary/BUILD2
-rw-r--r--tests/select_file/BUILD2
-rw-r--r--tests/selects_tests.bzl4
-rw-r--r--tests/subpackages_tests.bzl88
-rw-r--r--tests/types_tests.bzl2
-rwxr-xr-xtests/unittest.bash10
-rwxr-xr-xtests/unittest_test.sh18
-rw-r--r--tests/versions_tests.bzl5
-rwxr-xr-xtests/write_file/write_file_tests.sh10
-rw-r--r--version.bzl3
107 files changed, 2901 insertions, 584 deletions
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index d7e4845..661c84d 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -1,13 +1,23 @@
---
+.reusable_config: &reusable_config
+ build_targets:
+ - "--"
+ - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+ test_targets:
+ - "--"
+ - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+
tasks:
ubuntu1804_latest:
+ <<: *reusable_config
name: "Latest Bazel"
platform: ubuntu1804
bazel: latest
- build_targets:
- - "//..."
- test_targets:
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
- "--test_env=PATH"
@@ -15,46 +25,57 @@ tasks:
name: "Latest Bazel"
platform: ubuntu1604
bazel: latest
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
build_targets:
+ - "--"
- "//..."
- test_targets:
- - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+ # //distribution requires Python >= 3.6 for some rules_pkg scripts; Ubuntu 16.04 has Python 3.5
+ - "-//distribution/..."
test_flags:
- "--test_env=PATH"
+ test_targets:
+ - "--"
+ - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+ # //distribution requires Python >= 3.6 for some rules_pkg scripts; Ubuntu 16.04 has Python 3.5
+ - "-//distribution/..."
macos_latest:
+ <<: *reusable_config
name: "Latest Bazel"
platform: macos
bazel: latest
- build_targets:
- - "//..."
- test_targets:
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
- "--test_env=PATH"
windows_latest:
+ <<: *reusable_config
name: "Latest Bazel"
platform: windows
bazel: latest
- build_targets:
- - "//..."
- test_targets:
- - "--"
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
# TODO(laszlocsomor): remove "--test_env=LOCALAPPDATA" after
# https://github.com/bazelbuild/bazel/issues/7761 is fixed
- "--test_env=LOCALAPPDATA"
+ - "--test_tag_filters=-no_windows"
ubuntu1804_last_green:
+ <<: *reusable_config
name: "Last Green Bazel"
platform: ubuntu1804
bazel: last_green
- build_targets:
- - "//..."
- test_targets:
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
- "--test_env=PATH"
@@ -62,36 +83,60 @@ tasks:
name: "Last Green Bazel"
platform: ubuntu1604
bazel: last_green
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
build_targets:
+ - "--"
- "//..."
- test_targets:
- - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+ # //distribution requires Python >= 3.6 for some rules_pkg scripts; Ubuntu 16.04 has Python 3.5
+ - "-//distribution/..."
test_flags:
- "--test_env=PATH"
+ test_targets:
+ - "--"
+ - "//..."
+ - "@bazel_skylib_gazelle_plugin//..."
+ # //distribution requires Python >= 3.6 for some rules_pkg scripts; Ubuntu 16.04 has Python 3.5
+ - "-//distribution/..."
macos_last_green:
+ <<: *reusable_config
name: "Last Green Bazel"
platform: macos
bazel: last_green
- build_targets:
- - "//..."
- test_targets:
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
- "--test_env=PATH"
windows_last_green:
+ <<: *reusable_config
name: "Last Green Bazel"
platform: windows
bazel: last_green
- build_targets:
- - "//..."
- test_targets:
- - "--"
- - "//..."
+ build_flags:
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
test_flags:
# TODO(laszlocsomor): remove "--test_env=LOCALAPPDATA" after
# https://github.com/bazelbuild/bazel/issues/7761 is fixed
- "--test_env=LOCALAPPDATA"
+ - "--test_tag_filters=-no_windows"
+
+ ubuntu1804_last_green_bzlmod:
+ <<: *reusable_config
+ name: "Last Green Bazel (with bzlmod)"
+ platform: ubuntu1804
+ bazel: last_green
+ build_flags:
+ - "--enable_bzlmod"
+ - "--incompatible_config_setting_private_default_visibility"
+ - "--incompatible_disallow_empty_glob"
+ test_flags:
+ - "--enable_bzlmod"
+ - "--test_env=PATH"
buildifier: latest
diff --git a/.bazelignore b/.bazelignore
new file mode 100644
index 0000000..dbff643
--- /dev/null
+++ b/.bazelignore
@@ -0,0 +1 @@
+gazelle/
diff --git a/BUILD b/BUILD
index fd7798b..3a0651a 100644
--- a/BUILD
+++ b/BUILD
@@ -7,7 +7,11 @@ package(default_visibility = ["//visibility:public"])
# buildifier: disable=skylark-comment
# gazelle:exclude skylark_library.bzl
-exports_files(["LICENSE"])
+exports_files([
+ "LICENSE",
+ "MODULE.bazel",
+ "WORKSPACE",
+])
filegroup(
name = "test_deps",
@@ -65,10 +69,11 @@ bzl_library(
filegroup(
name = "distribution",
srcs = [
- "LICENSE",
"BUILD",
"CODEOWNERS",
"CONTRIBUTORS",
+ "LICENSE",
+ "WORKSPACE.bzlmod",
"//lib:distribution",
"//rules:distribution",
"//rules/private:distribution",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4567ed3..cd7ef4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,76 @@
+Release 1.5.0
+
+## What's Changed
+* Expose int- and string-valued build settings as Make variables by @fmeum in https://github.com/bazelbuild/bazel-skylib/pull/440
+* Modify actions in order not to need `toolchain` param by @kotlaja in https://github.com/bazelbuild/bazel-skylib/pull/455
+* versions: Don't fail on Bazel dev builds by @fmeum in https://github.com/bazelbuild/bazel-skylib/pull/463
+* Add error for empty `bzl_library` by @keith in https://github.com/bazelbuild/bazel-skylib/pull/457
+* Add `doc` param to `unittest.make` by @UebelAndre in https://github.com/bazelbuild/bazel-skylib/pull/464
+
+## New Contributors
+* @kotlaja made their first contribution in https://github.com/bazelbuild/bazel-skylib/pull/455
+* @keith made their first contribution in https://github.com/bazelbuild/bazel-skylib/pull/457
+
+**Full Changelog**: https://github.com/bazelbuild/bazel-skylib/compare/1.4.2...1.5.0
+
+
+Release 1.4.2
+
+Bugfix release: fixes `build_test` to respect `target_compatible_with` (#448)
+
+**New Features**
+- `bzl_library` allows `.scl` files (new Starlark dialect loadable by Bazel at
+ HEAD with `--experimental_enable_scl_dialect`)
+
+**Contributors**
+Alexandre Rostovtsev, UebelAndre, Vertexwahn, Xavier Bonaventura
+
+
+Release 1.4.1
+
+Bugfix release: fixes gazelle plugin failure with
+`--incompatible_disallow_empty_glob` (#431) and (for released versions) with
+`--incompatible_disable_starlark_host_transitions` (#433).
+
+**Contributors**
+Alexandre Rostovtsev, Chuck Grindel
+
+
+Release 1.4.0
+
+**New Features**
+- The Gazelle plugin is marked stable for general use (#400, #424)
+
+**Other Notable Changes**
+- copy_file/copy_directory again allow sandboxing (#392)
+
+**Contributors**
+Alexandre Rostovtsev, Nick Gooding, Simon Stewart, Xùdōng Yáng
+
+
+Release 1.3.0
+
+**New Features**
+- Added `dicts.omit` and `dicts.pick` (#304)
+- Added `expand_template` rule (#330)
+- Added `subpackages` module (#348)
+- Added `copy_directory` rule (#366)
+- Added `bzlmod` support (#385)
+
+**Incompatible Changes**
+- `native_binary` and `native_test` now use symlinks instead of copying, if
+ the OS supports it (#340)
+- `native_binary` and `native_test` now build in target configuration instead
+ of host configuration (#341)
+- `copy_file` no longer adds non-executables to `default_runfiles` (#326)
+
+**Contributors**
+
+Alex Eagle, Alexandre Rostovtsev, Barry McNamara, Derek Cormier, Fabian
+Meumertzheim, Geoffrey Martin-Noble, hchsiao, Kevin Kres, nickgooding,
+Vertexwahn, Vinh Tran
+
+
Release 1.2.1
Bugfix release: fixes build failure with --incompatible_disallow_empty_glob
diff --git a/METADATA b/METADATA
index 0c4d938..af4cef3 100644
--- a/METADATA
+++ b/METADATA
@@ -1,7 +1,9 @@
-name: "bazel-skylib"
-description:
- ""
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update bazel-skylib
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+name: "bazel-skylib"
+description: ""
third_party {
url {
type: HOMEPAGE
@@ -11,6 +13,11 @@ third_party {
type: GIT
value: "https://github.com/bazelbuild/bazel-skylib.git"
}
- version: "1.2.1"
- last_upgrade_date { year: 2022 month: 6 day: 21 }
+ license_type: NOTICE
+ version: "1.5.0"
+ last_upgrade_date {
+ year: 2023
+ month: 11
+ day: 20
+ }
}
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..298974a
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,29 @@
+module(
+ name = "bazel_skylib",
+ # Keep in sync with version.bzl and @bazel_skylib_gazelle_plugin//:MODULE.bazel
+ version = "1.5.0",
+ compatibility_level = 1,
+)
+
+register_toolchains(
+ "//toolchains/unittest:cmd_toolchain",
+ "//toolchains/unittest:bash_toolchain",
+)
+
+bazel_dep(name = "platforms", version = "0.0.4")
+
+### INTERNAL ONLY - lines after this are not included in the release packaging.
+
+# Build-only / test-only dependencies
+bazel_dep(name = "stardoc", version = "0.5.6", dev_dependency = True, repo_name = "io_bazel_stardoc")
+bazel_dep(name = "rules_pkg", version = "0.9.1", dev_dependency = True)
+bazel_dep(name = "rules_cc", version = "0.0.2", dev_dependency = True)
+
+# Needed for bazelci and for building distribution tarballs.
+# If using an unreleased version of bazel_skylib via git_override, apply
+# MODULE.bazel-remove-override.patch to remove the following lines:
+bazel_dep(name = "bazel_skylib_gazelle_plugin", dev_dependency = True)
+local_path_override(
+ module_name = "bazel_skylib_gazelle_plugin",
+ path = "gazelle",
+)
diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch
new file mode 100644
index 0000000..0f30777
--- /dev/null
+++ b/MODULE.bazel-remove-override.patch
@@ -0,0 +1,16 @@
+--- MODULE.bazel
++++ MODULE.bazel
+@@ -22,8 +22,8 @@
+ # Needed for bazelci and for building distribution tarballs.
+ # If using an unreleased version of bazel_skylib via git_override, apply
+ # MODULE.bazel-remove-override.patch to remove the following lines:
+-bazel_dep(name = "bazel_skylib_gazelle_plugin", dev_dependency = True)
+-local_path_override(
+- module_name = "bazel_skylib_gazelle_plugin",
+- path = "gazelle",
+-)
++# bazel_dep(name = "bazel_skylib_gazelle_plugin", dev_dependency = True)
++# local_path_override(
++# module_name = "bazel_skylib_gazelle_plugin",
++# path = "gazelle",
++# )
diff --git a/README.md b/README.md
index 58e0878..0c13d32 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,7 @@ s = shell.quote(p)
* [new_sets](docs/new_sets_doc.md)
* [shell](docs/shell_doc.md)
* [structs](docs/structs_doc.md)
+* [subpackages](docs/subpackages_doc.md)
* [types](docs/types_doc.md)
* [unittest](docs/unittest_doc.md)
* [versions](docs/versions_doc.md)
@@ -59,14 +60,21 @@ s = shell.quote(p)
* [analysis_test](docs/analysis_test_doc.md)
* [build_test](docs/build_test_doc.md)
+* [common_settings](docs/common_settings_doc.md)
+* [copy_directory](docs/copy_directory_doc.md)
* [copy_file](docs/copy_file_doc.md)
+* [diff_test](docs/diff_test_doc.md)
+* [expand_template](docs/expand_template_doc.md)
+* [native_binary and native_test](docs/native_binary_doc.md)
+* [run_binary](docs/run_binary_doc.md)
+* [select_file](docs/select_file_doc.md)
* [write_file](docs/write_file_doc.md)
## Writing a new module
The criteria for adding a new function or module to this repository are:
-1. Is it widely needed? The new code must solve a problem that occurs often during the development of Bazel build rules. It is not sufficient that the new code is merely useful. Candidate code should generally have been proven to be necessary across several projects, either because it provides indispensible common functionality, or because it requires a single standardized implementation.
+1. Is it widely needed? The new code must solve a problem that occurs often during the development of Bazel build rules. It is not sufficient that the new code is merely useful. Candidate code should generally have been proven to be necessary across several projects, either because it provides indispensable common functionality, or because it requires a single standardized implementation.
1. Is its interface simpler than its implementation? A good abstraction provides a simple interface to a complex implementation, relieving the user from the burden of understanding. By contrast, a shallow abstraction provides little that the user could not easily have written out for themselves. If a function's doc comment is longer than its body, it's a good sign that the abstraction is too shallow.
@@ -124,3 +132,38 @@ then you probably forgot to load and call `bazel_skylib_workspace()` in your
See the [maintaner's guide](docs/maintainers_guide.md) for instructions for
cutting a new release.
+
+## Gazelle Plugin
+
+`bazel_skylib` ships with a [gazelle](https://github.com/bazelbuild/bazel-gazelle)
+plugin to generate `bzl_library` entries in build files. To use this, in your
+`WORKSPACE`:
+
+```starlark
+load("@bazel_skylib_gazelle_plugin//:workspace.bzl", "bazel_skylib_gazelle_plugin_workspace")
+
+bazel_skylib_gazelle_plugin_workspace()
+
+load("@bazel_skylib_gazelle_plugin//:setup.bzl", "bazel_skylib_gazelle_plugin_setup")
+
+bazel_skylib_gazelle_plugin_setup()
+```
+
+You may then include the plugin using code similar to this in your `BUILD.bazel`
+file:
+
+```starlark
+load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary")
+
+gazelle(
+ name = "gazelle",
+ gazelle = ":gazelle_bin",
+)
+
+gazelle_binary(
+ name = "gazelle_bin",
+ languages = DEFAULT_LANGUAGES + [
+ "@bazel_skylib_gazelle_plugin//bzl",
+ ],
+)
+```
diff --git a/WORKSPACE b/WORKSPACE
index 00f86ab..de97069 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,35 +1,36 @@
workspace(name = "bazel_skylib")
+load(":workspace.bzl", "bazel_skylib_workspace")
+
+bazel_skylib_workspace()
+
+### INTERNAL ONLY - lines after this are not included in the release packaging.
+# Lines below are for tests, documentation generation, and distribution archive
+# generation only, and should thus not be included by dependencies on bazel-skylib.
+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
-maybe(
- name = "io_bazel_rules_go",
- repo_rule = http_archive,
- sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
- urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
- "https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
- ],
+local_repository(
+ name = "bazel_skylib_gazelle_plugin",
+ path = "gazelle",
)
-load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
+load("@bazel_skylib_gazelle_plugin//:workspace.bzl", "bazel_skylib_gazelle_plugin_workspace")
-go_rules_dependencies()
+bazel_skylib_gazelle_plugin_workspace()
-go_register_toolchains(version = "1.17.1")
+load("@bazel_skylib_gazelle_plugin//:setup.bzl", "bazel_skylib_gazelle_plugin_setup")
-# Below this line is for documentation generation only,
-# and should thus not be included by dependencies on
-# bazel-skylib.
+bazel_skylib_gazelle_plugin_setup()
maybe(
http_archive,
name = "io_bazel_stardoc",
- sha256 = "c9794dcc8026a30ff67cf7cf91ebe245ca294b20b071845d12c192afe243ad72",
+ sha256 = "dfbc364aaec143df5e6c52faf1f1166775a5b4408243f445f44b661cfdc3134f",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz",
- "https://github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/stardoc/releases/download/0.5.6/stardoc-0.5.6.tar.gz",
+ "https://github.com/bazelbuild/stardoc/releases/download/0.5.6/stardoc-0.5.6.tar.gz",
],
)
@@ -40,10 +41,10 @@ stardoc_repositories()
maybe(
http_archive,
name = "rules_pkg",
- sha256 = "a89e203d3cf264e564fcb96b6e06dd70bc0557356eb48400ce4b5d97c2c3720d",
+ sha256 = "8f9ee2dc10c1ae514ee599a8b42ed99fa262b757058f65ad3c384289ff70c4b8",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz",
- "https://github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
+ "https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
],
)
@@ -64,22 +65,3 @@ maybe(
load("//lib:unittest.bzl", "register_unittest_toolchains")
register_unittest_toolchains()
-
-# Provide a repository hint for Gazelle to inform it that the go package
-# github.com/bazelbuild/rules_go is available from io_bazel_rules_go and it
-# doesn't need to duplicatively fetch it.
-# gazelle:repository go_repository name=io_bazel_rules_go importpath=github.com/bazelbuild/rules_go
-http_archive(
- name = "bazel_gazelle",
- sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb",
- urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
- "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
- ],
-)
-# Another Gazelle repository hint.
-# gazelle:repository go_repository name=bazel_gazelle importpath=github.com/bazelbuild/bazel-gazelle/testtools
-
-load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
-
-gazelle_dependencies()
diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod
new file mode 100644
index 0000000..5a16370
--- /dev/null
+++ b/WORKSPACE.bzlmod
@@ -0,0 +1,2 @@
+# Workaround so that targets prefixed with @bazel_skylib still work
+workspace(name = "bazel_skylib")
diff --git a/bzl_library.bzl b/bzl_library.bzl
index 1b59440..9091894 100644
--- a/bzl_library.bzl
+++ b/bzl_library.bzl
@@ -26,6 +26,9 @@ StarlarkLibraryInfo = provider(
def _bzl_library_impl(ctx):
deps_files = [x.files for x in ctx.attr.deps]
all_files = depset(ctx.files.srcs, order = "postorder", transitive = deps_files)
+ if not ctx.files.srcs and not deps_files:
+ fail("bzl_library rule '%s' has no srcs or deps" % ctx.label)
+
return [
# All dependent files should be listed in both `files` and in `runfiles`;
# this ensures that a `bzl_library` can be referenced as `data` from
@@ -46,11 +49,11 @@ bzl_library = rule(
implementation = _bzl_library_impl,
attrs = {
"srcs": attr.label_list(
- allow_files = [".bzl"],
- doc = "List of `.bzl` files that are processed to create this target.",
+ allow_files = [".bzl", ".scl"],
+ doc = "List of `.bzl` and `.scl` files that are processed to create this target.",
),
"deps": attr.label_list(
- allow_files = [".bzl"],
+ allow_files = [".bzl", ".scl"],
providers = [
[StarlarkLibraryInfo],
],
@@ -58,7 +61,7 @@ bzl_library = rule(
Starlark files listed in `srcs`.""",
),
},
- doc = """Creates a logical collection of Starlark .bzl files.
+ doc = """Creates a logical collection of Starlark .bzl and .scl files.
Example:
Suppose your project has the following structure:
diff --git a/distribution/BUILD b/distribution/BUILD
index 8a9b1e7..4465779 100644
--- a/distribution/BUILD
+++ b/distribution/BUILD
@@ -1,27 +1,84 @@
load("@bazel_skylib//:version.bzl", "version")
+load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
-load("@rules_pkg//releasing:defs.bzl", "print_rel_notes")
+load("distribution.bzl", "remove_internal_only")
package(
default_visibility = ["//visibility:private"],
)
-# Build the artifact to put on the github release page.
+remove_internal_only(
+ name = "distro_workspace",
+ src = "//:WORKSPACE",
+ out = "WORKSPACE",
+)
+
+remove_internal_only(
+ name = "distro_module_bazel",
+ src = "//:MODULE.bazel",
+ out = "MODULE.bazel",
+)
+
+# remove "distribution/" path prefix
+pkg_files(
+ name = "distro-files-without-prefix",
+ srcs = [
+ "distro_module_bazel",
+ "distro_workspace",
+ ],
+ strip_prefix = strip_prefix.from_pkg(),
+)
+
+pkg_tar(
+ name = "bazel-skylib",
+ srcs = [
+ "distro-files-without-prefix",
+ "//:distribution",
+ ],
+ out = "bazel-skylib-%s.tar.gz" % version,
+ extension = "tar.gz",
+ mode = "0644",
+ # Make it owned by root so it does not have the uid of the CI robot.
+ owner = "0.0",
+ strip_prefix = strip_prefix.from_root(),
+)
+
+# @bazel_skylib_gazelle_plugin//:WORKSPACE refers to bazel-skylib in the parent
+# directory. For distribution, use the minimal WORSKPACE.bzlmod instead.
+pkg_files(
+ name = "bazel-skylib-gazelle-plugin-distro_workspace",
+ srcs = ["@bazel_skylib_gazelle_plugin//:WORKSPACE.bzlmod"],
+ renames = {"@bazel_skylib_gazelle_plugin//:WORKSPACE.bzlmod": "WORKSPACE"},
+)
+
+pkg_files(
+ name = "bazel-skylib-gazelle-plugin-without-external-prefix",
+ srcs = [
+ "@bazel_skylib_gazelle_plugin//:distribution",
+ "@bazel_skylib_gazelle_plugin//bzl:distribution",
+ ],
+ strip_prefix = strip_prefix.from_root(),
+)
+
pkg_tar(
- name = "bazel-skylib-%s" % version,
- srcs = ["//:distribution"],
+ name = "bazel-skylib-gazelle-plugin",
+ srcs = [
+ "bazel-skylib-gazelle-plugin-distro_workspace",
+ "bazel-skylib-gazelle-plugin-without-external-prefix",
+ "//:LICENSE",
+ ],
+ out = "bazel-skylib-gazelle-plugin-%s.tar.gz" % version,
extension = "tar.gz",
mode = "0644",
# Make it owned by root so it does not have the uid of the CI robot.
owner = "0.0",
- strip_prefix = ".",
)
-print_rel_notes(
- name = "relnotes",
- outs = ["relnotes.txt"],
- deps_method = "bazel_skylib_workspace",
- repo = "bazel-skylib",
- setup_file = ":workspace.bzl",
- version = version,
+# Build the artifacts to put on the github release page.
+filegroup(
+ name = "distribution",
+ srcs = [
+ "bazel-skylib",
+ "bazel-skylib-gazelle-plugin",
+ ],
)
diff --git a/distribution/distribution.bzl b/distribution/distribution.bzl
new file mode 100644
index 0000000..e1dd14e
--- /dev/null
+++ b/distribution/distribution.bzl
@@ -0,0 +1,32 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Helper utilities for generating distribution tarballs."""
+
+def remove_internal_only(name, src, out, **kwargs):
+ """Removes '### INTERNAL ONLY' line and all lines below from a file.
+
+ Args:
+ name: Name of the rule.
+ src: File to process.
+ out: Path of the output file.
+ **kwargs: further keyword arguments.
+ """
+ native.genrule(
+ name = name,
+ srcs = [src],
+ outs = [out],
+ cmd = "sed -e '/### INTERNAL ONLY/,$$d' $< >$@",
+ **kwargs
+ )
diff --git a/docs/BUILD b/docs/BUILD
index 2ccd60e..a809f2f 100644
--- a/docs/BUILD
+++ b/docs/BUILD
@@ -1,137 +1,153 @@
-load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
+load("//docs/private:stardoc_with_diff_test.bzl", "stardoc_with_diff_test", "update_docs")
licenses(["notice"])
-# Note that due to a bug in Bazel 0.22.0, these targets cannot be built without
-# the --incompatible_remap_main_repo flag.
-stardoc(
- name = "build_test_docs",
- out = "build_test_doc_gen.md",
- input = "//rules:build_test.bzl",
- deps = ["//rules:build_test"],
+stardoc_with_diff_test(
+ name = "analysis_test",
+ bzl_library_target = "//rules:analysis_test",
+ out_label = "//docs:analysis_test_doc.md",
)
-stardoc(
- name = "analysis_test_docs",
- out = "analysis_test_doc_gen.md",
- input = "//rules:analysis_test.bzl",
+stardoc_with_diff_test(
+ name = "build_test",
+ bzl_library_target = "//rules:build_test",
+ out_label = "//docs:build_test_doc.md",
)
-stardoc(
- name = "collections_docs",
- out = "collections_doc_gen.md",
- input = "//lib:collections.bzl",
- deps = ["//lib:collections"],
+stardoc_with_diff_test(
+ name = "bzl_library",
+ bzl_library_target = "//:bzl_library",
+ out_label = "//docs:bzl_library.md",
)
-stardoc(
- name = "dicts_docs",
- out = "dicts_doc_gen.md",
- input = "//lib:dicts.bzl",
- deps = ["//lib:dicts"],
+stardoc_with_diff_test(
+ name = "collections",
+ bzl_library_target = "//lib:collections",
+ out_label = "//docs:collections_doc.md",
)
-stardoc(
- name = "partial_docs",
- out = "partial_doc_gen.md",
- input = "//lib:partial.bzl",
- deps = ["//lib:partial"],
+stardoc_with_diff_test(
+ name = "common_settings",
+ bzl_library_target = "//rules:common_settings",
+ out_label = "//docs:common_settings_doc.md",
)
-stardoc(
- name = "paths_docs",
- out = "paths_doc_gen.md",
- input = "//lib:paths.bzl",
- deps = ["//lib:paths"],
+stardoc_with_diff_test(
+ name = "copy_directory",
+ bzl_library_target = "//rules:copy_directory",
+ out_label = "//docs:copy_directory_doc.md",
)
-stardoc(
- name = "selects_docs",
- out = "selects_doc_gen.md",
- input = "//lib:selects.bzl",
- deps = ["//lib:selects"],
+stardoc_with_diff_test(
+ name = "copy_file",
+ bzl_library_target = "//rules:copy_file",
+ out_label = "//docs:copy_file_doc.md",
)
-stardoc(
- name = "new_sets_docs",
- out = "new_sets_doc_gen.md",
- input = "//lib:new_sets.bzl",
- deps = ["//lib:new_sets"],
+stardoc_with_diff_test(
+ name = "dicts",
+ bzl_library_target = "//lib:dicts",
+ out_label = "//docs:dicts_doc.md",
)
-stardoc(
- name = "shell_docs",
- out = "shell_doc_gen.md",
- input = "//lib:shell.bzl",
- deps = ["//lib:shell"],
+stardoc_with_diff_test(
+ name = "diff_test",
+ bzl_library_target = "//rules:diff_test",
+ out_label = "//docs:diff_test_doc.md",
)
-stardoc(
- name = "structs_docs",
- out = "structs_doc_gen.md",
- input = "//lib:structs.bzl",
- deps = ["//lib:structs"],
+stardoc_with_diff_test(
+ name = "expand_template",
+ bzl_library_target = "//rules:expand_template",
+ out_label = "//docs:expand_template_doc.md",
)
-stardoc(
- name = "types_docs",
- out = "types_doc_gen.md",
- input = "//lib:types.bzl",
- deps = ["//lib:types"],
+stardoc_with_diff_test(
+ name = "native_binary",
+ bzl_library_target = "//rules:native_binary",
+ out_label = "//docs:native_binary_doc.md",
)
-stardoc(
- name = "unittest_docs",
- out = "unittest_doc_gen.md",
- input = "//lib:unittest.bzl",
- deps = ["//lib:unittest"],
+stardoc_with_diff_test(
+ name = "new_sets",
+ bzl_library_target = "//lib:new_sets",
+ out_label = "//docs:new_sets_doc.md",
)
-stardoc(
- name = "versions_docs",
- out = "versions_doc_gen.md",
- input = "//lib:versions.bzl",
- deps = ["//lib:versions"],
+stardoc_with_diff_test(
+ name = "partial",
+ bzl_library_target = "//lib:partial",
+ out_label = "//docs:partial_doc.md",
)
-stardoc(
- name = "copy_file_docs",
- out = "copy_file_doc_gen.md",
- input = "//rules:copy_file.bzl",
- deps = ["//rules:copy_file"],
+stardoc_with_diff_test(
+ name = "paths",
+ bzl_library_target = "//lib:paths",
+ out_label = "//docs:paths_doc.md",
)
-stardoc(
- name = "write_file_docs",
- out = "write_file_doc_gen.md",
- input = "//rules:write_file.bzl",
- deps = ["//rules:write_file"],
+stardoc_with_diff_test(
+ name = "run_binary",
+ bzl_library_target = "//rules:run_binary",
+ out_label = "//docs:run_binary_doc.md",
)
-stardoc(
- name = "diff_test_docs",
- out = "diff_test_doc_gen.md",
- input = "//rules:diff_test.bzl",
- deps = ["//rules:diff_test"],
+stardoc_with_diff_test(
+ name = "selects",
+ bzl_library_target = "//lib:selects",
+ out_label = "//docs:selects_doc.md",
)
-stardoc(
- name = "native_binary_docs",
- out = "native_binary_doc_gen.md",
- input = "//rules:native_binary.bzl",
- deps = ["//rules:native_binary"],
+stardoc_with_diff_test(
+ name = "select_file",
+ bzl_library_target = "//rules:select_file",
+ out_label = "//docs:select_file_doc.md",
)
-stardoc(
- name = "run_binary_docs",
- out = "run_binary_doc_gen.md",
- input = "//rules:run_binary.bzl",
- deps = ["//rules:run_binary"],
+stardoc_with_diff_test(
+ name = "shell",
+ bzl_library_target = "//lib:shell",
+ out_label = "//docs:shell_doc.md",
)
-stardoc(
- name = "common_settings_docs",
- out = "common_settings_doc_gen.md",
- input = "//rules:common_settings.bzl",
- deps = ["//rules:common_settings"],
+stardoc_with_diff_test(
+ name = "structs",
+ bzl_library_target = "//lib:structs",
+ out_label = "//docs:structs_doc.md",
+)
+
+stardoc_with_diff_test(
+ name = "subpackages",
+ bzl_library_target = "//lib:subpackages",
+ out_label = "//docs:subpackages_doc.md",
+)
+
+stardoc_with_diff_test(
+ name = "types",
+ bzl_library_target = "//lib:types",
+ out_label = "//docs:types_doc.md",
+)
+
+stardoc_with_diff_test(
+ name = "unittest",
+ bzl_library_target = "//lib:unittest",
+ out_label = "//docs:unittest_doc.md",
+)
+
+stardoc_with_diff_test(
+ name = "versions",
+ bzl_library_target = "//lib:versions",
+ out_label = "//docs:versions_doc.md",
+)
+
+stardoc_with_diff_test(
+ name = "write_file",
+ bzl_library_target = "//rules:write_file",
+ out_label = "//docs:write_file_doc.md",
+)
+
+# update_docs must be at the bottom of the BUILD file
+update_docs(
+ name = "update",
+ docs_folder = "docs",
)
diff --git a/docs/analysis_test_doc.md b/docs/analysis_test_doc.md
index 1a564ae..ebb95a4 100755
--- a/docs/analysis_test_doc.md
+++ b/docs/analysis_test_doc.md
@@ -2,7 +2,7 @@
A test verifying other targets can be successfully analyzed as part of a `bazel test`
-<a id="#analysis_test"></a>
+<a id="analysis_test"></a>
## analysis_test
@@ -42,7 +42,7 @@ Test rule checking that other targets can be successfully analyzed.
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="analysis_test-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
-| <a id="analysis_test-targets"></a>targets | - | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | required | |
+| <a id="analysis_test-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="analysis_test-targets"></a>targets | - | <a href="https://bazel.build/concepts/labels">List of labels</a> | required | |
diff --git a/docs/build_test_doc.md b/docs/build_test_doc.md
index 332dc58..ba13978 100755
--- a/docs/build_test_doc.md
+++ b/docs/build_test_doc.md
@@ -2,7 +2,7 @@
A test verifying other targets build as part of a `bazel test`
-<a id="#build_test"></a>
+<a id="build_test"></a>
## build_test
@@ -36,6 +36,6 @@ Typical usage:
| :------------- | :------------- | :------------- |
| <a id="build_test-name"></a>name | The name of the test rule. | none |
| <a id="build_test-targets"></a>targets | A list of targets to ensure build. | none |
-| <a id="build_test-kwargs"></a>kwargs | The &lt;a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests"&gt;common attributes for tests&lt;/a&gt;. | none |
+| <a id="build_test-kwargs"></a>kwargs | The [common attributes for tests](https://bazel.build/reference/be/common-definitions#common-attributes-tests). | none |
diff --git a/docs/bzl_library.md b/docs/bzl_library.md
new file mode 100755
index 0000000..f4b0dc7
--- /dev/null
+++ b/docs/bzl_library.md
@@ -0,0 +1,88 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+Skylib module containing a library rule for aggregating rules files.
+
+<a id="bzl_library"></a>
+
+## bzl_library
+
+<pre>
+bzl_library(<a href="#bzl_library-name">name</a>, <a href="#bzl_library-deps">deps</a>, <a href="#bzl_library-srcs">srcs</a>)
+</pre>
+
+Creates a logical collection of Starlark .bzl and .scl files.
+
+Example:
+ Suppose your project has the following structure:
+
+ ```
+ [workspace]/
+ WORKSPACE
+ BUILD
+ checkstyle/
+ BUILD
+ checkstyle.bzl
+ lua/
+ BUILD
+ lua.bzl
+ luarocks.bzl
+ ```
+
+ In this case, you can have `bzl_library` targets in `checkstyle/BUILD` and
+ `lua/BUILD`:
+
+ `checkstyle/BUILD`:
+
+ ```python
+ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+ bzl_library(
+ name = "checkstyle-rules",
+ srcs = ["checkstyle.bzl"],
+ )
+ ```
+
+ `lua/BUILD`:
+
+ ```python
+ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+ bzl_library(
+ name = "lua-rules",
+ srcs = [
+ "lua.bzl",
+ "luarocks.bzl",
+ ],
+ )
+ ```
+
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="bzl_library-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="bzl_library-deps"></a>deps | List of other <code>bzl_library</code> targets that are required by the Starlark files listed in <code>srcs</code>. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
+| <a id="bzl_library-srcs"></a>srcs | List of <code>.bzl</code> and <code>.scl</code> files that are processed to create this target. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
+
+
+<a id="StarlarkLibraryInfo"></a>
+
+## StarlarkLibraryInfo
+
+<pre>
+StarlarkLibraryInfo(<a href="#StarlarkLibraryInfo-srcs">srcs</a>, <a href="#StarlarkLibraryInfo-transitive_srcs">transitive_srcs</a>)
+</pre>
+
+Information on contained Starlark rules.
+
+**FIELDS**
+
+
+| Name | Description |
+| :------------- | :------------- |
+| <a id="StarlarkLibraryInfo-srcs"></a>srcs | Top level rules files. |
+| <a id="StarlarkLibraryInfo-transitive_srcs"></a>transitive_srcs | Transitive closure of rules files required for interpretation of the srcs |
+
+
diff --git a/docs/collections_doc.md b/docs/collections_doc.md
index 1138850..cd9db8b 100755
--- a/docs/collections_doc.md
+++ b/docs/collections_doc.md
@@ -2,7 +2,7 @@
Skylib module containing functions that operate on collections.
-<a id="#collections.after_each"></a>
+<a id="collections.after_each"></a>
## collections.after_each
@@ -25,7 +25,7 @@ Inserts `separator` after each item in `iterable`.
A new list with `separator` after each item in `iterable`.
-<a id="#collections.before_each"></a>
+<a id="collections.before_each"></a>
## collections.before_each
@@ -48,7 +48,7 @@ Inserts `separator` before each item in `iterable`.
A new list with `separator` before each item in `iterable`.
-<a id="#collections.uniq"></a>
+<a id="collections.uniq"></a>
## collections.uniq
diff --git a/docs/common_settings_doc.md b/docs/common_settings_doc.md
index 736e48c..b224f52 100755
--- a/docs/common_settings_doc.md
+++ b/docs/common_settings_doc.md
@@ -6,10 +6,10 @@ These rules return a BuildSettingInfo with the value of the build setting.
For label-typed settings, use the native label_flag and label_setting rules.
More documentation on how to use build settings at
-https://docs.bazel.build/versions/main/skylark/config.html#user-defined-build-settings
+https://bazel.build/extending/config#user-defined-build-settings
-<a id="#bool_flag"></a>
+<a id="bool_flag"></a>
## bool_flag
@@ -24,10 +24,10 @@ A bool-typed build setting that can be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="bool_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="bool_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
-<a id="#bool_setting"></a>
+<a id="bool_setting"></a>
## bool_setting
@@ -42,15 +42,15 @@ A bool-typed build setting that cannot be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="bool_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="bool_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
-<a id="#int_flag"></a>
+<a id="int_flag"></a>
## int_flag
<pre>
-int_flag(<a href="#int_flag-name">name</a>)
+int_flag(<a href="#int_flag-name">name</a>, <a href="#int_flag-make_variable">make_variable</a>)
</pre>
An int-typed build setting that can be set on the command line
@@ -60,15 +60,16 @@ An int-typed build setting that can be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="int_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="int_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="int_flag-make_variable"></a>make_variable | If set, the build setting's value will be available as a Make variable with this name in the attributes of rules that list this build setting in their 'toolchains' attribute. | String | optional | <code>""</code> |
-<a id="#int_setting"></a>
+<a id="int_setting"></a>
## int_setting
<pre>
-int_setting(<a href="#int_setting-name">name</a>)
+int_setting(<a href="#int_setting-name">name</a>, <a href="#int_setting-make_variable">make_variable</a>)
</pre>
An int-typed build setting that cannot be set on the command line
@@ -78,15 +79,16 @@ An int-typed build setting that cannot be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="int_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="int_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="int_setting-make_variable"></a>make_variable | If set, the build setting's value will be available as a Make variable with this name in the attributes of rules that list this build setting in their 'toolchains' attribute. | String | optional | <code>""</code> |
-<a id="#string_flag"></a>
+<a id="string_flag"></a>
## string_flag
<pre>
-string_flag(<a href="#string_flag-name">name</a>, <a href="#string_flag-values">values</a>)
+string_flag(<a href="#string_flag-name">name</a>, <a href="#string_flag-make_variable">make_variable</a>, <a href="#string_flag-values">values</a>)
</pre>
A string-typed build setting that can be set on the command line
@@ -96,11 +98,12 @@ A string-typed build setting that can be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="string_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
-| <a id="string_flag-values"></a>values | The list of allowed values for this setting. An error is raised if any other value is given. | List of strings | optional | [] |
+| <a id="string_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="string_flag-make_variable"></a>make_variable | If set, the build setting's value will be available as a Make variable with this name in the attributes of rules that list this build setting in their 'toolchains' attribute. | String | optional | <code>""</code> |
+| <a id="string_flag-values"></a>values | The list of allowed values for this setting. An error is raised if any other value is given. | List of strings | optional | <code>[]</code> |
-<a id="#string_list_flag"></a>
+<a id="string_list_flag"></a>
## string_list_flag
@@ -115,10 +118,10 @@ A string list-typed build setting that can be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="string_list_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="string_list_flag-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
-<a id="#string_list_setting"></a>
+<a id="string_list_setting"></a>
## string_list_setting
@@ -133,15 +136,15 @@ A string list-typed build setting that cannot be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="string_list_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
+| <a id="string_list_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
-<a id="#string_setting"></a>
+<a id="string_setting"></a>
## string_setting
<pre>
-string_setting(<a href="#string_setting-name">name</a>, <a href="#string_setting-values">values</a>)
+string_setting(<a href="#string_setting-name">name</a>, <a href="#string_setting-make_variable">make_variable</a>, <a href="#string_setting-values">values</a>)
</pre>
A string-typed build setting that cannot be set on the command line
@@ -151,11 +154,12 @@ A string-typed build setting that cannot be set on the command line
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="string_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
-| <a id="string_setting-values"></a>values | The list of allowed values for this setting. An error is raised if any other value is given. | List of strings | optional | [] |
+| <a id="string_setting-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="string_setting-make_variable"></a>make_variable | If set, the build setting's value will be available as a Make variable with this name in the attributes of rules that list this build setting in their 'toolchains' attribute. | String | optional | <code>""</code> |
+| <a id="string_setting-values"></a>values | The list of allowed values for this setting. An error is raised if any other value is given. | List of strings | optional | <code>[]</code> |
-<a id="#BuildSettingInfo"></a>
+<a id="BuildSettingInfo"></a>
## BuildSettingInfo
diff --git a/docs/copy_directory_doc.md b/docs/copy_directory_doc.md
new file mode 100755
index 0000000..1177d20
--- /dev/null
+++ b/docs/copy_directory_doc.md
@@ -0,0 +1,63 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+A rule that copies a directory to another place.
+
+The rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command
+on Windows (no Bash is required).
+
+
+<a id="copy_directory"></a>
+
+## copy_directory
+
+<pre>
+copy_directory(<a href="#copy_directory-name">name</a>, <a href="#copy_directory-src">src</a>, <a href="#copy_directory-out">out</a>, <a href="#copy_directory-kwargs">kwargs</a>)
+</pre>
+
+Copies a directory to another location.
+
+This rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command on Windows (no Bash is required).
+
+If using this rule with source directories, it is recommended that you use the
+`--host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1` startup option so that changes
+to files within source directories are detected. See
+https://github.com/bazelbuild/bazel/commit/c64421bc35214f0414e4f4226cc953e8c55fa0d2
+for more context.
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="copy_directory-name"></a>name | Name of the rule. | none |
+| <a id="copy_directory-src"></a>src | The directory to make a copy of. Can be a source directory or TreeArtifact. | none |
+| <a id="copy_directory-out"></a>out | Path of the output directory, relative to this package. | none |
+| <a id="copy_directory-kwargs"></a>kwargs | further keyword arguments, e.g. <code>visibility</code> | none |
+
+
+<a id="copy_directory_action"></a>
+
+## copy_directory_action
+
+<pre>
+copy_directory_action(<a href="#copy_directory_action-ctx">ctx</a>, <a href="#copy_directory_action-src">src</a>, <a href="#copy_directory_action-dst">dst</a>, <a href="#copy_directory_action-is_windows">is_windows</a>)
+</pre>
+
+Helper function that creates an action to copy a directory from src to dst.
+
+This helper is used by copy_directory. It is exposed as a public API so it can be used within
+other rule implementations.
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="copy_directory_action-ctx"></a>ctx | The rule context. | none |
+| <a id="copy_directory_action-src"></a>src | The directory to make a copy of. Can be a source directory or TreeArtifact. | none |
+| <a id="copy_directory_action-dst"></a>dst | The directory to copy to. Must be a TreeArtifact. | none |
+| <a id="copy_directory_action-is_windows"></a>is_windows | If true, an cmd.exe action is created so there is no bash dependency. | <code>False</code> |
+
+
diff --git a/docs/copy_file_doc.md b/docs/copy_file_doc.md
index 47a1244..ed297a6 100755
--- a/docs/copy_file_doc.md
+++ b/docs/copy_file_doc.md
@@ -9,7 +9,7 @@ The rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command
on Windows (no Bash is required).
-<a id="#copy_file"></a>
+<a id="copy_file"></a>
## copy_file
diff --git a/docs/dicts_doc.md b/docs/dicts_doc.md
index 5e8bce6..2360325 100755
--- a/docs/dicts_doc.md
+++ b/docs/dicts_doc.md
@@ -2,7 +2,7 @@
Skylib module containing functions that operate on dictionaries.
-<a id="#dicts.add"></a>
+<a id="dicts.add"></a>
## dicts.add
@@ -34,3 +34,49 @@ dictionary, and the sum of a single dictionary is a copy of itself.
A new `dict` that has all the entries of the given dictionaries.
+<a id="dicts.omit"></a>
+
+## dicts.omit
+
+<pre>
+dicts.omit(<a href="#dicts.omit-dictionary">dictionary</a>, <a href="#dicts.omit-keys">keys</a>)
+</pre>
+
+Returns a new `dict` that has all the entries of `dictionary` with keys not in `keys`.
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="dicts.omit-dictionary"></a>dictionary | A <code>dict</code>. | none |
+| <a id="dicts.omit-keys"></a>keys | A sequence. | none |
+
+**RETURNS**
+
+A new `dict` that has all the entries of `dictionary` with keys not in `keys`.
+
+
+<a id="dicts.pick"></a>
+
+## dicts.pick
+
+<pre>
+dicts.pick(<a href="#dicts.pick-dictionary">dictionary</a>, <a href="#dicts.pick-keys">keys</a>)
+</pre>
+
+Returns a new `dict` that has all the entries of `dictionary` with keys in `keys`.
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="dicts.pick-dictionary"></a>dictionary | A <code>dict</code>. | none |
+| <a id="dicts.pick-keys"></a>keys | A sequence. | none |
+
+**RETURNS**
+
+A new `dict` that has all the entries of `dictionary` with keys in `keys`.
+
+
diff --git a/docs/diff_test_doc.md b/docs/diff_test_doc.md
index fd62a38..c9189ec 100755
--- a/docs/diff_test_doc.md
+++ b/docs/diff_test_doc.md
@@ -6,12 +6,12 @@ The rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).
-<a id="#diff_test"></a>
+<a id="diff_test"></a>
## diff_test
<pre>
-diff_test(<a href="#diff_test-name">name</a>, <a href="#diff_test-file1">file1</a>, <a href="#diff_test-file2">file2</a>, <a href="#diff_test-kwargs">kwargs</a>)
+diff_test(<a href="#diff_test-name">name</a>, <a href="#diff_test-file1">file1</a>, <a href="#diff_test-file2">file2</a>, <a href="#diff_test-failure_message">failure_message</a>, <a href="#diff_test-kwargs">kwargs</a>)
</pre>
A test that compares two files.
@@ -25,8 +25,9 @@ The test succeeds if the files' contents match.
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="diff_test-name"></a>name | The name of the test rule. | none |
-| <a id="diff_test-file1"></a>file1 | Label of the file to compare to &lt;code&gt;file2&lt;/code&gt;. | none |
-| <a id="diff_test-file2"></a>file2 | Label of the file to compare to &lt;code&gt;file1&lt;/code&gt;. | none |
-| <a id="diff_test-kwargs"></a>kwargs | The &lt;a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests"&gt;common attributes for tests&lt;/a&gt;. | none |
+| <a id="diff_test-file1"></a>file1 | Label of the file to compare to <code>file2</code>. | none |
+| <a id="diff_test-file2"></a>file2 | Label of the file to compare to <code>file1</code>. | none |
+| <a id="diff_test-failure_message"></a>failure_message | Additional message to log if the files' contents do not match. | <code>None</code> |
+| <a id="diff_test-kwargs"></a>kwargs | The [common attributes for tests](https://bazel.build/reference/be/common-definitions#common-attributes-tests). | none |
diff --git a/docs/expand_template_doc.md b/docs/expand_template_doc.md
new file mode 100755
index 0000000..6d6dd2a
--- /dev/null
+++ b/docs/expand_template_doc.md
@@ -0,0 +1,32 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+A rule that performs template expansion.
+
+
+<a id="expand_template"></a>
+
+## expand_template
+
+<pre>
+expand_template(<a href="#expand_template-name">name</a>, <a href="#expand_template-out">out</a>, <a href="#expand_template-substitutions">substitutions</a>, <a href="#expand_template-template">template</a>)
+</pre>
+
+Template expansion
+
+This performs a simple search over the template file for the keys in
+substitutions, and replaces them with the corresponding values.
+
+There is no special syntax for the keys. To avoid conflicts, you would need to
+explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@".
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="expand_template-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="expand_template-out"></a>out | The destination of the expanded file. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
+| <a id="expand_template-substitutions"></a>substitutions | A dictionary mapping strings to their substitutions. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | required | |
+| <a id="expand_template-template"></a>template | The template file to expand. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
+
+
diff --git a/docs/maintainers_guide.md b/docs/maintainers_guide.md
index 8a009c2..f5408ce 100644
--- a/docs/maintainers_guide.md
+++ b/docs/maintainers_guide.md
@@ -25,7 +25,7 @@ widespread pain, and shouldn't be done lightly. Therefore:
1. In the first place, avoid adding insufficiently thought out, insufficiently
tested features which will later need to be replaced in a
backwards-incompatible manner. See the criteria in README.md.
-2. Given a choice between breaking backwards compatibilty and keeping it, try
+2. Given a choice between breaking backwards compatibility and keeping it, try
to keep backwards compatibility. For example, if adding a new argument to a
function, add it to the end of the argument list, so that existing callers'
positional arguments continue to work.
@@ -40,11 +40,13 @@ widespread pain, and shouldn't be done lightly. Therefore:
In addition, make sure that new code is documented and tested.
-If a PR adds or changes any docstrings, check that Markdown docs in `docs`
-directory are updated; if not, ask the PR author to run
-`./docs/regenerate_docs.sh`. (See
-https://github.com/bazelbuild/bazel-skylib/pull/321 for the proposal to automate
-this.)
+If a PR changes any docstring in an existing module, the corresponding
+`stardoc_with_diff_test` in `docs` will fail. To fix the test, ask the PR
+author to run `bazel run //docs:update`.
+
+If a PR adds a new module, make sure that the PR also adds a corresponding
+`stardoc_with_diff_test` target in `docs/BUILD` and a corresponding `*doc.md`
+file under `docs` (generated by `bazel run //docs:update`).
## Making a New Release
@@ -70,24 +72,33 @@ Name 1, Name 2, Name 3 (alphabetically from `git log`)
--------------------------------------------------------------------------------
-2. Bump `version` in version.bzl to the new version.
+2. Bump `version` in version.bzl, MODULE.bazel, *and* gazelle/MODULE.bazel to
+ the new version.
+ TODO(#386): add a test to make sure all the versions are in sync.
3. Ensure that the commits for steps 1 and 2 have been merged. All further
steps must be performed on a single, known-good git commit.
-4. `bazel build //distribution:bazel-skylib-$VERSION.tar.gz`
-5. Copy the `bazel-skylib-$VERSION.tar.gz` tarball to the mirror (you'll need
- Bazel developer gcloud credentials; assuming you are a Bazel developer, you
- can obtain them via `gcloud init`):
-
-```
-gsutil cp bazel-bin/distro/bazel-skylib-$VERSION.tar.gz gs://bazel-mirror/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-$VERSION.tar.gz
-gsutil setmeta -h "Cache-Control: public, max-age=31536000" "gs://bazel-mirror/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-$VERSION.tar.gz"
+4. `bazel build //distribution`
+5. Copy the `bazel-skylib-$VERSION.tar.gz` and
+ `bazel-skylib-gazelle-plugin-$VERSION.tar.gz` tarballs to the mirror (you'll
+ need Bazel developer gcloud credentials; assuming you are a Bazel developer,
+ you can obtain them via `gcloud init`):
+
+```bash
+gsutil cp bazel-bin/distribution/bazel-skylib{,-gazelle-plugin}-$VERSION.tar.gz gs://bazel-mirror/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/
+gsutil setmeta -h "Cache-Control: public, max-age=31536000" gs://bazel-mirror/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib{,-gazelle-plugin}-$VERSION.tar.gz
```
-6. Run `sha256sum bazel-bin/distro/bazel-skylib-$VERSION.tar.gz`; you'll need
- the checksum for the release notes.
+6. Obtain checksums for release notes:
+
+```bash
+sha256sum bazel-bin/distribution/bazel-skylib-$VERSION.tar.gz
+sha256sum bazel-bin/distribution/bazel-skylib-gazelle-plugin-$VERSION.tar.gz
+````
+
7. Draft a new release with a new tag named $VERSION in github. Attach
- `bazel-skylib-$VERSION.tar.gz` to the release. For the release notes, use
- the CHANGELOG.md entry plus the following template:
+ `bazel-skylib-$VERSION.tar.gz` and
+ `bazel-skylib-gazelle-plugin-$VERSION.tar.gz` to the release. For the
+ release notes, use the CHANGELOG.md entry plus the following template:
--------------------------------------------------------------------------------
@@ -95,20 +106,88 @@ gsutil setmeta -h "Cache-Control: public, max-age=31536000" "gs://bazel-mirror/g
```
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
http_archive(
name = "bazel_skylib",
+ sha256 = "$SHA256SUM"
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-$VERSION.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-$VERSION.tar.gz",
],
- sha256 = "$SHA256SUM",
)
+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+
bazel_skylib_workspace()
```
+***Additional WORKSPACE setup for the Gazelle plugin***
+
+```starlark
+http_archive(
+ name = "bazel_skylib_gazelle_plugin",
+ sha256 = "$SHA256SUM_GAZELLE_PLUGIN",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-gazelle-plugin-$VERSION.tar.gz",
+ "https://github.com/bazelbuild/bazel-skylib/releases/download/$VERSION/bazel-skylib-gazelle-plugin-$VERSION.tar.gz",
+ ],
+)
+
+load("@bazel_skylib_gazelle_plugin//:workspace.bzl", "bazel_skylib_gazelle_plugin_workspace")
+
+bazel_skylib_gazelle_plugin_workspace()
+
+load("@bazel_skylib_gazelle_plugin//:setup.bzl", "bazel_skylib_gazelle_plugin_setup")
+
+bazel_skylib_gazelle_plugin_setup()
+```
+
**Using the rules**
See [the source](https://github.com/bazelbuild/bazel-skylib/tree/$VERSION).
--------------------------------------------------------------------------------- \ No newline at end of file
+--------------------------------------------------------------------------------
+
+8. Obtain [Subresource Integrity](https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description)
+ format checksums for bzlmod:
+
+```bash
+echo -n sha256-; cat bazel-bin/distribution/bazel-skylib-$VERSION.tar.gz | openssl dgst -sha256 -binary | base64
+echo -n sha256-; cat bazel-bin/distribution/bazel-skylib-gazelle-plugin-$VERSION.tar.gz | openssl dgst -sha256 -binary | base64
+```
+
+9. Create a PR at [Bazel Central Registry](https://github.com/bazelbuild/bazel-central-registry)
+ to update the registry's versions of bazel_skylib and
+ bazel_skylib_gazelle_plugin.
+
+ Use https://github.com/bazelbuild/bazel-central-registry/pull/403 as the
+ model; you will need to update `modules/bazel_skylib/metadata.json` and
+ `modules/bazel_skylib_gazelle_plugin/metadata.json` to list the new version
+ in `versions`, and create new $VERSION subdirectories for the updated
+ modules, using the latest existing version subdirectories as the guide. Use
+ Subresource Integrity checksums obtained above in the new `source.json`
+ files.
+
+ Ensure that the MODULE.bazel files you add in the new $VERSION
+ subdirectories exactly match the MODULE.bazel file packaged in
+ bazel-skylib-$VERSION.tar.gz and bazel-skylib-gazelle-plugin-$VERSION.tar.gz
+ tarballs - or buildkite checks will fail.
+
+10. Once the Bazel Central Registry PR is merged, insert in the release
+ description after the WORKSPACE setup section:
+
+--------------------------------------------------------------------------------
+
+**MODULE.bazel setup**
+
+```starlark
+bazel_dep(name = "bazel_skylib", version = "$VERSION")
+```
+
+And for the Gazelle plugin:
+
+```starlark
+bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "$VERSION", dev_dependency = True)
+```
+
+--------------------------------------------------------------------------------
diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md
index 1a330ca..2b603be 100755
--- a/docs/native_binary_doc.md
+++ b/docs/native_binary_doc.md
@@ -5,57 +5,58 @@ native_binary() and native_test() rule implementations.
These rules let you wrap a pre-built binary or script in a conventional binary
and test rule respectively. They fulfill the same goal as sh_binary and sh_test
do, but they run the wrapped binary directly, instead of through Bash, so they
-don't depend on Bash and work with --shell_exectuable="".
+don't depend on Bash and work with --shell_executable="".
-<a id="#native_binary"></a>
+<a id="native_binary"></a>
## native_binary
<pre>
-native_binary(<a href="#native_binary-name">name</a>, <a href="#native_binary-src">src</a>, <a href="#native_binary-out">out</a>, <a href="#native_binary-data">data</a>, <a href="#native_binary-kwargs">kwargs</a>)
+native_binary(<a href="#native_binary-name">name</a>, <a href="#native_binary-data">data</a>, <a href="#native_binary-out">out</a>, <a href="#native_binary-src">src</a>)
</pre>
+
Wraps a pre-built binary or script with a binary rule.
-You can "bazel run" this rule like any other binary rule, and use it as a tool in genrule.tools for example. You can also augment the binary with runfiles.
+You can "bazel run" this rule like any other binary rule, and use it as a tool
+in genrule.tools for example. You can also augment the binary with runfiles.
-**PARAMETERS**
+**ATTRIBUTES**
-| Name | Description | Default Value |
-| :------------- | :------------- | :------------- |
-| <a id="native_binary-name"></a>name | The name of the rule. | none |
-| <a id="native_binary-src"></a>src | label; path of the pre-built executable | none |
-| <a id="native_binary-out"></a>out | output; an output name for the copy of the binary. (Bazel requires that this rule make a copy of 'src'.) | none |
-| <a id="native_binary-data"></a>data | list of labels; data dependencies | <code>None</code> |
-| <a id="native_binary-kwargs"></a>kwargs | The &lt;a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-binaries"&gt;common attributes for binaries&lt;/a&gt;. | none |
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="native_binary-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="native_binary-data"></a>data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
+| <a id="native_binary-out"></a>out | An output name for the copy of the binary | String | required | |
+| <a id="native_binary-src"></a>src | path of the pre-built executable | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
-<a id="#native_test"></a>
+<a id="native_test"></a>
## native_test
<pre>
-native_test(<a href="#native_test-name">name</a>, <a href="#native_test-src">src</a>, <a href="#native_test-out">out</a>, <a href="#native_test-data">data</a>, <a href="#native_test-kwargs">kwargs</a>)
+native_test(<a href="#native_test-name">name</a>, <a href="#native_test-data">data</a>, <a href="#native_test-out">out</a>, <a href="#native_test-src">src</a>)
</pre>
+
Wraps a pre-built binary or script with a test rule.
-You can "bazel test" this rule like any other test rule. You can also augment the binary with
-runfiles.
+You can "bazel test" this rule like any other test rule. You can also augment
+the binary with runfiles.
-**PARAMETERS**
+**ATTRIBUTES**
-| Name | Description | Default Value |
-| :------------- | :------------- | :------------- |
-| <a id="native_test-name"></a>name | The name of the test rule. | none |
-| <a id="native_test-src"></a>src | label; path of the pre-built executable | none |
-| <a id="native_test-out"></a>out | output; an output name for the copy of the binary. (Bazel requires that this rule make a copy of 'src'.) | none |
-| <a id="native_test-data"></a>data | list of labels; data dependencies | <code>None</code> |
-| <a id="native_test-kwargs"></a>kwargs | The &lt;a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests"&gt;common attributes for tests&lt;/a&gt;. | none |
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="native_test-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="native_test-data"></a>data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
+| <a id="native_test-out"></a>out | An output name for the copy of the binary | String | required | |
+| <a id="native_test-src"></a>src | path of the pre-built executable | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
diff --git a/docs/new_sets_doc.md b/docs/new_sets_doc.md
index e34107f..4f7fde2 100755
--- a/docs/new_sets_doc.md
+++ b/docs/new_sets_doc.md
@@ -11,7 +11,7 @@ Skylib module containing common hash-set algorithms.
`types.is_set()` method in types.bzl.
-<a id="#sets.make"></a>
+<a id="sets.make"></a>
## sets.make
@@ -36,7 +36,7 @@ All elements must be hashable.
A set containing the passed in values.
-<a id="#sets.copy"></a>
+<a id="sets.copy"></a>
## sets.copy
@@ -58,7 +58,7 @@ Creates a new set from another set.
A new set containing the same elements as `s`.
-<a id="#sets.to_list"></a>
+<a id="sets.to_list"></a>
## sets.to_list
@@ -80,7 +80,7 @@ Creates a list from the values in the set.
A list of values inserted into the set.
-<a id="#sets.insert"></a>
+<a id="sets.insert"></a>
## sets.insert
@@ -106,7 +106,7 @@ Element must be hashable. This mutates the original set.
The set `s` with `e` included.
-<a id="#sets.contains"></a>
+<a id="sets.contains"></a>
## sets.contains
@@ -129,7 +129,7 @@ Checks for the existence of an element in a set.
True if the element exists in the set, False if the element does not.
-<a id="#sets.is_equal"></a>
+<a id="sets.is_equal"></a>
## sets.is_equal
@@ -152,7 +152,7 @@ Returns whether two sets are equal.
True if `a` is equal to `b`, False otherwise.
-<a id="#sets.is_subset"></a>
+<a id="sets.is_subset"></a>
## sets.is_subset
@@ -175,7 +175,7 @@ Returns whether `a` is a subset of `b`.
True if `a` is a subset of `b`, False otherwise.
-<a id="#sets.disjoint"></a>
+<a id="sets.disjoint"></a>
## sets.disjoint
@@ -201,7 +201,7 @@ Two sets are disjoint if they have no elements in common.
True if `a` and `b` are disjoint, False otherwise.
-<a id="#sets.intersection"></a>
+<a id="sets.intersection"></a>
## sets.intersection
@@ -224,7 +224,7 @@ Returns the intersection of two sets.
A set containing the elements that are in both `a` and `b`.
-<a id="#sets.union"></a>
+<a id="sets.union"></a>
## sets.union
@@ -246,7 +246,7 @@ Returns the union of several sets.
The set union of all sets in `*args`.
-<a id="#sets.difference"></a>
+<a id="sets.difference"></a>
## sets.difference
@@ -269,7 +269,7 @@ Returns the elements in `a` that are not in `b`.
A set containing the elements that are in `a` but not in `b`.
-<a id="#sets.length"></a>
+<a id="sets.length"></a>
## sets.length
@@ -291,7 +291,7 @@ Returns the number of elements in a set.
An integer representing the number of elements in the set.
-<a id="#sets.remove"></a>
+<a id="sets.remove"></a>
## sets.remove
@@ -317,7 +317,7 @@ Element must be hashable. This mutates the original set.
The set `s` with `e` removed.
-<a id="#sets.repr"></a>
+<a id="sets.repr"></a>
## sets.repr
@@ -339,7 +339,7 @@ Returns a string value representing the set.
A string representing the set.
-<a id="#sets.str"></a>
+<a id="sets.str"></a>
## sets.str
diff --git a/docs/partial_doc.md b/docs/partial_doc.md
index d772ec8..97d4094 100755
--- a/docs/partial_doc.md
+++ b/docs/partial_doc.md
@@ -7,7 +7,7 @@ Partial function objects allow some parameters are bound before the call.
Similar to https://docs.python.org/3/library/functools.html#functools.partial.
-<a id="#partial.make"></a>
+<a id="partial.make"></a>
## partial.make
@@ -123,7 +123,7 @@ partial.call(func, x=2)
A new `partial` that can be called using `call`
-<a id="#partial.call"></a>
+<a id="partial.call"></a>
## partial.call
@@ -147,7 +147,7 @@ Calls a partial created using `make`.
Whatever the function in the partial returns.
-<a id="#partial.is_instance"></a>
+<a id="partial.is_instance"></a>
## partial.is_instance
diff --git a/docs/paths_doc.md b/docs/paths_doc.md
index e0d8116..e9d619d 100755
--- a/docs/paths_doc.md
+++ b/docs/paths_doc.md
@@ -7,7 +7,7 @@ path separators (forward slash, "/"); they do not handle Windows-style paths
with backslash separators or drive letters.
-<a id="#paths.basename"></a>
+<a id="paths.basename"></a>
## paths.basename
@@ -35,7 +35,7 @@ the final slash).
The basename of the path, which includes the extension.
-<a id="#paths.dirname"></a>
+<a id="paths.dirname"></a>
## paths.dirname
@@ -62,7 +62,7 @@ included, unless omitting them would make the dirname empty.
The dirname of the path.
-<a id="#paths.is_absolute"></a>
+<a id="paths.is_absolute"></a>
## paths.is_absolute
@@ -84,7 +84,7 @@ Returns `True` if `path` is an absolute path.
`True` if `path` is an absolute path.
-<a id="#paths.join"></a>
+<a id="paths.join"></a>
## paths.join
@@ -116,7 +116,7 @@ If any component is an absolute path, all previous components are discarded.
A string containing the joined paths.
-<a id="#paths.normalize"></a>
+<a id="paths.normalize"></a>
## paths.normalize
@@ -153,7 +153,7 @@ POSIX platforms; specifically:
The normalized path.
-<a id="#paths.relativize"></a>
+<a id="paths.relativize"></a>
## paths.relativize
@@ -185,7 +185,7 @@ the path both start with the same initial parent references.
The portion of `path` that is relative to `start`.
-<a id="#paths.replace_extension"></a>
+<a id="paths.replace_extension"></a>
## paths.replace_extension
@@ -211,7 +211,7 @@ If the path has no extension, the new extension is added to it.
The path with the extension replaced (or added, if it did not have one).
-<a id="#paths.split_extension"></a>
+<a id="paths.split_extension"></a>
## paths.split_extension
diff --git a/docs/private/BUILD b/docs/private/BUILD
new file mode 100644
index 0000000..f8c832b
--- /dev/null
+++ b/docs/private/BUILD
@@ -0,0 +1 @@
+# No targets in this package
diff --git a/docs/private/stardoc_with_diff_test.bzl b/docs/private/stardoc_with_diff_test.bzl
new file mode 100644
index 0000000..a8542f3
--- /dev/null
+++ b/docs/private/stardoc_with_diff_test.bzl
@@ -0,0 +1,111 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Helpers for keeping stardoc documentation up-to-date.
+
+These are currently a private API in bazel-skylib.
+See discussion:
+https://github.com/bazelbuild/bazel-skylib/pull/321#issuecomment-1081166216
+
+If you need a similar feature, you can consider using a similar rule
+available from a third-party:
+https://github.com/aspect-build/bazel-lib/blob/main/docs/docs.md
+"""
+
+load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
+load("@bazel_skylib//rules:write_file.bzl", "write_file")
+load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
+
+def stardoc_with_diff_test(
+ name,
+ bzl_library_target,
+ out_label):
+ """Creates a stardoc target coupled with a `diff_test` for a given `bzl_library`.
+
+ This is helpful for minimizing boilerplate in repos with lots of stardoc targets.
+
+ Args:
+ name: the stardoc target name
+ bzl_library_target: the label of the `bzl_library` target to generate documentation for
+ out_label: the label of the output MD file
+ """
+ out_file = out_label.replace("//", "").replace(":", "/")
+
+ # Generate MD from .bzl
+ stardoc(
+ name = name,
+ out = out_file.replace(".md", "-docgen.md"),
+ input = bzl_library_target + ".bzl",
+ deps = [bzl_library_target],
+ )
+
+ # Ensure that the generated MD has been updated in the local source tree
+ diff_test(
+ name = out_file.replace("/", "_").replace(".md", "-difftest"),
+ failure_message = "Please run \"bazel run //docs:update\"",
+ # Source file
+ file1 = out_label,
+ # Output from stardoc rule above
+ file2 = out_file.replace(".md", "-docgen.md"),
+ tags = ["no_windows"],
+ )
+
+def update_docs(
+ name = "update",
+ docs_folder = "docs"):
+ """Creates a `sh_binary` target which copies over generated doc files to the local source tree.
+
+ This is to be used in tandem with `stardoc_with_diff_test()` to produce a convenient workflow
+ for generating, testing, and updating all doc files as follows:
+
+ ``` bash
+ bazel build //{docs_folder}/... && bazel test //{docs_folder}/... && bazel run //{docs_folder}:update
+ ```
+
+ eg.
+
+ ``` bash
+ bazel build //docs/... && bazel test //docs/... && bazel run //docs:update
+ ```
+
+ The `update_docs()` invocation must come after/below any `stardoc_with_diff_test()` invocations
+ in the BUILD file.
+
+ Args:
+ name: the name of the `sh_binary` target
+ docs_folder: the name of the folder containing the doc files in the local source tree
+ """
+ content = ["#!/usr/bin/env bash", "cd ${BUILD_WORKSPACE_DIRECTORY}"]
+ data = []
+ for r in native.existing_rules().values():
+ if r["kind"] == "stardoc":
+ doc_gen = r["out"]
+ if doc_gen.startswith(":"):
+ doc_gen = doc_gen[1:]
+ doc_dest = doc_gen.replace("-docgen.md", ".md")
+ data.append(doc_gen)
+ content.append("cp -fv bazel-bin/{0}/{1} {2}".format(docs_folder, doc_gen, doc_dest))
+
+ update_script = name + ".sh"
+ write_file(
+ name = "gen_" + name,
+ out = update_script,
+ content = content,
+ )
+
+ native.sh_binary(
+ name = name,
+ srcs = [update_script],
+ data = data,
+ )
diff --git a/docs/run_binary_doc.md b/docs/run_binary_doc.md
index 96bada5..50b62e4 100755
--- a/docs/run_binary_doc.md
+++ b/docs/run_binary_doc.md
@@ -6,7 +6,7 @@ run_binary() build rule implementation.
Runs a binary as a build action. This rule does not require Bash (unlike native.genrule()).
-<a id="#run_binary"></a>
+<a id="run_binary"></a>
## run_binary
@@ -14,18 +14,20 @@ Runs a binary as a build action. This rule does not require Bash (unlike native.
run_binary(<a href="#run_binary-name">name</a>, <a href="#run_binary-args">args</a>, <a href="#run_binary-env">env</a>, <a href="#run_binary-outs">outs</a>, <a href="#run_binary-srcs">srcs</a>, <a href="#run_binary-tool">tool</a>)
</pre>
-Runs a binary as a build action.<br/><br/>This rule does not require Bash (unlike <code>native.genrule</code>).
+Runs a binary as a build action.
+
+This rule does not require Bash (unlike `native.genrule`).
**ATTRIBUTES**
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="run_binary-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
-| <a id="run_binary-args"></a>args | Command line arguments of the binary.&lt;br/&gt;&lt;br/&gt;Subject to&lt;code&gt;&lt;a href="https://docs.bazel.build/versions/main/be/make-variables.html#location"&gt;$(location)&lt;/a&gt;&lt;/code&gt; expansion. | List of strings | optional | [] |
-| <a id="run_binary-env"></a>env | Environment variables of the action.&lt;br/&gt;&lt;br/&gt;Subject to &lt;code&gt;&lt;a href="https://docs.bazel.build/versions/main/be/make-variables.html#location"&gt;$(location)&lt;/a&gt;&lt;/code&gt; expansion. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
-| <a id="run_binary-outs"></a>outs | Output files generated by the action.&lt;br/&gt;&lt;br/&gt;These labels are available for &lt;code&gt;$(location)&lt;/code&gt; expansion in &lt;code&gt;args&lt;/code&gt; and &lt;code&gt;env&lt;/code&gt;. | List of labels | required | |
-| <a id="run_binary-srcs"></a>srcs | Additional inputs of the action.&lt;br/&gt;&lt;br/&gt;These labels are available for &lt;code&gt;$(location)&lt;/code&gt; expansion in &lt;code&gt;args&lt;/code&gt; and &lt;code&gt;env&lt;/code&gt;. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
-| <a id="run_binary-tool"></a>tool | The tool to run in the action.&lt;br/&gt;&lt;br/&gt;Must be the label of a *_binary rule, of a rule that generates an executable file, or of a file that can be executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary with executable permission on Linux). This label is available for &lt;code&gt;$(location)&lt;/code&gt; expansion in &lt;code&gt;args&lt;/code&gt; and &lt;code&gt;env&lt;/code&gt;. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
+| <a id="run_binary-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="run_binary-args"></a>args | Command line arguments of the binary.<br><br>Subject to [<code>$(location)</code>](https://bazel.build/reference/be/make-variables#predefined_label_variables) expansion. | List of strings | optional | <code>[]</code> |
+| <a id="run_binary-env"></a>env | Environment variables of the action.<br><br>Subject to [<code>$(location)</code>](https://bazel.build/reference/be/make-variables#predefined_label_variables) expansion. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
+| <a id="run_binary-outs"></a>outs | Output files generated by the action.<br><br>These labels are available for <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | List of labels | required | |
+| <a id="run_binary-srcs"></a>srcs | Additional inputs of the action.<br><br>These labels are available for <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
+| <a id="run_binary-tool"></a>tool | The tool to run in the action.<br><br>Must be the label of a *_binary rule, of a rule that generates an executable file, or of a file that can be executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary with executable permission on Linux). This label is available for <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
diff --git a/docs/select_file_doc.md b/docs/select_file_doc.md
new file mode 100755
index 0000000..33c3bc4
--- /dev/null
+++ b/docs/select_file_doc.md
@@ -0,0 +1,28 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+
+select_file() build rule implementation.
+
+Selects a single file from the outputs of a target by given relative path.
+
+
+<a id="select_file"></a>
+
+## select_file
+
+<pre>
+select_file(<a href="#select_file-name">name</a>, <a href="#select_file-srcs">srcs</a>, <a href="#select_file-subpath">subpath</a>)
+</pre>
+
+Selects a single file from the outputs of a target by given relative path
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="select_file-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="select_file-srcs"></a>srcs | The target producing the file among other outputs | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
+| <a id="select_file-subpath"></a>subpath | Relative path to the file | String | required | |
+
+
diff --git a/docs/selects_doc.md b/docs/selects_doc.md
index 8bfd964..8e2f31b 100755
--- a/docs/selects_doc.md
+++ b/docs/selects_doc.md
@@ -2,7 +2,7 @@
Skylib module containing convenience interfaces for select().
-<a id="#selects.with_or"></a>
+<a id="selects.with_or"></a>
## selects.with_or
@@ -48,7 +48,7 @@ to
```
-<a id="#selects.with_or_dict"></a>
+<a id="selects.with_or_dict"></a>
## selects.with_or_dict
@@ -74,7 +74,7 @@ macros.
A dictionary usable by a native `select()`.
-<a id="#selects.config_setting_group"></a>
+<a id="selects.config_setting_group"></a>
## selects.config_setting_group
diff --git a/docs/shell_doc.md b/docs/shell_doc.md
index 0759434..bd559b9 100755
--- a/docs/shell_doc.md
+++ b/docs/shell_doc.md
@@ -2,7 +2,7 @@
Skylib module containing shell utility functions.
-<a id="#shell.array_literal"></a>
+<a id="shell.array_literal"></a>
## shell.array_literal
@@ -33,7 +33,7 @@ A string that represents the sequence as a shell array; that is,
parentheses containing the quoted elements.
-<a id="#shell.quote"></a>
+<a id="shell.quote"></a>
## shell.quote
diff --git a/docs/structs_doc.md b/docs/structs_doc.md
index a409d86..667aa46 100755
--- a/docs/structs_doc.md
+++ b/docs/structs_doc.md
@@ -2,7 +2,7 @@
Skylib module containing functions that operate on structs.
-<a id="#structs.to_dict"></a>
+<a id="structs.to_dict"></a>
## structs.to_dict
diff --git a/docs/subpackages_doc.md b/docs/subpackages_doc.md
new file mode 100755
index 0000000..8a0956f
--- /dev/null
+++ b/docs/subpackages_doc.md
@@ -0,0 +1,96 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+Skylib module containing common functions for working with native.subpackages()
+
+
+<a id="subpackages.all"></a>
+
+## subpackages.all
+
+<pre>
+subpackages.all(<a href="#subpackages.all-exclude">exclude</a>, <a href="#subpackages.all-allow_empty">allow_empty</a>, <a href="#subpackages.all-fully_qualified">fully_qualified</a>)
+</pre>
+
+List all direct subpackages of the current package regardless of directory depth.
+
+The returned list contains all subpackages, but not subpackages of subpackages.
+
+Example:
+Assuming the following BUILD files exist:
+
+ BUILD
+ foo/BUILD
+ foo/sub/BUILD
+ bar/BUILD
+ baz/deep/dir/BUILD
+
+If the current package is '//' all() will return ['//foo', '//bar',
+'//baz/deep/dir']. //foo/sub is not included because it is a direct
+subpackage of '//foo' not '//'
+
+NOTE: fail()s if native.subpackages() is not supported.
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="subpackages.all-exclude"></a>exclude | see native.subpackages(exclude) | <code>[]</code> |
+| <a id="subpackages.all-allow_empty"></a>allow_empty | see native.subpackages(allow_empty) | <code>False</code> |
+| <a id="subpackages.all-fully_qualified"></a>fully_qualified | It true return fully qualified Labels for subpackages, otherwise returns subpackage path relative to current package. | <code>True</code> |
+
+**RETURNS**
+
+A mutable sorted list containing all sub-packages of the current Bazel
+package.
+
+
+<a id="subpackages.exists"></a>
+
+## subpackages.exists
+
+<pre>
+subpackages.exists(<a href="#subpackages.exists-relative_path">relative_path</a>)
+</pre>
+
+Checks to see if relative_path is a direct subpackage of the current package.
+
+Example:
+
+ BUILD
+ foo/BUILD
+ foo/sub/BUILD
+
+If the current package is '//' (the top-level BUILD file):
+ subpackages.exists("foo") == True
+ subpackages.exists("foo/sub") == False
+ subpackages.exists("bar") == False
+
+NOTE: fail()s if native.subpackages() is not supported in the current Bazel version.
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="subpackages.exists-relative_path"></a>relative_path | a path to a subpackage to test, must not be an absolute Label. | none |
+
+**RETURNS**
+
+True if 'relative_path' is a subpackage of the current package.
+
+
+<a id="subpackages.supported"></a>
+
+## subpackages.supported
+
+<pre>
+subpackages.supported()
+</pre>
+
+
+
+
+
diff --git a/docs/types_doc.md b/docs/types_doc.md
index 7ab0a6c..bdc9cba 100755
--- a/docs/types_doc.md
+++ b/docs/types_doc.md
@@ -2,7 +2,7 @@
Skylib module containing functions checking types.
-<a id="#types.is_list"></a>
+<a id="types.is_list"></a>
## types.is_list
@@ -24,7 +24,7 @@ Returns True if v is an instance of a list.
True if v is an instance of a list, False otherwise.
-<a id="#types.is_string"></a>
+<a id="types.is_string"></a>
## types.is_string
@@ -46,7 +46,7 @@ Returns True if v is an instance of a string.
True if v is an instance of a string, False otherwise.
-<a id="#types.is_bool"></a>
+<a id="types.is_bool"></a>
## types.is_bool
@@ -68,7 +68,7 @@ Returns True if v is an instance of a bool.
True if v is an instance of a bool, False otherwise.
-<a id="#types.is_none"></a>
+<a id="types.is_none"></a>
## types.is_none
@@ -90,7 +90,7 @@ Returns True if v has the type of None.
True if v is None, False otherwise.
-<a id="#types.is_int"></a>
+<a id="types.is_int"></a>
## types.is_int
@@ -112,7 +112,7 @@ Returns True if v is an instance of a signed integer.
True if v is an instance of a signed integer, False otherwise.
-<a id="#types.is_tuple"></a>
+<a id="types.is_tuple"></a>
## types.is_tuple
@@ -134,7 +134,7 @@ Returns True if v is an instance of a tuple.
True if v is an instance of a tuple, False otherwise.
-<a id="#types.is_dict"></a>
+<a id="types.is_dict"></a>
## types.is_dict
@@ -156,7 +156,7 @@ Returns True if v is an instance of a dict.
True if v is an instance of a dict, False otherwise.
-<a id="#types.is_function"></a>
+<a id="types.is_function"></a>
## types.is_function
@@ -178,7 +178,7 @@ Returns True if v is an instance of a function.
True if v is an instance of a function, False otherwise.
-<a id="#types.is_depset"></a>
+<a id="types.is_depset"></a>
## types.is_depset
@@ -200,7 +200,7 @@ Returns True if v is an instance of a `depset`.
True if v is an instance of a `depset`, False otherwise.
-<a id="#types.is_set"></a>
+<a id="types.is_set"></a>
## types.is_set
diff --git a/docs/unittest_doc.md b/docs/unittest_doc.md
index 5472d74..353d05b 100755
--- a/docs/unittest_doc.md
+++ b/docs/unittest_doc.md
@@ -2,12 +2,21 @@
Unit testing support.
-Unlike most Skylib files, this exports two modules: `unittest` which contains
-functions to declare and define unit tests, and `asserts` which contains the
-assertions used to within tests.
+Unlike most Skylib files, this exports four modules:
+* `unittest` contains functions to declare and define unit tests for ordinary
+ Starlark functions;
+* `analysistest` contains functions to declare and define tests for analysis
+ phase behavior of a rule, such as a given target's providers or registered
+ actions;
+* `loadingtest` contains functions to declare and define tests for loading
+ phase behavior, such as macros and `native.*`;
+* `asserts` contains the assertions used within tests.
+See https://bazel.build/extending/concepts for background about macros, rules,
+and the different phases of a build.
-<a id="#unittest_toolchain"></a>
+
+<a id="unittest_toolchain"></a>
## unittest_toolchain
@@ -23,16 +32,16 @@ unittest_toolchain(<a href="#unittest_toolchain-name">name</a>, <a href="#unitte
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
-| <a id="unittest_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
-| <a id="unittest_toolchain-escape_chars_with"></a>escape_chars_with | Dictionary of characters that need escaping in test failure message to prefix appended to escape those characters. For example, <code>{"%": "%", "&gt;": "^"}</code> would replace <code>%</code> with <code>%%</code> and <code>&gt;</code> with <code>^&gt;</code> in the failure message before that is included in <code>success_templ</code>. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
-| <a id="unittest_toolchain-escape_other_chars_with"></a>escape_other_chars_with | String to prefix every character in test failure message which is not a key in <code>escape_chars_with</code> before including that in <code>success_templ</code>. For example, <code>""</code> would prefix every character in the failure message (except those in the keys of <code>escape_chars_with</code>) with <code>\</code>. | String | optional | "" |
+| <a id="unittest_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
+| <a id="unittest_toolchain-escape_chars_with"></a>escape_chars_with | Dictionary of characters that need escaping in test failure message to prefix appended to escape those characters. For example, <code>{"%": "%", "&gt;": "^"}</code> would replace <code>%</code> with <code>%%</code> and <code>&gt;</code> with <code>^&gt;</code> in the failure message before that is included in <code>success_templ</code>. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
+| <a id="unittest_toolchain-escape_other_chars_with"></a>escape_other_chars_with | String to prefix every character in test failure message which is not a key in <code>escape_chars_with</code> before including that in <code>success_templ</code>. For example, <code>""</code> would prefix every character in the failure message (except those in the keys of <code>escape_chars_with</code>) with <code>\</code>. | String | optional | <code>""</code> |
| <a id="unittest_toolchain-failure_templ"></a>failure_templ | Test script template with a single <code>%s</code>. That placeholder is replaced with the lines in the failure message joined with the string specified in <code>join_with</code>. The resulting script should print the failure message and exit with non-zero status. | String | required | |
| <a id="unittest_toolchain-file_ext"></a>file_ext | File extension for test script, including leading dot. | String | required | |
| <a id="unittest_toolchain-join_on"></a>join_on | String used to join the lines in the failure message before including the resulting string in the script specified in <code>failure_templ</code>. | String | required | |
| <a id="unittest_toolchain-success_templ"></a>success_templ | Test script generated when the test passes. Should exit with status 0. | String | required | |
-<a id="#analysistest.make"></a>
+<a id="analysistest.make"></a>
## analysistest.make
@@ -86,7 +95,7 @@ A rule definition that should be stored in a global whose name ends in
`_test`.
-<a id="#analysistest.begin"></a>
+<a id="analysistest.begin"></a>
## analysistest.begin
@@ -94,9 +103,9 @@ A rule definition that should be stored in a global whose name ends in
analysistest.begin(<a href="#analysistest.begin-ctx">ctx</a>)
</pre>
-Begins a unit test.
+Begins an analysis test.
-This should be the first function called in a unit test implementation
+This should be the first function called in an analysis test implementation
function. It initializes a "test environment" that is used to collect
assertion failures so that they can be reported and logged at the end of the
test.
@@ -112,11 +121,11 @@ test.
**RETURNS**
A test environment struct that must be passed to assertions and finally to
-`unittest.end`. Do not rely on internal details about the fields in this
+`analysistest.end`. Do not rely on internal details about the fields in this
struct as it may change.
-<a id="#analysistest.end"></a>
+<a id="analysistest.end"></a>
## analysistest.end
@@ -142,7 +151,7 @@ that the results are reported.
A list of providers needed to automatically register the analysis test result.
-<a id="#analysistest.fail"></a>
+<a id="analysistest.fail"></a>
## analysistest.fail
@@ -161,7 +170,7 @@ Unconditionally causes the current test to fail.
| <a id="analysistest.fail-msg"></a>msg | The message to log describing the failure. | none |
-<a id="#analysistest.target_actions"></a>
+<a id="analysistest.target_actions"></a>
## analysistest.target_actions
@@ -183,7 +192,7 @@ Returns a list of actions registered by the target under test.
A list of actions registered by the target under test
-<a id="#analysistest.target_bin_dir_path"></a>
+<a id="analysistest.target_bin_dir_path"></a>
## analysistest.target_bin_dir_path
@@ -205,7 +214,7 @@ Returns ctx.bin_dir.path for the target under test.
Output bin dir path string.
-<a id="#analysistest.target_under_test"></a>
+<a id="analysistest.target_under_test"></a>
## analysistest.target_under_test
@@ -227,7 +236,7 @@ Returns the target under test.
The target under test.
-<a id="#asserts.expect_failure"></a>
+<a id="asserts.expect_failure"></a>
## asserts.expect_failure
@@ -250,7 +259,7 @@ This requires that the analysis test is created with `analysistest.make()` and
| <a id="asserts.expect_failure-expected_failure_msg"></a>expected_failure_msg | The error message to expect as a result of analysis failures. | <code>""</code> |
-<a id="#asserts.equals"></a>
+<a id="asserts.equals"></a>
## asserts.equals
@@ -271,7 +280,7 @@ Asserts that the given `expected` and `actual` values are equal.
| <a id="asserts.equals-msg"></a>msg | An optional message that will be printed that describes the failure. If omitted, a default will be used. | <code>None</code> |
-<a id="#asserts.false"></a>
+<a id="asserts.false"></a>
## asserts.false
@@ -291,7 +300,7 @@ Asserts that the given `condition` is false.
| <a id="asserts.false-msg"></a>msg | An optional message that will be printed that describes the failure. If omitted, a default will be used. | <code>"Expected condition to be false, but was true."</code> |
-<a id="#asserts.set_equals"></a>
+<a id="asserts.set_equals"></a>
## asserts.set_equals
@@ -312,7 +321,7 @@ Asserts that the given `expected` and `actual` sets are equal.
| <a id="asserts.set_equals-msg"></a>msg | An optional message that will be printed that describes the failure. If omitted, a default will be used. | <code>None</code> |
-<a id="#asserts.new_set_equals"></a>
+<a id="asserts.new_set_equals"></a>
## asserts.new_set_equals
@@ -333,7 +342,7 @@ Asserts that the given `expected` and `actual` sets are equal.
| <a id="asserts.new_set_equals-msg"></a>msg | An optional message that will be printed that describes the failure. If omitted, a default will be used. | <code>None</code> |
-<a id="#asserts.true"></a>
+<a id="asserts.true"></a>
## asserts.true
@@ -353,7 +362,7 @@ Asserts that the given `condition` is true.
| <a id="asserts.true-msg"></a>msg | An optional message that will be printed that describes the failure. If omitted, a default will be used. | <code>"Expected condition to be true, but was false."</code> |
-<a id="#loadingtest.make"></a>
+<a id="loadingtest.make"></a>
## loadingtest.make
@@ -375,7 +384,7 @@ Creates a loading phase test environment and test_suite.
loading phase environment passed to other loadingtest functions
-<a id="#loadingtest.equals"></a>
+<a id="loadingtest.equals"></a>
## loadingtest.equals
@@ -400,7 +409,7 @@ Creates a test case for asserting state at LOADING phase.
None, creates test case
-<a id="#register_unittest_toolchains"></a>
+<a id="register_unittest_toolchains"></a>
## register_unittest_toolchains
@@ -412,12 +421,12 @@ Registers the toolchains for unittest users.
-<a id="#unittest.make"></a>
+<a id="unittest.make"></a>
## unittest.make
<pre>
-unittest.make(<a href="#unittest.make-impl">impl</a>, <a href="#unittest.make-attrs">attrs</a>)
+unittest.make(<a href="#unittest.make-impl">impl</a>, <a href="#unittest.make-attrs">attrs</a>, <a href="#unittest.make-doc">doc</a>)
</pre>
Creates a unit test rule from its implementation function.
@@ -453,6 +462,7 @@ Recall that names of test rules must end in `_test`.
| :------------- | :------------- | :------------- |
| <a id="unittest.make-impl"></a>impl | The implementation function of the unit test. | none |
| <a id="unittest.make-attrs"></a>attrs | An optional dictionary to supplement the attrs passed to the unit test's <code>rule()</code> constructor. | <code>{}</code> |
+| <a id="unittest.make-doc"></a>doc | A description of the rule that can be extracted by documentation generating tools. | <code>""</code> |
**RETURNS**
@@ -460,7 +470,7 @@ A rule definition that should be stored in a global whose name ends in
`_test`.
-<a id="#unittest.suite"></a>
+<a id="unittest.suite"></a>
## unittest.suite
@@ -516,7 +526,7 @@ name each target.
| <a id="unittest.suite-test_rules"></a>test_rules | A list of test rules defines by <code>unittest.test</code>. | none |
-<a id="#unittest.begin"></a>
+<a id="unittest.begin"></a>
## unittest.begin
@@ -546,7 +556,7 @@ A test environment struct that must be passed to assertions and finally to
struct as it may change.
-<a id="#unittest.end"></a>
+<a id="unittest.end"></a>
## unittest.end
@@ -572,7 +582,7 @@ that the results are reported.
A list of providers needed to automatically register the test result.
-<a id="#unittest.fail"></a>
+<a id="unittest.fail"></a>
## unittest.fail
diff --git a/docs/versions_doc.md b/docs/versions_doc.md
index 83ee7a7..8986737 100755
--- a/docs/versions_doc.md
+++ b/docs/versions_doc.md
@@ -2,7 +2,7 @@
Skylib module containing functions for checking Bazel versions.
-<a id="#versions.get"></a>
+<a id="versions.get"></a>
## versions.get
@@ -14,7 +14,7 @@ Returns the current Bazel version
-<a id="#versions.parse"></a>
+<a id="versions.parse"></a>
## versions.parse
@@ -24,7 +24,10 @@ versions.parse(<a href="#versions.parse-bazel_version">bazel_version</a>)
Parses a version string into a 3-tuple of ints
-int tuples can be compared directly using binary operators (<, >).
+int tuples can be compared directly using binary operators (&lt;, &gt;).
+
+For a development build of Bazel, this returns an unspecified version tuple
+that compares higher than any released version.
**PARAMETERS**
@@ -39,7 +42,7 @@ int tuples can be compared directly using binary operators (<, >).
An int 3-tuple of a (major, minor, patch) version.
-<a id="#versions.check"></a>
+<a id="versions.check"></a>
## versions.check
@@ -59,7 +62,7 @@ Check that the version of Bazel is valid within the specified range.
| <a id="versions.check-bazel_version"></a>bazel_version | the version of Bazel to check. Used for testing, defaults to native.bazel_version | <code>None</code> |
-<a id="#versions.is_at_most"></a>
+<a id="versions.is_at_most"></a>
## versions.is_at_most
@@ -79,10 +82,10 @@ Check that a version is lower or equals to a threshold.
**RETURNS**
-True if version <= threshold.
+True if version &lt;= threshold.
-<a id="#versions.is_at_least"></a>
+<a id="versions.is_at_least"></a>
## versions.is_at_least
@@ -102,6 +105,6 @@ Check that a version is higher or equals to a threshold.
**RETURNS**
-True if version >= threshold.
+True if version &gt;= threshold.
diff --git a/docs/write_file_doc.md b/docs/write_file_doc.md
index 8f39376..e7c99f6 100755
--- a/docs/write_file_doc.md
+++ b/docs/write_file_doc.md
@@ -10,7 +10,7 @@ file. Instead they use Starlark's built-in file writing action
(ctx.actions.write).
-<a id="#write_file"></a>
+<a id="write_file"></a>
## write_file
@@ -30,6 +30,6 @@ Creates a UTF-8 encoded text file.
| <a id="write_file-content"></a>content | A list of strings. Lines of text, the contents of the file. Newlines are added automatically after every line except the last one. | <code>[]</code> |
| <a id="write_file-is_executable"></a>is_executable | A boolean. Whether to make the output file executable. When True, the rule's output can be executed using <code>bazel run</code> and can be in the srcs of binary and test rules that require executable sources. | <code>False</code> |
| <a id="write_file-newline"></a>newline | one of ["auto", "unix", "windows"]: line endings to use. "auto" for platform-determined, "unix" for LF, and "windows" for CRLF. | <code>"auto"</code> |
-| <a id="write_file-kwargs"></a>kwargs | further keyword arguments, e.g. &lt;code&gt;visibility&lt;/code&gt; | none |
+| <a id="write_file-kwargs"></a>kwargs | further keyword arguments, e.g. <code>visibility</code> | none |
diff --git a/gazelle/BUILD b/gazelle/BUILD
new file mode 100644
index 0000000..d1c6daa
--- /dev/null
+++ b/gazelle/BUILD
@@ -0,0 +1,37 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+exports_files(["WORKSPACE.bzlmod"])
+
+bzl_library(
+ name = "setup",
+ srcs = ["setup.bzl"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@bazel_gazelle//:deps",
+ "@io_bazel_rules_go//go:deps",
+ ],
+)
+
+bzl_library(
+ name = "workspace",
+ srcs = ["workspace.bzl"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@bazel_skylib//:workspace",
+ "@bazel_tools//tools/build_defs/repo:http.bzl",
+ "@bazel_tools//tools/build_defs/repo:utils.bzl",
+ ],
+)
+
+# TODO(arostovtsev): exclude everything below from distro tarball
+filegroup(
+ name = "distribution",
+ srcs = [
+ "BUILD",
+ "MODULE.bazel",
+ "WORKSPACE.bzlmod",
+ "setup.bzl",
+ "workspace.bzl",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/gazelle/MODULE.bazel b/gazelle/MODULE.bazel
new file mode 100644
index 0000000..7afa242
--- /dev/null
+++ b/gazelle/MODULE.bazel
@@ -0,0 +1,21 @@
+module(
+ name = "bazel_skylib_gazelle_plugin",
+ # Keep in sync with @bazel_skylib//:MODULE.bazel and @bazel_skylib//:version.bzl
+ version = "1.5.0",
+ compatibility_level = 1,
+)
+
+# Keep in sync with @bazel_skylib//:MODULE.bazel and @bazel_skylib//:version.bzl
+bazel_dep(name = "bazel_skylib", version = "1.4.2")
+bazel_dep(name = "gazelle", version = "0.29.0", repo_name = "bazel_gazelle")
+bazel_dep(name = "rules_go", version = "0.41.0", repo_name = "io_bazel_rules_go")
+
+# `rules_go` will register a toolchain for us if the user doesn't do so
+
+go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
+go_deps.module(
+ path = "github.com/bazelbuild/buildtools",
+ sum = "h1:fmdo+fvvWlhldUcqkhAMpKndSxMN3vH5l7yow5cEaiQ=",
+ version = "v0.0.0-20220531122519-a43aed7014c8",
+)
+use_repo(go_deps, "com_github_bazelbuild_buildtools")
diff --git a/gazelle/WORKSPACE b/gazelle/WORKSPACE
new file mode 100644
index 0000000..cc0217d
--- /dev/null
+++ b/gazelle/WORKSPACE
@@ -0,0 +1,25 @@
+workspace(name = "bazel_skylib_gazelle_plugin")
+
+local_repository(
+ name = "bazel_skylib",
+ path = "..",
+)
+
+load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+
+bazel_skylib_workspace()
+
+load(":workspace.bzl", "bazel_skylib_gazelle_plugin_workspace")
+
+bazel_skylib_gazelle_plugin_workspace()
+
+load(":setup.bzl", "bazel_skylib_gazelle_plugin_setup")
+
+bazel_skylib_gazelle_plugin_setup()
+
+# Provide a repository hint for Gazelle to inform it that the go package
+# github.com/bazelbuild/rules_go is available from io_bazel_rules_go and it
+# doesn't need to duplicatively fetch it.
+# gazelle:repository go_repository name=io_bazel_rules_go importpath=github.com/bazelbuild/rules_go
+# Another Gazelle repository hint.
+# gazelle:repository go_repository name=bazel_gazelle importpath=github.com/bazelbuild/bazel-gazelle/testtools
diff --git a/gazelle/WORKSPACE.bzlmod b/gazelle/WORKSPACE.bzlmod
new file mode 100644
index 0000000..621db93
--- /dev/null
+++ b/gazelle/WORKSPACE.bzlmod
@@ -0,0 +1,8 @@
+workspace(name = "bazel_skylib_gazelle_plugin")
+
+# Provide a repository hint for Gazelle to inform it that the go package
+# github.com/bazelbuild/rules_go is available from io_bazel_rules_go and it
+# doesn't need to duplicatively fetch it.
+# gazelle:repository go_repository name=io_bazel_rules_go importpath=github.com/bazelbuild/rules_go
+# Another Gazelle repository hint.
+# gazelle:repository go_repository name=bazel_gazelle importpath=github.com/bazelbuild/bazel-gazelle/testtools
diff --git a/gazelle/bzl/BUILD b/gazelle/bzl/BUILD
index 29caeb0..0b8e6d3 100644
--- a/gazelle/bzl/BUILD
+++ b/gazelle/bzl/BUILD
@@ -1,5 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@bazel_gazelle//:def.bzl", "gazelle", "gazelle_binary")
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
# gazelle:exclude testdata
@@ -25,9 +25,12 @@ go_test(
srcs = ["gazelle_test.go"],
data = [
":gazelle-skylib",
- ] + glob([
- "testdata/**",
- ]),
+ ] + glob(
+ [
+ "testdata/**",
+ ],
+ allow_empty = True,
+ ),
embed = [":bzl"],
deps = [
"@bazel_gazelle//testtools:go_default_library",
@@ -51,3 +54,24 @@ gazelle(
name = "gazelle",
gazelle = ":gazelle-skylib",
)
+
+# TODO(arostovtsev): exclude everything below from distro tarball
+
+# The files needed for distribution
+# A fake testdata directory is created so that
+# the build file has nothing missing, but we
+# do not bloat the distribution tarball
+filegroup(
+ name = "distribution",
+ srcs = glob(["*.go"]) + [
+ "BUILD",
+ ":fake-testdata",
+ ],
+ visibility = ["//visibility:public"],
+)
+
+genrule(
+ name = "fake-testdata",
+ outs = ["testdata"],
+ cmd = "touch $@",
+)
diff --git a/gazelle/bzl/gazelle.go b/gazelle/bzl/gazelle.go
index dccec27..94c32e9 100644
--- a/gazelle/bzl/gazelle.go
+++ b/gazelle/bzl/gazelle.go
@@ -111,7 +111,7 @@ func (*bzlLibraryLang) Fix(c *config.Config, f *rule.File) {}
// returned, including an empty slice, the rule will be indexed.
func (b *bzlLibraryLang) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
srcs := r.AttrStrings("srcs")
- imports := make([]resolve.ImportSpec, len(srcs))
+ imports := make([]resolve.ImportSpec, 0, len(srcs))
for _, src := range srcs {
spec := resolve.ImportSpec{
@@ -173,7 +173,7 @@ func (*bzlLibraryLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo
if impLabel.Repo != "" || !c.IndexLibraries {
// This is a dependency that is external to the current repo, or indexing
- // is disabled so take a guess at what hte target name should be.
+ // is disabled so take a guess at what the target name should be.
deps = append(deps, strings.TrimSuffix(imp, fileType))
continue
}
diff --git a/gazelle/bzl/gazelle_test.go b/gazelle/bzl/gazelle_test.go
index e4f59e8..1554337 100644
--- a/gazelle/bzl/gazelle_test.go
+++ b/gazelle/bzl/gazelle_test.go
@@ -29,7 +29,7 @@ import (
var gazellePath = findGazelle()
-const testDataPath = "gazelle/bzl/testdata/"
+const testDataPath = "bzl/testdata/"
// TestGazelleBinary runs a gazelle binary with starlib installed on each
// directory in `testdata/*`. Please see `testdata/README.md` for more
@@ -135,7 +135,7 @@ func testPath(t *testing.T, name string, files []bazel.RunfileEntry) {
}
func findGazelle() string {
- gazellePath, ok := bazel.FindBinary("gazelle/bzl", "gazelle-skylib")
+ gazellePath, ok := bazel.FindBinary("bzl", "gazelle-skylib")
if !ok {
panic("could not find gazelle binary")
}
diff --git a/gazelle/bzl/testdata/README.md b/gazelle/bzl/testdata/README.md
index a6a3603..b498c66 100644
--- a/gazelle/bzl/testdata/README.md
+++ b/gazelle/bzl/testdata/README.md
@@ -3,7 +3,7 @@
This directory contains a suite of test cases for the Skylark language plugin
for Gazelle.
-Please note that there are no `BUILD` or `BUILD.bazel` files in subdirs, insted
+Please note that there are no `BUILD` or `BUILD.bazel` files in subdirs, instead
there are `BUILD.in` and `BUILD.out` describing what the `BUILD` should look
like initially and what the `BUILD` file should look like after the run. These
names are special because they are not recognized by Bazel as a proper `BUILD`
diff --git a/gazelle/bzl/testdata/empty/BUILD.in b/gazelle/bzl/testdata/empty/BUILD.in
index e1e154c..ce5d4cc 100644
--- a/gazelle/bzl/testdata/empty/BUILD.in
+++ b/gazelle/bzl/testdata/empty/BUILD.in
@@ -2,7 +2,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
bzl_library(
name = "weirdly_named_target_that_will_be_removed",
- srcs = ["nonexistant.bzl"],
+ srcs = ["nonexistent.bzl"],
visibility = ["//visibility:public"],
)
diff --git a/gazelle/setup.bzl b/gazelle/setup.bzl
new file mode 100644
index 0000000..06f911e
--- /dev/null
+++ b/gazelle/setup.bzl
@@ -0,0 +1,32 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Dependency registration helpers for the gazelle plugin."""
+
+load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
+load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
+
+def bazel_skylib_gazelle_plugin_setup(go_version = "1.20.5", register_go_toolchains = True):
+ """Set up the dependencies needed by the Gazelle plugin.
+
+ Args:
+ go_version: The version of Go registered as part of the build as a string
+ register_go_toolchains: A boolean indicating whether or not to register the Go toolchains. Defaults to `True`
+ """
+ go_rules_dependencies()
+
+ if register_go_toolchains:
+ go_register_toolchains(version = go_version)
+
+ gazelle_dependencies()
diff --git a/gazelle/workspace.bzl b/gazelle/workspace.bzl
new file mode 100644
index 0000000..0eca993
--- /dev/null
+++ b/gazelle/workspace.bzl
@@ -0,0 +1,43 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Dependency registration helpers for repositories which need to load bazel-skylib's gazelle plugin."""
+
+load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
+
+def bazel_skylib_gazelle_plugin_workspace():
+ """Loads dependencies required to use skylib's gazelle plugin"""
+ bazel_skylib_workspace()
+
+ maybe(
+ http_archive,
+ name = "io_bazel_rules_go",
+ sha256 = "278b7ff5a826f3dc10f04feaf0b70d48b68748ccd512d7f98bf442077f043fe3",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
+ ],
+ )
+
+ maybe(
+ http_archive,
+ name = "bazel_gazelle",
+ sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
+ "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
+ ],
+ )
diff --git a/lib/BUILD b/lib/BUILD
index 7e7a9a4..2328081 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -62,6 +62,11 @@ bzl_library(
)
bzl_library(
+ name = "subpackages",
+ srcs = ["subpackages.bzl"],
+)
+
+bzl_library(
name = "types",
srcs = ["types.bzl"],
)
diff --git a/lib/dicts.bzl b/lib/dicts.bzl
index 3f8e661..5a92aa1 100644
--- a/lib/dicts.bzl
+++ b/lib/dicts.bzl
@@ -38,6 +38,33 @@ def _add(*dictionaries, **kwargs):
result.update(kwargs)
return result
+def _omit(dictionary, keys):
+ """Returns a new `dict` that has all the entries of `dictionary` with keys not in `keys`.
+
+ Args:
+ dictionary: A `dict`.
+ keys: A sequence.
+
+ Returns:
+ A new `dict` that has all the entries of `dictionary` with keys not in `keys`.
+ """
+ keys_set = {k: None for k in keys}
+ return {k: dictionary[k] for k in dictionary if k not in keys_set}
+
+def _pick(dictionary, keys):
+ """Returns a new `dict` that has all the entries of `dictionary` with keys in `keys`.
+
+ Args:
+ dictionary: A `dict`.
+ keys: A sequence.
+
+ Returns:
+ A new `dict` that has all the entries of `dictionary` with keys in `keys`.
+ """
+ return {k: dictionary[k] for k in keys if k in dictionary}
+
dicts = struct(
add = _add,
+ omit = _omit,
+ pick = _pick,
)
diff --git a/lib/subpackages.bzl b/lib/subpackages.bzl
new file mode 100644
index 0000000..5b674fd
--- /dev/null
+++ b/lib/subpackages.bzl
@@ -0,0 +1,96 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Skylib module containing common functions for working with native.subpackages()
+"""
+_SUBPACKAGES_SUPPORTED = hasattr(native, "subpackages")
+
+def _supported():
+ return _SUBPACKAGES_SUPPORTED
+
+def _check_supported():
+ if not _SUBPACKAGES_SUPPORTED:
+ fail("native.subpackages not supported in this version of Bazel.")
+
+def _all(exclude = [], allow_empty = False, fully_qualified = True):
+ """List all direct subpackages of the current package regardless of directory depth.
+
+ The returned list contains all subpackages, but not subpackages of subpackages.
+
+ Example:
+ Assuming the following BUILD files exist:
+
+ BUILD
+ foo/BUILD
+ foo/sub/BUILD
+ bar/BUILD
+ baz/deep/dir/BUILD
+
+ If the current package is '//' all() will return ['//foo', '//bar',
+ '//baz/deep/dir']. //foo/sub is not included because it is a direct
+ subpackage of '//foo' not '//'
+
+ NOTE: fail()s if native.subpackages() is not supported.
+
+ Args:
+ exclude: see native.subpackages(exclude)
+ allow_empty: see native.subpackages(allow_empty)
+ fully_qualified: It true return fully qualified Labels for subpackages,
+ otherwise returns subpackage path relative to current package.
+
+ Returns:
+ A mutable sorted list containing all sub-packages of the current Bazel
+ package.
+ """
+ _check_supported()
+
+ subs = native.subpackages(include = ["**"], exclude = exclude, allow_empty = allow_empty)
+ if fully_qualified:
+ return [_fully_qualified(s) for s in subs]
+
+ return subs
+
+def _fully_qualified(relative_path):
+ return "//%s/%s" % (native.package_name(), relative_path)
+
+def _exists(relative_path):
+ """Checks to see if relative_path is a direct subpackage of the current package.
+
+ Example:
+
+ BUILD
+ foo/BUILD
+ foo/sub/BUILD
+
+ If the current package is '//' (the top-level BUILD file):
+ subpackages.exists("foo") == True
+ subpackages.exists("foo/sub") == False
+ subpackages.exists("bar") == False
+
+ NOTE: fail()s if native.subpackages() is not supported in the current Bazel version.
+
+ Args:
+ relative_path: a path to a subpackage to test, must not be an absolute Label.
+
+ Returns:
+ True if 'relative_path' is a subpackage of the current package.
+ """
+ _check_supported()
+ return relative_path in native.subpackages(include = [relative_path], allow_empty = True)
+
+subpackages = struct(
+ all = _all,
+ exists = _exists,
+ supported = _supported,
+)
diff --git a/lib/unittest.bzl b/lib/unittest.bzl
index 3757b08..02e374c 100644
--- a/lib/unittest.bzl
+++ b/lib/unittest.bzl
@@ -14,9 +14,18 @@
"""Unit testing support.
-Unlike most Skylib files, this exports two modules: `unittest` which contains
-functions to declare and define unit tests, and `asserts` which contains the
-assertions used to within tests.
+Unlike most Skylib files, this exports four modules:
+* `unittest` contains functions to declare and define unit tests for ordinary
+ Starlark functions;
+* `analysistest` contains functions to declare and define tests for analysis
+ phase behavior of a rule, such as a given target's providers or registered
+ actions;
+* `loadingtest` contains functions to declare and define tests for loading
+ phase behavior, such as macros and `native.*`;
+* `asserts` contains the assertions used within tests.
+
+See https://bazel.build/extending/concepts for background about macros, rules,
+and the different phases of a build.
"""
load(":new_sets.bzl", new_sets = "sets")
@@ -139,7 +148,7 @@ def _impl_function_name(impl):
impl_name = impl_name.partition("<function ")[-1]
return impl_name.rpartition(">")[0]
-def _make(impl, attrs = {}):
+def _make(impl, attrs = {}, doc = ""):
"""Creates a unit test rule from its implementation function.
Each unit test is defined in an implementation function that must then be
@@ -169,6 +178,7 @@ def _make(impl, attrs = {}):
impl: The implementation function of the unit test.
attrs: An optional dictionary to supplement the attrs passed to the
unit test's `rule()` constructor.
+ doc: A description of the rule that can be extracted by documentation generating tools.
Returns:
A rule definition that should be stored in a global whose name ends in
@@ -179,6 +189,7 @@ def _make(impl, attrs = {}):
return rule(
impl,
+ doc = doc,
attrs = attrs,
_skylark_testable = True,
test = True,
@@ -364,6 +375,25 @@ def _begin(ctx):
"""
return struct(ctx = ctx, failures = [])
+def _begin_analysis_test(ctx):
+ """Begins an analysis test.
+
+ This should be the first function called in an analysis test implementation
+ function. It initializes a "test environment" that is used to collect
+ assertion failures so that they can be reported and logged at the end of the
+ test.
+
+ Args:
+ ctx: The Starlark context. Pass the implementation function's `ctx` argument
+ in verbatim.
+
+ Returns:
+ A test environment struct that must be passed to assertions and finally to
+ `analysistest.end`. Do not rely on internal details about the fields in this
+ struct as it may change.
+ """
+ return struct(ctx = ctx, failures = [])
+
def _end_analysis_test(env):
"""Ends an analysis test and logs the results.
@@ -647,7 +677,7 @@ unittest = struct(
analysistest = struct(
make = _make_analysis_test,
- begin = _begin,
+ begin = _begin_analysis_test,
end = _end_analysis_test,
fail = _fail,
target_actions = _target_actions,
diff --git a/lib/versions.bzl b/lib/versions.bzl
index 0209a6f..87ca73c 100644
--- a/lib/versions.bzl
+++ b/lib/versions.bzl
@@ -44,6 +44,9 @@ def _parse_bazel_version(bazel_version):
int tuples can be compared directly using binary operators (<, >).
+ For a development build of Bazel, this returns an unspecified version tuple
+ that compares higher than any released version.
+
Args:
bazel_version: the Bazel version string
@@ -52,6 +55,8 @@ def _parse_bazel_version(bazel_version):
"""
version = _extract_version_number(bazel_version)
+ if not version:
+ return (999999, 999999, 999999)
return tuple([int(n) for n in version.split(".")])
def _is_at_most(threshold, version):
diff --git a/rules/BUILD b/rules/BUILD
index f7017bb..3a06554 100644
--- a/rules/BUILD
+++ b/rules/BUILD
@@ -22,6 +22,12 @@ bzl_library(
)
bzl_library(
+ name = "copy_directory",
+ srcs = ["copy_directory.bzl"],
+ deps = ["//rules/private:copy_directory_private"],
+)
+
+bzl_library(
name = "write_file",
srcs = ["write_file.bzl"],
deps = ["//rules/private:write_file_private"],
@@ -30,12 +36,17 @@ bzl_library(
bzl_library(
name = "diff_test",
srcs = ["diff_test.bzl"],
+ deps = ["//lib:shell"],
+)
+
+bzl_library(
+ name = "expand_template",
+ srcs = ["expand_template.bzl"],
)
bzl_library(
name = "native_binary",
srcs = ["native_binary.bzl"],
- deps = ["//rules/private:copy_file_private"],
)
bzl_library(
diff --git a/rules/build_test.bzl b/rules/build_test.bzl
index 9ec8ab1..e1baba6 100644
--- a/rules/build_test.bzl
+++ b/rules/build_test.bzl
@@ -41,6 +41,14 @@ _empty_test = rule(
test = True,
)
+_GENRULE_ATTRS = [
+ "compatible_with",
+ "exec_compatible_with",
+ "restricted_to",
+ "tags",
+ "target_compatible_with",
+]
+
def build_test(name, targets, **kwargs):
"""Test rule checking that other targets build.
@@ -63,7 +71,7 @@ def build_test(name, targets, **kwargs):
Args:
name: The name of the test rule.
targets: A list of targets to ensure build.
- **kwargs: The <a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests">common attributes for tests</a>.
+ **kwargs: The [common attributes for tests](https://bazel.build/reference/be/common-definitions#common-attributes-tests).
"""
if len(targets) == 0:
fail("targets must be non-empty", "targets")
@@ -81,8 +89,14 @@ def build_test(name, targets, **kwargs):
batch_size = max(1, len(targets) // 100)
# Pull a few args over from the test to the genrule.
- args_to_reuse = ["compatible_with", "restricted_to", "tags"]
- genrule_args = {k: kwargs.get(k) for k in args_to_reuse if k in kwargs}
+ genrule_args = {k: kwargs.get(k) for k in _GENRULE_ATTRS if k in kwargs}
+
+ # Only the test target should be used to determine whether or not the deps
+ # are built. Tagging the genrule targets as manual accomplishes this by
+ # preventing them from being picked up by recursive build patterns (`//...`).
+ genrule_tags = genrule_args.pop("tags", [])
+ if "manual" not in genrule_tags:
+ genrule_tags = genrule_tags + ["manual"]
# Pass an output from the genrules as data to a shell test to bundle
# it all up in a test.
@@ -99,6 +113,7 @@ def build_test(name, targets, **kwargs):
visibility = ["//visibility:private"],
cmd = "touch $@",
cmd_bat = "type nul > $@",
+ tags = genrule_tags,
**genrule_args
)
diff --git a/rules/common_settings.bzl b/rules/common_settings.bzl
index 7f56a7f..58a15ae 100644
--- a/rules/common_settings.bzl
+++ b/rules/common_settings.bzl
@@ -18,7 +18,7 @@ These rules return a BuildSettingInfo with the value of the build setting.
For label-typed settings, use the native label_flag and label_setting rules.
More documentation on how to use build settings at
-https://docs.bazel.build/versions/main/skylark/config.html#user-defined-build-settings
+https://bazel.build/extending/config#user-defined-build-settings
"""
BuildSettingInfo = provider(
@@ -30,18 +30,52 @@ BuildSettingInfo = provider(
},
)
+_MAKE_VARIABLE_ATTR = attr.string(
+ doc = "If set, the build setting's value will be available as a Make variable with this " +
+ "name in the attributes of rules that list this build setting in their 'toolchains' " +
+ "attribute.",
+)
+
+def _is_valid_make_variable_char(c):
+ # Restrict make variable names for consistency with predefined ones. There are no enforced
+ # restrictions on make variable names, but when they contain e.g. spaces or braces, they
+ # aren't expanded by e.g. cc_binary.
+ return c == "_" or c.isdigit() or (c.isalpha() and c.isupper())
+
+def _get_template_variable_info(ctx):
+ make_variable = getattr(ctx.attr, "make_variable", None)
+ if not make_variable:
+ return []
+
+ if not all([_is_valid_make_variable_char(c) for c in make_variable.elems()]):
+ fail("Error setting " + _no_at_str(ctx.label) + ": invalid make variable name '" + make_variable + "'. Make variable names may only contain uppercase letters, digits, and underscores.")
+
+ return [
+ platform_common.TemplateVariableInfo({
+ make_variable: str(ctx.build_setting_value),
+ }),
+ ]
+
def _impl(ctx):
- return BuildSettingInfo(value = ctx.build_setting_value)
+ return [
+ BuildSettingInfo(value = ctx.build_setting_value),
+ ] + _get_template_variable_info(ctx)
int_flag = rule(
implementation = _impl,
build_setting = config.int(flag = True),
+ attrs = {
+ "make_variable": _MAKE_VARIABLE_ATTR,
+ },
doc = "An int-typed build setting that can be set on the command line",
)
int_setting = rule(
implementation = _impl,
build_setting = config.int(),
+ attrs = {
+ "make_variable": _MAKE_VARIABLE_ATTR,
+ },
doc = "An int-typed build setting that cannot be set on the command line",
)
@@ -69,13 +103,22 @@ string_list_setting = rule(
doc = "A string list-typed build setting that cannot be set on the command line",
)
+def _no_at_str(label):
+ """Strips any leading '@'s for labels in the main repo, so that the error string is more friendly."""
+ s = str(label)
+ if s.startswith("@@//"):
+ return s[2:]
+ if s.startswith("@//"):
+ return s[1:]
+ return s
+
def _string_impl(ctx):
allowed_values = ctx.attr.values
value = ctx.build_setting_value
if len(allowed_values) == 0 or value in ctx.attr.values:
- return BuildSettingInfo(value = value)
+ return [BuildSettingInfo(value = value)] + _get_template_variable_info(ctx)
else:
- fail("Error setting " + str(ctx.label) + ": invalid value '" + value + "'. Allowed values are " + str(allowed_values))
+ fail("Error setting " + _no_at_str(ctx.label) + ": invalid value '" + value + "'. Allowed values are " + str(allowed_values))
string_flag = rule(
implementation = _string_impl,
@@ -84,6 +127,7 @@ string_flag = rule(
"values": attr.string_list(
doc = "The list of allowed values for this setting. An error is raised if any other value is given.",
),
+ "make_variable": _MAKE_VARIABLE_ATTR,
},
doc = "A string-typed build setting that can be set on the command line",
)
@@ -95,6 +139,7 @@ string_setting = rule(
"values": attr.string_list(
doc = "The list of allowed values for this setting. An error is raised if any other value is given.",
),
+ "make_variable": _MAKE_VARIABLE_ATTR,
},
doc = "A string-typed build setting that cannot be set on the command line",
)
diff --git a/rules/copy_directory.bzl b/rules/copy_directory.bzl
new file mode 100644
index 0000000..d181b77
--- /dev/null
+++ b/rules/copy_directory.bzl
@@ -0,0 +1,28 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A rule that copies a directory to another place.
+
+The rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command
+on Windows (no Bash is required).
+"""
+
+load(
+ "//rules/private:copy_directory_private.bzl",
+ _copy_directory = "copy_directory",
+ _copy_directory_action = "copy_directory_action",
+)
+
+copy_directory = _copy_directory
+copy_directory_action = _copy_directory_action
diff --git a/rules/diff_test.bzl b/rules/diff_test.bzl
index 49a1968..0f27f35 100644
--- a/rules/diff_test.bzl
+++ b/rules/diff_test.bzl
@@ -18,6 +18,8 @@ The rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).
"""
+load("//lib:shell.bzl", "shell")
+
def _runfiles_path(f):
if f.root.path:
return f.path[len(f.root.path) + 1:] # generated file
@@ -44,8 +46,14 @@ for /F "tokens=2* usebackq" %%i in (`findstr.exe /l /c:"!F1! " "%MF%"`) do (
set RF1=!RF1:/=\\!
)
if "!RF1!" equ "" (
- if exist "{file1}" (
- set RF1="{file1}"
+ if "%RUNFILES_MANIFEST_ONLY%" neq "1" if exist "%RUNFILES_DIR%\\%F1%" (
+ set RF1="%RUNFILES_DIR%\\%F1%"
+ ) else (
+ if exist "{file1}" (
+ set RF1="{file1}"
+ )
+ )
+ if "!RF1!" neq "" (
set RF1=!RF1:/=\\!
) else (
echo>&2 ERROR: !F1! not found
@@ -57,8 +65,14 @@ for /F "tokens=2* usebackq" %%i in (`findstr.exe /l /c:"!F2! " "%MF%"`) do (
set RF2=!RF2:/=\\!
)
if "!RF2!" equ "" (
- if exist "{file2}" (
- set RF2="{file2}"
+ if "%RUNFILES_MANIFEST_ONLY%" neq "1" if exist "%RUNFILES_DIR%\\%F2%" (
+ set RF2="%RUNFILES_DIR%\\%F2%"
+ ) else (
+ if exist "{file2}" (
+ set RF2="{file2}"
+ )
+ )
+ if "!RF2!" neq "" (
set RF2=!RF2:/=\\!
) else (
echo>&2 ERROR: !F2! not found
@@ -76,6 +90,7 @@ if %ERRORLEVEL% neq 0 (
)
)
""".format(
+ # TODO(arostovtsev): use shell.escape_for_bat when https://github.com/bazelbuild/bazel-skylib/pull/363 is merged
fail_msg = ctx.attr.failure_message,
file1 = _runfiles_path(ctx.file.file1),
file2 = _runfiles_path(ctx.file.file2),
@@ -106,11 +121,11 @@ else
exit 1
fi
if ! diff "$RF1" "$RF2"; then
- echo >&2 "FAIL: files \"{file1}\" and \"{file2}\" differ. {fail_msg}"
+ echo >&2 "FAIL: files \"{file1}\" and \"{file2}\" differ. "{fail_msg}
exit 1
fi
""".format(
- fail_msg = ctx.attr.failure_message,
+ fail_msg = shell.quote(ctx.attr.failure_message),
file1 = _runfiles_path(ctx.file.file1),
file2 = _runfiles_path(ctx.file.file2),
),
@@ -139,21 +154,23 @@ _diff_test = rule(
implementation = _diff_test_impl,
)
-def diff_test(name, file1, file2, **kwargs):
+def diff_test(name, file1, file2, failure_message = None, **kwargs):
"""A test that compares two files.
The test succeeds if the files' contents match.
Args:
name: The name of the test rule.
- file1: Label of the file to compare to <code>file2</code>.
- file2: Label of the file to compare to <code>file1</code>.
- **kwargs: The <a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests">common attributes for tests</a>.
+ file1: Label of the file to compare to `file2`.
+ file2: Label of the file to compare to `file1`.
+ failure_message: Additional message to log if the files' contents do not match.
+ **kwargs: The [common attributes for tests](https://bazel.build/reference/be/common-definitions#common-attributes-tests).
"""
_diff_test(
name = name,
file1 = file1,
file2 = file2,
+ failure_message = failure_message,
is_windows = select({
"@bazel_tools//src/conditions:host_windows": True,
"//conditions:default": False,
diff --git a/rules/expand_template.bzl b/rules/expand_template.bzl
new file mode 100644
index 0000000..f933500
--- /dev/null
+++ b/rules/expand_template.bzl
@@ -0,0 +1,50 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A rule that performs template expansion.
+"""
+
+def _expand_template_impl(ctx):
+ ctx.actions.expand_template(
+ template = ctx.file.template,
+ output = ctx.outputs.out,
+ substitutions = ctx.attr.substitutions,
+ )
+
+expand_template = rule(
+ implementation = _expand_template_impl,
+ doc = """Template expansion
+
+This performs a simple search over the template file for the keys in
+substitutions, and replaces them with the corresponding values.
+
+There is no special syntax for the keys. To avoid conflicts, you would need to
+explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@".""",
+ attrs = {
+ "template": attr.label(
+ mandatory = True,
+ allow_single_file = True,
+ doc = "The template file to expand.",
+ ),
+ "substitutions": attr.string_dict(
+ mandatory = True,
+ doc = "A dictionary mapping strings to their substitutions.",
+ ),
+ "out": attr.output(
+ mandatory = True,
+ doc = "The destination of the expanded file.",
+ ),
+ },
+ output_to_genfiles = True,
+)
diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl
index 9a1725f..b33347b 100644
--- a/rules/native_binary.bzl
+++ b/rules/native_binary.bzl
@@ -17,100 +17,76 @@
These rules let you wrap a pre-built binary or script in a conventional binary
and test rule respectively. They fulfill the same goal as sh_binary and sh_test
do, but they run the wrapped binary directly, instead of through Bash, so they
-don't depend on Bash and work with --shell_exectuable="".
+don't depend on Bash and work with --shell_executable="".
"""
-load("//rules/private:copy_file_private.bzl", "copy_bash", "copy_cmd")
-
-def _impl_rule(ctx, is_windows):
+def _impl_rule(ctx):
out = ctx.actions.declare_file(ctx.attr.out)
- if is_windows:
- copy_cmd(ctx, ctx.file.src, out)
+ ctx.actions.symlink(
+ target_file = ctx.executable.src,
+ output = out,
+ is_executable = True,
+ )
+ runfiles = ctx.runfiles(files = ctx.files.data)
+
+ # Bazel 4.x LTS does not support `merge_all`.
+ # TODO: remove `merge` branch once we drop support for Bazel 4.x.
+ if hasattr(runfiles, "merge_all"):
+ runfiles = runfiles.merge_all([
+ d[DefaultInfo].default_runfiles
+ for d in ctx.attr.data + [ctx.attr.src]
+ ])
else:
- copy_bash(ctx, ctx.file.src, out)
+ for d in ctx.attr.data:
+ runfiles = runfiles.merge(d[DefaultInfo].default_runfiles)
+ runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles)
+
return DefaultInfo(
executable = out,
files = depset([out]),
- runfiles = ctx.runfiles(
- files = [out],
- collect_data = True,
- collect_default = True,
- ),
+ runfiles = runfiles,
)
-def _impl(ctx):
- return _impl_rule(ctx, ctx.attr.is_windows)
-
_ATTRS = {
"src": attr.label(
executable = True,
- allow_single_file = True,
+ # This must be used instead of `allow_single_file` because otherwise a
+ # target with multiple default outputs (e.g. py_binary) would not be
+ # allowed.
+ allow_files = True,
mandatory = True,
- cfg = "host",
+ cfg = "target",
+ doc = "path of the pre-built executable",
+ ),
+ "data": attr.label_list(
+ allow_files = True,
+ doc = "data dependencies. See" +
+ " https://bazel.build/reference/be/common-definitions#typical.data",
),
- "data": attr.label_list(allow_files = True),
# "out" is attr.string instead of attr.output, so that it is select()'able.
- "out": attr.string(mandatory = True),
- "is_windows": attr.bool(mandatory = True),
+ "out": attr.string(mandatory = True, doc = "An output name for the copy of the binary"),
}
-_native_binary = rule(
- implementation = _impl,
+native_binary = rule(
+ implementation = _impl_rule,
attrs = _ATTRS,
executable = True,
+ doc = """
+Wraps a pre-built binary or script with a binary rule.
+
+You can "bazel run" this rule like any other binary rule, and use it as a tool
+in genrule.tools for example. You can also augment the binary with runfiles.
+""",
)
-_native_test = rule(
- implementation = _impl,
+native_test = rule(
+ implementation = _impl_rule,
attrs = _ATTRS,
test = True,
-)
+ doc = """
+Wraps a pre-built binary or script with a test rule.
-def native_binary(name, src, out, data = None, **kwargs):
- """Wraps a pre-built binary or script with a binary rule.
-
- You can "bazel run" this rule like any other binary rule, and use it as a tool in genrule.tools for example. You can also augment the binary with runfiles.
-
- Args:
- name: The name of the rule.
- src: label; path of the pre-built executable
- out: output; an output name for the copy of the binary. (Bazel requires that this rule make a copy of 'src'.)
- data: list of labels; data dependencies
- **kwargs: The <a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-binaries">common attributes for binaries</a>.
- """
- _native_binary(
- name = name,
- src = src,
- out = out,
- data = data,
- is_windows = select({
- "@bazel_tools//src/conditions:host_windows": True,
- "//conditions:default": False,
- }),
- **kwargs
- )
-
-def native_test(name, src, out, data = None, **kwargs):
- """Wraps a pre-built binary or script with a test rule.
-
- You can "bazel test" this rule like any other test rule. You can also augment the binary with
- runfiles.
-
- Args:
- name: The name of the test rule.
- src: label; path of the pre-built executable
- out: output; an output name for the copy of the binary. (Bazel requires that this rule make a copy of 'src'.)
- data: list of labels; data dependencies
- **kwargs: The <a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests">common attributes for tests</a>.
- """
- _native_test(
- name = name,
- src = src,
- out = out,
- data = data,
- is_windows = select({
- "@bazel_tools//src/conditions:host_windows": True,
- "//conditions:default": False,
- }),
- **kwargs
- )
+You can "bazel test" this rule like any other test rule. You can also augment
+the binary with runfiles.
+""",
+)
diff --git a/rules/private/BUILD b/rules/private/BUILD
index f835fb4..7bd3652 100644
--- a/rules/private/BUILD
+++ b/rules/private/BUILD
@@ -3,9 +3,23 @@ load("//:bzl_library.bzl", "bzl_library")
licenses(["notice"])
bzl_library(
+ name = "copy_common",
+ srcs = ["copy_common.bzl"],
+ visibility = ["//rules:__pkg__"],
+)
+
+bzl_library(
+ name = "copy_directory_private",
+ srcs = ["copy_directory_private.bzl"],
+ visibility = ["//rules:__pkg__"],
+ deps = [":copy_common"],
+)
+
+bzl_library(
name = "copy_file_private",
srcs = ["copy_file_private.bzl"],
visibility = ["//rules:__pkg__"],
+ deps = [":copy_common"],
)
bzl_library(
diff --git a/rules/private/copy_common.bzl b/rules/private/copy_common.bzl
new file mode 100644
index 0000000..a8f7243
--- /dev/null
+++ b/rules/private/copy_common.bzl
@@ -0,0 +1,45 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"Helpers for copy rules"
+
+# Hints for Bazel spawn strategy
+COPY_EXECUTION_REQUIREMENTS = {
+ # ----------------+-----------------------------------------------------------------------------
+ # no-remote | Prevents the action or test from being executed remotely or cached remotely.
+ # | This is equivalent to using both `no-remote-cache` and `no-remote-exec`.
+ # ----------------+-----------------------------------------------------------------------------
+ # no-cache | Results in the action or test never being cached (remotely or locally)
+ # ----------------+-----------------------------------------------------------------------------
+ # See https://bazel.build/reference/be/common-definitions#common-attributes
+ #
+ # Copying file & directories is entirely IO-bound and there is no point doing this work
+ # remotely.
+ #
+ # Also, remote-execution does not allow source directory inputs, see
+ # https://github.com/bazelbuild/bazel/commit/c64421bc35214f0414e4f4226cc953e8c55fa0d2 So we must
+ # not attempt to execute remotely in that case.
+ #
+ # There is also no point pulling the output file or directory from the remote cache since the
+ # bytes to copy are already available locally. Conversely, no point in writing to the cache if
+ # no one has any reason to check it for this action.
+ #
+ # Read and writing to disk cache is disabled as well primarily to reduce disk usage on the local
+ # machine. A disk cache hit of a directory copy could be slghtly faster than a copy since the
+ # disk cache stores the directory artifact as a single entry, but the slight performance bump
+ # comes at the cost of heavy disk cache usage, which is an unmanaged directory that grow beyond
+ # the bounds of the physical disk.
+ "no-remote": "1",
+ "no-cache": "1",
+}
diff --git a/rules/private/copy_directory_private.bzl b/rules/private/copy_directory_private.bzl
new file mode 100644
index 0000000..da60c8b
--- /dev/null
+++ b/rules/private/copy_directory_private.bzl
@@ -0,0 +1,157 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation of copy_directory macro and underlying rules.
+
+This rule copies a directory to another location using Bash (on Linux/macOS) or
+cmd.exe (on Windows).
+"""
+
+load(":copy_common.bzl", "COPY_EXECUTION_REQUIREMENTS")
+
+def _copy_cmd(ctx, src, dst):
+ # Most Windows binaries built with MSVC use a certain argument quoting
+ # scheme. Bazel uses that scheme too to quote arguments. However,
+ # cmd.exe uses different semantics, so Bazel's quoting is wrong here.
+ # To fix that we write the command to a .bat file so no command line
+ # quoting or escaping is required.
+ # Put a hash of the file name into the name of the generated batch file to
+ # make it unique within the package, so that users can define multiple copy_file's.
+ bat = ctx.actions.declare_file("%s-%s-cmd.bat" % (ctx.label.name, hash(src.path)))
+
+ # Flags are documented at
+ # https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
+ # NB: robocopy return non-zero exit codes on success so we must exit 0 after calling it
+ cmd_tmpl = """\
+if not exist \"{src}\\\" (
+ echo Error: \"{src}\" is not a directory
+ @exit 1
+)
+@robocopy \"{src}\" \"{dst}\" /E /MIR >NUL & @exit 0
+"""
+ mnemonic = "CopyDirectory"
+ progress_message = "Copying directory %{input}"
+
+ ctx.actions.write(
+ output = bat,
+ # Do not use lib/shell.bzl's shell.quote() method, because that uses
+ # Bash quoting syntax, which is different from cmd.exe's syntax.
+ content = cmd_tmpl.format(
+ src = src.path.replace("/", "\\"),
+ dst = dst.path.replace("/", "\\"),
+ ),
+ is_executable = True,
+ )
+ ctx.actions.run(
+ inputs = [src],
+ tools = [bat],
+ outputs = [dst],
+ executable = "cmd.exe",
+ arguments = ["/C", bat.path.replace("/", "\\")],
+ mnemonic = mnemonic,
+ progress_message = progress_message,
+ use_default_shell_env = True,
+ execution_requirements = COPY_EXECUTION_REQUIREMENTS,
+ )
+
+def _copy_bash(ctx, src, dst):
+ cmd = """\
+if [ ! -d \"$1\" ]; then
+ echo \"Error: $1 is not a directory\"
+ exit 1
+fi
+
+rm -rf \"$2\" && cp -fR \"$1/\" \"$2\"
+"""
+ mnemonic = "CopyDirectory"
+ progress_message = "Copying directory %s" % src.path
+
+ ctx.actions.run_shell(
+ tools = [src],
+ outputs = [dst],
+ command = cmd,
+ arguments = [src.path, dst.path],
+ mnemonic = mnemonic,
+ progress_message = progress_message,
+ use_default_shell_env = True,
+ execution_requirements = COPY_EXECUTION_REQUIREMENTS,
+ )
+
+def copy_directory_action(ctx, src, dst, is_windows = False):
+ """Helper function that creates an action to copy a directory from src to dst.
+
+ This helper is used by copy_directory. It is exposed as a public API so it can be used within
+ other rule implementations.
+
+ Args:
+ ctx: The rule context.
+ src: The directory to make a copy of. Can be a source directory or TreeArtifact.
+ dst: The directory to copy to. Must be a TreeArtifact.
+ is_windows: If true, an cmd.exe action is created so there is no bash dependency.
+ """
+ if dst.is_source or not dst.is_directory:
+ fail("dst must be a TreeArtifact")
+ if is_windows:
+ _copy_cmd(ctx, src, dst)
+ else:
+ _copy_bash(ctx, src, dst)
+
+def _copy_directory_impl(ctx):
+ dst = ctx.actions.declare_directory(ctx.attr.out)
+ copy_directory_action(ctx, ctx.file.src, dst, ctx.attr.is_windows)
+
+ files = depset(direct = [dst])
+ runfiles = ctx.runfiles(files = [dst])
+
+ return [DefaultInfo(files = files, runfiles = runfiles)]
+
+_copy_directory = rule(
+ implementation = _copy_directory_impl,
+ provides = [DefaultInfo],
+ attrs = {
+ "src": attr.label(mandatory = True, allow_single_file = True),
+ "is_windows": attr.bool(mandatory = True),
+ # Cannot declare out as an output here, because there's no API for declaring
+ # TreeArtifact outputs.
+ "out": attr.string(mandatory = True),
+ },
+)
+
+def copy_directory(name, src, out, **kwargs):
+ """Copies a directory to another location.
+
+ This rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command on Windows (no Bash is required).
+
+ If using this rule with source directories, it is recommended that you use the
+ `--host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1` startup option so that changes
+ to files within source directories are detected. See
+ https://github.com/bazelbuild/bazel/commit/c64421bc35214f0414e4f4226cc953e8c55fa0d2
+ for more context.
+
+ Args:
+ name: Name of the rule.
+ src: The directory to make a copy of. Can be a source directory or TreeArtifact.
+ out: Path of the output directory, relative to this package.
+ **kwargs: further keyword arguments, e.g. `visibility`
+ """
+ _copy_directory(
+ name = name,
+ src = src,
+ is_windows = select({
+ "@bazel_tools//src/conditions:host_windows": True,
+ "//conditions:default": False,
+ }),
+ out = out,
+ **kwargs
+ )
diff --git a/rules/private/copy_file_private.bzl b/rules/private/copy_file_private.bzl
index 44f133a..15e1d4b 100644
--- a/rules/private/copy_file_private.bzl
+++ b/rules/private/copy_file_private.bzl
@@ -19,6 +19,8 @@ cmd.exe (on Windows). '_copy_xfile' marks the resulting file executable,
'_copy_file' does not.
"""
+load(":copy_common.bzl", "COPY_EXECUTION_REQUIREMENTS")
+
def copy_cmd(ctx, src, dst):
# Most Windows binaries built with MSVC use a certain argument quoting
# scheme. Bazel uses that scheme too to quote arguments. However,
@@ -37,25 +39,26 @@ def copy_cmd(ctx, src, dst):
is_executable = True,
)
ctx.actions.run(
- inputs = [src],
- tools = [bat],
+ inputs = [src, bat],
outputs = [dst],
executable = "cmd.exe",
arguments = ["/C", bat.path.replace("/", "\\")],
mnemonic = "CopyFile",
progress_message = "Copying files",
use_default_shell_env = True,
+ execution_requirements = COPY_EXECUTION_REQUIREMENTS,
)
def copy_bash(ctx, src, dst):
ctx.actions.run_shell(
- tools = [src],
+ inputs = [src],
outputs = [dst],
command = "cp -f \"$1\" \"$2\"",
arguments = [src.path, dst.path],
mnemonic = "CopyFile",
progress_message = "Copying files",
use_default_shell_env = True,
+ execution_requirements = COPY_EXECUTION_REQUIREMENTS,
)
def _copy_file_impl(ctx):
@@ -75,7 +78,10 @@ def _copy_file_impl(ctx):
if ctx.attr.is_executable:
return [DefaultInfo(files = files, runfiles = runfiles, executable = ctx.outputs.out)]
else:
- return [DefaultInfo(files = files, runfiles = runfiles)]
+ # Do not include the copied file into the default runfiles of the
+ # target, but ensure that it is picked up by native rule's data
+ # attribute despite https://github.com/bazelbuild/bazel/issues/15043.
+ return [DefaultInfo(files = files, data_runfiles = runfiles)]
_ATTRS = {
"src": attr.label(mandatory = True, allow_single_file = True),
diff --git a/rules/private/write_file_private.bzl b/rules/private/write_file_private.bzl
index ac8ce9c..cdb37c8 100644
--- a/rules/private/write_file_private.bzl
+++ b/rules/private/write_file_private.bzl
@@ -37,7 +37,10 @@ def _common_impl(ctx, is_windows, is_executable):
if is_executable:
return [DefaultInfo(files = files, runfiles = runfiles, executable = ctx.outputs.out)]
else:
- return [DefaultInfo(files = files, runfiles = runfiles)]
+ # Do not include the copied file into the default runfiles of the
+ # target, but ensure that it is picked up by native rule's data
+ # attribute despite https://github.com/bazelbuild/bazel/issues/15043.
+ return [DefaultInfo(files = files, data_runfiles = runfiles)]
def _impl(ctx):
return _common_impl(ctx, ctx.attr.is_windows, False)
@@ -85,7 +88,7 @@ def write_file(
sources.
newline: one of ["auto", "unix", "windows"]: line endings to use. "auto"
for platform-determined, "unix" for LF, and "windows" for CRLF.
- **kwargs: further keyword arguments, e.g. <code>visibility</code>
+ **kwargs: further keyword arguments, e.g. `visibility`
"""
if is_executable:
_write_xfile(
diff --git a/rules/run_binary.bzl b/rules/run_binary.bzl
index c251019..7701fa0 100644
--- a/rules/run_binary.bzl
+++ b/rules/run_binary.bzl
@@ -22,7 +22,6 @@ load("//lib:dicts.bzl", "dicts")
def _impl(ctx):
tool_as_list = [ctx.attr.tool]
- tool_inputs, tool_input_mfs = ctx.resolve_tools(tools = tool_as_list)
args = [
# Expand $(location) / $(locations) in args.
#
@@ -45,13 +44,12 @@ def _impl(ctx):
ctx.actions.run(
outputs = ctx.outputs.outs,
inputs = ctx.files.srcs,
- tools = tool_inputs,
+ tools = [ctx.executable.tool],
executable = ctx.executable.tool,
arguments = args,
mnemonic = "RunBinary",
use_default_shell_env = False,
env = dicts.add(ctx.configuration.default_shell_env, envs),
- input_manifests = tool_input_mfs,
)
return DefaultInfo(
files = depset(ctx.outputs.outs),
@@ -60,38 +58,38 @@ def _impl(ctx):
run_binary = rule(
implementation = _impl,
- doc = "Runs a binary as a build action.<br/><br/>This rule does not require Bash (unlike" +
- " <code>native.genrule</code>).",
+ doc = "Runs a binary as a build action.\n\nThis rule does not require Bash (unlike" +
+ " `native.genrule`).",
attrs = {
"tool": attr.label(
- doc = "The tool to run in the action.<br/><br/>Must be the label of a *_binary rule," +
+ doc = "The tool to run in the action.\n\nMust be the label of a *_binary rule," +
" of a rule that generates an executable file, or of a file that can be" +
" executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary" +
" with executable permission on Linux). This label is available for" +
- " <code>$(location)</code> expansion in <code>args</code> and <code>env</code>.",
+ " `$(location)` expansion in `args` and `env`.",
executable = True,
allow_files = True,
mandatory = True,
- cfg = "host",
+ cfg = "exec",
),
"env": attr.string_dict(
- doc = "Environment variables of the action.<br/><br/>Subject to " +
- " <code><a href=\"https://docs.bazel.build/versions/main/be/make-variables.html#location\">$(location)</a></code>" +
+ doc = "Environment variables of the action.\n\nSubject to " +
+ " [`$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
" expansion.",
),
"srcs": attr.label_list(
allow_files = True,
- doc = "Additional inputs of the action.<br/><br/>These labels are available for" +
- " <code>$(location)</code> expansion in <code>args</code> and <code>env</code>.",
+ doc = "Additional inputs of the action.\n\nThese labels are available for" +
+ " `$(location)` expansion in `args` and `env`.",
),
"outs": attr.output_list(
mandatory = True,
- doc = "Output files generated by the action.<br/><br/>These labels are available for" +
- " <code>$(location)</code> expansion in <code>args</code> and <code>env</code>.",
+ doc = "Output files generated by the action.\n\nThese labels are available for" +
+ " `$(location)` expansion in `args` and `env`.",
),
"args": attr.string_list(
- doc = "Command line arguments of the binary.<br/><br/>Subject to" +
- "<code><a href=\"https://docs.bazel.build/versions/main/be/make-variables.html#location\">$(location)</a></code>" +
+ doc = "Command line arguments of the binary.\n\nSubject to" +
+ " [`$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
" expansion.",
),
},
diff --git a/rules/select_file.bzl b/rules/select_file.bzl
index f359e43..1b73093 100644
--- a/rules/select_file.bzl
+++ b/rules/select_file.bzl
@@ -15,7 +15,7 @@
"""
select_file() build rule implementation.
-Selects a single file from the outputs of some target by given relative path.
+Selects a single file from the outputs of a target by given relative path.
"""
def _impl(ctx):
@@ -38,8 +38,7 @@ def _impl(ctx):
select_file = rule(
implementation = _impl,
- doc = "Selects a single file from the outputs of some target \
-by given relative path",
+ doc = "Selects a single file from the outputs of a target by given relative path",
attrs = {
"srcs": attr.label(
allow_files = True,
diff --git a/tests/BUILD b/tests/BUILD
index c2a4223..7f056d2 100644
--- a/tests/BUILD
+++ b/tests/BUILD
@@ -1,6 +1,7 @@
load("//:bzl_library.bzl", "bzl_library")
load(":build_test_tests.bzl", "build_test_test_suite")
load(":collections_tests.bzl", "collections_test_suite")
+load(":common_settings_tests.bzl", "common_settings_test_suite")
load(":dicts_tests.bzl", "dicts_test_suite")
load(":new_sets_tests.bzl", "new_sets_test_suite")
load(":partial_tests.bzl", "partial_test_suite")
@@ -8,6 +9,7 @@ load(":paths_tests.bzl", "paths_test_suite")
load(":selects_tests.bzl", "selects_test_suite")
load(":shell_tests.bzl", "shell_args_test_gen", "shell_test_suite")
load(":structs_tests.bzl", "structs_test_suite")
+load(":subpackages_tests.bzl", "subpackages_test_suite")
load(":types_tests.bzl", "types_test_suite")
load(":unittest_tests.bzl", "unittest_passing_tests_suite")
load(":versions_tests.bzl", "versions_test_suite")
@@ -23,6 +25,8 @@ build_test_test_suite()
collections_test_suite()
+common_settings_test_suite()
+
dicts_test_suite()
new_sets_test_suite()
@@ -37,6 +41,8 @@ shell_test_suite()
structs_test_suite()
+subpackages_test_suite()
+
types_test_suite()
unittest_passing_tests_suite()
diff --git a/tests/analysis_test_test.sh b/tests/analysis_test_test.sh
index 2edae15..5d5d7de 100755
--- a/tests/analysis_test_test.sh
+++ b/tests/analysis_test_test.sh
@@ -41,7 +41,7 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function create_pkg() {
@@ -58,7 +58,22 @@ EOF
exports_files(["*.bzl"])
EOF
- ln -sf "$(rlocation bazel_skylib/rules/analysis_test.bzl)" rules/analysis_test.bzl
+ mkdir -p lib
+ cat > lib/BUILD <<EOF
+exports_files(["*.bzl"])
+EOF
+ cat > lib/types.bzl <<EOF
+_a_tuple_type = type(())
+
+def _is_tuple(v):
+ return type(v) == _a_tuple_type
+
+types = struct(
+ is_tuple = _is_tuple,
+)
+EOF
+
+ ln -sf "$(rlocation $TEST_WORKSPACE/rules/analysis_test.bzl)" rules/analysis_test.bzl
mkdir -p fakerules
cat > fakerules/rules.bzl <<EOF
diff --git a/tests/build_test_tests.bzl b/tests/build_test_tests.bzl
index 5bcbbd3..4d3dfb6 100644
--- a/tests/build_test_tests.bzl
+++ b/tests/build_test_tests.bzl
@@ -14,8 +14,8 @@
"""Unit tests for build_test.bzl."""
-load("//rules:build_test.bzl", "build_test")
load("@rules_cc//cc:defs.bzl", "cc_library")
+load("//rules:build_test.bzl", "build_test")
# buildifier: disable=unnamed-macro
def build_test_test_suite():
diff --git a/tests/common_settings/BUILD b/tests/common_settings/BUILD
new file mode 100644
index 0000000..bbf32d5
--- /dev/null
+++ b/tests/common_settings/BUILD
@@ -0,0 +1,25 @@
+load("//rules:common_settings.bzl", "int_flag", "string_flag")
+
+int_flag(
+ name = "my_int_flag",
+ build_setting_default = 42,
+ make_variable = "MY_INT_FLAG",
+)
+
+string_flag(
+ name = "my_string_flag",
+ build_setting_default = "foo",
+ make_variable = "MY_STRING_FLAG",
+)
+
+sh_test(
+ name = "make_variable_test",
+ srcs = ["make_variable_test.sh"],
+ env = {
+ "MESSAGE": "Hello, $(MY_STRING_FLAG)! My name is $(MY_INT_FLAG).",
+ },
+ toolchains = [
+ ":my_int_flag",
+ ":my_string_flag",
+ ],
+)
diff --git a/docs/regenerate_docs.sh b/tests/common_settings/make_variable_test.sh
index d16ea63..546c53d 100755
--- a/docs/regenerate_docs.sh
+++ b/tests/common_settings/make_variable_test.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-# Copyright 2019 The Bazel Authors. All rights reserved.
+# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,15 +13,5 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-# A script to manually regenerate the documentation contained in the docs/ directory.
-# Should be run from the WORKSPACE root.
-
-set -euo pipefail
-
-bazel build docs:all
-for filename in bazel-bin/docs/*_gen.md; do
- target_filename="$(echo $filename | sed -En "s/bazel-bin\/(.*)_gen.md/\1/p").md"
- cp $filename $target_filename
-done
+[[ "$MESSAGE" == "Hello, foo! My name is 42." ]]
diff --git a/tests/common_settings_test.sh b/tests/common_settings_test.sh
index 1e3d03d..51eb38e 100755
--- a/tests/common_settings_test.sh
+++ b/tests/common_settings_test.sh
@@ -38,7 +38,7 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function create_volcano_pkg() {
@@ -55,7 +55,7 @@ EOF
exports_files(["*.bzl"])
EOF
- ln -sf "$(rlocation bazel_skylib/rules/common_settings.bzl)" rules/common_settings.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/rules/common_settings.bzl)" rules/common_settings.bzl
mkdir -p volcano
cat > volcano/rules.bzl <<EOF
diff --git a/tests/common_settings_tests.bzl b/tests/common_settings_tests.bzl
new file mode 100644
index 0000000..efbe0e0
--- /dev/null
+++ b/tests/common_settings_tests.bzl
@@ -0,0 +1,167 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Analysis tests for common_settings.bzl."""
+
+load("//lib:unittest.bzl", "analysistest", "asserts")
+load("//rules:common_settings.bzl", "int_flag", "int_setting", "string_flag", "string_setting")
+
+def _template_variable_info_contents_test_impl(ctx):
+ env = analysistest.begin(ctx)
+
+ target_under_test = analysistest.target_under_test(env)
+ if ctx.attr.expected:
+ asserts.equals(
+ env,
+ expected = ctx.attr.expected,
+ actual = target_under_test[platform_common.TemplateVariableInfo].variables,
+ )
+ else:
+ asserts.false(env, platform_common.TemplateVariableInfo in target_under_test)
+
+ return analysistest.end(env)
+
+_template_variable_info_contents_test = analysistest.make(
+ _template_variable_info_contents_test_impl,
+ attrs = {
+ "expected": attr.string_dict(),
+ },
+)
+
+def _test_template_variable_info_contents():
+ int_flag(
+ name = "my_int_flag",
+ build_setting_default = 42,
+ make_variable = "MY_INT_1",
+ )
+
+ _template_variable_info_contents_test(
+ name = "my_int_flag_test",
+ target_under_test = ":my_int_flag",
+ expected = {
+ "MY_INT_1": "42",
+ },
+ )
+
+ int_setting(
+ name = "my_int_setting",
+ build_setting_default = 21,
+ make_variable = "MY_INT_2",
+ )
+
+ _template_variable_info_contents_test(
+ name = "my_int_setting_test",
+ target_under_test = ":my_int_setting",
+ expected = {
+ "MY_INT_2": "21",
+ },
+ )
+
+ string_flag(
+ name = "my_string_flag",
+ build_setting_default = "foo",
+ make_variable = "MY_STRING_1",
+ )
+
+ _template_variable_info_contents_test(
+ name = "my_string_flag_test",
+ target_under_test = ":my_string_flag",
+ expected = {
+ "MY_STRING_1": "foo",
+ },
+ )
+
+ string_setting(
+ name = "my_string_setting",
+ build_setting_default = "bar",
+ make_variable = "MY_STRING_2",
+ )
+
+ _template_variable_info_contents_test(
+ name = "my_string_setting_test",
+ target_under_test = ":my_string_setting",
+ expected = {
+ "MY_STRING_2": "bar",
+ },
+ )
+
+ string_flag(
+ name = "my_string_flag_without_make_variable",
+ build_setting_default = "foo",
+ )
+
+ _template_variable_info_contents_test(
+ name = "my_string_flag_without_make_variable_test",
+ target_under_test = ":my_string_flag_without_make_variable",
+ expected = {},
+ )
+
+def _failure_test_impl(ctx):
+ env = analysistest.begin(ctx)
+
+ asserts.expect_failure(env, ctx.attr.expected_failure)
+
+ return analysistest.end(env)
+
+_failure_test = analysistest.make(
+ _failure_test_impl,
+ attrs = {
+ "expected_failure": attr.string(),
+ },
+ expect_failure = True,
+)
+
+def _test_make_variable_name_failures():
+ int_flag(
+ name = "my_failing_int_flag",
+ build_setting_default = 42,
+ make_variable = "my_int_1",
+ tags = ["manual"],
+ )
+
+ _failure_test(
+ name = "my_failing_int_flag_test",
+ target_under_test = ":my_failing_int_flag",
+ expected_failure = "Error setting //tests:my_failing_int_flag: invalid make variable name 'my_int_1'. Make variable names may only contain uppercase letters, digits, and underscores.",
+ )
+
+ string_flag(
+ name = "my_failing_string_flag",
+ build_setting_default = "foo",
+ make_variable = "MY STRING",
+ tags = ["manual"],
+ )
+
+ _failure_test(
+ name = "my_failing_string_flag_test",
+ target_under_test = ":my_failing_string_flag",
+ expected_failure = "Error setting //tests:my_failing_string_flag: invalid make variable name 'MY STRING'. Make variable names may only contain uppercase letters, digits, and underscores.",
+ )
+
+def common_settings_test_suite(name = "common_settings_test_suite"):
+ _test_template_variable_info_contents()
+ _test_make_variable_name_failures()
+
+ native.test_suite(
+ name = "common_settings_test_suite",
+ tests = [
+ "my_int_flag_test",
+ "my_int_setting_test",
+ "my_string_flag_test",
+ "my_string_setting_test",
+ "my_string_flag_without_make_variable_test",
+ "my_failing_int_flag_test",
+ "my_failing_string_flag_test",
+ ],
+ )
diff --git a/tests/copy_directory/BUILD.bazel b/tests/copy_directory/BUILD.bazel
new file mode 100644
index 0000000..f766e99
--- /dev/null
+++ b/tests/copy_directory/BUILD.bazel
@@ -0,0 +1,43 @@
+# This package aids testing the 'copy_directory' rule.
+
+load("//rules:copy_directory.bzl", "copy_directory")
+load(":empty_directory.bzl", "empty_directory")
+
+licenses(["notice"])
+
+package(default_testonly = 1)
+
+# Copy of directory containing files a and b, and a subdir containing c
+copy_directory(
+ name = "copy_of_dir_with_subdir",
+ src = "dir_with_subdir",
+ out = "dir_copy",
+)
+
+empty_directory(
+ name = "empty_dir",
+)
+
+copy_directory(
+ name = "copy_of_empty_dir",
+ src = "empty_dir",
+ out = "empty_dir_copy",
+)
+
+copy_directory(
+ name = "copy_of_dir_with_symlink",
+ src = "dir_with_symlink",
+ out = "dir_with_symlink_copy",
+)
+
+sh_test(
+ name = "copy_directory_tests",
+ srcs = ["copy_directory_tests.sh"],
+ data = [
+ ":copy_of_dir_with_subdir",
+ ":copy_of_dir_with_symlink",
+ ":copy_of_empty_dir",
+ "//tests:unittest.bash",
+ ],
+ deps = ["@bazel_tools//tools/bash/runfiles"],
+)
diff --git a/tests/copy_directory/copy_directory_tests.sh b/tests/copy_directory/copy_directory_tests.sh
new file mode 100755
index 0000000..0448b51
--- /dev/null
+++ b/tests/copy_directory/copy_directory_tests.sh
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# --- begin runfiles.bash initialization ---
+# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
+set -euo pipefail
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+ if [[ -f "$0.runfiles_manifest" ]]; then
+ export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+ elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+ export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+ elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+ export RUNFILES_DIR="$0.runfiles"
+ fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+ source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+ source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+ "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+ echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+ exit 1
+fi
+# --- end runfiles.bash initialization ---
+
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
+ || { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
+
+function test_copy_dir_with_subdir__copies_a() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_copy)/a" >"$TEST_log"
+ expect_log '^foo$'
+}
+
+function test_copy_dir_with_subdir__copies_b() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_copy)/b" >"$TEST_log"
+ expect_log '^bar$'
+}
+
+function test_copy_dir_with_subdir__copies_c() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_copy)/subdir/c" >"$TEST_log"
+ expect_log '^moocow$'
+}
+
+function test_copy_dir_with_subdir__correct_filecounts() {
+ local -r dir_filecount=$(ls "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_copy)" | wc -l)
+ assert_equals $dir_filecount 3
+ local -r subdir_filecount=$(ls "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_copy)/subdir" | wc -l)
+ assert_equals $subdir_filecount 1
+}
+
+function test_copy_empty_dir() {
+ local -r filecount=$(ls "$(rlocation $TEST_WORKSPACE/tests/copy_directory/empty_dir_copy)" | wc -l)
+ assert_equals $filecount 0
+}
+
+function test_copy_dir_with_symlink__copies_file() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_with_symlink_copy)/file" >"$TEST_log"
+ expect_log '^foo$'
+}
+
+function test_copy_dir_with_symlink__copies_symlink() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_directory/dir_with_symlink_copy)/symlink" >"$TEST_log"
+ expect_log '^foo$'
+}
+
+
+run_suite "copy_directory test suite"
diff --git a/tests/copy_directory/dir_with_subdir/a b/tests/copy_directory/dir_with_subdir/a
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/tests/copy_directory/dir_with_subdir/a
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/copy_directory/dir_with_subdir/b b/tests/copy_directory/dir_with_subdir/b
new file mode 100644
index 0000000..ba0e162
--- /dev/null
+++ b/tests/copy_directory/dir_with_subdir/b
@@ -0,0 +1 @@
+bar \ No newline at end of file
diff --git a/tests/copy_directory/dir_with_subdir/subdir/c b/tests/copy_directory/dir_with_subdir/subdir/c
new file mode 100644
index 0000000..062f177
--- /dev/null
+++ b/tests/copy_directory/dir_with_subdir/subdir/c
@@ -0,0 +1 @@
+moocow \ No newline at end of file
diff --git a/tests/copy_directory/dir_with_symlink/file b/tests/copy_directory/dir_with_symlink/file
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/tests/copy_directory/dir_with_symlink/file
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/tests/copy_directory/dir_with_symlink/symlink b/tests/copy_directory/dir_with_symlink/symlink
new file mode 120000
index 0000000..7b22242
--- /dev/null
+++ b/tests/copy_directory/dir_with_symlink/symlink
@@ -0,0 +1 @@
+./file \ No newline at end of file
diff --git a/tests/copy_directory/empty_directory.bzl b/tests/copy_directory/empty_directory.bzl
new file mode 100644
index 0000000..92c5a5f
--- /dev/null
+++ b/tests/copy_directory/empty_directory.bzl
@@ -0,0 +1,34 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Creates an empty directory."""
+
+def _empty_directory_impl(ctx):
+ out = ctx.actions.declare_directory(ctx.attr.name)
+ ctx.actions.run_shell(
+ outputs = [out],
+ command = "mkdir -p $@",
+ arguments = [out.path],
+ mnemonic = "EmptyDirectory",
+ progress_message = "Creating empty directory %s" % out.path,
+ use_default_shell_env = True,
+ execution_requirements = {"no-remote": "1"}, # see rules/private/copy_directory_private.bzl
+ )
+ return [DefaultInfo(files = depset(direct = [out]))]
+
+empty_directory = rule(
+ implementation = _empty_directory_impl,
+ provides = [DefaultInfo],
+ doc = "Creates an empty directory with the same name as the target",
+)
diff --git a/tests/copy_file/copy_file_tests.sh b/tests/copy_file/copy_file_tests.sh
index 737afd7..f7f14ac 100755
--- a/tests/copy_file/copy_file_tests.sh
+++ b/tests/copy_file/copy_file_tests.sh
@@ -37,50 +37,50 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function test_copy_src() {
- cat "$(rlocation bazel_skylib/tests/copy_file/out/a-out.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/out/a-out.txt)" >"$TEST_log"
expect_log '^#!/usr/bin/env bash$'
expect_log '^echo aaa$'
}
function test_copy_src_symlink() {
- cat "$(rlocation bazel_skylib/tests/copy_file/out/a-out-symlink.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/out/a-out-symlink.txt)" >"$TEST_log"
expect_log '^#!/usr/bin/env bash$'
expect_log '^echo aaa$'
}
function test_copy_gen() {
- cat "$(rlocation bazel_skylib/tests/copy_file/out/gen-out.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/out/gen-out.txt)" >"$TEST_log"
expect_log '^#!/usr/bin/env bash$'
expect_log '^echo potato$'
}
function test_copy_gen_symlink() {
- cat "$(rlocation bazel_skylib/tests/copy_file/out/gen-out-symlink.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/out/gen-out-symlink.txt)" >"$TEST_log"
expect_log '^#!/usr/bin/env bash$'
expect_log '^echo potato$'
}
function test_copy_xsrc() {
- cat "$(rlocation bazel_skylib/tests/copy_file/xsrc-out.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/xsrc-out.txt)" >"$TEST_log"
expect_log '^aaa$'
}
function test_copy_xsrc_symlink() {
- cat "$(rlocation bazel_skylib/tests/copy_file/xsrc-out-symlink.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/xsrc-out-symlink.txt)" >"$TEST_log"
expect_log '^aaa$'
}
function test_copy_xgen() {
- cat "$(rlocation bazel_skylib/tests/copy_file/xgen-out.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/xgen-out.txt)" >"$TEST_log"
expect_log '^potato$'
}
function test_copy_xgen_symlink() {
- cat "$(rlocation bazel_skylib/tests/copy_file/xgen-out-symlink.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/copy_file/xgen-out-symlink.txt)" >"$TEST_log"
expect_log '^potato$'
}
diff --git a/tests/dicts_tests.bzl b/tests/dicts_tests.bzl
index 2fc407d..816fcea 100644
--- a/tests/dicts_tests.bzl
+++ b/tests/dicts_tests.bzl
@@ -83,9 +83,77 @@ def _add_test(ctx):
add_test = unittest.make(_add_test)
+def _omit_test(ctx):
+ """Unit tests for dicts.omit."""
+ env = unittest.begin(ctx)
+
+ # Test empty dict, empty list.
+ asserts.equals(env, {}, dicts.omit({}, []))
+
+ # Test empty dict, nonempty list.
+ asserts.equals(env, {}, dicts.omit({}, ["a"]))
+
+ # Test nonempty dict, empty list.
+ asserts.equals(env, {"a": 1}, dicts.omit({"a": 1}, []))
+
+ # Test key in dict.
+ asserts.equals(env, {}, dicts.omit({"a": 1}, ["a"]))
+
+ # Test key not in dict.
+ asserts.equals(env, {"a": 1}, dicts.omit({"a": 1}, ["b"]))
+
+ # Since dictionaries are passed around by reference, make sure that the
+ # result of dicts.omit is always a *copy* by modifying it afterwards and
+ # ensuring that the original argument doesn't also reflect the change. We do
+ # this to protect against someone who might attempt to optimize the function
+ # by returning the argument itself in the empty list case.
+ original = {"a": 1}
+ result = dicts.omit(original, [])
+ result["a"] = 2
+ asserts.equals(env, 1, original["a"])
+
+ return unittest.end(env)
+
+omit_test = unittest.make(_omit_test)
+
+def _pick_test(ctx):
+ """Unit tests for dicts.pick."""
+ env = unittest.begin(ctx)
+
+ # Test empty dict, empty list.
+ asserts.equals(env, {}, dicts.pick({}, []))
+
+ # Test empty dict, nonempty list.
+ asserts.equals(env, {}, dicts.pick({}, ["a"]))
+
+ # Test nonempty dict, empty list.
+ asserts.equals(env, {}, dicts.pick({"a": 1}, []))
+
+ # Test key in dict.
+ asserts.equals(env, {"a": 1}, dicts.pick({"a": 1}, ["a"]))
+
+ # Test key not in dict.
+ asserts.equals(env, {}, dicts.pick({"a": 1}, ["b"]))
+
+ # Since dictionaries are passed around by reference, make sure that the
+ # result of dicts.pick is always a *copy* by modifying it afterwards and
+ # ensuring that the original argument doesn't also reflect the change. We do
+ # this to protect against someone who might attempt to optimize the function
+ # by returning the argument itself.
+ original = {"a": 1}
+ result = dicts.pick(original, ["a"])
+ result["a"] = 2
+ asserts.equals(env, 1, original["a"])
+
+ return unittest.end(env)
+
+pick_test = unittest.make(_pick_test)
+
def dicts_test_suite():
"""Creates the test targets and test suite for dicts.bzl tests."""
unittest.suite(
"dicts_tests",
add_test,
+ omit_test,
+ pick_test,
)
diff --git a/tests/diff_test/diff_test_tests.sh b/tests/diff_test/diff_test_tests.sh
index 4b58e6c..9fffcc6 100755
--- a/tests/diff_test/diff_test_tests.sh
+++ b/tests/diff_test/diff_test_tests.sh
@@ -37,20 +37,24 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function import_diff_test() {
local -r repo="$1"
mkdir -p "${repo}/rules"
+ mkdir -p "${repo}/lib"
+ touch "${repo}/lib/BUILD"
touch "${repo}/WORKSPACE"
- ln -sf "$(rlocation bazel_skylib/rules/diff_test.bzl)" \
+ ln -sf "$(rlocation $TEST_WORKSPACE/rules/diff_test.bzl)" \
"${repo}/rules/diff_test.bzl"
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/shell.bzl)" \
+ "${repo}/lib/shell.bzl"
echo "exports_files(['diff_test.bzl'])" > "${repo}/rules/BUILD"
}
function assert_simple_diff_test() {
- local -r flag="$1"
+ local -r flags="$1"
local -r ws="${TEST_TMPDIR}/$2"
local -r subdir="$3"
@@ -76,17 +80,17 @@ eof
echo bar > "$ws/$subdir/b.txt"
(cd "$ws" && \
- bazel test "$flag" "//${subdir%/}:same" --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} "//${subdir%/}:same" --test_output=errors 1>"$TEST_log" 2>&1 \
|| fail "expected success")
(cd "$ws" && \
- bazel test "$flag" "//${subdir%/}:different" --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} "//${subdir%/}:different" --test_output=errors 1>"$TEST_log" 2>&1 \
&& fail "expected failure" || true)
expect_log "FAIL: files \"${subdir}a.txt\" and \"${subdir}b.txt\" differ"
}
function assert_from_ext_repo() {
- local -r flag="$1"
+ local -r flags="$1"
local -r ws="${TEST_TMPDIR}/$2"
# Import the rule to an external repository.
@@ -171,47 +175,97 @@ diff_test(
eof
(cd "$ws/main" && \
- bazel test "$flag" //:same --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} //:same --test_output=errors 1>"$TEST_log" 2>&1 \
|| fail "expected success")
(cd "$ws/main" && \
- bazel test "$flag" //:different1 --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} //:different1 --test_output=errors 1>"$TEST_log" 2>&1 \
&& fail "expected failure" || true)
expect_log 'FAIL: files "external/ext1/foo/foo.txt" and "external/ext2/foo/bar.txt" differ'
(cd "$ws/main" && \
- bazel test "$flag" //:different2 --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} //:different2 --test_output=errors 1>"$TEST_log" 2>&1 \
&& fail "expected failure" || true)
expect_log 'FAIL: files "external/ext1/foo/foo.txt" and "ext1/foo/foo.txt" differ'
(cd "$ws/main" && \
- bazel test "$flag" //:different3 --test_output=errors 1>"$TEST_log" 2>&1 \
+ bazel test ${flags} //:different3 --test_output=errors 1>"$TEST_log" 2>&1 \
&& fail "expected failure" || true)
expect_log 'FAIL: files "ext2/foo/foo.txt" and "external/ext2/foo/foo.txt" differ'
}
function test_simple_diff_test_with_legacy_external_runfiles() {
- assert_simple_diff_test "--legacy_external_runfiles" "${FUNCNAME[0]}" ""
+ assert_simple_diff_test "--enable_runfiles --legacy_external_runfiles" "${FUNCNAME[0]}" ""
}
function test_simple_diff_test_without_legacy_external_runfiles() {
- assert_simple_diff_test "--nolegacy_external_runfiles" "${FUNCNAME[0]}" ""
+ assert_simple_diff_test "--enable_runfiles --nolegacy_external_runfiles" "${FUNCNAME[0]}" ""
+}
+
+function test_simple_diff_test_with_manifest() {
+ assert_simple_diff_test "--noenable_runfiles" "${FUNCNAME[0]}" ""
}
function test_directory_named_external_with_legacy_external_runfiles() {
- assert_simple_diff_test "--legacy_external_runfiles" "${FUNCNAME[0]}" "path/to/direcotry/external/in/name/"
+ assert_simple_diff_test "--enable_runfiles --legacy_external_runfiles" "${FUNCNAME[0]}" "path/to/directory/external/in/name/"
}
function test_directory_named_external_without_legacy_external_runfiles() {
- assert_simple_diff_test "--nolegacy_external_runfiles" "${FUNCNAME[0]}" "path/to/direcotry/external/in/name/"
+ assert_simple_diff_test "--enable_runfiles --nolegacy_external_runfiles" "${FUNCNAME[0]}" "path/to/directory/external/in/name/"
+}
+
+function test_directory_named_external_with_manifest() {
+ assert_simple_diff_test "--noenable_runfiles" "${FUNCNAME[0]}" "path/to/directory/external/in/name/"
}
function test_from_ext_repo_with_legacy_external_runfiles() {
- assert_from_ext_repo "--legacy_external_runfiles" "${FUNCNAME[0]}"
+ assert_from_ext_repo "--enable_runfiles --legacy_external_runfiles" "${FUNCNAME[0]}"
}
function test_from_ext_repo_without_legacy_external_runfiles() {
- assert_from_ext_repo "--nolegacy_external_runfiles" "${FUNCNAME[0]}"
+ assert_from_ext_repo "--enable_runfiles --nolegacy_external_runfiles" "${FUNCNAME[0]}"
+}
+
+function test_from_ext_repo_with_manifest() {
+ assert_from_ext_repo "--noenable_runfiles" "${FUNCNAME[0]}"
+}
+
+function test_failure_message() {
+ local -r ws="${TEST_TMPDIR}/${FUNCNAME[0]}"
+
+ import_diff_test "$ws"
+ touch "$ws/WORKSPACE"
+ cat >"$ws/BUILD" <<'eof'
+load("//rules:diff_test.bzl", "diff_test")
+
+diff_test(
+ name = "different_with_message",
+ failure_message = "This is an `$error`", # TODO(arostovtsev): also test Windows cmd.exe escapes when https://github.com/bazelbuild/bazel-skylib/pull/363 is merged
+ file1 = "a.txt",
+ file2 = "b.txt",
+)
+
+diff_test(
+ name = "different_without_message",
+ file1 = "c.txt",
+ file2 = "d.txt",
+)
+eof
+ echo foo > "$ws/a.txt"
+ echo bar > "$ws/b.txt"
+ echo foo > "$ws/c.txt"
+ echo bar > "$ws/d.txt"
+
+ (cd "$ws" && \
+ bazel test //:different_with_message --test_output=errors 1>"$TEST_log" 2>&1 \
+ && fail "expected failure" || true)
+ # TODO(arostovtsev): also test Windows cmd.exe escapes when https://github.com/bazelbuild/bazel-skylib/pull/363 is merged
+ expect_log "FAIL: files \"a.txt\" and \"b.txt\" differ. This is an \`\$error\`"
+
+ (cd "$ws" && \
+ bazel test //:different_without_message --test_output=errors 1>"$TEST_log" 2>&1 \
+ && fail "expected failure" || true)
+ expect_log "FAIL: files \"c.txt\" and \"d.txt\" differ. $"
}
cd "$TEST_TMPDIR"
diff --git a/tests/expand_template/BUILD b/tests/expand_template/BUILD
new file mode 100644
index 0000000..0607111
--- /dev/null
+++ b/tests/expand_template/BUILD
@@ -0,0 +1,57 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This package aids testing the 'diff_test' rule.
+
+load("//rules:expand_template.bzl", "expand_template")
+
+expand_template(
+ name = "filled_template",
+ out = "foo/test.yaml",
+ substitutions = {
+ "@name@": "test",
+ "@version@": "1.1.1",
+ },
+ template = "test.tpl.yaml",
+)
+
+sh_test(
+ name = "template_test",
+ srcs = ["template_test.sh"],
+ data = [
+ "foo/test.yaml",
+ ":filled_template",
+ "//tests:unittest.bash",
+ ],
+ deps = [
+ "@bazel_tools//tools/bash/runfiles",
+ ],
+)
+
+expand_template(
+ name = "version",
+ out = "version.h",
+ substitutions = {
+ "@VERSION@": "2.3.4",
+ },
+ template = "version.h.in",
+)
+
+cc_test(
+ name = "test",
+ srcs = [
+ "test.cc",
+ ":version",
+ ],
+)
diff --git a/tests/expand_template/template_test.sh b/tests/expand_template/template_test.sh
new file mode 100755
index 0000000..10099a4
--- /dev/null
+++ b/tests/expand_template/template_test.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# --- begin runfiles.bash initialization v2 ---
+# Copy-pasted from the Bazel Bash runfiles library v2.
+set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
+source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
+ source "$0.runfiles/$f" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+ { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
+# --- end runfiles.bash initialization v2 ---
+
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
+ || { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
+
+function test_expand_template() {
+ cat "$(rlocation $TEST_WORKSPACE/tests/expand_template/foo/test.yaml)" >"$TEST_log"
+ expect_log 'name: test'
+ expect_log 'version: 1.1.1'
+}
+
+run_suite "expand_template_tests test suite" \ No newline at end of file
diff --git a/tests/expand_template/test.cc b/tests/expand_template/test.cc
new file mode 100644
index 0000000..3b13e7a
--- /dev/null
+++ b/tests/expand_template/test.cc
@@ -0,0 +1,27 @@
+// Copyright 2022 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/expand_template/version.h"
+
+#include <cstring>
+
+int main(int argc, char **argv) {
+ // VERSION should be "2.3.4"
+ if(strcmp(VERSION, "2.3.4") == 0) {
+ return 0; // success
+ }
+ else {
+ return 1; // failure
+ }
+}
diff --git a/tests/expand_template/test.tpl.yaml b/tests/expand_template/test.tpl.yaml
new file mode 100644
index 0000000..03d9fdd
--- /dev/null
+++ b/tests/expand_template/test.tpl.yaml
@@ -0,0 +1,2 @@
+name: @name@
+version: @version@
diff --git a/tests/expand_template/version.h.in b/tests/expand_template/version.h.in
new file mode 100644
index 0000000..deb8418
--- /dev/null
+++ b/tests/expand_template/version.h.in
@@ -0,0 +1 @@
+#define VERSION "@VERSION@" \ No newline at end of file
diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD
index 852d607..997270f 100644
--- a/tests/native_binary/BUILD
+++ b/tests/native_binary/BUILD
@@ -1,6 +1,6 @@
+load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//rules:copy_file.bzl", "copy_file")
load("//rules:native_binary.bzl", "native_binary", "native_test")
-load("@rules_cc//cc:defs.bzl", "cc_binary")
package(
default_testonly = 1,
@@ -21,6 +21,15 @@ cc_binary(
# rule.
)
+cc_binary(
+ name = "assertdata_with_runfiles",
+ srcs = ["assertdata.cc"],
+ # This version depends on runfiles directly, to ensure runfiles from the
+ # binary are picked up by native_test/native_binary
+ data = ["testdata.txt"],
+ deps = ["@bazel_tools//tools/cpp/runfiles"],
+)
+
# A rule that copies "assertarg"'s output as an opaque executable, simulating a
# binary that's not built from source and needs to be wrapped in native_binary.
copy_file(
@@ -51,11 +60,7 @@ _ARGS = [
"$(location testdata.txt) $$(location testdata.txt) $(location testdata.txt)",
"'$(location testdata.txt) $$(location testdata.txt) $(location testdata.txt)'",
"$$TEST_SRCDIR",
-
- # TODO(laszlocsomor): uncomment this (and its counterpart in assertarg.cc)
- # after https://github.com/bazelbuild/bazel/issues/6622 is resolved and the
- # Bash-less test wrapper is the default on Windows.
- # "$${TEST_SRCDIR}",
+ "$${TEST_SRCDIR}",
]
native_binary(
@@ -101,3 +106,12 @@ native_test(
out = "data_test.exe",
data = ["testdata.txt"],
)
+
+native_test(
+ name = "data_from_binary_test",
+ src = ":assertdata_with_runfiles",
+ # On Windows we need the ".exe" extension.
+ # On other platforms the extension doesn't matter.
+ # Therefore we can use ".exe" on every platform.
+ out = "data_from_binary_test.exe",
+)
diff --git a/tests/native_binary/assertarg.cc b/tests/native_binary/assertarg.cc
index 02cb0fd..6506635 100644
--- a/tests/native_binary/assertarg.cc
+++ b/tests/native_binary/assertarg.cc
@@ -25,12 +25,7 @@ int main(int argc, char** argv) {
"tests/native_binary/testdata.txt",
"tests/native_binary/testdata.txt $(location testdata.txt) tests/native_binary/testdata.txt",
"$TEST_SRCDIR",
-
- // TODO(laszlocsomor): uncomment this (and its counterpart in the BUILD
- // file) after https://github.com/bazelbuild/bazel/issues/6622 is resolved
- // and the Bash-less test wrapper is the default on Windows.
- // "${TEST_SRCDIR}",
-
+ "${TEST_SRCDIR}",
"",
};
diff --git a/tests/native_binary/assertdata.cc b/tests/native_binary/assertdata.cc
index 111aaa2..6ae42e1 100644
--- a/tests/native_binary/assertdata.cc
+++ b/tests/native_binary/assertdata.cc
@@ -21,7 +21,7 @@
using bazel::tools::cpp::runfiles::Runfiles;
-int main(int argc, char** argv) {
+int main(int argc, char **argv) {
std::string error;
std::unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0], &error));
if (runfiles == nullptr) {
@@ -30,17 +30,23 @@ int main(int argc, char** argv) {
return 1;
}
- // Even though this cc_binary rule has no data-dependencies, the
- // native_binary that wraps a copy of this binary does, so we have some
- // runfiles.
- std::string path =
- runfiles->Rlocation("bazel_skylib/tests/native_binary/testdata.txt");
- if (path.empty()) {
- fprintf(stderr, "ERROR(" __FILE__ ":%d): Could not find runfile\n",
+ char* workspace = getenv("TEST_WORKSPACE");
+ if (workspace == nullptr) {
+ fprintf(stderr, "ERROR(" __FILE__ ":%d): envvar TEST_WORKSPACE is undefined\n",
__LINE__);
+ return 1;
+ }
+
+ // This should have runfiles, either from the binary itself or from the
+ // native_test.
+ std::string path =
+ runfiles->Rlocation(std::string(workspace) + "/tests/native_binary/testdata.txt");
+ FILE *f = fopen(path.c_str(), "rt");
+ if (!f) {
+ fprintf(stderr, "ERROR(" __FILE__ ":%d): Could not find runfile '%s'\n",
+ __LINE__, path.c_str());
}
- FILE* f = fopen(path.c_str(), "rt");
char buf[6];
size_t s = fread(buf, 1, 5, f);
fclose(f);
@@ -53,4 +59,3 @@ int main(int argc, char** argv) {
return 0;
}
-
diff --git a/tests/run_binary/BUILD b/tests/run_binary/BUILD
index 85c10f3..259c84a 100644
--- a/tests/run_binary/BUILD
+++ b/tests/run_binary/BUILD
@@ -1,7 +1,7 @@
+load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//rules:diff_test.bzl", "diff_test")
load("//rules:run_binary.bzl", "run_binary")
load("//rules:write_file.bzl", "write_file")
-load("@rules_cc//cc:defs.bzl", "cc_binary")
package(
default_testonly = 1,
diff --git a/tests/select_file/BUILD b/tests/select_file/BUILD
index a498a1e..a91c231 100644
--- a/tests/select_file/BUILD
+++ b/tests/select_file/BUILD
@@ -1,5 +1,5 @@
-load("//rules:select_file.bzl", "select_file")
load("//rules:diff_test.bzl", "diff_test")
+load("//rules:select_file.bzl", "select_file")
licenses(["notice"])
diff --git a/tests/selects_tests.bzl b/tests/selects_tests.bzl
index a7697f2..8227bf8 100644
--- a/tests/selects_tests.bzl
+++ b/tests/selects_tests.bzl
@@ -261,7 +261,7 @@ and_config_setting_group_multiple_matches_fail_test = analysistest.make(
)
def _and_config_setting_group_multiple_matches_fail_test():
- """Test verifying multple conditions mismatch on an ANDing config_setting_group."""
+ """Test verifying multiple conditions mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_multiple_matches_fail_rule",
myboolean = select(
@@ -453,7 +453,7 @@ or_config_setting_group_multiple_conds_match_test = analysistest.make(
)
def _or_config_setting_group_multiple_conds_match_test():
- """Test verifying multple conditions matching on an ORing config_setting_group."""
+ """Test verifying multiple conditions matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_multiple_conds_match_rule",
myboolean = select(
diff --git a/tests/subpackages_tests.bzl b/tests/subpackages_tests.bzl
new file mode 100644
index 0000000..3c494d6
--- /dev/null
+++ b/tests/subpackages_tests.bzl
@@ -0,0 +1,88 @@
+# Copyright 2022 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for subpackages.bzl."""
+
+load("//lib:subpackages.bzl", "subpackages")
+load("//lib:unittest.bzl", "loadingtest")
+
+def _all_test(env):
+ """Unit tests for subpackages.all."""
+
+ all_pkgs = [
+ "common_settings",
+ "copy_directory",
+ "copy_file",
+ "diff_test",
+ "expand_template",
+ "select_file",
+ "write_file",
+ ]
+
+ # Not all pkgs exist in all test environments.
+ if subpackages.exists("run_binary"):
+ all_pkgs.append("run_binary")
+
+ if subpackages.exists("native_binary"):
+ all_pkgs.append("native_binary")
+
+ # These exist in all cases
+ filtered_pkgs = [
+ "common_settings",
+ "copy_directory",
+ "copy_file",
+ "expand_template",
+ "select_file",
+ "write_file",
+ ]
+
+ # subpackages is always in sorted order:
+ all_pkgs = sorted(all_pkgs)
+
+ # test defaults
+ loadingtest.equals(
+ env,
+ "all",
+ ["//tests/" + pkg for pkg in all_pkgs],
+ subpackages.all(),
+ )
+
+ # test non-fully-qualified output
+ loadingtest.equals(
+ env,
+ "all_not_fully_qualified",
+ all_pkgs,
+ subpackages.all(fully_qualified = False),
+ )
+
+ # test exclusion
+ loadingtest.equals(
+ env,
+ "all_w_exclude",
+ filtered_pkgs,
+ subpackages.all(exclude = ["diff_test", "run_binary", "native_binary"], fully_qualified = False),
+ )
+
+def _exists_test(env):
+ """Unit tests for subpackages.exists."""
+ loadingtest.equals(env, "exists_yes", True, subpackages.exists("copy_file"))
+ loadingtest.equals(env, "exists_no", False, subpackages.exists("never_existed"))
+
+def subpackages_test_suite():
+ """Creates the test targets and test suite for subpackages.bzl tests."""
+
+ if subpackages.supported():
+ env = loadingtest.make("subpackages")
+ _all_test(env)
+ _exists_test(env)
diff --git a/tests/types_tests.bzl b/tests/types_tests.bzl
index aaf7cab..a3c654b 100644
--- a/tests/types_tests.bzl
+++ b/tests/types_tests.bzl
@@ -13,9 +13,9 @@
# limitations under the License.
"""Unit tests for types.bzl."""
+load("//lib:new_sets.bzl", "sets")
load("//lib:types.bzl", "types")
load("//lib:unittest.bzl", "asserts", "unittest")
-load("//lib:new_sets.bzl", "sets")
def _a_function():
"""A dummy function for testing."""
diff --git a/tests/unittest.bash b/tests/unittest.bash
index a43678d..9a9a7a5 100755
--- a/tests/unittest.bash
+++ b/tests/unittest.bash
@@ -238,7 +238,7 @@ capture_test_stderr () {
# Force XML_OUTPUT_FILE to an existing path
if [ -z "${XML_OUTPUT_FILE:-}" ]; then
- XML_OUTPUT_FILE=${TEST_TMPDIR}/ouput.xml
+ XML_OUTPUT_FILE=${TEST_TMPDIR}/output.xml
fi
#### Global variables:
@@ -674,8 +674,12 @@ if [ "$UNAME" = "linux" ] || [[ "$UNAME" =~ msys_nt* ]]; then
}
else
function timestamp() {
- # OS X and FreeBSD do not have %N so python is the best we can do
- python -c 'import time; print int(round(time.time() * 1000))'
+ # macOS and BSDs do not have %N, so Python is the best we can do.
+ # LC_ALL=C works around python 3.8 and 3.9 crash on macOS when the
+ # filesystem encoding is unspecified (e.g. when LANG=en_US).
+ local PYTHON=python
+ command -v python3 &> /dev/null && PYTHON=python3
+ LC_ALL=C "${PYTHON}" -c 'import time; print(int(round(time.time() * 1000)))'
}
fi
diff --git a/tests/unittest_test.sh b/tests/unittest_test.sh
index 4795b7e..c773d70 100755
--- a/tests/unittest_test.sh
+++ b/tests/unittest_test.sh
@@ -42,7 +42,7 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function create_pkg() {
@@ -64,22 +64,22 @@ EOF
cat > tests/BUILD <<EOF
exports_files(["*.bzl"])
EOF
- ln -sf "$(rlocation bazel_skylib/tests/unittest_tests.bzl)" tests/unittest_tests.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/tests/unittest_tests.bzl)" tests/unittest_tests.bzl
mkdir -p lib
touch lib/BUILD
cat > lib/BUILD <<EOF
exports_files(["*.bzl"])
EOF
- ln -sf "$(rlocation bazel_skylib/lib/dicts.bzl)" lib/dicts.bzl
- ln -sf "$(rlocation bazel_skylib/lib/new_sets.bzl)" lib/new_sets.bzl
- ln -sf "$(rlocation bazel_skylib/lib/partial.bzl)" lib/partial.bzl
- ln -sf "$(rlocation bazel_skylib/lib/sets.bzl)" lib/sets.bzl
- ln -sf "$(rlocation bazel_skylib/lib/types.bzl)" lib/types.bzl
- ln -sf "$(rlocation bazel_skylib/lib/unittest.bzl)" lib/unittest.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/dicts.bzl)" lib/dicts.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/new_sets.bzl)" lib/new_sets.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/partial.bzl)" lib/partial.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/sets.bzl)" lib/sets.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/types.bzl)" lib/types.bzl
+ ln -sf "$(rlocation $TEST_WORKSPACE/lib/unittest.bzl)" lib/unittest.bzl
mkdir -p toolchains/unittest
- ln -sf "$(rlocation bazel_skylib/toolchains/unittest/BUILD)" toolchains/unittest/BUILD
+ ln -sf "$(rlocation $TEST_WORKSPACE/toolchains/unittest/BUILD)" toolchains/unittest/BUILD
# Create test files.
mkdir -p testdir
diff --git a/tests/versions_tests.bzl b/tests/versions_tests.bzl
index 422cb41..a2e2308 100644
--- a/tests/versions_tests.bzl
+++ b/tests/versions_tests.bzl
@@ -26,6 +26,9 @@ def _parse_test(ctx):
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0"))
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0rc"))
+ # Verify that this doesn't fail - it corresponds to a dev build of Bazel.
+ versions.parse("")
+
return unittest.end(env)
def _version_comparison_test(ctx):
@@ -36,11 +39,13 @@ def _version_comparison_test(ctx):
asserts.true(env, versions.is_at_least("0.9.0", "0.10.0rc2"))
asserts.true(env, versions.is_at_least("0.9.0", "0.9.0rc3"))
asserts.true(env, versions.is_at_least("0.9.0", "1.2.3"))
+ asserts.true(env, versions.is_at_least("0.9.0", ""))
asserts.false(env, versions.is_at_most("0.4.0 123abcd", "0.10.0rc1 abcd123"))
asserts.true(env, versions.is_at_most("0.4.0", "0.3.0rc2"))
asserts.true(env, versions.is_at_most("0.4.0", "0.4.0rc3"))
asserts.true(env, versions.is_at_most("1.4.0", "0.4.0rc3"))
+ asserts.false(env, versions.is_at_most("1.4.0", ""))
return unittest.end(env)
diff --git a/tests/write_file/write_file_tests.sh b/tests/write_file/write_file_tests.sh
index e7039d0..c146948 100755
--- a/tests/write_file/write_file_tests.sh
+++ b/tests/write_file/write_file_tests.sh
@@ -37,7 +37,7 @@ else
fi
# --- end runfiles.bash initialization ---
-source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+source "$(rlocation $TEST_WORKSPACE/tests/unittest.bash)" \
|| { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
function assert_empty_file() {
@@ -47,21 +47,21 @@ function assert_empty_file() {
}
function test_write_empty_text() {
- assert_empty_file "$(rlocation bazel_skylib/tests/write_file/out/empty.txt)"
+ assert_empty_file "$(rlocation $TEST_WORKSPACE/tests/write_file/out/empty.txt)"
}
function test_write_nonempty_text() {
- cat "$(rlocation bazel_skylib/tests/write_file/out/nonempty.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/write_file/out/nonempty.txt)" >"$TEST_log"
expect_log '^aaa'
expect_log '^bbb'
}
function test_write_empty_bin() {
- assert_empty_file "$(rlocation bazel_skylib/tests/write_file/empty-bin-out.txt)"
+ assert_empty_file "$(rlocation $TEST_WORKSPACE/tests/write_file/empty-bin-out.txt)"
}
function test_write_nonempty_bin() {
- cat "$(rlocation bazel_skylib/tests/write_file/nonempty-bin-out.txt)" >"$TEST_log"
+ cat "$(rlocation $TEST_WORKSPACE/tests/write_file/nonempty-bin-out.txt)" >"$TEST_log"
expect_log '^potato'
}
diff --git a/version.bzl b/version.bzl
index 324adb5..b004ba1 100644
--- a/version.bzl
+++ b/version.bzl
@@ -13,4 +13,5 @@
# limitations under the License.
"""The version of bazel-skylib."""
-version = "1.2.1"
+# Keep in sync with MODULE.bazel and @bazel_skylib_gazelle_plugin//:MODULE.bazel
+version = "1.5.0"