diff --git a/Cargo.lock b/Cargo.lock index 1f8dd9542f..0af4f60b95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1922,6 +1922,7 @@ dependencies = [ "nom 5.0.1", "nom-tracable", "nom_locate", + "nu-build", "nu-errors", "nu-parser", "nu-protocol", @@ -1970,6 +1971,16 @@ dependencies = [ "which", ] +[[package]] +name = "nu-build" +version = "0.1.0" +dependencies = [ + "lazy_static 1.4.0", + "serde 1.0.103", + "serde_json", + "toml 0.5.5", +] + [[package]] name = "nu-errors" version = "0.1.0" @@ -1980,6 +1991,7 @@ dependencies = [ "language-reporting", "nom 5.0.1", "nom_locate", + "nu-build", "nu-source", "num-bigint", "num-traits 0.2.10", @@ -2006,6 +2018,7 @@ dependencies = [ "nom 5.0.1", "nom-tracable", "nom_locate", + "nu-build", "nu-errors", "nu-protocol", "nu-source", @@ -2035,6 +2048,7 @@ dependencies = [ "nom 5.0.1", "nom-tracable", "nom_locate", + "nu-build", "nu-errors", "nu-source", "num-bigint", @@ -2058,6 +2072,7 @@ dependencies = [ "language-reporting", "nom-tracable", "nom_locate", + "nu-build", "pretty", "serde 1.0.103", "termcolor", @@ -2070,6 +2085,7 @@ dependencies = [ "ansi_term 0.12.1", "crossterm", "nu", + "nu-build", "nu-protocol", "nu-source", "syntect", diff --git a/Cargo.toml b/Cargo.toml index bebbd24214..eb11e61680 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://book.nushell.sh" [workspace] -members = ["crates/nu-errors", "crates/nu-source", "crates/nu-textview", "crates/nu-protocol", "crates/nu-parser"] +members = ["crates/nu-errors", "crates/nu-source", "crates/nu-textview", "crates/nu-protocol", "crates/nu-parser", "crates/nu-build"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -126,6 +126,7 @@ pretty_assertions = "0.6.1" [build-dependencies] toml = "0.5.5" serde = { version = "1.0.102", features = ["derive"] } +nu-build = { version = "0.1.0", path = "./crates/nu-build" } [lib] name = "nu" diff --git a/build.rs b/build.rs index 44a55f9573..b7511cfc6a 100644 --- a/build.rs +++ b/build.rs @@ -1,39 +1,3 @@ -use serde::Deserialize; -use std::collections::HashMap; -use std::collections::HashSet; -use std::env; -use std::path::Path; - -#[derive(Deserialize)] -struct Feature { - #[allow(unused)] - description: String, - enabled: bool, -} - fn main() -> Result<(), Box> { - let input = env::var("CARGO_MANIFEST_DIR").unwrap(); - let all_on = env::var("NUSHELL_ENABLE_ALL_FLAGS").is_ok(); - let flags: HashSet = env::var("NUSHELL_ENABLE_FLAGS") - .map(|s| s.split(",").map(|s| s.to_string()).collect()) - .unwrap_or_else(|_| HashSet::new()); - - if all_on && !flags.is_empty() { - println!( - "cargo:warning={}", - "Both NUSHELL_ENABLE_ALL_FLAGS and NUSHELL_ENABLE_FLAGS were set. You don't need both." - ); - } - - let path = Path::new(&input).join("features.toml"); - - let toml: HashMap = toml::from_str(&std::fs::read_to_string(path)?)?; - - for (key, value) in toml.iter() { - if value.enabled == true || all_on || flags.contains(key) { - println!("cargo:rustc-cfg={}", key); - } - } - - Ok(()) + nu_build::build() } diff --git a/crates/nu-build/Cargo.toml b/crates/nu-build/Cargo.toml new file mode 100644 index 0000000000..66a6ffbbe0 --- /dev/null +++ b/crates/nu-build/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "nu-build" +version = "0.1.0" +authors = ["Yehuda Katz "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0.102", features = ["derive"] } +lazy_static = "1.2.0" +serde_json = "1.0.35" +toml = "0.5.5" diff --git a/crates/nu-build/src/lib.rs b/crates/nu-build/src/lib.rs new file mode 100644 index 0000000000..1689dfd11f --- /dev/null +++ b/crates/nu-build/src/lib.rs @@ -0,0 +1,82 @@ +use lazy_static::lazy_static; +use serde::Deserialize; +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::collections::HashSet; +use std::env; +use std::path::{Path, PathBuf}; +use std::sync::Mutex; + +lazy_static! { + static ref WORKSPACES: Mutex> = Mutex::new(BTreeMap::new()); +} + +// got from https://github.com/mitsuhiko/insta/blob/b113499249584cb650150d2d01ed96ee66db6b30/src/runtime.rs#L67-L88 + +fn get_cargo_workspace(manifest_dir: &str) -> Option<&Path> { + let mut workspaces = WORKSPACES.lock().unwrap(); + if let Some(rv) = workspaces.get(manifest_dir) { + Some(rv) + } else { + #[derive(Deserialize)] + struct Manifest { + workspace_root: String, + } + let output = std::process::Command::new(env!("CARGO")) + .arg("metadata") + .arg("--format-version=1") + .current_dir(manifest_dir) + .output() + .unwrap(); + let manifest: Manifest = serde_json::from_slice(&output.stdout).unwrap(); + let path = Box::leak(Box::new(PathBuf::from(manifest.workspace_root))); + workspaces.insert(manifest_dir.to_string(), path.as_path()); + workspaces.get(manifest_dir).map(|w| *w) + } +} + +#[derive(Deserialize)] +struct Feature { + #[allow(unused)] + description: String, + enabled: bool, +} + +pub fn build() -> Result<(), Box> { + let input = env::var("CARGO_MANIFEST_DIR").unwrap(); + + let all_on = env::var("NUSHELL_ENABLE_ALL_FLAGS").is_ok(); + let flags: HashSet = env::var("NUSHELL_ENABLE_FLAGS") + .map(|s| s.split(",").map(|s| s.to_string()).collect()) + .unwrap_or_else(|_| HashSet::new()); + + if all_on && !flags.is_empty() { + println!( + "cargo:warning={}", + "Both NUSHELL_ENABLE_ALL_FLAGS and NUSHELL_ENABLE_FLAGS were set. You don't need both." + ); + } + + let workspace = match get_cargo_workspace(&input) { + // If the crate is being downloaded from crates.io, it won't have a workspace root, and that's ok + None => return Ok(()), + Some(workspace) => workspace, + }; + + let path = Path::new(&workspace).join("features.toml"); + + // If the crate is being downloaded from crates.io, it won't have a features.toml, and that's ok + if !path.exists() { + return Ok(()); + } + + let toml: HashMap = toml::from_str(&std::fs::read_to_string(path)?)?; + + for (key, value) in toml.iter() { + if value.enabled == true || all_on || flags.contains(key) { + println!("cargo:rustc-cfg={}", key); + } + } + + Ok(()) +} diff --git a/crates/nu-errors/Cargo.toml b/crates/nu-errors/Cargo.toml index 4a512200e0..3c3f4a4409 100644 --- a/crates/nu-errors/Cargo.toml +++ b/crates/nu-errors/Cargo.toml @@ -24,3 +24,6 @@ subprocess = "0.1.18" serde_yaml = "0.8" toml = "0.5.5" serde_json = "1.0.41" + +[build-dependencies] +nu-build = { version = "0.1.0", path = "../nu-build" } diff --git a/crates/nu-errors/build.rs b/crates/nu-errors/build.rs new file mode 100644 index 0000000000..b7511cfc6a --- /dev/null +++ b/crates/nu-errors/build.rs @@ -0,0 +1,3 @@ +fn main() -> Result<(), Box> { + nu_build::build() +} diff --git a/crates/nu-parser/Cargo.toml b/crates/nu-parser/Cargo.toml index b375df22a9..a6eadc4efe 100644 --- a/crates/nu-parser/Cargo.toml +++ b/crates/nu-parser/Cargo.toml @@ -35,3 +35,6 @@ unicode-xid = "0.2.0" [dev-dependencies] pretty_assertions = "0.6.1" + +[build-dependencies] +nu-build = { version = "0.1.0", path = "../nu-build" } diff --git a/crates/nu-parser/build.rs b/crates/nu-parser/build.rs new file mode 100644 index 0000000000..b7511cfc6a --- /dev/null +++ b/crates/nu-parser/build.rs @@ -0,0 +1,3 @@ +fn main() -> Result<(), Box> { + nu_build::build() +} diff --git a/crates/nu-protocol/Cargo.toml b/crates/nu-protocol/Cargo.toml index 79169e7bc2..4379527189 100644 --- a/crates/nu-protocol/Cargo.toml +++ b/crates/nu-protocol/Cargo.toml @@ -33,3 +33,5 @@ serde_yaml = "0.8" toml = "0.5.5" serde_json = "1.0.41" +[build-dependencies] +nu-build = { version = "0.1.0", path = "../nu-build" } diff --git a/crates/nu-protocol/build.rs b/crates/nu-protocol/build.rs new file mode 100644 index 0000000000..b7511cfc6a --- /dev/null +++ b/crates/nu-protocol/build.rs @@ -0,0 +1,3 @@ +fn main() -> Result<(), Box> { + nu_build::build() +} diff --git a/crates/nu-source/Cargo.toml b/crates/nu-source/Cargo.toml index 1515dfa732..f30a937267 100644 --- a/crates/nu-source/Cargo.toml +++ b/crates/nu-source/Cargo.toml @@ -18,3 +18,6 @@ nom-tracable = "0.4.1" language-reporting = "0.4.0" termcolor = "1.0.5" pretty = "0.5.2" + +[build-dependencies] +nu-build = { version = "0.1.0", path = "../nu-build" } diff --git a/crates/nu-source/build.rs b/crates/nu-source/build.rs new file mode 100644 index 0000000000..b7511cfc6a --- /dev/null +++ b/crates/nu-source/build.rs @@ -0,0 +1,3 @@ +fn main() -> Result<(), Box> { + nu_build::build() +} diff --git a/crates/nu-textview/Cargo.toml b/crates/nu-textview/Cargo.toml index 3baaf708f2..dab1b330b6 100644 --- a/crates/nu-textview/Cargo.toml +++ b/crates/nu-textview/Cargo.toml @@ -20,3 +20,6 @@ nu = { path = "../.." } nu-protocol = { path = "../nu-protocol" } nu-source = { path = "../nu-source" } url = "2.1.0" + +[build-dependencies] +nu-build = { version = "0.1.0", path = "../nu-build" } diff --git a/crates/nu-textview/build.rs b/crates/nu-textview/build.rs new file mode 100644 index 0000000000..b7511cfc6a --- /dev/null +++ b/crates/nu-textview/build.rs @@ -0,0 +1,3 @@ +fn main() -> Result<(), Box> { + nu_build::build() +}