diff --git a/BUILD.bazel b/BUILD.bazel index 1bb4cdb62..ef35330f7 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -6,7 +6,17 @@ load("@rules_rust//rust:defs.bzl", "rust_clippy", "rustfmt_test") load("@rules_shell//shell:sh_binary.bzl", "sh_binary") load("@rules_shell//shell:sh_test.bzl", "sh_test") load("@rules_shellcheck//:def.bzl", "shellcheck_test") -load(":cargo_build.bzl", "cargo_run", "cargo_test", "cargo_vendor", "cargo_vendor_provider", "python_venv", "python_venv_provider", "uv_python_install", "uv_python_venv") +load(":cargo_build.bzl", "cargo_run", "cargo_test", "cargo_vendor", "cargo_vendor_provider", "hack_command", "python_venv", "python_venv_provider", "uv_python_install", "uv_python_venv") +load("//crates/cli:hack.bzl", cli_hack = "HACK", cli_manifest = "MANIFEST") +load("//crates/cli-lib:hack.bzl", cli_lib_hack = "HACK", cli_lib_manifest = "MANIFEST") +load("//crates/cli-python:hack.bzl", cli_python_hack = "HACK", cli_python_manifest = "MANIFEST") +load("//crates/lib:hack.bzl", lib_hack = "HACK", lib_manifest = "MANIFEST") +load("//crates/lib-core:hack.bzl", lib_core_hack = "HACK", lib_core_manifest = "MANIFEST") +load("//crates/lib-dialects:hack.bzl", lib_dialects_hack = "HACK", lib_dialects_manifest = "MANIFEST") +load("//crates/lib-wasm:hack.bzl", lib_wasm_hack = "HACK", lib_wasm_manifest = "MANIFEST") +load("//crates/lineage:hack.bzl", lineage_hack = "HACK", lineage_manifest = "MANIFEST") +load("//crates/lsp:hack.bzl", lsp_hack = "HACK", lsp_manifest = "MANIFEST") +load("//crates/sqlinference:hack.bzl", sqlinference_hack = "HACK", sqlinference_manifest = "MANIFEST") # Link all npm packages into node_modules npm_link_all_packages(name = "node_modules") @@ -232,6 +242,19 @@ RUST_TARGETS = [ "//crates/sqlinference:sqruff-sqlinference", ] +# Workspace-level manifests shared by every per-crate hack target. Combined +# with a crate's dependency-closure machete_srcs, this is the scoped input set +# that lets unrelated crate edits stay cache hits (see cargo_hack_suite). +filegroup( + name = "workspace_manifest", + srcs = [ + "Cargo.lock", + "Cargo.toml", + "rust-toolchain.toml", + ], + visibility = ["//visibility:public"], +) + # Common Cargo source files for cargo-based checks # Used by cargo_machete, cargo_check, cargo_hack_check, rust_lint filegroup( @@ -251,6 +274,7 @@ filegroup( "//crates/lsp:machete_srcs", "//crates/sqlinference:machete_srcs", ], + visibility = ["//visibility:public"], ) # Vendor cargo dependencies and install Rust toolchain (cached until Cargo.lock changes) @@ -269,6 +293,7 @@ cargo_vendor( cargo_vendor_provider( name = "cargo_deps", vendor = ":cargo_vendor", + visibility = ["//visibility:public"], ) # Pre-cache Python venv with all dev dependencies (cached until pyproject.toml changes) @@ -460,16 +485,87 @@ cargo test --all --all-features --exclude sqruff --exclude sqruff-lib-core --exc """, ) -# Cargo hack check - verify each feature compiles in isolation -# This ensures no feature combination is broken -# Uses vendored dependencies for hermetic builds +# Cargo hack check - verify each feature compiles in isolation. +# +# Instead of one monolithic `cargo hack check --each-feature` action (serial, +# all-or-nothing caching), the sweep is decomposed into one `cargo check` +# target per feature per crate. Each crate owns its variation map in its +# hack.bzl (see cargo_hack_suite); the targets run in parallel and give +# per-feature failure attribution. The whole sweep is the union of every +# crate's hack suite. +# +# hack_reconcile (below) guarantees that decomposition stays a one-to-one +# match with what cargo-hack itself would enumerate, so no feature is silently +# dropped. + +# Expected command list derived from every crate's hack.bzl map. Compared +# against `cargo hack ... --print-command-list` by hack_reconcile. +_HACK_MODULES = [ + (cli_manifest, cli_hack), + (cli_lib_manifest, cli_lib_hack), + (cli_python_manifest, cli_python_hack), + (lib_manifest, lib_hack), + (lib_core_manifest, lib_core_hack), + (lib_dialects_manifest, lib_dialects_hack), + (lib_wasm_manifest, lib_wasm_hack), + (lineage_manifest, lineage_hack), + (lsp_manifest, lsp_hack), + (sqlinference_manifest, sqlinference_hack), +] + +_EXPECTED_HACK_COMMANDS = [ + hack_command(manifest, args) + for manifest, hack in _HACK_MODULES + for args in hack.values() +] + +_HACK_WANT = "\n".join(sorted(_EXPECTED_HACK_COMMANDS)) + +# Reconciliation test: the per-crate hack.bzl maps must match, one-to-one, the +# commands `cargo hack check --each-feature` would run. Uses --print-command-list +# so nothing is compiled; CARGO_NET_OFFLINE (not --offline) keeps the printed +# lines clean for diffing. cargo_test( - name = "cargo_hack_check", - size = "enormous", + name = "hack_reconcile", + size = "medium", srcs = [":cargo_srcs"], tools = ["@cargo_hack//:cargo-hack"], vendor = ":cargo_deps", - script = "cargo hack check --each-feature --exclude-features=codegen-docs --offline", + script = ( + "cat > want.txt <<'HACK_WANT_EOF'\n" + + _HACK_WANT + "\n" + + "HACK_WANT_EOF\n" + + "sort -o want.txt want.txt\n" + + "CARGO_NET_OFFLINE=true cargo hack check --each-feature --exclude-features=codegen-docs --print-command-list | sort > got.txt\n" + + "if ! diff -u want.txt got.txt; then\n" + + " echo ''\n" + + " echo 'ERROR: the per-crate hack.bzl maps are out of sync with cargo-hack.'\n" + + " echo ' < want.txt = enumerated from crates/*/hack.bzl FEATURES lists'\n" + + " echo ' > got.txt = what cargo hack check --each-feature enumerates'\n" + + " echo 'Update the FEATURES lists in the relevant crates/*/hack.bzl to match.'\n" + + " exit 1\n" + + "fi\n" + + "echo 'OK: hack.bzl maps match cargo hack --each-feature one-to-one.'\n" + ), +) + +# Aggregates the whole feature sweep plus the reconciliation guard. +# Usage: bazel test //:cargo_hack_check +test_suite( + name = "cargo_hack_check", + tests = [ + "//crates/cli:hack", + "//crates/cli-lib:hack", + "//crates/cli-python:hack", + "//crates/lib:hack", + "//crates/lib-core:hack", + "//crates/lib-dialects:hack", + "//crates/lib-wasm:hack", + "//crates/lineage:hack", + "//crates/lsp:hack", + "//crates/sqlinference:hack", + ":hack_reconcile", + ], ) # Zensical docs build - verify documentation builds successfully diff --git a/cargo_build.bzl b/cargo_build.bzl index 8bc8cc7dd..15fb421fa 100644 --- a/cargo_build.bzl +++ b/cargo_build.bzl @@ -616,3 +616,83 @@ cargo_run = rule( executable = True, attrs = _cargo_attrs, ) + +def each_feature(features): + """Builds the `--each-feature` variation map for a crate. + + Mirrors `cargo hack check --each-feature`: one `--no-default-features` run + plus one `--features X` run per declared feature. For a crate with no + features, pass `[]` to get a single plain `cargo check` (matching what + cargo-hack emits for featureless crates). + + Returns a map of {target-name-suffix: cargo feature arguments}. The keys are + used as Bazel target name suffixes, so they must be valid target names. + + The resulting set is reconciled one-to-one against cargo-hack itself by + //:hack_reconcile, which fails if a crate's hack.bzl drifts from the + features cargo-hack actually enumerates. + """ + if not features: + return {"check": ""} + variations = {"none": "--no-default-features"} + for f in features: + variations[f] = "--no-default-features --features " + f + return variations + +def hack_command(manifest, args): + """Formats a single cargo-hack-equivalent `cargo check` command line. + + Matches the exact form printed by `cargo hack ... --print-command-list` + (no `--offline`), so the reconciliation diff stays byte-for-byte. + """ + cmd = "cargo check --manifest-path " + manifest + if args: + cmd += " " + args + return cmd + +def cargo_hack_suite(name, manifest, variations, closure, vendor, size = "large"): + """Generates one `cargo check` test per feature variation, plus a suite. + + Each generated target runs exactly the `cargo check` invocation that + `cargo hack check --each-feature` would run for `manifest` and one feature, + using the hermetic vendored toolchain. Splitting cargo-hack's serial sweep + into individual targets lets Bazel run them in parallel and attribute + failures per feature. + + `closure` is the crate's own directory plus the directories of its + transitive in-workspace dependencies (e.g. ["crates/lib-dialects", + "crates/lib-core"]). The action's inputs are scoped to just those crates' + sources, and the workspace `members`/`default-members` are trimmed to the + same set in-sandbox so cargo only loads the closure (rather than validating + every workspace member). This way an edit to an unrelated crate does not + invalidate this crate's targets, maximising Bazel cache hits. + """ + srcs = ["//:workspace_manifest"] + ["//{}:machete_srcs".format(d) for d in closure] + + members_toml = "[" + ", ".join(['"{}"'.format(d) for d in closure]) + "]" + + # Restrict the workspace to the dependency closure before running cargo, so + # missing (out-of-closure) crate sources don't fail workspace loading. + # Portable in-place edit (works with both GNU and BSD sed). + rewrite = ( + "sed -e 's|^members = \\[\"crates/\\*\"\\]|members = " + members_toml + "|'" + + " -e 's|^default-members = .*|default-members = " + members_toml + "|'" + + " Cargo.toml > Cargo.toml.scoped && mv Cargo.toml.scoped Cargo.toml\n" + ) + + tests = [] + for suffix, args in variations.items(): + tname = "{}_{}".format(name, suffix) + cargo_test( + name = tname, + size = size, + srcs = srcs, + vendor = vendor, + script = rewrite + hack_command(manifest, args) + " --offline", + ) + tests.append(":" + tname) + native.test_suite( + name = name, + tests = tests, + visibility = ["//visibility:public"], + ) diff --git a/crates/cli-lib/BUILD.bazel b/crates/cli-lib/BUILD.bazel index 7e6de2356..a4c25a5bd 100644 --- a/crates/cli-lib/BUILD.bazel +++ b/crates/cli-lib/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/cli-lib:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_library( name = "sqruff-cli-lib", diff --git a/crates/cli-lib/hack.bzl b/crates/cli-lib/hack.bzl new file mode 100644 index 000000000..708c1edf2 --- /dev/null +++ b/crates/cli-lib/hack.bzl @@ -0,0 +1,29 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +`FEATURES` lists the features declared in Cargo.toml that cargo-hack checks in +isolation (excluding `codegen-docs`, which is excluded from the sweep). The +derived `HACK` map drives the per-feature `cargo check` targets in BUILD.bazel +and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/cli-lib/Cargo.toml" + +FEATURES = [ + "parser", + "python", +] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/cli-lib", + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", + "crates/lsp", +] diff --git a/crates/cli-python/BUILD.bazel b/crates/cli-python/BUILD.bazel index bfc94d470..ac30ead07 100644 --- a/crates/cli-python/BUILD.bazel +++ b/crates/cli-python/BUILD.bazel @@ -1,8 +1,22 @@ +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + exports_files([ "Cargo.toml", "pyproject.toml", ]) +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/cli-python:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) + # Python source files for linting filegroup( name = "python_srcs", diff --git a/crates/cli-python/hack.bzl b/crates/cli-python/hack.bzl new file mode 100644 index 000000000..639458097 --- /dev/null +++ b/crates/cli-python/hack.bzl @@ -0,0 +1,26 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +This crate declares no Cargo features, so cargo-hack emits a single plain +`cargo check`. The derived `HACK` map drives the `cargo check` target in +BUILD.bazel and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/cli-python/Cargo.toml" + +FEATURES = [] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/cli-python", + "crates/cli-lib", + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", + "crates/lsp", +] diff --git a/crates/cli/BUILD.bazel b/crates/cli/BUILD.bazel index 9c446fde2..a28b2e576 100644 --- a/crates/cli/BUILD.bazel +++ b/crates/cli/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_binary") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/cli:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_binary( name = "sqruff", diff --git a/crates/cli/hack.bzl b/crates/cli/hack.bzl new file mode 100644 index 000000000..621245cb1 --- /dev/null +++ b/crates/cli/hack.bzl @@ -0,0 +1,34 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +`FEATURES` lists the features declared in Cargo.toml that cargo-hack checks in +isolation (excluding `codegen-docs`, which is excluded from the sweep). The +derived `HACK` map drives the per-feature `cargo check` targets in BUILD.bazel +and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/cli/Cargo.toml" + +FEATURES = [ + "bench", + "default", + "dhat-heap", + "mimalloc", + "parser", + "python", +] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/cli", + "crates/cli-lib", + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", + "crates/lsp", +] diff --git a/crates/lib-core/BUILD.bazel b/crates/lib-core/BUILD.bazel index 192fce2f6..afc623787 100644 --- a/crates/lib-core/BUILD.bazel +++ b/crates/lib-core/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lib-core:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) ALL_FEATURES = [ "serde", diff --git a/crates/lib-core/hack.bzl b/crates/lib-core/hack.bzl new file mode 100644 index 000000000..4f878be53 --- /dev/null +++ b/crates/lib-core/hack.bzl @@ -0,0 +1,25 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +`FEATURES` lists the features declared in Cargo.toml that cargo-hack checks in +isolation (excluding `codegen-docs`, which is excluded from the sweep). The +derived `HACK` map drives the per-feature `cargo check` targets in BUILD.bazel +and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lib-core/Cargo.toml" + +FEATURES = [ + "serde", + "stringify", +] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lib-core", +] diff --git a/crates/lib-dialects/BUILD.bazel b/crates/lib-dialects/BUILD.bazel index bdd7f7fd0..1bc598004 100644 --- a/crates/lib-dialects/BUILD.bazel +++ b/crates/lib-dialects/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lib-dialects:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) ALL_FEATURES = [ "athena", diff --git a/crates/lib-dialects/hack.bzl b/crates/lib-dialects/hack.bzl new file mode 100644 index 000000000..a14e01dec --- /dev/null +++ b/crates/lib-dialects/hack.bzl @@ -0,0 +1,42 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +`FEATURES` lists the features declared in Cargo.toml that cargo-hack checks in +isolation (excluding `codegen-docs`, which is excluded from the sweep). The +derived `HACK` map drives the per-feature `cargo check` targets in BUILD.bazel +and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lib-dialects/Cargo.toml" + +FEATURES = [ + "default", + "athena", + "bigquery", + "clickhouse", + "databricks", + "db2", + "duckdb", + "greenplum", + "hive", + "mysql", + "oracle", + "postgres", + "redshift", + "snowflake", + "sparksql", + "sqlite", + "trino", + "tsql", +] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lib-dialects", + "crates/lib-core", +] diff --git a/crates/lib-wasm/BUILD.bazel b/crates/lib-wasm/BUILD.bazel index b67f6c8fa..ecbdaa035 100644 --- a/crates/lib-wasm/BUILD.bazel +++ b/crates/lib-wasm/BUILD.bazel @@ -1,6 +1,19 @@ load("@crates//:defs.bzl", "all_crate_deps", "crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_shared_library") load("@rules_rust_wasm_bindgen//:defs.bzl", "rust_wasm_bindgen") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lib-wasm:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_library( name = "sqruff-wasm", diff --git a/crates/lib-wasm/hack.bzl b/crates/lib-wasm/hack.bzl new file mode 100644 index 000000000..615036b9d --- /dev/null +++ b/crates/lib-wasm/hack.bzl @@ -0,0 +1,25 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +This crate declares no Cargo features, so cargo-hack emits a single plain +`cargo check`. The derived `HACK` map drives the `cargo check` target in +BUILD.bazel and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lib-wasm/Cargo.toml" + +FEATURES = [] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lib-wasm", + "crates/lineage", + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", +] diff --git a/crates/lib/BUILD.bazel b/crates/lib/BUILD.bazel index 5e0432e70..c18d29970 100644 --- a/crates/lib/BUILD.bazel +++ b/crates/lib/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps", "crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_shared_library") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lib:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) ALL_FEATURES = [ "parser", diff --git a/crates/lib/hack.bzl b/crates/lib/hack.bzl new file mode 100644 index 000000000..f173cf8b5 --- /dev/null +++ b/crates/lib/hack.bzl @@ -0,0 +1,27 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +`FEATURES` lists the features declared in Cargo.toml that cargo-hack checks in +isolation (excluding `codegen-docs`, which is excluded from the sweep). The +derived `HACK` map drives the per-feature `cargo check` targets in BUILD.bazel +and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lib/Cargo.toml" + +FEATURES = [ + "parser", + "python", +] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", +] diff --git a/crates/lineage/BUILD.bazel b/crates/lineage/BUILD.bazel index 1e29fb0dd..5983fc73e 100644 --- a/crates/lineage/BUILD.bazel +++ b/crates/lineage/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lineage:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_library( name = "lineage", diff --git a/crates/lineage/hack.bzl b/crates/lineage/hack.bzl new file mode 100644 index 000000000..26d4a7bbe --- /dev/null +++ b/crates/lineage/hack.bzl @@ -0,0 +1,23 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +This crate declares no Cargo features, so cargo-hack emits a single plain +`cargo check`. The derived `HACK` map drives the `cargo check` target in +BUILD.bazel and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lineage/Cargo.toml" + +FEATURES = [] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lineage", + "crates/lib-core", + "crates/lib-dialects", +] diff --git a/crates/lsp/BUILD.bazel b/crates/lsp/BUILD.bazel index af0a8d965..9477b2726 100644 --- a/crates/lsp/BUILD.bazel +++ b/crates/lsp/BUILD.bazel @@ -1,6 +1,19 @@ load("@crates//:defs.bzl", "all_crate_deps", "crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_shared_library") load("@rules_rust_wasm_bindgen//:defs.bzl", "rust_wasm_bindgen") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/lsp:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_library( name = "sqruff-lsp", diff --git a/crates/lsp/hack.bzl b/crates/lsp/hack.bzl new file mode 100644 index 000000000..7c3f1ab62 --- /dev/null +++ b/crates/lsp/hack.bzl @@ -0,0 +1,24 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +This crate declares no Cargo features, so cargo-hack emits a single plain +`cargo check`. The derived `HACK` map drives the `cargo check` target in +BUILD.bazel and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/lsp/Cargo.toml" + +FEATURES = [] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/lsp", + "crates/lib", + "crates/lib-core", + "crates/lib-dialects", +] diff --git a/crates/sqlinference/BUILD.bazel b/crates/sqlinference/BUILD.bazel index 1f651bada..4ac938f79 100644 --- a/crates/sqlinference/BUILD.bazel +++ b/crates/sqlinference/BUILD.bazel @@ -1,5 +1,18 @@ load("@crates//:defs.bzl", "all_crate_deps") load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") +load("//:cargo_build.bzl", "cargo_hack_suite") +load(":hack.bzl", "CLOSURE", "HACK", "MANIFEST") + +# Per-feature `cargo check` targets mirroring `cargo hack --each-feature`. +# The HACK map lives in hack.bzl and is reconciled against cargo-hack by +# //:hack_reconcile. Run the whole crate sweep via `bazel test //crates/sqlinference:hack`. +cargo_hack_suite( + name = "hack", + closure = CLOSURE, + manifest = MANIFEST, + variations = HACK, + vendor = "//:cargo_deps", +) rust_library( name = "sqruff-sqlinference", diff --git a/crates/sqlinference/hack.bzl b/crates/sqlinference/hack.bzl new file mode 100644 index 000000000..a0e512a2a --- /dev/null +++ b/crates/sqlinference/hack.bzl @@ -0,0 +1,23 @@ +"""Feature variations for `cargo hack --each-feature` on this crate. + +This crate declares no Cargo features, so cargo-hack emits a single plain +`cargo check`. The derived `HACK` map drives the `cargo check` target in +BUILD.bazel and is reconciled one-to-one against cargo-hack by //:hack_reconcile. +""" + +load("//:cargo_build.bzl", "each_feature") + +MANIFEST = "crates/sqlinference/Cargo.toml" + +FEATURES = [] + +HACK = each_feature(FEATURES) + +# This crate plus its transitive in-workspace dependencies. Scopes the Bazel +# action inputs (and the in-sandbox workspace) so edits to unrelated crates +# remain cache hits. See cargo_hack_suite. +CLOSURE = [ + "crates/sqlinference", + "crates/lib-core", + "crates/lib-dialects", +]