From aa4ec3bc4040bc49db56a7fc62008a1a9e4ed0a5 Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Wed, 14 Oct 2020 10:22:06 -0700 Subject: [PATCH] Moved utility functions out of `bazel` and into `util` (#248) --- impl/src/bazel.rs | 329 +------------------------------------ impl/src/bin/cargo-raze.rs | 6 +- impl/src/planning.rs | 60 ++++--- impl/src/util.rs | 317 ++++++++++++++++++++++++++++++++++- 4 files changed, 352 insertions(+), 360 deletions(-) diff --git a/impl/src/bazel.rs b/impl/src/bazel.rs index 88db8773f..76427a3e7 100644 --- a/impl/src/bazel.rs +++ b/impl/src/bazel.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use anyhow::{anyhow, Result}; +use anyhow::Result; use tera::{self, Context, Tera}; @@ -23,208 +23,7 @@ use crate::{ util::RazeError, }; -use std::{env, error::Error, iter::Iterator, path::PathBuf}; - -use cfg_expr::{targets::get_builtin_target_by_triple, Expression, Predicate}; - -static SUPPORTED_PLATFORM_TRIPLES: &'static [&'static str] = &[ - // SUPPORTED_T1_PLATFORM_TRIPLES - "i686-apple-darwin", - "i686-pc-windows-gnu", - "i686-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-pc-windows-gnu", - "x86_64-unknown-linux-gnu", - // SUPPORTED_T2_PLATFORM_TRIPLES - "aarch64-apple-ios", - "aarch64-linux-android", - "aarch64-unknown-linux-gnu", - "arm-unknown-linux-gnueabi", - "i686-linux-android", - "i686-unknown-freebsd", - "powerpc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "wasm32-unknown-unknown", - "x86_64-apple-ios", - "x86_64-linux-android", - "x86_64-unknown-freebsd", -]; - -/** Determines if the target matches those supported by and defined in rules_rust - * - * Examples can be seen below: - * - * | target | returns | reason | - * | ------------------------------------- | ---------------- | ------------------------------------------------ | - * | `cfg(not(fuchsia))` | `(true, true)` | `fuchsia` would be considered a 'default' | - * | | | dependency since no supported target maps to it. | - * | | | | - * | `cfg(unix)` | `(true, false)` | There are supported platforms from the `unix` | - * | | | `target_family` but not all platforms are of | - * | | | the `unix` family. | - * | | | | - * | `cfg(not(windows))` | `(true, false)` | There are supported platforms in addition to | - * | | | those in the `windows` `target_family` | - * | | | | - * | `x86_64-apple-darwin` | `(true, false)` | This is a supported target triple but obviously | - * | | | won't match with other triples. | - * | | | | - * | `unknown-unknown-unknown` | `(false, false)` | This will not match any triple. | - * | | | | - * | `cfg(foo)` | `(false, false)` | `foo` is not a strongly defined cfg value. | - * | `cfg(target_os = "redox")` | `(false, false)` | `redox` is not a supported platform. | - */ -pub fn is_bazel_supported_platform(target: &str) -> (bool, bool) { - // Ensure the target is represented as an expression - let target_exp = match target.starts_with("cfg(") { - true => target.to_owned(), - false => format!("cfg(target = \"{}\")", target), - }; - - let expression = match Expression::parse(&target_exp) { - Ok(exp) => exp, - // If the target expression cannot be parsed it is not considered a Bazel platform - Err(_) => { - return (false, false); - }, - }; - - let mut is_supported = false; - let mut matches_all = true; - - // Attempt to match the expression - for target_info in SUPPORTED_PLATFORM_TRIPLES - .iter() - .map(|x| get_builtin_target_by_triple(x).unwrap()) - { - if expression.eval(|pred| { - match pred { - Predicate::Target(tp) => tp.matches(target_info), - Predicate::KeyValue { - key, - val, - } => (*key == "target") && (*val == target_info.triple), - // For now there is no other kind of matching - _ => false, - } - }) { - is_supported = true; - } else { - matches_all = false; - } - } - - (is_supported, matches_all) -} - -/** Maps a Rust cfg or triple target to Bazel supported triples. - * - * Note, the Bazel triples must be defined in: - * https://github.com/bazelbuild/rules_rust/blob/master/rust/platform/platform.bzl - */ -pub fn get_matching_bazel_triples(target: &str) -> Result> { - let target_exp = match target.starts_with("cfg(") { - true => target.to_owned(), - false => format!("cfg(target = \"{}\")", target), - }; - - let expression = Expression::parse(&target_exp)?; - let triples: Vec = SUPPORTED_PLATFORM_TRIPLES - .iter() - .filter_map(|triple| { - let target_info = get_builtin_target_by_triple(triple).unwrap(); - match expression.eval(|pred| { - match pred { - Predicate::Target(tp) => tp.matches(target_info), - Predicate::KeyValue { - key, - val, - } => (*key == "target") && (*val == target_info.triple), - // For now there is no other kind of matching - _ => false, - } - }) { - true => Some(String::from((*target_info).triple)), - false => None, - } - }) - .collect(); - - Ok(triples) -} - -/** Produces a list of triples based on a provided whitelist */ -pub fn filter_bazel_triples(triples: &mut Vec, triples_whitelist: &Vec) { - // Early-out if the filter list is empty - if triples_whitelist.len() == 0 { - return; - } - - // Prune everything that's not found in the whitelist - triples.retain(|triple| triples_whitelist.iter().any(|i| i == triple)); - - triples.sort(); -} - -/** Returns a list of Bazel targets for use in `select` statements based on a - * given list of triples. - */ -pub fn generate_bazel_conditions(triples: &Vec) -> Result> { - // Sanity check ensuring all strings represent real triples - for triple in triples.iter() { - match get_builtin_target_by_triple(triple) { - None => { - return Err(anyhow!("Not a triple: '{}'", triple)); - }, - _ => {}, - } - } - - let mut bazel_triples: Vec = triples - .iter() - .map(|triple| format!("@io_bazel_rules_rust//rust/platform:{}", triple)) - .collect(); - - bazel_triples.sort(); - - Ok(bazel_triples) -} - -/** Returns whether or not the given path is a Bazel workspace root */ -pub fn is_workspace_root(dir: &PathBuf) -> bool { - let workspace_files = [dir.join("WORKSPACE.bazel"), dir.join("WORKSPACE")]; - - for workspace in workspace_files.iter() { - if workspace.exists() { - return true; - } - } - - return false; -} - -/** Returns a path to a Bazel workspace root based on the current working - * directory, otherwise None if not workspace is detected. - */ -pub fn find_workspace_root() -> Option { - let mut dir = match env::current_dir() { - Ok(result) => Some(result), - Err(_) => None, - }; - - while let Some(current_dir) = dir { - if is_workspace_root(¤t_dir) { - return Some(current_dir); - } - - dir = match current_dir.parent() { - Some(parent) => Some(parent.to_path_buf()), - None => None, - }; - } - - return None; -} +use std::error::Error; #[derive(Default)] pub struct BazelRenderer { @@ -412,9 +211,7 @@ impl BuildRenderer for BazelRenderer { include_additional_build_file(package, rendered_crate_build_file)?; file_outputs.push(FileOutputs { - path: path_prefix - .as_path() - .join(&package.expected_build_path), + path: path_prefix.as_path().join(&package.expected_build_path), contents: final_crate_build_file, }) } @@ -453,10 +250,7 @@ impl BuildRenderer for BazelRenderer { // N.B. File needs to exist so that contained xyz-1.2.3.BUILD can be referenced file_outputs.push(FileOutputs { - path: path_prefix - .as_path() - .join("remote") - .join(buildfile_suffix), + path: path_prefix.as_path().join("remote").join(buildfile_suffix), contents: String::new(), }); @@ -472,9 +266,7 @@ impl BuildRenderer for BazelRenderer { include_additional_build_file(package, rendered_crate_build_file)?; file_outputs.push(FileOutputs { - path: path_prefix - .as_path() - .join(&package.expected_build_path), + path: path_prefix.as_path().join(&package.expected_build_path), contents: final_crate_build_file, }) } @@ -537,9 +329,7 @@ mod tests { use super::*; - use std::{collections::HashMap, fs::File}; - - use tempfile::TempDir; + use std::{collections::HashMap, path::PathBuf}; fn dummy_render_details(buildfile_suffix: &str) -> RenderDetails { RenderDetails { @@ -862,111 +652,4 @@ mod tests { && file_output.contents == "World".to_string() })) } - - #[test] - fn detecting_workspace_root() { - // Cache the cwd - let cwd = env::current_dir().unwrap(); - - // Run test - let result = std::panic::catch_unwind(|| { - // Generate a temporary directory to do testing in - let bazel_root = TempDir::new().unwrap(); - assert!(env::set_current_dir(&bazel_root).is_ok()); - - // Starting within the temp directory, we'll find that there are no WORKSPACE.bazel files - // and thus return None to indicate a Bazel workspace root could not be found. - assert_eq!(find_workspace_root(), None); - - // After creating a WORKSPACE.bazel file in that directory, we expect to find to be - // returned a path to the temporary directory - File::create(bazel_root.path().join("WORKSPACE.bazel")).unwrap(); - assert_eq!( - find_workspace_root().unwrap().canonicalize().unwrap(), - bazel_root.into_path().canonicalize().unwrap() - ); - }); - - // Restore cwd - assert!(env::set_current_dir(&cwd).is_ok()); - - // Ensure test results were successful - assert!(result.is_ok()); - } - - #[test] - fn detect_bazel_platforms() { - assert_eq!( - is_bazel_supported_platform("cfg(not(fuchsia))"), - (true, true) - ); - assert_eq!( - is_bazel_supported_platform("cfg(not(target_os = \"redox\"))"), - (true, true) - ); - assert_eq!(is_bazel_supported_platform("cfg(unix)"), (true, false)); - assert_eq!( - is_bazel_supported_platform("cfg(not(windows))"), - (true, false) - ); - assert_eq!( - is_bazel_supported_platform("cfg(target = \"x86_64-apple-darwin\")"), - (true, false) - ); - assert_eq!( - is_bazel_supported_platform("x86_64-apple-darwin"), - (true, false) - ); - assert_eq!( - is_bazel_supported_platform("unknown-unknown-unknown"), - (false, false) - ); - assert_eq!(is_bazel_supported_platform("cfg(foo)"), (false, false)); - assert_eq!( - is_bazel_supported_platform("cfg(target_os = \"redox\")"), - (false, false) - ); - } - - #[test] - fn all_supported_platform_triples_unwrap() { - for triple in SUPPORTED_PLATFORM_TRIPLES.iter() { - get_builtin_target_by_triple(triple).unwrap(); - } - } - - #[test] - fn generate_condition_strings() { - assert_eq!( - generate_bazel_conditions(&vec![ - "aarch64-unknown-linux-gnu".to_string(), - "aarch64-apple-ios".to_string(), - ]) - .unwrap(), - vec![ - "@io_bazel_rules_rust//rust/platform:aarch64-apple-ios", - "@io_bazel_rules_rust//rust/platform:aarch64-unknown-linux-gnu", - ] - ); - - assert_eq!( - generate_bazel_conditions(&vec!["aarch64-unknown-linux-gnu".to_string()]).unwrap(), - vec!["@io_bazel_rules_rust//rust/platform:aarch64-unknown-linux-gnu"] - ); - - assert!(generate_bazel_conditions(&vec![ - "aarch64-unknown-linux-gnu".to_string(), - "unknown-unknown-unknown".to_string(), - ]) - .is_err()); - - assert!(generate_bazel_conditions(&vec!["unknown-unknown-unknown".to_string()]).is_err()); - - assert!(generate_bazel_conditions(&vec![ - "foo".to_string(), - "bar".to_string(), - "baz".to_string() - ]) - .is_err()); - } } diff --git a/impl/src/bin/cargo-raze.rs b/impl/src/bin/cargo-raze.rs index 6b7deae7b..14334fdf8 100644 --- a/impl/src/bin/cargo-raze.rs +++ b/impl/src/bin/cargo-raze.rs @@ -23,12 +23,12 @@ use anyhow::Result; use docopt::Docopt; use cargo_raze::{ - bazel::{find_workspace_root, BazelRenderer}, + bazel::BazelRenderer, metadata::{CargoMetadataFetcher, CargoWorkspaceFiles, MetadataFetcher}, planning::{BuildPlanner, BuildPlannerImpl}, rendering::{BuildRenderer, FileOutputs, RenderDetails}, settings::{load_settings, GenMode}, - util::PlatformDetails, + util::{find_bazel_workspace_root, PlatformDetails}, }; use serde::Deserialize; @@ -174,7 +174,7 @@ fn calculate_workspace_root( }, None => { if new_behavior { - if let Some(workspace_root) = find_workspace_root() { + if let Some(workspace_root) = find_bazel_workspace_root() { prefix_path.clear(); prefix_path.push(workspace_root); prefix_path.push( diff --git a/impl/src/planning.rs b/impl/src/planning.rs index 61ae968fc..7f90d03bd 100644 --- a/impl/src/planning.rs +++ b/impl/src/planning.rs @@ -21,17 +21,13 @@ use std::{ use anyhow::{anyhow, Result}; -use cargo_lock::{SourceId, Version, lockfile::Lockfile}; +use cargo_lock::{lockfile::Lockfile, SourceId, Version}; use cargo_platform::Platform; use itertools::Itertools; use tempfile::TempDir; use crate::{ - bazel::{ - filter_bazel_triples, find_workspace_root, generate_bazel_conditions, - get_matching_bazel_triples, is_bazel_supported_platform, - }, context::{ BuildableDependency, BuildableTarget, CrateContext, CrateDependencyContext, CrateTargetedDepContext, DependencyAlias, GitRepo, LicenseData, SourceDetails, @@ -43,7 +39,11 @@ use crate::{ DependencyKind, Metadata, MetadataFetcher, Node, Package, PackageId, }, settings::{format_registry_url, CrateSettings, GenMode, RazeSettings}, - util::{self, PlatformDetails, RazeError, PLEASE_FILE_A_BUG}, + util::{ + self, filter_bazel_triples, find_bazel_workspace_root, generate_bazel_conditions, + get_matching_bazel_triples, is_bazel_supported_platform, PlatformDetails, RazeError, + PLEASE_FILE_A_BUG, + }, }; pub const VENDOR_DIR: &str = "vendor/"; @@ -212,7 +212,7 @@ impl CrateCatalogEntry { * Not for use except during planning as path is local to run location. */ pub fn expected_vendored_path(&self, workspace_path: &str) -> String { - let mut dir = find_workspace_root().unwrap_or(PathBuf::from(".")); + let mut dir = find_bazel_workspace_root().unwrap_or(PathBuf::from(".")); // Trim the absolute label identifier from the start of the workspace path dir.push(workspace_path.trim_start_matches('/')); @@ -427,12 +427,7 @@ impl<'planner> WorkspaceSubplanner<'planner> { pub fn produce_planned_build(&self) -> Result { checks::check_resolve_matches_packages(&self.crate_catalog.metadata)?; - let mut packages: Vec<&Package> = self - .crate_catalog - .metadata - .packages - .iter() - .collect(); + let mut packages: Vec<&Package> = self.crate_catalog.metadata.packages.iter().collect(); match self.settings.genmode { GenMode::Remote => { @@ -466,7 +461,12 @@ impl<'planner> WorkspaceSubplanner<'planner> { } } - fn create_crate_context(&self, node: &Node, package_to_checksum: &HashMap<(String, Version), String>, catalog: &CrateCatalog) -> Option> { + fn create_crate_context( + &self, + node: &Node, + package_to_checksum: &HashMap<(String, Version), String>, + catalog: &CrateCatalog, + ) -> Option> { let own_crate_catalog_entry = catalog.entry_for_package_id(&node.id)?; let own_package = own_crate_catalog_entry.package(); @@ -920,24 +920,20 @@ impl<'planner> CrateSubplanner<'planner> { /** Generates source details for internal crate. */ fn produce_source_details(&self, package: &Package, package_root: &Path) -> SourceDetails { SourceDetails { - git_data: self - .source_id - .as_ref() - .filter(|id| id.is_git()) - .map(|id| { - let manifest_parent = package.manifest_path.parent().unwrap(); - let path_to_crate_root = manifest_parent.strip_prefix(package_root).unwrap(); - let path_to_crate_root = if path_to_crate_root.components().next().is_some() { - Some(path_to_crate_root.to_string_lossy().to_string()) - } else { - None - }; - GitRepo { - remote: id.url().to_string(), - commit: id.precise().unwrap().to_owned(), - path_to_crate_root, - } - }), + git_data: self.source_id.as_ref().filter(|id| id.is_git()).map(|id| { + let manifest_parent = package.manifest_path.parent().unwrap(); + let path_to_crate_root = manifest_parent.strip_prefix(package_root).unwrap(); + let path_to_crate_root = if path_to_crate_root.components().next().is_some() { + Some(path_to_crate_root.to_string_lossy().to_string()) + } else { + None + }; + GitRepo { + remote: id.url().to_string(), + commit: id.precise().unwrap().to_owned(), + path_to_crate_root, + } + }), } } diff --git a/impl/src/util.rs b/impl/src/util.rs index dad2cf751..593f2bce3 100644 --- a/impl/src/util.rs +++ b/impl/src/util.rs @@ -13,16 +13,218 @@ // limitations under the License. use std::{ - fmt, + env, fmt, iter::Iterator, + path::PathBuf, process::Command, str::{self, FromStr}, }; -use anyhow::Result; +use anyhow::{anyhow, Result}; use cargo_platform::Cfg; +use cfg_expr::{targets::get_builtin_target_by_triple, Expression, Predicate}; + +static SUPPORTED_PLATFORM_TRIPLES: &'static [&'static str] = &[ + // SUPPORTED_T1_PLATFORM_TRIPLES + "i686-apple-darwin", + "i686-pc-windows-gnu", + "i686-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-gnu", + "x86_64-unknown-linux-gnu", + // SUPPORTED_T2_PLATFORM_TRIPLES + "aarch64-apple-ios", + "aarch64-linux-android", + "aarch64-unknown-linux-gnu", + "arm-unknown-linux-gnueabi", + "i686-linux-android", + "i686-unknown-freebsd", + "powerpc-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "wasm32-unknown-unknown", + "x86_64-apple-ios", + "x86_64-linux-android", + "x86_64-unknown-freebsd", +]; + +/** Determines if the target matches those supported by and defined in rules_rust + * + * Examples can be seen below: + * + * | target | returns | reason | + * | ------------------------------------- | ---------------- | ------------------------------------------------ | + * | `cfg(not(fuchsia))` | `(true, true)` | `fuchsia` would be considered a 'default' | + * | | | dependency since no supported target maps to it. | + * | | | | + * | `cfg(unix)` | `(true, false)` | There are supported platforms from the `unix` | + * | | | `target_family` but not all platforms are of | + * | | | the `unix` family. | + * | | | | + * | `cfg(not(windows))` | `(true, false)` | There are supported platforms in addition to | + * | | | those in the `windows` `target_family` | + * | | | | + * | `x86_64-apple-darwin` | `(true, false)` | This is a supported target triple but obviously | + * | | | won't match with other triples. | + * | | | | + * | `unknown-unknown-unknown` | `(false, false)` | This will not match any triple. | + * | | | | + * | `cfg(foo)` | `(false, false)` | `foo` is not a strongly defined cfg value. | + * | `cfg(target_os = "redox")` | `(false, false)` | `redox` is not a supported platform. | + */ +pub fn is_bazel_supported_platform(target: &str) -> (bool, bool) { + // Ensure the target is represented as an expression + let target_exp = match target.starts_with("cfg(") { + true => target.to_owned(), + false => format!("cfg(target = \"{}\")", target), + }; + + let expression = match Expression::parse(&target_exp) { + Ok(exp) => exp, + // If the target expression cannot be parsed it is not considered a Bazel platform + Err(_) => { + return (false, false); + }, + }; + + let mut is_supported = false; + let mut matches_all = true; + + // Attempt to match the expression + for target_info in SUPPORTED_PLATFORM_TRIPLES + .iter() + .map(|x| get_builtin_target_by_triple(x).unwrap()) + { + if expression.eval(|pred| { + match pred { + Predicate::Target(tp) => tp.matches(target_info), + Predicate::KeyValue { + key, + val, + } => (*key == "target") && (*val == target_info.triple), + // For now there is no other kind of matching + _ => false, + } + }) { + is_supported = true; + } else { + matches_all = false; + } + } + + (is_supported, matches_all) +} + +/** Maps a Rust cfg or triple target to Bazel supported triples. + * + * Note, the Bazel triples must be defined in: + * https://github.com/bazelbuild/rules_rust/blob/master/rust/platform/platform.bzl + */ +pub fn get_matching_bazel_triples(target: &str) -> Result> { + let target_exp = match target.starts_with("cfg(") { + true => target.to_owned(), + false => format!("cfg(target = \"{}\")", target), + }; + + let expression = Expression::parse(&target_exp)?; + let triples: Vec = SUPPORTED_PLATFORM_TRIPLES + .iter() + .filter_map(|triple| { + let target_info = get_builtin_target_by_triple(triple).unwrap(); + match expression.eval(|pred| { + match pred { + Predicate::Target(tp) => tp.matches(target_info), + Predicate::KeyValue { + key, + val, + } => (*key == "target") && (*val == target_info.triple), + // For now there is no other kind of matching + _ => false, + } + }) { + true => Some(String::from((*target_info).triple)), + false => None, + } + }) + .collect(); + + Ok(triples) +} + +/** Produces a list of triples based on a provided whitelist */ +pub fn filter_bazel_triples(triples: &mut Vec, triples_whitelist: &Vec) { + // Early-out if the filter list is empty + if triples_whitelist.len() == 0 { + return; + } + + // Prune everything that's not found in the whitelist + triples.retain(|triple| triples_whitelist.iter().any(|i| i == triple)); + + triples.sort(); +} + +/** Returns a list of Bazel targets for use in `select` statements based on a + * given list of triples. + */ +pub fn generate_bazel_conditions(triples: &Vec) -> Result> { + // Sanity check ensuring all strings represent real triples + for triple in triples.iter() { + match get_builtin_target_by_triple(triple) { + None => { + return Err(anyhow!("Not a triple: '{}'", triple)); + }, + _ => {}, + } + } + + let mut bazel_triples: Vec = triples + .iter() + .map(|triple| format!("@io_bazel_rules_rust//rust/platform:{}", triple)) + .collect(); + + bazel_triples.sort(); + + Ok(bazel_triples) +} + +/** Returns whether or not the given path is a Bazel workspace root */ +pub fn is_bazel_workspace_root(dir: &PathBuf) -> bool { + let workspace_files = [dir.join("WORKSPACE.bazel"), dir.join("WORKSPACE")]; + + for workspace in workspace_files.iter() { + if workspace.exists() { + return true; + } + } + + return false; +} + +/** Returns a path to a Bazel workspace root based on the current working + * directory, otherwise None if not workspace is detected. + */ +pub fn find_bazel_workspace_root() -> Option { + let mut dir = match env::current_dir() { + Ok(result) => Some(result), + Err(_) => None, + }; + + while let Some(current_dir) = dir { + if is_bazel_workspace_root(¤t_dir) { + return Some(current_dir); + } + + dir = match current_dir.parent() { + Some(parent) => Some(parent.to_path_buf()), + None => None, + }; + } + + return None; +} + pub const PLEASE_FILE_A_BUG: &str = "Please file an issue at github.com/google/cargo-raze with details."; @@ -193,6 +395,10 @@ fn fetch_attrs(target: &str) -> Result> { #[cfg(test)] mod tests { + use std::fs::File; + + use tempfile::TempDir; + use super::*; #[test] @@ -218,4 +424,111 @@ mod tests { assert_eq!(results.count_extras, 1); assert!(!results.is_empty()); } + + #[test] + fn detecting_workspace_root() { + // Cache the cwd + let cwd = env::current_dir().unwrap(); + + // Run test + let result = std::panic::catch_unwind(|| { + // Generate a temporary directory to do testing in + let bazel_root = TempDir::new().unwrap(); + assert!(env::set_current_dir(&bazel_root).is_ok()); + + // Starting within the temp directory, we'll find that there are no WORKSPACE.bazel files + // and thus return None to indicate a Bazel workspace root could not be found. + assert_eq!(find_bazel_workspace_root(), None); + + // After creating a WORKSPACE.bazel file in that directory, we expect to find to be + // returned a path to the temporary directory + File::create(bazel_root.path().join("WORKSPACE.bazel")).unwrap(); + assert_eq!( + find_bazel_workspace_root().unwrap().canonicalize().unwrap(), + bazel_root.into_path().canonicalize().unwrap() + ); + }); + + // Restore cwd + assert!(env::set_current_dir(&cwd).is_ok()); + + // Ensure test results were successful + assert!(result.is_ok()); + } + + #[test] + fn detect_bazel_platforms() { + assert_eq!( + is_bazel_supported_platform("cfg(not(fuchsia))"), + (true, true) + ); + assert_eq!( + is_bazel_supported_platform("cfg(not(target_os = \"redox\"))"), + (true, true) + ); + assert_eq!(is_bazel_supported_platform("cfg(unix)"), (true, false)); + assert_eq!( + is_bazel_supported_platform("cfg(not(windows))"), + (true, false) + ); + assert_eq!( + is_bazel_supported_platform("cfg(target = \"x86_64-apple-darwin\")"), + (true, false) + ); + assert_eq!( + is_bazel_supported_platform("x86_64-apple-darwin"), + (true, false) + ); + assert_eq!( + is_bazel_supported_platform("unknown-unknown-unknown"), + (false, false) + ); + assert_eq!(is_bazel_supported_platform("cfg(foo)"), (false, false)); + assert_eq!( + is_bazel_supported_platform("cfg(target_os = \"redox\")"), + (false, false) + ); + } + + #[test] + fn all_supported_platform_triples_unwrap() { + for triple in SUPPORTED_PLATFORM_TRIPLES.iter() { + get_builtin_target_by_triple(triple).unwrap(); + } + } + + #[test] + fn generate_condition_strings() { + assert_eq!( + generate_bazel_conditions(&vec![ + "aarch64-unknown-linux-gnu".to_string(), + "aarch64-apple-ios".to_string(), + ]) + .unwrap(), + vec![ + "@io_bazel_rules_rust//rust/platform:aarch64-apple-ios", + "@io_bazel_rules_rust//rust/platform:aarch64-unknown-linux-gnu", + ] + ); + + assert_eq!( + generate_bazel_conditions(&vec!["aarch64-unknown-linux-gnu".to_string()]).unwrap(), + vec!["@io_bazel_rules_rust//rust/platform:aarch64-unknown-linux-gnu"] + ); + + assert!(generate_bazel_conditions(&vec![ + "aarch64-unknown-linux-gnu".to_string(), + "unknown-unknown-unknown".to_string(), + ]) + .is_err()); + + assert!(generate_bazel_conditions(&vec!["unknown-unknown-unknown".to_string()]).is_err()); + + assert!(generate_bazel_conditions(&vec![ + "foo".to_string(), + "bar".to_string(), + "baz".to_string() + ]) + .is_err()); + } }