Fixed use of rust-analyzer with rust_static_library and rust_shared_library (#1482)
diff --git a/examples/WORKSPACE.bazel b/examples/WORKSPACE.bazel
index 005d052..ad29a83 100644
--- a/examples/WORKSPACE.bazel
+++ b/examples/WORKSPACE.bazel
@@ -16,6 +16,10 @@
edition = "2018",
)
+load("@rules_rust//tools/rust_analyzer:deps.bzl", "rust_analyzer_dependencies")
+
+rust_analyzer_dependencies()
+
load("@rules_rust//bindgen:repositories.bzl", "rust_bindgen_dependencies", "rust_bindgen_register_toolchains")
rust_bindgen_dependencies()
diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl
index 8408197..48582b3 100644
--- a/rust/private/rust_analyzer.bzl
+++ b/rust/private/rust_analyzer.bzl
@@ -39,7 +39,7 @@
)
def _rust_analyzer_aspect_impl(target, ctx):
- if rust_common.crate_info not in target:
+ if rust_common.crate_info not in target and rust_common.test_crate_info not in target:
return []
toolchain = find_toolchain(ctx)
@@ -70,7 +70,12 @@
crate_spec = ctx.actions.declare_file(ctx.label.name + ".rust_analyzer_crate_spec")
- crate_info = target[rust_common.crate_info]
+ if rust_common.crate_info in target:
+ crate_info = target[rust_common.crate_info]
+ elif rust_common.test_crate_info in target:
+ crate_info = target[rust_common.test_crate_info].crate
+ else:
+ fail("Unexpected target type: {}".format(target))
rust_analyzer_info = RustAnalyzerInfo(
crate = crate_info,
@@ -101,7 +106,14 @@
Returns:
(path): The path to the proc macro dylib, or None if this crate is not a proc-macro.
"""
- if target[rust_common.crate_info].type != "proc-macro":
+ if rust_common.crate_info in target:
+ crate_info = target[rust_common.crate_info]
+ elif rust_common.test_crate_info in target:
+ crate_info = target[rust_common.test_crate_info].crate
+ else:
+ return None
+
+ if crate_info.type != "proc-macro":
return None
dylib_ext = system_to_dylib_ext(triple_to_system(toolchain.target_triple))
diff --git a/test/rust_analyzer/rust_analyzer_test_runner.sh b/test/rust_analyzer/rust_analyzer_test_runner.sh
index 781fd34..1696506 100755
--- a/test/rust_analyzer/rust_analyzer_test_runner.sh
+++ b/test/rust_analyzer/rust_analyzer_test_runner.sh
@@ -21,7 +21,7 @@
local new_workspace="${temp_dir}/rules_rust_test_rust_analyzer"
mkdir -p "${new_workspace}"
- cat << EOF > "${new_workspace}/WORKSPACE.bazel"
+ cat <<EOF >"${new_workspace}/WORKSPACE.bazel"
workspace(name = "rules_rust_test_rust_analyzer")
local_repository(
name = "rules_rust",
@@ -33,7 +33,7 @@
rust_analyzer_dependencies()
EOF
-cat << EOF > "${new_workspace}/.bazelrc"
+ cat <<EOF >"${new_workspace}/.bazelrc"
build --keep_going
test --test_output=errors
# The 'strict' config is used to ensure extra checks are run on the test
@@ -45,17 +45,18 @@
build:strict --output_groups=+clippy_checks
EOF
- echo "${new_workspace}"
+ echo "${new_workspace}"
}
function rust_analyzer_test() {
local source_dir="$1"
local workspace="$2"
-
+ local generator_arg="$3"
+
echo "Testing '$(basename "${source_dir}")'"
- rm -f "${workspace}"/*.rs "${workspace}"/*.json "${workspace}/BUILD.bazel"
+ rm -f "${workspace}"/*.rs "${workspace}"/*.json "${workspace}"/*.bzl "${workspace}/BUILD.bazel" "${workspace}/BUILD.bazel-e"
cp -r "${source_dir}"/* "${workspace}"
-
+
# Drop the 'manual' tags
if [ "$(uname)" == "Darwin" ]; then
SEDOPTS=(-i '' -e)
@@ -63,17 +64,29 @@
SEDOPTS=(-i)
fi
sed ${SEDOPTS[@]} 's/"manual"//' "${workspace}/BUILD.bazel"
-
- pushd "${workspace}" &> /dev/null
+
+ pushd "${workspace}" &>/dev/null
echo "Generating rust-project.json..."
- bazel run "@rules_rust//tools/rust_analyzer:gen_rust_project" -- //:mylib_test
+ if [[ -n "${generator_arg}" ]]; then
+ bazel run "@rules_rust//tools/rust_analyzer:gen_rust_project" -- "${generator_arg}"
+ else
+ bazel run "@rules_rust//tools/rust_analyzer:gen_rust_project"
+ fi
echo "Building..."
bazel build //...
echo "Testing..."
bazel test //...
echo "Building with Aspects..."
bazel build //... --config=strict
- popd &> /dev/null
+ popd &>/dev/null
+}
+
+function cleanup() {
+ local workspace="$1"
+ pushd "${workspace}" &>/dev/null
+ bazel clean --async
+ popd &>/dev/null
+ rm -rf "${workspace}"
}
function run_test_suite() {
@@ -86,10 +99,20 @@
continue
fi
- rust_analyzer_test "${test_dir}" "${temp_workspace}"
+ # Some tests have arguments that need to be passed to the rust-project.json generator.
+ if [[ "${test_dir}" = "aspect_traversal_test" ]]; then
+ test_arg="//mylib_test"
+ elif [[ "${test_dir}" = "merging_crates_test" ]]; then
+ test_arg="//mylib_test"
+ else
+ test_arg=""
+ fi
+
+ rust_analyzer_test "${test_dir}" "${temp_workspace}" "${test_arg}"
done
- rm -rf "${temp_workspace}"
+ echo "Done"
+ cleanup "${temp_workspace}"
}
run_test_suite
diff --git a/test/rust_analyzer/static_and_shared_lib_test/BUILD.bazel b/test/rust_analyzer/static_and_shared_lib_test/BUILD.bazel
new file mode 100644
index 0000000..7efd036
--- /dev/null
+++ b/test/rust_analyzer/static_and_shared_lib_test/BUILD.bazel
@@ -0,0 +1,38 @@
+load(
+ "@rules_rust//rust:defs.bzl",
+ "rust_shared_library",
+ "rust_static_library",
+ "rust_test",
+)
+
+rust_shared_library(
+ name = "greeter_cdylib",
+ srcs = [
+ "greeter.rs",
+ "shared_lib.rs",
+ ],
+ crate_root = "shared_lib.rs",
+ edition = "2018",
+)
+
+rust_static_library(
+ name = "greeter_staticlib",
+ srcs = [
+ "greeter.rs",
+ "static_lib.rs",
+ ],
+ crate_root = "static_lib.rs",
+ edition = "2018",
+)
+
+rust_test(
+ name = "rust_project_json_test",
+ srcs = ["rust_project_json_test.rs"],
+ data = [":rust-project.json"],
+ edition = "2018",
+ env = {"RUST_PROJECT_JSON": "$(rootpath :rust-project.json)"},
+ # This target is tagged as manual since it's not expected to pass in
+ # contexts outside of `//test/rust_analyzer:rust_analyzer_test`. Run
+ # that target to execute this test.
+ tags = ["manual"],
+)
diff --git a/test/rust_analyzer/static_and_shared_lib_test/greeter.rs b/test/rust_analyzer/static_and_shared_lib_test/greeter.rs
new file mode 100644
index 0000000..ac87521
--- /dev/null
+++ b/test/rust_analyzer/static_and_shared_lib_test/greeter.rs
@@ -0,0 +1,61 @@
+/// Object that displays a greeting.
+pub struct Greeter {
+ greeting: String,
+}
+
+/// Implementation of Greeter.
+impl Greeter {
+ /// Constructs a new `Greeter`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter::Greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// ```
+ pub fn new(greeting: &str) -> Greeter {
+ Greeter {
+ greeting: greeting.to_string(),
+ }
+ }
+
+ /// Returns the greeting as a string.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter::Greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// let greeting = greeter.greeting("World");
+ /// ```
+ pub fn greeting(&self, thing: &str) -> String {
+ format!("{} {}", &self.greeting, thing)
+ }
+
+ /// Prints the greeting.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use hello_lib::greeter::Greeter;
+ ///
+ /// let greeter = Greeter::new("Hello");
+ /// greeter.greet("World");
+ /// ```
+ pub fn greet(&self, thing: &str) {
+ println!("{} {}", &self.greeting, thing);
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::Greeter;
+
+ #[test]
+ fn test_greeting() {
+ let hello = Greeter::new("Hi");
+ assert_eq!("Hi Rust", hello.greeting("Rust"));
+ }
+}
diff --git a/test/rust_analyzer/static_and_shared_lib_test/rust_project_json_test.rs b/test/rust_analyzer/static_and_shared_lib_test/rust_project_json_test.rs
new file mode 100644
index 0000000..fc573d6
--- /dev/null
+++ b/test/rust_analyzer/static_and_shared_lib_test/rust_project_json_test.rs
@@ -0,0 +1,22 @@
+#[cfg(test)]
+mod tests {
+ use std::env;
+ use std::path::PathBuf;
+
+ #[test]
+ fn test_deps_of_crate_and_its_test_are_merged() {
+ let rust_project_path = PathBuf::from(env::var("RUST_PROJECT_JSON").unwrap());
+
+ let content = std::fs::read_to_string(&rust_project_path)
+ .unwrap_or_else(|_| panic!("couldn't open {:?}", &rust_project_path));
+
+ assert!(
+ content.contains(r#"{"display_name":"greeter_cdylib","root_module":"shared_lib.rs"#),
+ "expected rust-project.json to contain a rust_shared_library target."
+ );
+ assert!(
+ content.contains(r#"{"display_name":"greeter_staticlib","root_module":"static_lib.rs"#),
+ "expected rust-project.json to contain a rust_static_library target."
+ );
+ }
+}
diff --git a/test/rust_analyzer/static_and_shared_lib_test/shared_lib.rs b/test/rust_analyzer/static_and_shared_lib_test/shared_lib.rs
new file mode 100644
index 0000000..44969c6
--- /dev/null
+++ b/test/rust_analyzer/static_and_shared_lib_test/shared_lib.rs
@@ -0,0 +1 @@
+pub mod greeter;
diff --git a/test/rust_analyzer/static_and_shared_lib_test/static_lib.rs b/test/rust_analyzer/static_and_shared_lib_test/static_lib.rs
new file mode 100644
index 0000000..44969c6
--- /dev/null
+++ b/test/rust_analyzer/static_and_shared_lib_test/static_lib.rs
@@ -0,0 +1 @@
+pub mod greeter;