From cd50c8116766dacc694e823416d407f67ad41e90 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Wed, 16 Oct 2024 12:37:21 +0000 Subject: [PATCH 1/6] Maintenance: critical bug fix upgrade for duckscript --- CHANGELOG.md | 4 ++++ Cargo.toml | 4 ++-- docs/_config.yml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0c8b74..ae1c9fb2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## CHANGELOG +### v0.37.23 (2024-10-16) + +* Maintenance: critical bug fix upgrade for duckscript + ### v0.37.22 (2024-10-12) * Fix: set env CARGO_MAKE_CURRENT_TASK_NAME before condition invocation #1173 diff --git a/Cargo.toml b/Cargo.toml index c959f700..a30e2468 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-make" -version = "0.37.22" +version = "0.37.23" authors = ["Sagie Gur-Ari "] description = "Rust task runner and build tool." license = "Apache-2.0" @@ -51,7 +51,7 @@ colored = "^2" ctrlc = "^3" dirs-next = "^2" duckscript = "^0.10" -duckscriptsdk = { version = "^0.11", default-features = false } +duckscriptsdk = { version = "^0.11.1", default-features = false } envmnt = "^0.10.4" fern = "^0.6" fsio = { version = "^0.4", features = ["temp-path"] } diff --git a/docs/_config.yml b/docs/_config.yml index 574447dd..0b8762d4 100755 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -2,4 +2,4 @@ theme: jekyll-theme-cayman title: cargo-make description: Rust task runner and build tool. show_downloads: false -version: 0.37.22 +version: 0.37.23 From 8e7ca82fbb0f1be4f267af9fa936fcc8cd93bdbf Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Wed, 16 Oct 2024 12:52:34 +0000 Subject: [PATCH 2/6] Maintenance: critical bug fix upgrade for duckscript --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- docs/_config.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae1c9fb2..2a4b15eb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## CHANGELOG -### v0.37.23 (2024-10-16) +### v0.37.23 * Maintenance: critical bug fix upgrade for duckscript diff --git a/Cargo.toml b/Cargo.toml index a30e2468..49705dae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-make" -version = "0.37.23" +version = "0.37.22" authors = ["Sagie Gur-Ari "] description = "Rust task runner and build tool." license = "Apache-2.0" diff --git a/docs/_config.yml b/docs/_config.yml index 0b8762d4..574447dd 100755 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -2,4 +2,4 @@ theme: jekyll-theme-cayman title: cargo-make description: Rust task runner and build tool. show_downloads: false -version: 0.37.23 +version: 0.37.22 From 0d3901a9845fb7bfe77760442800a1875a2befc9 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Thu, 17 Oct 2024 17:08:46 +0000 Subject: [PATCH 3/6] Enhancement: support relative keyword for makefile extending to enable easy crate/workspace root extending #1175 --- CHANGELOG.md | 1 + Cargo.lock | 4 +- docs/_includes/content.md | 17 +++++++- examples/extends_list.toml | 7 ++++ src/lib/descriptor/mod.rs | 75 ++++++++++++++++++++++++++++------ src/lib/descriptor/mod_test.rs | 68 ++++++++++++++++++++++++++---- src/lib/environment/mod.rs | 17 ++++++-- src/lib/types.rs | 3 ++ 8 files changed, 163 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a4b15eb..a6871bd0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### v0.37.23 +* Enhancement: support relative keyword for makefile extending to enable easy crate/workspace root extending #1175 * Maintenance: critical bug fix upgrade for duckscript ### v0.37.22 (2024-10-12) diff --git a/Cargo.lock b/Cargo.lock index 4db7246d..6388acf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -423,9 +423,9 @@ dependencies = [ [[package]] name = "duckscriptsdk" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45817ca2f227ffd723d5f55ce2a0a11fb7b70e7e1c87e6e66c9c3d4784fc94f5" +checksum = "29c5669655efc2ef2293344a52bf4254d66026d703f8d89224e32f3de7ab6b46" dependencies = [ "attohttpc", "base64", diff --git a/docs/_includes/content.md b/docs/_includes/content.md index f20450e9..99b8de63 100755 --- a/docs/_includes/content.md +++ b/docs/_includes/content.md @@ -1031,9 +1031,24 @@ All will be loaded in the order you define.
For example: ```toml -extend = [ { path = "must_have_makefile.toml" }, { path = "optional_makefile.toml", optional = true }, { path = "another_must_have_makefile.toml" } ] +extend = [ + { path = "alias.toml" }, + { path = "optional_makefile.toml", optional = true }, + { path = "cwd.toml" }, +] +``` + +You can also change the relative path from the current makefile location to the crate root folder or workspace root folder by adding the relative keyword as follows: + +```toml +extend = { path = "./examples/python.toml", relative = "crate" } ``` +Where relative can have the following values: +* crate - For crate root (based on first Cargo.toml file) +* workspace - For workspace root (based on second top Cargo.toml file) +Any other value defaults to the current makefile location. + #### Automatically Extend Workspace Makefile When running cargo make for modules which are part of a workspace, you can automatically have the member crates makefile (even if doesn't exist) extend the workspace level makefile. diff --git a/examples/extends_list.toml b/examples/extends_list.toml index b5889bef..0bb6b046 100755 --- a/examples/extends_list.toml +++ b/examples/extends_list.toml @@ -3,7 +3,14 @@ extend = [ { path = "alias.toml" }, { path = "optional_makefile.toml", optional = true }, { path = "cwd.toml" }, + { path = "./examples/python.toml", relative = "crate" }, ] +[config] +skip_core_tasks = true +skip_git_env_info = true +skip_rust_env_info = true +skip_crate_env_info = true + [tasks.extended] alias = "D2" diff --git a/src/lib/descriptor/mod.rs b/src/lib/descriptor/mod.rs index 0a84fe4b..927751e7 100755 --- a/src/lib/descriptor/mod.rs +++ b/src/lib/descriptor/mod.rs @@ -15,13 +15,8 @@ pub(crate) mod descriptor_deserializer; mod env; mod makefiles; -use std::path::{Path, PathBuf}; - -use fsio::path::as_path::AsPath; -use fsio::path::from_path::FromPath; -use indexmap::IndexMap; - use crate::descriptor::env::{merge_env, merge_env_files, merge_env_scripts}; +use crate::environment; use crate::error::CargoMakeError; use crate::plugin::descriptor::merge_plugins_config; use crate::types::{ @@ -29,6 +24,17 @@ use crate::types::{ Task, }; use crate::{io, scriptengine, version}; +use fsio::path::as_path::AsPath; +use fsio::path::from_path::FromPath; +use indexmap::IndexMap; +use std::path::{Path, PathBuf}; + +#[derive(Debug)] +enum RelativeTo { + Makefile, + CrateRoot, + WorkspaceRoot, +} fn merge_tasks( base: &mut IndexMap, @@ -249,10 +255,22 @@ fn load_descriptor_extended_makefiles( extend_struct: &Extend, ) -> Result { match extend_struct { - Extend::Path(base_file) => load_external_descriptor(parent_path, &base_file, true, false), + Extend::Path(base_file) => { + load_external_descriptor(parent_path, &base_file, true, false, RelativeTo::Makefile) + } Extend::Options(extend_options) => { let force = !extend_options.optional.unwrap_or(false); - load_external_descriptor(parent_path, &extend_options.path, force, false) + let relative_to = match extend_options + .relative + .clone() + .unwrap_or("makefile".to_string()) + .as_str() + { + "crate" => RelativeTo::CrateRoot, + "workspace" => RelativeTo::WorkspaceRoot, + _ => RelativeTo::Makefile, + }; + load_external_descriptor(parent_path, &extend_options.path, force, false, relative_to) } Extend::List(extend_list) => { let mut ordered_list_config = ExternalConfig::new(); @@ -302,13 +320,42 @@ fn load_external_descriptor( file_name: &str, force: bool, set_env: bool, + relative_to: RelativeTo, ) -> Result { debug!( - "Loading tasks from file: {} base directory: {}", - &file_name, &base_path + "Loading tasks from file: {} base directory: {}, relative to: {:#?}", + &file_name, &base_path, &relative_to, ); - let file_path = Path::new(base_path).join(file_name); + let descriptor_dir = match relative_to { + RelativeTo::Makefile => base_path, + RelativeTo::CrateRoot => { + let project_root = environment::get_project_root_for_path(&PathBuf::from(base_path)); + debug!("project root: {:#?}", &project_root); + match project_root { + Some(crate_dir) => &crate_dir.clone(), + None => base_path, + } + } + RelativeTo::WorkspaceRoot => { + let base_path_buf = PathBuf::from(base_path); + let project_root = environment::get_project_root_for_path(&base_path_buf); + debug!("project root: {:#?}", &project_root); + match project_root { + Some(crate_dir) => { + let crate_parent_path = PathBuf::from(&crate_dir).join(".."); + let workspace_root = environment::get_project_root_for_path(&crate_parent_path); + debug!("workspace root: {:#?}", &workspace_root); + match workspace_root { + Some(workspace_dir) => &workspace_dir.clone(), + None => &crate_dir.clone(), + } + } + None => base_path, + } + } + }; + let file_path = Path::new(descriptor_dir).join(file_name); if file_path.exists() && file_path.is_file() { let file_path_string: String = FromPath::from_path(&file_path); @@ -332,7 +379,7 @@ fn load_external_descriptor( match file_config.extend { Some(ref extend_struct) => { - let parent_path_buf = Path::new(base_path).join(file_name).join(".."); + let parent_path_buf = Path::new(&file_path_string).join(".."); let parent_path = file_path .parent() .unwrap_or(&parent_path_buf) @@ -515,7 +562,8 @@ fn load_descriptors( ) -> Result { let default_config = load_internal_descriptors(stable, experimental, modify_core_tasks)?; - let mut external_config = load_external_descriptor(".", file_name, force, true)?; + let mut external_config = + load_external_descriptor(".", file_name, force, true, RelativeTo::Makefile)?; external_config = match std::env::var("CARGO_MAKE_WORKSPACE_MAKEFILE") { Ok(workspace_makefile) => { @@ -532,6 +580,7 @@ fn load_descriptors( workspace_file_name_str, false, false, + RelativeTo::Makefile, )?; merge_external_configs(external_config, workspace_config)? } diff --git a/src/lib/descriptor/mod_test.rs b/src/lib/descriptor/mod_test.rs index 40bd9e0c..c6cafd07 100755 --- a/src/lib/descriptor/mod_test.rs +++ b/src/lib/descriptor/mod_test.rs @@ -492,7 +492,9 @@ fn load_internal_descriptors_modify_namespace() { #[test] #[ignore] fn load_external_descriptor_no_file() { - let config = load_external_descriptor(".", "bad_file.toml2", false, false).unwrap(); + let config = + load_external_descriptor(".", "bad_file.toml2", false, false, RelativeTo::Makefile) + .unwrap(); assert!(config.config.is_none()); assert!(config.env.is_none()); @@ -502,19 +504,33 @@ fn load_external_descriptor_no_file() { #[test] #[should_panic] fn load_external_descriptor_no_file_force() { - load_external_descriptor(".", "bad_file.toml2", true, false).unwrap(); + load_external_descriptor(".", "bad_file.toml2", true, false, RelativeTo::Makefile).unwrap(); } #[test] #[should_panic] fn load_external_descriptor_extended_not_found_force() { - load_external_descriptor(".", "./examples/extends_not_found.toml", true, false).unwrap(); + load_external_descriptor( + ".", + "./examples/extends_not_found.toml", + true, + false, + RelativeTo::Makefile, + ) + .unwrap(); } #[test] #[ignore] fn load_external_descriptor_simple_file() { - let config = load_external_descriptor(".", "./examples/alias.toml", true, false).unwrap(); + let config = load_external_descriptor( + ".", + "./examples/alias.toml", + true, + false, + RelativeTo::Makefile, + ) + .unwrap(); assert!(config.config.is_none()); assert!(config.env.is_none()); @@ -529,7 +545,14 @@ fn load_external_descriptor_simple_file() { #[test] #[ignore] fn load_external_descriptor_extending_file() { - let config = load_external_descriptor(".", "examples/extending.toml", true, false).unwrap(); + let config = load_external_descriptor( + ".", + "examples/extending.toml", + true, + false, + RelativeTo::Makefile, + ) + .unwrap(); assert!(config.config.is_some()); assert!(config.env.is_some()); @@ -550,8 +573,14 @@ fn load_external_descriptor_extending_file() { #[test] #[ignore] fn load_external_descriptor_extending_file_sub_folder() { - let config = - load_external_descriptor(".", "examples/files/extending.toml", true, false).unwrap(); + let config = load_external_descriptor( + ".", + "examples/files/extending.toml", + true, + false, + RelativeTo::Makefile, + ) + .unwrap(); assert!(config.config.is_some()); assert!(config.env.is_some()); @@ -584,7 +613,14 @@ fn load_external_descriptor_set_env() { envmnt::set("CARGO_MAKE_MAKEFILE_PATH", "EMPTY"); assert_eq!(envmnt::get_or_panic("CARGO_MAKE_MAKEFILE_PATH"), "EMPTY"); - load_external_descriptor(".", "./examples/alias.toml", true, true).unwrap(); + load_external_descriptor( + ".", + "./examples/alias.toml", + true, + true, + RelativeTo::Makefile, + ) + .unwrap(); assert!(envmnt::get_or_panic("CARGO_MAKE_MAKEFILE_PATH").ends_with("alias.toml")); } @@ -598,7 +634,8 @@ fn load_external_descriptor_min_version_broken_makefile_nopanic() { ".", "src/lib/test/makefiles/broken_makefile_minversion.toml", false, - false + false, + RelativeTo::Makefile ) .err() .unwrap() @@ -618,6 +655,7 @@ fn load_external_descriptor_broken_makefile_panic() { "src/lib/test/makefiles/broken_makefile.toml", false, false, + RelativeTo::Makefile, ) .unwrap(); } @@ -726,6 +764,7 @@ fn load_descriptor_extended_makefiles_options_exists() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: None, + relative: None, }), ) .unwrap(); @@ -744,6 +783,7 @@ fn load_descriptor_extended_makefiles_options_not_exists() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/bad.toml".to_string(), optional: None, + relative: None, }), ) .unwrap(); @@ -758,6 +798,7 @@ fn load_descriptor_extended_makefiles_options_exists_optional() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: Some(true), + relative: None, }), ) .unwrap(); @@ -775,6 +816,7 @@ fn load_descriptor_extended_makefiles_options_exists_not_optional() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: Some(false), + relative: None, }), ) .unwrap(); @@ -793,6 +835,7 @@ fn load_descriptor_extended_makefiles_options_not_exists_optional() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/bad.toml".to_string(), optional: Some(true), + relative: None, }), ) .unwrap(); @@ -811,6 +854,7 @@ fn load_descriptor_extended_makefiles_options_not_exists_not_optional() { &Extend::Options(ExtendOptions { path: "src/lib/test/makefiles/bad.toml".to_string(), optional: Some(false), + relative: None, }), ) .unwrap(); @@ -824,10 +868,12 @@ fn load_descriptor_extended_makefiles_list_exists() { ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: Some(false), + relative: None, }, ExtendOptions { path: "src/lib/test/makefiles/test2.toml".to_string(), optional: Some(false), + relative: None, }, ]; let descriptor = load_descriptor_extended_makefiles(&parent_path, &Extend::List(list)).unwrap(); @@ -846,10 +892,12 @@ fn load_descriptor_extended_makefiles_list_not_exists() { ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: Some(false), + relative: None, }, ExtendOptions { path: "src/lib/test/makefiles/bad.toml".to_string(), optional: Some(false), + relative: None, }, ]; load_descriptor_extended_makefiles(&parent_path, &Extend::List(list)).unwrap(); @@ -863,10 +911,12 @@ fn load_descriptor_extended_makefiles_list_exists_optional() { ExtendOptions { path: "src/lib/test/makefiles/test1.toml".to_string(), optional: Some(false), + relative: None, }, ExtendOptions { path: "src/lib/test/makefiles/bad.toml".to_string(), optional: Some(true), + relative: None, }, ]; let descriptor = load_descriptor_extended_makefiles(&parent_path, &Extend::List(list)).unwrap(); diff --git a/src/lib/environment/mod.rs b/src/lib/environment/mod.rs index a4e6b051..8628dfc1 100644 --- a/src/lib/environment/mod.rs +++ b/src/lib/environment/mod.rs @@ -779,16 +779,25 @@ fn load_env_file_with_base_directory( } } -fn get_project_root_for_path(directory: &PathBuf) -> Option { - let file_path = Path::new(directory).join("Cargo.toml"); +pub(crate) fn get_project_root_for_path(directory: &PathBuf) -> Option { + let from_dir = if directory.to_str().unwrap_or(".") == "." { + match env::current_dir() { + Ok(value) => &value.clone(), + _ => directory, + } + } else { + directory + }; + debug!("Looking for project root from directory: {:?}", from_dir); + let file_path = Path::new(from_dir).join("Cargo.toml"); if file_path.exists() { - match directory.to_str() { + match from_dir.to_str() { Some(directory_string) => Some(directory_string.to_string()), _ => None, } } else { - match directory.parent() { + match from_dir.parent() { Some(parent_directory) => { let parent_directory_path = parent_directory.to_path_buf(); get_project_root_for_path(&parent_directory_path) diff --git a/src/lib/types.rs b/src/lib/types.rs index 7124f934..f4bb8cb6 100755 --- a/src/lib/types.rs +++ b/src/lib/types.rs @@ -2072,6 +2072,9 @@ pub struct ExtendOptions { pub path: String, /// Enable optional extend (default to false) pub optional: Option, + /// Relative to option, sub as current makefile, crate root, workspace root, etc... + /// Possible values: (makefile, crate, workspace) + pub relative: Option, } #[derive(Serialize, Deserialize, Debug, Clone)] From 35ba29dc2c53dbff585e1d4865af249823c13669 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Fri, 18 Oct 2024 04:53:43 +0000 Subject: [PATCH 4/6] Build fix --- src/lib/descriptor/mod.rs | 14 +++++++------- src/lib/environment/mod.rs | 24 +++++++++++++----------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/lib/descriptor/mod.rs b/src/lib/descriptor/mod.rs index 927751e7..08f05118 100755 --- a/src/lib/descriptor/mod.rs +++ b/src/lib/descriptor/mod.rs @@ -328,13 +328,13 @@ fn load_external_descriptor( ); let descriptor_dir = match relative_to { - RelativeTo::Makefile => base_path, + RelativeTo::Makefile => base_path.to_string(), RelativeTo::CrateRoot => { let project_root = environment::get_project_root_for_path(&PathBuf::from(base_path)); debug!("project root: {:#?}", &project_root); match project_root { - Some(crate_dir) => &crate_dir.clone(), - None => base_path, + Some(crate_dir) => crate_dir.clone(), + None => base_path.to_string(), } } RelativeTo::WorkspaceRoot => { @@ -347,15 +347,15 @@ fn load_external_descriptor( let workspace_root = environment::get_project_root_for_path(&crate_parent_path); debug!("workspace root: {:#?}", &workspace_root); match workspace_root { - Some(workspace_dir) => &workspace_dir.clone(), - None => &crate_dir.clone(), + Some(workspace_dir) => workspace_dir.clone(), + None => crate_dir.clone(), } } - None => base_path, + None => base_path.to_string(), } } }; - let file_path = Path::new(descriptor_dir).join(file_name); + let file_path = Path::new(&descriptor_dir).join(file_name); if file_path.exists() && file_path.is_file() { let file_path_string: String = FromPath::from_path(&file_path); diff --git a/src/lib/environment/mod.rs b/src/lib/environment/mod.rs index 8628dfc1..d296cfc4 100644 --- a/src/lib/environment/mod.rs +++ b/src/lib/environment/mod.rs @@ -779,17 +779,21 @@ fn load_env_file_with_base_directory( } } +fn current_dir_or(fallback: &PathBuf) -> PathBuf { + match env::current_dir() { + Ok(value) => value.clone(), + _ => fallback.clone(), + } +} + pub(crate) fn get_project_root_for_path(directory: &PathBuf) -> Option { let from_dir = if directory.to_str().unwrap_or(".") == "." { - match env::current_dir() { - Ok(value) => &value.clone(), - _ => directory, - } + current_dir_or(directory) } else { - directory + directory.to_path_buf() }; - debug!("Looking for project root from directory: {:?}", from_dir); - let file_path = Path::new(from_dir).join("Cargo.toml"); + debug!("Looking for project root from directory: {:?}", &from_dir); + let file_path = Path::new(&from_dir).join("Cargo.toml"); if file_path.exists() { match from_dir.to_str() { @@ -808,10 +812,8 @@ pub(crate) fn get_project_root_for_path(directory: &PathBuf) -> Option { } pub(crate) fn get_project_root() -> Option { - match env::current_dir() { - Ok(directory) => get_project_root_for_path(&directory), - _ => None, - } + let directory = PathBuf::from("."); + get_project_root_for_path(&directory) } fn expand_env_for_script_runner_arguments(task: &mut Task) { From 7646eb273d86b601b5c9dc5a606b3a0b7b081f2e Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Fri, 18 Oct 2024 05:01:19 +0000 Subject: [PATCH 5/6] add example for workspace level relative usage #1175 --- examples/workspace/common.toml | 4 ++++ examples/workspace/member2/Makefile.toml | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 examples/workspace/common.toml diff --git a/examples/workspace/common.toml b/examples/workspace/common.toml new file mode 100644 index 00000000..5213ad4f --- /dev/null +++ b/examples/workspace/common.toml @@ -0,0 +1,4 @@ + +[tasks.common] +command = "echo" +args = ["common"] diff --git a/examples/workspace/member2/Makefile.toml b/examples/workspace/member2/Makefile.toml index fa403997..621dd2bc 100755 --- a/examples/workspace/member2/Makefile.toml +++ b/examples/workspace/member2/Makefile.toml @@ -1,3 +1,5 @@ +extend = { path = "./common.toml", relative = "workspace" } + [tasks.echo] script = ["echo hello from member2"] From 257e9bb5293a85a1a3eab5374ca46787e58b77f6 Mon Sep 17 00:00:00 2001 From: sagie gur ari Date: Sat, 19 Oct 2024 07:03:23 +0000 Subject: [PATCH 6/6] adding git root support #1175 --- CHANGELOG.md | 2 +- docs/_includes/content.md | 8 +++++-- examples/extends_list.toml | 2 ++ src/lib/descriptor/mod.rs | 26 ++++++++++++++++---- src/lib/descriptor/mod_test.rs | 44 ++++++++++++++++++++++++++++++++++ src/lib/environment/mod.rs | 25 +++++++++++++++++++ src/lib/types.rs | 4 ++-- 7 files changed, 101 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6871bd0..669a2b77 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### v0.37.23 -* Enhancement: support relative keyword for makefile extending to enable easy crate/workspace root extending #1175 +* Enhancement: support relative keyword for makefile extending to enable easy git/crate/workspace root extending #1175 * Maintenance: critical bug fix upgrade for duckscript ### v0.37.22 (2024-10-12) diff --git a/docs/_includes/content.md b/docs/_includes/content.md index 99b8de63..352ac455 100755 --- a/docs/_includes/content.md +++ b/docs/_includes/content.md @@ -1038,16 +1038,20 @@ extend = [ ] ``` -You can also change the relative path from the current makefile location to the crate root folder or workspace root folder by adding the relative keyword as follows: +You can also change the relative path from the current makefile location to the git root folder, crate root folder or workspace root folder by adding the relative keyword as follows: ```toml extend = { path = "./examples/python.toml", relative = "crate" } ``` Where relative can have the following values: + +* git - For nearest (up) .git folder location. * crate - For crate root (based on first Cargo.toml file) * workspace - For workspace root (based on second top Cargo.toml file) -Any other value defaults to the current makefile location. + +Any other value defaults to the current makefile location.
+Important to mention, all paths are relative from the currently parsed makefile. #### Automatically Extend Workspace Makefile diff --git a/examples/extends_list.toml b/examples/extends_list.toml index 0bb6b046..ce8fcdf3 100755 --- a/examples/extends_list.toml +++ b/examples/extends_list.toml @@ -3,7 +3,9 @@ extend = [ { path = "alias.toml" }, { path = "optional_makefile.toml", optional = true }, { path = "cwd.toml" }, + { path = "cwd.toml", relative = "bad" }, { path = "./examples/python.toml", relative = "crate" }, + { path = "./examples/javascript.toml", relative = "git" }, ] [config] diff --git a/src/lib/descriptor/mod.rs b/src/lib/descriptor/mod.rs index 08f05118..1dd292c1 100755 --- a/src/lib/descriptor/mod.rs +++ b/src/lib/descriptor/mod.rs @@ -32,6 +32,7 @@ use std::path::{Path, PathBuf}; #[derive(Debug)] enum RelativeTo { Makefile, + GitRoot, CrateRoot, WorkspaceRoot, } @@ -260,15 +261,22 @@ fn load_descriptor_extended_makefiles( } Extend::Options(extend_options) => { let force = !extend_options.optional.unwrap_or(false); - let relative_to = match extend_options + let relative_to_str = extend_options .relative .clone() - .unwrap_or("makefile".to_string()) - .as_str() - { + .unwrap_or("makefile".to_string()); + let relative_to = match relative_to_str.as_str() { + "git" => RelativeTo::GitRoot, "crate" => RelativeTo::CrateRoot, "workspace" => RelativeTo::WorkspaceRoot, - _ => RelativeTo::Makefile, + "makefile" => RelativeTo::Makefile, + _ => { + warn!( + "Unknown relative-to value: {}, defaulting to makefile", + &relative_to_str + ); + RelativeTo::Makefile + } }; load_external_descriptor(parent_path, &extend_options.path, force, false, relative_to) } @@ -329,6 +337,14 @@ fn load_external_descriptor( let descriptor_dir = match relative_to { RelativeTo::Makefile => base_path.to_string(), + RelativeTo::GitRoot => { + let git_root = environment::find_git_root(&PathBuf::from(base_path)); + debug!("git root: {:#?}", &git_root); + match git_root { + Some(git_root_dir) => git_root_dir.clone(), + None => base_path.to_string(), + } + } RelativeTo::CrateRoot => { let project_root = environment::get_project_root_for_path(&PathBuf::from(base_path)); debug!("project root: {:#?}", &project_root); diff --git a/src/lib/descriptor/mod_test.rs b/src/lib/descriptor/mod_test.rs index c6cafd07..efadf977 100755 --- a/src/lib/descriptor/mod_test.rs +++ b/src/lib/descriptor/mod_test.rs @@ -607,6 +607,50 @@ fn load_external_descriptor_extending_file_sub_folder() { assert_eq!(alias.unwrap(), "extended"); } +#[test] +#[ignore] +fn load_external_descriptor_simple_file_from_crate_root() { + let config = load_external_descriptor( + ".", + "./examples/alias.toml", + true, + false, + RelativeTo::CrateRoot, + ) + .unwrap(); + + assert!(config.config.is_none()); + assert!(config.env.is_none()); + assert!(config.tasks.is_some()); + + let tasks = config.tasks.unwrap(); + let test_task = tasks.get("D2").unwrap(); + let alias = test_task.alias.clone(); + assert_eq!(alias.unwrap(), "D"); +} + +#[test] +#[ignore] +fn load_external_descriptor_simple_file_from_git_root() { + let config = load_external_descriptor( + ".", + "./examples/alias.toml", + true, + false, + RelativeTo::GitRoot, + ) + .unwrap(); + + assert!(config.config.is_none()); + assert!(config.env.is_none()); + assert!(config.tasks.is_some()); + + let tasks = config.tasks.unwrap(); + let test_task = tasks.get("D2").unwrap(); + let alias = test_task.alias.clone(); + assert_eq!(alias.unwrap(), "D"); +} + #[test] #[ignore] fn load_external_descriptor_set_env() { diff --git a/src/lib/environment/mod.rs b/src/lib/environment/mod.rs index d296cfc4..814d8469 100644 --- a/src/lib/environment/mod.rs +++ b/src/lib/environment/mod.rs @@ -786,6 +786,31 @@ fn current_dir_or(fallback: &PathBuf) -> PathBuf { } } +pub(crate) fn find_git_root(directory: &PathBuf) -> Option { + let from_dir = if directory.to_str().unwrap_or(".") == "." { + current_dir_or(directory) + } else { + directory.to_path_buf() + }; + debug!("Looking for git root from directory: {:?}", &from_dir); + let file_path = Path::new(&from_dir).join(".git"); + + if file_path.exists() { + match from_dir.to_str() { + Some(directory_string) => Some(directory_string.to_string()), + _ => None, + } + } else { + match from_dir.parent() { + Some(parent_directory) => { + let parent_directory_path = parent_directory.to_path_buf(); + find_git_root(&parent_directory_path) + } + None => None, + } + } +} + pub(crate) fn get_project_root_for_path(directory: &PathBuf) -> Option { let from_dir = if directory.to_str().unwrap_or(".") == "." { current_dir_or(directory) diff --git a/src/lib/types.rs b/src/lib/types.rs index f4bb8cb6..9f4fe0a7 100755 --- a/src/lib/types.rs +++ b/src/lib/types.rs @@ -2072,8 +2072,8 @@ pub struct ExtendOptions { pub path: String, /// Enable optional extend (default to false) pub optional: Option, - /// Relative to option, sub as current makefile, crate root, workspace root, etc... - /// Possible values: (makefile, crate, workspace) + /// Relative to option, sub as current makefile, git root, crate root, workspace root, etc... + /// Possible values: (makefile, git, crate, workspace) pub relative: Option, }