Skip to content

Commit

Permalink
Fixed use of rust-analyzer with rust_static_library and rust_shared_l…
Browse files Browse the repository at this point in the history
…ibrary (#1482)
  • Loading branch information
UebelAndre authored Jul 26, 2022
1 parent 2d7f945 commit 685dfda
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 15 deletions.
4 changes: 4 additions & 0 deletions examples/WORKSPACE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ rust_register_toolchains(
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()
Expand Down
18 changes: 15 additions & 3 deletions rust/private/rust_analyzer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ RustAnalyzerInfo = provider(
)

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)
Expand Down Expand Up @@ -70,7 +70,12 @@ def _rust_analyzer_aspect_impl(target, ctx):

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,
Expand Down Expand Up @@ -101,7 +106,14 @@ def find_proc_macro_dylib_path(toolchain, target):
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))
Expand Down
47 changes: 35 additions & 12 deletions test/rust_analyzer/rust_analyzer_test_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function generate_workspace() {
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",
Expand All @@ -33,7 +33,7 @@ load("@rules_rust//tools/rust_analyzer:deps.bzl", "rust_analyzer_dependencies")
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
Expand All @@ -45,35 +45,48 @@ build:strict --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect
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)
else
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() {
Expand All @@ -86,10 +99,20 @@ function run_test_suite() {
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
38 changes: 38 additions & 0 deletions test/rust_analyzer/static_and_shared_lib_test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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"],
)
61 changes: 61 additions & 0 deletions test/rust_analyzer/static_and_shared_lib_test/greeter.rs
Original file line number Diff line number Diff line change
@@ -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"));
}
}
Original file line number Diff line number Diff line change
@@ -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."
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod greeter;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod greeter;

0 comments on commit 685dfda

Please sign in to comment.