diff --git a/examples/remote/binary_dependencies/BUILD.bazel b/examples/remote/binary_dependencies/BUILD.bazel index 752bc5653..ad45cbf10 100644 --- a/examples/remote/binary_dependencies/BUILD.bazel +++ b/examples/remote/binary_dependencies/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//remote/binary_dependencies/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -8,7 +9,5 @@ rust_binary( data = [ "//remote/binary_dependencies/cargo:cargo_bin_texture_synthesis", ], - deps = [ - "//remote/binary_dependencies/cargo:ferris_says", - ], + deps = all_crate_deps(), ) diff --git a/examples/remote/binary_dependencies/Cargo.toml b/examples/remote/binary_dependencies/Cargo.toml index 83be18f2a..cf53ba734 100644 --- a/examples/remote/binary_dependencies/Cargo.toml +++ b/examples/remote/binary_dependencies/Cargo.toml @@ -16,6 +16,7 @@ gen_workspace_prefix = "remote_binary_dependencies" genmode = "Remote" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true [package.metadata.raze.binary_deps] texture-synthesis-cli = "0.8.0" diff --git a/examples/remote/binary_dependencies/cargo/crates.bzl b/examples/remote/binary_dependencies/cargo/crates.bzl index 67b6500fb..b41421031 100644 --- a/examples/remote/binary_dependencies/cargo/crates.bzl +++ b/examples/remote/binary_dependencies/cargo/crates.bzl @@ -9,6 +9,164 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") # bui load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # buildifier: disable=load load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") # buildifier: disable=load +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dependencies for the Rust targets of that package. +_DEPENDENCIES = { + "remote/binary_dependencies": { + "ferris-says": "@remote_binary_dependencies__ferris_says__0_2_0//:ferris_says", + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dependencies for the Rust targets of that package. +_PROC_MACRO_DEPENDENCIES = { + "remote/binary_dependencies": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dev dependencies for the Rust targets of that package. +_DEV_DEPENDENCIES = { + "remote/binary_dependencies": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dev dependencies for the Rust targets of that package. +_DEV_PROC_MACRO_DEPENDENCIES = { + "remote/binary_dependencies": { + }, +} + +def crate_deps(deps, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of the requested crates for the package where this macro is called. + + WARNING: This macro is part of an expeirmental API and is subject to change. + + Args: + deps (list): The desired list of crate targets. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Join both sets of dependencies + dependencies = _flatten_dependency_maps([ + _DEPENDENCIES, + _PROC_MACRO_DEPENDENCIES, + _DEV_DEPENDENCIES, + _DEV_PROC_MACRO_DEPENDENCIES, + ]) + + if not deps: + return [] + + missing_crates = [] + crate_targets = [] + for crate_target in deps: + if crate_target not in dependencies[package_name]: + missing_crates.append(crate_target) + else: + crate_targets.append(dependencies[package_name][crate_target]) + + if missing_crates: + fail("Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`".format( + missing_crates, + package_name, + dependencies[package_name], + )) + + return crate_targets + +def all_crate_deps(normal = False, normal_dev = False, proc_macro = False, proc_macro_dev = False, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of all requested direct crate dependencies \ + for the package where this macro is called. + + If no parameters are set, all normal dependencies are returned. Setting any one flag will + otherwise impact the contents of the returned list. + + Args: + normal (bool, optional): If True, normal dependencies are included in the + output list. Defaults to False. + normal_dev (bool, optional): If True, normla dev dependencies will be + included in the output list. Defaults to False. + proc_macro (bool, optional): If True, proc_macro dependencies are included + in the output list. Defaults to False. + proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are + included in the output list. Defaults to False. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Determine the relevant maps to use + all_dependency_maps = [] + if normal: + all_dependency_maps.append(_DEPENDENCIES) + if normal_dev: + all_dependency_maps.append(_DEV_DEPENDENCIES) + if proc_macro: + all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES) + if proc_macro_dev: + all_dependency_maps.append(_DEV_PROC_MACRO_DEPENDENCIES) + + # Default to always using normal dependencies + if not all_dependency_maps: + all_dependency_maps.append(_DEPENDENCIES) + + dependencies = _flatten_dependency_maps(all_dependency_maps) + + if not dependencies: + return [] + + return dependencies[package_name].values() + +def _flatten_dependency_maps(all_dependency_maps): + """Flatten a list of dependency maps into one dictionary. + + Dependency maps have the following structure: + + ```python + DEPENDENCIES_MAP = { + # The first key in the map is a Bazel package + # name of the workspace this file is defined in. + "package_name": { + + # An alias to a crate target. # The label of the crate target the + # Aliases are only crate names. # alias refers to. + "alias": "@full//:label", + } + } + ``` + + Args: + all_dependency_maps (list): A list of dicts as described above + + Returns: + dict: A dictionary as described above + """ + dependencies = {} + + for dep_map in all_dependency_maps: + for pkg_name in dep_map: + if pkg_name not in dependencies: + # Add a non-frozen dict to the collection of dependencies + dependencies.setdefault(pkg_name, dict(dep_map[pkg_name].items())) + continue + + duplicate_crate_aliases = [key for key in dependencies[pkg_name] if key in dep_map[pkg_name]] + if duplicate_crate_aliases: + fail("There should be no duplicate crate aliases: {}".format(duplicate_crate_aliases)) + + dependencies[pkg_name].update(dep_map[pkg_name]) + + return dependencies + def remote_binary_dependencies_fetch_remote_crates(): """This function defines a collection of repos and should be called in a WORKSPACE file""" maybe( diff --git a/examples/remote/cargo_workspace/Cargo.toml b/examples/remote/cargo_workspace/Cargo.toml index 097d943c4..76984ed7b 100644 --- a/examples/remote/cargo_workspace/Cargo.toml +++ b/examples/remote/cargo_workspace/Cargo.toml @@ -11,3 +11,4 @@ gen_workspace_prefix = "remote_cargo_workspace" genmode = "Remote" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true diff --git a/examples/remote/cargo_workspace/cargo/crates.bzl b/examples/remote/cargo_workspace/cargo/crates.bzl index d4e562fe2..4c4d5fc93 100644 --- a/examples/remote/cargo_workspace/cargo/crates.bzl +++ b/examples/remote/cargo_workspace/cargo/crates.bzl @@ -9,6 +9,182 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") # bui load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # buildifier: disable=load load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") # buildifier: disable=load +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dependencies for the Rust targets of that package. +_DEPENDENCIES = { + "remote/cargo_workspace/num_printer": { + "clap": "@remote_cargo_workspace__clap__2_33_3//:clap", + }, + "remote/cargo_workspace/printer": { + "ferris-says": "@remote_cargo_workspace__ferris_says__0_2_0//:ferris_says", + }, + "remote/cargo_workspace/rng": { + "rand": "@remote_cargo_workspace__rand__0_7_3//:rand", + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dependencies for the Rust targets of that package. +_PROC_MACRO_DEPENDENCIES = { + "remote/cargo_workspace/num_printer": { + }, + "remote/cargo_workspace/printer": { + }, + "remote/cargo_workspace/rng": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dev dependencies for the Rust targets of that package. +_DEV_DEPENDENCIES = { + "remote/cargo_workspace/num_printer": { + }, + "remote/cargo_workspace/printer": { + }, + "remote/cargo_workspace/rng": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dev dependencies for the Rust targets of that package. +_DEV_PROC_MACRO_DEPENDENCIES = { + "remote/cargo_workspace/num_printer": { + }, + "remote/cargo_workspace/printer": { + }, + "remote/cargo_workspace/rng": { + }, +} + +def crate_deps(deps, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of the requested crates for the package where this macro is called. + + WARNING: This macro is part of an expeirmental API and is subject to change. + + Args: + deps (list): The desired list of crate targets. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Join both sets of dependencies + dependencies = _flatten_dependency_maps([ + _DEPENDENCIES, + _PROC_MACRO_DEPENDENCIES, + _DEV_DEPENDENCIES, + _DEV_PROC_MACRO_DEPENDENCIES, + ]) + + if not deps: + return [] + + missing_crates = [] + crate_targets = [] + for crate_target in deps: + if crate_target not in dependencies[package_name]: + missing_crates.append(crate_target) + else: + crate_targets.append(dependencies[package_name][crate_target]) + + if missing_crates: + fail("Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`".format( + missing_crates, + package_name, + dependencies[package_name], + )) + + return crate_targets + +def all_crate_deps(normal = False, normal_dev = False, proc_macro = False, proc_macro_dev = False, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of all requested direct crate dependencies \ + for the package where this macro is called. + + If no parameters are set, all normal dependencies are returned. Setting any one flag will + otherwise impact the contents of the returned list. + + Args: + normal (bool, optional): If True, normal dependencies are included in the + output list. Defaults to False. + normal_dev (bool, optional): If True, normla dev dependencies will be + included in the output list. Defaults to False. + proc_macro (bool, optional): If True, proc_macro dependencies are included + in the output list. Defaults to False. + proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are + included in the output list. Defaults to False. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Determine the relevant maps to use + all_dependency_maps = [] + if normal: + all_dependency_maps.append(_DEPENDENCIES) + if normal_dev: + all_dependency_maps.append(_DEV_DEPENDENCIES) + if proc_macro: + all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES) + if proc_macro_dev: + all_dependency_maps.append(_DEV_PROC_MACRO_DEPENDENCIES) + + # Default to always using normal dependencies + if not all_dependency_maps: + all_dependency_maps.append(_DEPENDENCIES) + + dependencies = _flatten_dependency_maps(all_dependency_maps) + + if not dependencies: + return [] + + return dependencies[package_name].values() + +def _flatten_dependency_maps(all_dependency_maps): + """Flatten a list of dependency maps into one dictionary. + + Dependency maps have the following structure: + + ```python + DEPENDENCIES_MAP = { + # The first key in the map is a Bazel package + # name of the workspace this file is defined in. + "package_name": { + + # An alias to a crate target. # The label of the crate target the + # Aliases are only crate names. # alias refers to. + "alias": "@full//:label", + } + } + ``` + + Args: + all_dependency_maps (list): A list of dicts as described above + + Returns: + dict: A dictionary as described above + """ + dependencies = {} + + for dep_map in all_dependency_maps: + for pkg_name in dep_map: + if pkg_name not in dependencies: + # Add a non-frozen dict to the collection of dependencies + dependencies.setdefault(pkg_name, dict(dep_map[pkg_name].items())) + continue + + duplicate_crate_aliases = [key for key in dependencies[pkg_name] if key in dep_map[pkg_name]] + if duplicate_crate_aliases: + fail("There should be no duplicate crate aliases: {}".format(duplicate_crate_aliases)) + + dependencies[pkg_name].update(dep_map[pkg_name]) + + return dependencies + def remote_cargo_workspace_fetch_remote_crates(): """This function defines a collection of repos and should be called in a WORKSPACE file""" maybe( diff --git a/examples/remote/cargo_workspace/num_printer/BUILD.bazel b/examples/remote/cargo_workspace/num_printer/BUILD.bazel index 3bb84ecf1..594b75725 100644 --- a/examples/remote/cargo_workspace/num_printer/BUILD.bazel +++ b/examples/remote/cargo_workspace/num_printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//remote/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_binary( srcs = ["src/main.rs"], edition = "2018", deps = [ - "//remote/cargo_workspace/num_printer/cargo:clap", "//remote/cargo_workspace/printer", - ], + ] + all_crate_deps(), ) diff --git a/examples/remote/cargo_workspace/printer/BUILD.bazel b/examples/remote/cargo_workspace/printer/BUILD.bazel index 577522f78..ca64bede4 100644 --- a/examples/remote/cargo_workspace/printer/BUILD.bazel +++ b/examples/remote/cargo_workspace/printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//remote/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_library( srcs = ["src/lib.rs"], edition = "2018", deps = [ - "//remote/cargo_workspace/printer/cargo:ferris_says", "//remote/cargo_workspace/rng", - ], + ] + all_crate_deps(), ) diff --git a/examples/remote/cargo_workspace/rng/BUILD.bazel b/examples/remote/cargo_workspace/rng/BUILD.bazel index cac2e8ed4..5c31664fc 100644 --- a/examples/remote/cargo_workspace/rng/BUILD.bazel +++ b/examples/remote/cargo_workspace/rng/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//remote/cargo_workspace/cargo:crates.bzl", "crate_deps") package(default_visibility = ["//visibility:public"]) @@ -6,7 +7,7 @@ rust_library( name = "rng", srcs = ["src/lib.rs"], edition = "2018", - deps = [ - "//remote/cargo_workspace/rng/cargo:rand", - ], + deps = crate_deps([ + "rand", + ]), ) diff --git a/examples/vendored/cargo_workspace/Cargo.toml b/examples/vendored/cargo_workspace/Cargo.toml index 575276a17..ea5db053a 100644 --- a/examples/vendored/cargo_workspace/Cargo.toml +++ b/examples/vendored/cargo_workspace/Cargo.toml @@ -11,3 +11,5 @@ gen_workspace_prefix = "vendored_cargo_workspace" genmode = "Vendored" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true + diff --git a/examples/vendored/cargo_workspace/cargo/BUILD.bazel b/examples/vendored/cargo_workspace/cargo/BUILD.bazel new file mode 100644 index 000000000..2b78032ca --- /dev/null +++ b/examples/vendored/cargo_workspace/cargo/BUILD.bazel @@ -0,0 +1,6 @@ +""" +@generated +cargo-raze generated Bazel file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" diff --git a/examples/vendored/cargo_workspace/cargo/crates.bzl b/examples/vendored/cargo_workspace/cargo/crates.bzl new file mode 100644 index 000000000..f2be6bc58 --- /dev/null +++ b/examples/vendored/cargo_workspace/cargo/crates.bzl @@ -0,0 +1,182 @@ +""" +@generated +cargo-raze generated Bazel file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dependencies for the Rust targets of that package. +_DEPENDENCIES = { + "vendored/cargo_workspace/num_printer": { + "clap": "//vendored/cargo_workspace/cargo/vendor/clap-2.33.3:clap", + }, + "vendored/cargo_workspace/printer": { + "ferris-says": "//vendored/cargo_workspace/cargo/vendor/ferris-says-0.2.0:ferris_says", + }, + "vendored/cargo_workspace/rng": { + "rand": "//vendored/cargo_workspace/cargo/vendor/rand-0.7.3:rand", + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dependencies for the Rust targets of that package. +_PROC_MACRO_DEPENDENCIES = { + "vendored/cargo_workspace/num_printer": { + }, + "vendored/cargo_workspace/printer": { + }, + "vendored/cargo_workspace/rng": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dev dependencies for the Rust targets of that package. +_DEV_DEPENDENCIES = { + "vendored/cargo_workspace/num_printer": { + }, + "vendored/cargo_workspace/printer": { + }, + "vendored/cargo_workspace/rng": { + }, +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dev dependencies for the Rust targets of that package. +_DEV_PROC_MACRO_DEPENDENCIES = { + "vendored/cargo_workspace/num_printer": { + }, + "vendored/cargo_workspace/printer": { + }, + "vendored/cargo_workspace/rng": { + }, +} + +def crate_deps(deps, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of the requested crates for the package where this macro is called. + + WARNING: This macro is part of an expeirmental API and is subject to change. + + Args: + deps (list): The desired list of crate targets. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Join both sets of dependencies + dependencies = _flatten_dependency_maps([ + _DEPENDENCIES, + _PROC_MACRO_DEPENDENCIES, + _DEV_DEPENDENCIES, + _DEV_PROC_MACRO_DEPENDENCIES, + ]) + + if not deps: + return [] + + missing_crates = [] + crate_targets = [] + for crate_target in deps: + if crate_target not in dependencies[package_name]: + missing_crates.append(crate_target) + else: + crate_targets.append(dependencies[package_name][crate_target]) + + if missing_crates: + fail("Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`".format( + missing_crates, + package_name, + dependencies[package_name], + )) + + return crate_targets + +def all_crate_deps(normal = False, normal_dev = False, proc_macro = False, proc_macro_dev = False, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of all requested direct crate dependencies \ + for the package where this macro is called. + + If no parameters are set, all normal dependencies are returned. Setting any one flag will + otherwise impact the contents of the returned list. + + Args: + normal (bool, optional): If True, normal dependencies are included in the + output list. Defaults to False. + normal_dev (bool, optional): If True, normla dev dependencies will be + included in the output list. Defaults to False. + proc_macro (bool, optional): If True, proc_macro dependencies are included + in the output list. Defaults to False. + proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are + included in the output list. Defaults to False. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Determine the relevant maps to use + all_dependency_maps = [] + if normal: + all_dependency_maps.append(_DEPENDENCIES) + if normal_dev: + all_dependency_maps.append(_DEV_DEPENDENCIES) + if proc_macro: + all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES) + if proc_macro_dev: + all_dependency_maps.append(_DEV_PROC_MACRO_DEPENDENCIES) + + # Default to always using normal dependencies + if not all_dependency_maps: + all_dependency_maps.append(_DEPENDENCIES) + + dependencies = _flatten_dependency_maps(all_dependency_maps) + + if not dependencies: + return [] + + return dependencies[package_name].values() + +def _flatten_dependency_maps(all_dependency_maps): + """Flatten a list of dependency maps into one dictionary. + + Dependency maps have the following structure: + + ```python + DEPENDENCIES_MAP = { + # The first key in the map is a Bazel package + # name of the workspace this file is defined in. + "package_name": { + + # An alias to a crate target. # The label of the crate target the + # Aliases are only crate names. # alias refers to. + "alias": "@full//:label", + } + } + ``` + + Args: + all_dependency_maps (list): A list of dicts as described above + + Returns: + dict: A dictionary as described above + """ + dependencies = {} + + for dep_map in all_dependency_maps: + for pkg_name in dep_map: + if pkg_name not in dependencies: + # Add a non-frozen dict to the collection of dependencies + dependencies.setdefault(pkg_name, dict(dep_map[pkg_name].items())) + continue + + duplicate_crate_aliases = [key for key in dependencies[pkg_name] if key in dep_map[pkg_name]] + if duplicate_crate_aliases: + fail("There should be no duplicate crate aliases: {}".format(duplicate_crate_aliases)) + + dependencies[pkg_name].update(dep_map[pkg_name]) + + return dependencies diff --git a/examples/vendored/cargo_workspace/num_printer/BUILD.bazel b/examples/vendored/cargo_workspace/num_printer/BUILD.bazel index e4bb982b4..5fdeb2842 100644 --- a/examples/vendored/cargo_workspace/num_printer/BUILD.bazel +++ b/examples/vendored/cargo_workspace/num_printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_binary( srcs = ["src/main.rs"], edition = "2018", deps = [ - "//vendored/cargo_workspace/num_printer/cargo:clap", "//vendored/cargo_workspace/printer", - ], + ] + all_crate_deps(), ) diff --git a/examples/vendored/cargo_workspace/printer/BUILD.bazel b/examples/vendored/cargo_workspace/printer/BUILD.bazel index 4ad2dbeeb..5914ea71d 100644 --- a/examples/vendored/cargo_workspace/printer/BUILD.bazel +++ b/examples/vendored/cargo_workspace/printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_library( srcs = ["src/lib.rs"], edition = "2018", deps = [ - "//vendored/cargo_workspace/printer/cargo:ferris_says", "//vendored/cargo_workspace/rng", - ], + ] + all_crate_deps(), ) diff --git a/examples/vendored/cargo_workspace/rng/BUILD.bazel b/examples/vendored/cargo_workspace/rng/BUILD.bazel index c8746ff38..126790dda 100644 --- a/examples/vendored/cargo_workspace/rng/BUILD.bazel +++ b/examples/vendored/cargo_workspace/rng/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -6,7 +7,5 @@ rust_library( name = "rng", srcs = ["src/lib.rs"], edition = "2018", - deps = [ - "//vendored/cargo_workspace/rng/cargo:rand", - ], + deps = all_crate_deps(), ) diff --git a/impl/src/bin/cargo-raze.rs b/impl/src/bin/cargo-raze.rs index 0f6cebe1e..3e9ae2593 100644 --- a/impl/src/bin/cargo-raze.rs +++ b/impl/src/bin/cargo-raze.rs @@ -135,6 +135,7 @@ fn main() -> Result<()> { package_aliases_dir: settings.package_aliases_dir, vendored_buildfile_name: settings.output_buildfile_suffix, bazel_root: cargo_raze_working_dir, + experimental_api: settings.experimental_api, }; let bazel_file_outputs = match &settings.genmode { GenMode::Vendored => bazel_renderer.render_planned_build(&render_details, &planned_build)?, diff --git a/impl/src/context.rs b/impl/src/context.rs index fa7edc99c..4e4132dca 100644 --- a/impl/src/context.rs +++ b/impl/src/context.rs @@ -128,6 +128,7 @@ pub struct CrateContext { pub features: Vec, pub workspace_path_to_crate: String, pub workspace_member_dependents: Vec, + pub workspace_member_dev_dependents: Vec, pub is_workspace_member_dependency: bool, pub is_binary_dependency: bool, pub targets: Vec, @@ -147,6 +148,9 @@ pub struct CrateContext { // The name of the main lib target for this crate (if present). // Currently only one such lib can exist per crate. pub lib_target_name: Option, + // This field tracks whether or not the lib target of `lib_target_name` + // is a proc_macro library or not. + pub is_proc_macro: bool, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)] diff --git a/impl/src/planning/subplanners.rs b/impl/src/planning/subplanners.rs index 6228c90a8..3415edf64 100644 --- a/impl/src/planning/subplanners.rs +++ b/impl/src/planning/subplanners.rs @@ -19,7 +19,7 @@ use std::{ str::FromStr, }; -use anyhow::{Context, Result}; +use anyhow::{anyhow, Context, Result}; use cargo_lock::SourceId; use cargo_metadata::{DependencyKind, Node, Package}; use cargo_platform::Platform; @@ -265,9 +265,15 @@ impl<'planner> CrateSubplanner<'planner> { let build_script_target_opt = self.take_build_script_target(&mut targets); let mut lib_target_name = None; + let mut is_proc_macro = false; { for target in &targets { - if target.kind == "lib" || target.kind == "proc-macro" { + if target.kind == "lib" { + lib_target_name = Some(target.name.clone()); + break; + } + if target.kind == "proc-macro" { + is_proc_macro = true; lib_target_name = Some(target.name.clone()); break; } @@ -312,35 +318,53 @@ impl<'planner> CrateSubplanner<'planner> { filtered_deps.sort(); - let workspace_member_dependents: Vec = self - .crate_catalog_entry - .workspace_member_dependents - .iter() - .filter_map(|pkg_id| { - let workspace_member = self - .crate_catalog - .metadata - .packages + let mut workspace_member_dependents: Vec = Vec::new(); + let mut workspace_member_dev_dependents: Vec = Vec::new(); + + for pkg_id in self.crate_catalog_entry.workspace_member_dependents.iter() { + let workspace_member = self + .crate_catalog + .metadata + .packages + .iter() + .find(|pkg| pkg.id == *pkg_id); + + if let Some(member) = workspace_member { + // UNWRAP: This should always return a dependency + let current_dependency = member + .dependencies .iter() - .find(|pkg| pkg.id == *pkg_id); - if let Some(package) = workspace_member { - util::get_workspace_member_path( - &package.manifest_path, - &self.crate_catalog.metadata.workspace_root, - ) - } else { - None + .find(|dep| dep.name == package.name) + .unwrap(); + + let workspace_member_path = util::get_workspace_member_path( + &member.manifest_path, + &self.crate_catalog.metadata.workspace_root, + ) + .ok_or(anyhow!( + "Failed to generate workspace_member_path for {} and {}", + &package.manifest_path.display(), + &self.crate_catalog.metadata.workspace_root.display() + ))?; + + match current_dependency.kind { + DependencyKind::Development => { + workspace_member_dev_dependents.push(workspace_member_path) + }, + DependencyKind::Normal => workspace_member_dependents.push(workspace_member_path), + /* TODO: For now only Development and Normal dependencies are + needed but Build surely has it's use as well */ + _ => {}, } - }) - .collect(); + } + } let is_workspace_member_dependency = !&workspace_member_dependents.is_empty(); let is_binary_dependency = self.settings.binary_deps.contains_key(&package.name); - let raze_settings = self.crate_settings.cloned().unwrap_or_default(); - // Generate canonicalized paths to additional build files so they're guaranteed to exist // and always locatable. + let raze_settings = self.crate_settings.cloned().unwrap_or_default(); let canonical_additional_build_file = match &raze_settings.additional_build_file { Some(build_file) => Some( cargo_workspace_root @@ -362,9 +386,11 @@ impl<'planner> CrateSubplanner<'planner> { edition: package.edition.clone(), license: self.produce_license(), features: self.node.features.clone(), - workspace_member_dependents: workspace_member_dependents, + workspace_member_dependents, + workspace_member_dev_dependents, is_workspace_member_dependency: is_workspace_member_dependency, is_binary_dependency: is_binary_dependency, + is_proc_macro, default_deps: CrateDependencyContext { dependencies: normal_deps, proc_macro_dependencies: proc_macro_deps, @@ -590,7 +616,7 @@ impl<'planner> CrateSubplanner<'planner> { aliased_dep_names: HashMap::new(), }, ); - // This unwrap should be safe given the insert above + // UNWRAP: This unwrap should be safe given the insert above targeted_dep_names.get_mut(&target_str).unwrap() }, }; diff --git a/impl/src/rendering.rs b/impl/src/rendering.rs index abe087bf9..9cec8c9b7 100644 --- a/impl/src/rendering.rs +++ b/impl/src/rendering.rs @@ -48,4 +48,5 @@ pub struct RenderDetails { pub package_aliases_dir: String, pub vendored_buildfile_name: String, pub bazel_root: PathBuf, + pub experimental_api: bool, } diff --git a/impl/src/rendering/bazel.rs b/impl/src/rendering/bazel.rs index f2c3754e9..df1532e52 100644 --- a/impl/src/rendering/bazel.rs +++ b/impl/src/rendering/bazel.rs @@ -13,6 +13,7 @@ // limitations under the License. use anyhow::Result; +use pathdiff::diff_paths; use tera::{self, Context, Tera}; use crate::{ @@ -55,10 +56,19 @@ pub struct BazelRenderer { internal_renderer: Tera, } +/** Generate the expected Bazel package name */ +fn bazel_package_name(render_details: &RenderDetails) -> String { + if let Some(package_name) = diff_paths(&render_details.cargo_root, &render_details.bazel_root) { + package_name.display().to_string().replace("\\", "/") + } else { + "".to_owned() + } +} + impl BazelRenderer { pub fn new() -> Self { // Configure tera with a bogus template dir: We don't want any runtime template support - let mut internal_renderer = Tera::new("src/not/a/dir/*").unwrap(); + let mut internal_renderer = Tera::new("/tmp/cargo-raze/doesnt/exist/*").unwrap(); internal_renderer .add_raw_templates(vec![ ( @@ -73,6 +83,10 @@ impl BazelRenderer { "templates/partials/common_attrs.template", include_str!("templates/partials/common_attrs.template"), ), + ( + "templates/partials/crates_macro.template", + include_str!("templates/partials/crates_macro.template"), + ), ( "templates/partials/header.template", include_str!("templates/partials/header.template"), @@ -163,14 +177,20 @@ impl BazelRenderer { .render("templates/workspace.BUILD.template", &context) } - pub fn render_bzl_fetch( + pub fn render_crates_bzl( &self, workspace_context: &WorkspaceContext, all_packages: &[CrateContext], + bazel_package_name: &str, + is_remote_genmode: bool, + experimental_api: bool, ) -> Result { let mut context = Context::new(); context.insert("workspace", &workspace_context); context.insert("crates", &all_packages); + context.insert("bazel_package_name", &bazel_package_name); + context.insert("is_remote_genmode", &is_remote_genmode); + context.insert("experimental_api", &experimental_api); self .internal_renderer .render("templates/remote_crates.bzl.template", &context) @@ -303,6 +323,40 @@ impl BuildRenderer for BazelRenderer { .as_path() .join(&render_details.path_prefix); + if render_details.experimental_api { + let crates_bzl_file_path = path_prefix.as_path().join("crates.bzl"); + let rendered_crates_bzl_file = self + .render_crates_bzl( + &workspace_context, + &crate_contexts, + &bazel_package_name(render_details), + /*is_remote_genmode=*/ false, + render_details.experimental_api, + ) + .map_err(|e| RazeError::Rendering { + crate_name_opt: None, + message: unwind_tera_error!(e), + })?; + file_outputs.push(FileOutputs { + path: crates_bzl_file_path, + contents: rendered_crates_bzl_file, + }); + + // Ensure there is always a `BUILD.bazel` file to accompany `crates.bzl` + let crates_bzl_pkg_file = path_prefix.as_path().join("BUILD.bazel"); + let outputs_contain_crates_bzl_build_file = file_outputs + .iter() + .any(|output| output.path == crates_bzl_pkg_file); + if !outputs_contain_crates_bzl_build_file { + file_outputs.push(FileOutputs { + path: crates_bzl_pkg_file, + contents: self + .internal_renderer + .render("templates/partials/header.template", &tera::Context::new())?, + }); + } + } + for package in crate_contexts { let rendered_crate_build_file = self @@ -369,16 +423,22 @@ impl BuildRenderer for BazelRenderer { file_outputs.extend(self.render_aliases(planned_build, render_details, true)?); - let bzl_fetch_file_path = path_prefix.as_path().join("crates.bzl"); + let crates_bzl_file_path = path_prefix.as_path().join("crates.bzl"); let rendered_bzl_fetch_file = self - .render_bzl_fetch(&workspace_context, &crate_contexts) + .render_crates_bzl( + &workspace_context, + &crate_contexts, + &bazel_package_name(render_details), + /*is_remote_genmode=*/ true, + render_details.experimental_api, + ) .map_err(|e| RazeError::Rendering { crate_name_opt: None, message: unwind_tera_error!(e), })?; file_outputs.push(FileOutputs { - path: bzl_fetch_file_path, + path: crates_bzl_file_path, contents: rendered_bzl_fetch_file, }); @@ -428,6 +488,7 @@ mod tests { package_aliases_dir: "cargo".to_string(), vendored_buildfile_name: buildfile_suffix.to_owned(), bazel_root: PathBuf::from("/some/bazel/root"), + experimental_api: true, } } @@ -468,8 +529,10 @@ mod tests { }, targeted_deps: Vec::new(), workspace_member_dependents: Vec::new(), + workspace_member_dev_dependents: Vec::new(), is_workspace_member_dependency: false, is_binary_dependency: false, + is_proc_macro: false, workspace_path_to_crate: "@raze__test_binary__1_1_1//".to_owned(), targets: vec![BuildableTarget { name: "some_binary".to_owned(), @@ -514,8 +577,10 @@ mod tests { }, targeted_deps: Vec::new(), workspace_member_dependents: Vec::new(), + workspace_member_dev_dependents: Vec::new(), is_workspace_member_dependency: false, is_binary_dependency: false, + is_proc_macro: false, workspace_path_to_crate: "@raze__test_library__1_1_1//".to_owned(), targets: vec![BuildableTarget { name: "some_library".to_owned(), @@ -577,7 +642,9 @@ mod tests { assert_that!( &file_names, contains(vec![ - "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_string() + "/some/bazel/root/./some_render_prefix/BUILD.bazel".to_owned(), + "/some/bazel/root/./some_render_prefix/crates.bzl".to_owned(), + "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_owned(), ]) .exactly() ); @@ -594,8 +661,10 @@ mod tests { assert_that!( &file_names, contains(vec![ - "/some/bazel/root/./some_render_prefix/vendor/test-library-1.1.1/BUILD".to_string(), - "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_string(), + "/some/bazel/root/./some_render_prefix/BUILD.bazel".to_owned(), + "/some/bazel/root/./some_render_prefix/crates.bzl".to_owned(), + "/some/bazel/root/./some_render_prefix/vendor/test-library-1.1.1/BUILD".to_owned(), + "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_owned(), ]) .exactly() ); @@ -615,8 +684,10 @@ mod tests { assert_that!( &file_names, contains(vec![ - "/some/bazel/root/./some_render_prefix/vendor/test-library-1.1.1/BUILD.bazel".to_string(), - "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_string(), + "/some/bazel/root/./some_render_prefix/BUILD.bazel".to_owned(), + "/some/bazel/root/./some_render_prefix/crates.bzl".to_owned(), + "/some/bazel/root/./some_render_prefix/vendor/test-library-1.1.1/BUILD.bazel".to_owned(), + "/some/cargo/root/some/crate/cargo/BUILD.bazel".to_owned(), ]) .exactly() ); diff --git a/impl/src/rendering/templates/partials/crates_macro.template b/impl/src/rendering/templates/partials/crates_macro.template new file mode 100644 index 000000000..5a9e0e8e0 --- /dev/null +++ b/impl/src/rendering/templates/partials/crates_macro.template @@ -0,0 +1,204 @@ +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dependencies for the Rust targets of that package. +_DEPENDENCIES = { +{%- for workspace_member in workspace.workspace_members %} +{%- if workspace_member %} + "{{ bazel_package_name }}/{{ workspace_member }}": { +{%- else %} + "{{ bazel_package_name }}": { +{%- endif %} +{%- for crate in crates %} +{%- if not crate.is_proc_macro and workspace_member in crate.workspace_member_dependents %} +{%- set crate_name_sanitized = crate.pkg_name | replace(from="-", to="_") %} + "{{ crate.pkg_name }}": "{{ crate.workspace_path_to_crate }}:{{ crate_name_sanitized }}", +{%- endif %} +{%- endfor %} + }, +{%- endfor %} +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dependencies for the Rust targets of that package. +_PROC_MACRO_DEPENDENCIES = { +{%- for workspace_member in workspace.workspace_members %} +{%- if workspace_member %} + "{{ bazel_package_name }}/{{ workspace_member }}": { +{%- else %} + "{{ bazel_package_name }}": { +{%- endif %} +{%- for crate in crates %} +{%- if crate.is_proc_macro and workspace_member in crate.workspace_member_dependents %} +{%- set crate_name_sanitized = crate.pkg_name | replace(from="-", to="_") %} + "{{ crate.pkg_name }}": "{{ crate.workspace_path_to_crate }}:{{ crate_name_sanitized }}", +{%- endif %} +{%- endfor %} + }, +{%- endfor %} +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of normal dev dependencies for the Rust targets of that package. +_DEV_DEPENDENCIES = { +{%- for workspace_member in workspace.workspace_members %} +{%- if workspace_member %} + "{{ bazel_package_name }}/{{ workspace_member }}": { +{%- else %} + "{{ bazel_package_name }}": { +{%- endif %} +{%- for crate in crates %} +{%- if not crate.is_proc_macro and workspace_member in crate.workspace_member_dev_dependents %} +{%- set crate_name_sanitized = crate.pkg_name | replace(from="-", to="_") %} + "{{ crate.pkg_name }}": "{{ crate.workspace_path_to_crate }}:{{ crate_name_sanitized }}", +{%- endif %} +{%- endfor %} + }, +{%- endfor %} +} + +# EXPERIMENTAL -- MAY CHANGE AT ANY TIME: A mapping of package names to a set of proc_macro dev dependencies for the Rust targets of that package. +_DEV_PROC_MACRO_DEPENDENCIES = { +{%- for workspace_member in workspace.workspace_members %} +{%- if workspace_member %} + "{{ bazel_package_name }}/{{ workspace_member }}": { +{%- else %} + "{{ bazel_package_name }}": { +{%- endif %} +{%- for crate in crates %} +{%- if crate.is_proc_macro and workspace_member in crate.workspace_member_dev_dependents %} +{%- set crate_name_sanitized = crate.pkg_name | replace(from="-", to="_") %} + "{{ crate.pkg_name }}": "{{ crate.workspace_path_to_crate }}:{{ crate_name_sanitized }}", +{%- endif %} +{%- endfor %} + }, +{%- endfor %} +} + +def crate_deps(deps, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of the requested crates for the package where this macro is called. + + WARNING: This macro is part of an expeirmental API and is subject to change. + + Args: + deps (list): The desired list of crate targets. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Join both sets of dependencies + dependencies = _flatten_dependency_maps([ + _DEPENDENCIES, + _PROC_MACRO_DEPENDENCIES, + _DEV_DEPENDENCIES, + _DEV_PROC_MACRO_DEPENDENCIES, + ]) + + if not deps: + return [] + + missing_crates = [] + crate_targets = [] + for crate_target in deps: + if crate_target not in dependencies[package_name]: + missing_crates.append(crate_target) + else: + crate_targets.append(dependencies[package_name][crate_target]) + + if missing_crates: + fail("Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`".format( + missing_crates, + package_name, + dependencies[package_name], + )) + + return crate_targets + +def all_crate_deps(normal = False, normal_dev = False, proc_macro = False, proc_macro_dev = False, package_name = None): + """EXPERIMENTAL -- MAY CHANGE AT ANY TIME: Finds the fully qualified label of all requested direct crate dependencies \ + for the package where this macro is called. + + If no parameters are set, all normal dependencies are returned. Setting any one flag will + otherwise impact the contents of the returned list. + + Args: + normal (bool, optional): If True, normal dependencies are included in the + output list. Defaults to False. + normal_dev (bool, optional): If True, normla dev dependencies will be + included in the output list. Defaults to False. + proc_macro (bool, optional): If True, proc_macro dependencies are included + in the output list. Defaults to False. + proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are + included in the output list. Defaults to False. + package_name (str, optional): The package name of the set of dependencies to look up. + Defaults to `native.package_name()`. + + Returns: + list: A list of labels to cargo-raze generated targets (str) + """ + + if not package_name: + package_name = native.package_name() + + # Determine the relevant maps to use + all_dependency_maps = [] + if normal: + all_dependency_maps.append(_DEPENDENCIES) + if normal_dev: + all_dependency_maps.append(_DEV_DEPENDENCIES) + if proc_macro: + all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES) + if proc_macro_dev: + all_dependency_maps.append(_DEV_PROC_MACRO_DEPENDENCIES) + + # Default to always using normal dependencies + if not all_dependency_maps: + all_dependency_maps.append(_DEPENDENCIES) + + dependencies = _flatten_dependency_maps(all_dependency_maps) + + if not dependencies: + return [] + + return dependencies[package_name].values() + +def _flatten_dependency_maps(all_dependency_maps): + """Flatten a list of dependency maps into one dictionary. + + Dependency maps have the following structure: + + ```python + DEPENDENCIES_MAP = { + # The first key in the map is a Bazel package + # name of the workspace this file is defined in. + "package_name": { + + # An alias to a crate target. # The label of the crate target the + # Aliases are only crate names. # alias refers to. + "alias": "@full//:label", + } + } + ``` + + Args: + all_dependency_maps (list): A list of dicts as described above + + Returns: + dict: A dictionary as described above + """ + dependencies = {} + + for dep_map in all_dependency_maps: + for pkg_name in dep_map: + if pkg_name not in dependencies: + # Add a non-frozen dict to the collection of dependencies + dependencies.setdefault(pkg_name, dict(dep_map[pkg_name].items())) + continue + + duplicate_crate_aliases = [key for key in dependencies[pkg_name] if key in dep_map[pkg_name]] + if duplicate_crate_aliases: + fail("There should be no duplicate crate aliases: {}".format(duplicate_crate_aliases)) + + dependencies[pkg_name].update(dep_map[pkg_name]) + + return dependencies \ No newline at end of file diff --git a/impl/src/rendering/templates/remote_crates.bzl.template b/impl/src/rendering/templates/remote_crates.bzl.template index 06f3861ed..884893f09 100644 --- a/impl/src/rendering/templates/remote_crates.bzl.template +++ b/impl/src/rendering/templates/remote_crates.bzl.template @@ -1,8 +1,11 @@ {%- include "templates/partials/header.template" %} +{%- if is_remote_genmode %} load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") # buildifier: disable=load load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") # buildifier: disable=load load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") # buildifier: disable=load - +{% if experimental_api %} +{% include "templates/partials/crates_macro.template" %} +{% endif %} def {{workspace.gen_workspace_prefix}}_fetch_remote_crates(): {%- if crates %} """This function defines a collection of repos and should be called in a WORKSPACE file""" @@ -35,4 +38,7 @@ def {{workspace.gen_workspace_prefix}}_fetch_remote_crates(): {%- else %} """No crates were detected in the source Cargo.toml. This is a no-op""" pass -{% endif -%} \ No newline at end of file +{% endif %} +{%- else %} +{% include "templates/partials/crates_macro.template" %} +{% endif %} \ No newline at end of file diff --git a/impl/src/settings.rs b/impl/src/settings.rs index 1c2223537..cb616f9aa 100644 --- a/impl/src/settings.rs +++ b/impl/src/settings.rs @@ -136,6 +136,13 @@ pub struct RazeSettings { */ #[serde(default = "default_raze_settings_vendor_dir")] pub vendor_dir: String, + + /** + * If true, an experimetnal API for accessing crates will be rendered into + * `crates.bzl` for both Remote and Vendored genmodes. + */ + #[serde(default = "default_raze_settings_experimental_api")] + pub experimental_api: bool, } /** Override settings for individual crates (as part of `RazeSettings`). */ @@ -346,6 +353,10 @@ fn default_raze_settings_vendor_dir() -> String { "vendor".to_owned() } +fn default_raze_settings_experimental_api() -> bool { + false +} + fn default_crate_settings_field_gen_buildrs() -> Option { None } @@ -497,6 +508,8 @@ struct RawRazeSettings { pub rust_rules_workspace_name: Option, #[serde(default)] pub vendor_dir: Option, + #[serde(default)] + pub experimental_api: Option } impl RawRazeSettings { @@ -514,6 +527,7 @@ impl RawRazeSettings { || self.index_url.is_some() || self.rust_rules_workspace_name.is_some() || self.vendor_dir.is_some() + || self.experimental_api.is_some() } fn print_notices_and_warnings(&self) { @@ -822,6 +836,7 @@ pub mod tests { index_url: default_raze_settings_index_url(), rust_rules_workspace_name: default_raze_settings_rust_rules_workspace_name(), vendor_dir: default_raze_settings_vendor_dir(), + experimental_api: default_raze_settings_experimental_api(), } } diff --git a/smoke_test/remote/binary_dependencies/BUILD.bazel b/smoke_test/remote/binary_dependencies/BUILD.bazel index 752bc5653..ad45cbf10 100644 --- a/smoke_test/remote/binary_dependencies/BUILD.bazel +++ b/smoke_test/remote/binary_dependencies/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//remote/binary_dependencies/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -8,7 +9,5 @@ rust_binary( data = [ "//remote/binary_dependencies/cargo:cargo_bin_texture_synthesis", ], - deps = [ - "//remote/binary_dependencies/cargo:ferris_says", - ], + deps = all_crate_deps(), ) diff --git a/smoke_test/remote/binary_dependencies/Cargo.toml b/smoke_test/remote/binary_dependencies/Cargo.toml index 83be18f2a..cf53ba734 100644 --- a/smoke_test/remote/binary_dependencies/Cargo.toml +++ b/smoke_test/remote/binary_dependencies/Cargo.toml @@ -16,6 +16,7 @@ gen_workspace_prefix = "remote_binary_dependencies" genmode = "Remote" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true [package.metadata.raze.binary_deps] texture-synthesis-cli = "0.8.0" diff --git a/smoke_test/remote/cargo_workspace/Cargo.toml b/smoke_test/remote/cargo_workspace/Cargo.toml index 097d943c4..76984ed7b 100644 --- a/smoke_test/remote/cargo_workspace/Cargo.toml +++ b/smoke_test/remote/cargo_workspace/Cargo.toml @@ -11,3 +11,4 @@ gen_workspace_prefix = "remote_cargo_workspace" genmode = "Remote" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true diff --git a/smoke_test/remote/cargo_workspace/num_printer/BUILD.bazel b/smoke_test/remote/cargo_workspace/num_printer/BUILD.bazel index 3bb84ecf1..594b75725 100644 --- a/smoke_test/remote/cargo_workspace/num_printer/BUILD.bazel +++ b/smoke_test/remote/cargo_workspace/num_printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//remote/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_binary( srcs = ["src/main.rs"], edition = "2018", deps = [ - "//remote/cargo_workspace/num_printer/cargo:clap", "//remote/cargo_workspace/printer", - ], + ] + all_crate_deps(), ) diff --git a/smoke_test/remote/cargo_workspace/printer/BUILD.bazel b/smoke_test/remote/cargo_workspace/printer/BUILD.bazel index 577522f78..ca64bede4 100644 --- a/smoke_test/remote/cargo_workspace/printer/BUILD.bazel +++ b/smoke_test/remote/cargo_workspace/printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//remote/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_library( srcs = ["src/lib.rs"], edition = "2018", deps = [ - "//remote/cargo_workspace/printer/cargo:ferris_says", "//remote/cargo_workspace/rng", - ], + ] + all_crate_deps(), ) diff --git a/smoke_test/remote/cargo_workspace/rng/BUILD.bazel b/smoke_test/remote/cargo_workspace/rng/BUILD.bazel index cac2e8ed4..5c31664fc 100644 --- a/smoke_test/remote/cargo_workspace/rng/BUILD.bazel +++ b/smoke_test/remote/cargo_workspace/rng/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//remote/cargo_workspace/cargo:crates.bzl", "crate_deps") package(default_visibility = ["//visibility:public"]) @@ -6,7 +7,7 @@ rust_library( name = "rng", srcs = ["src/lib.rs"], edition = "2018", - deps = [ - "//remote/cargo_workspace/rng/cargo:rand", - ], + deps = crate_deps([ + "rand", + ]), ) diff --git a/smoke_test/vendored/cargo_workspace/Cargo.toml b/smoke_test/vendored/cargo_workspace/Cargo.toml index 575276a17..ea5db053a 100644 --- a/smoke_test/vendored/cargo_workspace/Cargo.toml +++ b/smoke_test/vendored/cargo_workspace/Cargo.toml @@ -11,3 +11,5 @@ gen_workspace_prefix = "vendored_cargo_workspace" genmode = "Vendored" default_gen_buildrs = true package_aliases_dir = "cargo" +experimental_api = true + diff --git a/smoke_test/vendored/cargo_workspace/num_printer/BUILD.bazel b/smoke_test/vendored/cargo_workspace/num_printer/BUILD.bazel index e4bb982b4..5fdeb2842 100644 --- a/smoke_test/vendored/cargo_workspace/num_printer/BUILD.bazel +++ b/smoke_test/vendored/cargo_workspace/num_printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_binary( srcs = ["src/main.rs"], edition = "2018", deps = [ - "//vendored/cargo_workspace/num_printer/cargo:clap", "//vendored/cargo_workspace/printer", - ], + ] + all_crate_deps(), ) diff --git a/smoke_test/vendored/cargo_workspace/printer/BUILD.bazel b/smoke_test/vendored/cargo_workspace/printer/BUILD.bazel index 4ad2dbeeb..5914ea71d 100644 --- a/smoke_test/vendored/cargo_workspace/printer/BUILD.bazel +++ b/smoke_test/vendored/cargo_workspace/printer/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -7,7 +8,6 @@ rust_library( srcs = ["src/lib.rs"], edition = "2018", deps = [ - "//vendored/cargo_workspace/printer/cargo:ferris_says", "//vendored/cargo_workspace/rng", - ], + ] + all_crate_deps(), ) diff --git a/smoke_test/vendored/cargo_workspace/rng/BUILD.bazel b/smoke_test/vendored/cargo_workspace/rng/BUILD.bazel index c8746ff38..126790dda 100644 --- a/smoke_test/vendored/cargo_workspace/rng/BUILD.bazel +++ b/smoke_test/vendored/cargo_workspace/rng/BUILD.bazel @@ -1,4 +1,5 @@ load("@io_bazel_rules_rust//rust:rust.bzl", "rust_library") +load("//vendored/cargo_workspace/cargo:crates.bzl", "all_crate_deps") package(default_visibility = ["//visibility:public"]) @@ -6,7 +7,5 @@ rust_library( name = "rng", srcs = ["src/lib.rs"], edition = "2018", - deps = [ - "//vendored/cargo_workspace/rng/cargo:rand", - ], + deps = all_crate_deps(), )