diff --git a/crates/config/src/toolchain_config.rs b/crates/config/src/toolchain_config.rs index 21bcda74c5b..ec5baad23c9 100644 --- a/crates/config/src/toolchain_config.rs +++ b/crates/config/src/toolchain_config.rs @@ -98,6 +98,7 @@ impl ToolchainConfig { tools.push(Id::raw("rust")); } + tools.push(Id::raw("system")); tools } diff --git a/crates/project-builder/src/project_builder.rs b/crates/project-builder/src/project_builder.rs index 81edd5897c9..35e5a9a8f02 100644 --- a/crates/project-builder/src/project_builder.rs +++ b/crates/project-builder/src/project_builder.rs @@ -117,6 +117,7 @@ impl<'app> ProjectBuilder<'app> { // Infer toolchains from language if self.toolchains.is_empty() { self.toolchains = detect_project_toolchains( + self.context.workspace_root, &self.root, &self.language, self.context.enabled_toolchains, @@ -198,6 +199,7 @@ impl<'app> ProjectBuilder<'app> { language: self.language, root: self.root, source: self.source.to_owned(), + toolchains: self.toolchains, ..Project::default() }; diff --git a/crates/project-builder/tests/__fixtures__/builder/baz/moon.yml b/crates/project-builder/tests/__fixtures__/builder/baz/moon.yml index 2dc6404bb8b..a4a35eb3f4a 100644 --- a/crates/project-builder/tests/__fixtures__/builder/baz/moon.yml +++ b/crates/project-builder/tests/__fixtures__/builder/baz/moon.yml @@ -1,5 +1,4 @@ language: 'javascript' -platform: 'node' dependsOn: - 'bar' diff --git a/crates/project-builder/tests/__fixtures__/builder/foo/tsconfig.json b/crates/project-builder/tests/__fixtures__/builder/baz/package.json similarity index 100% rename from crates/project-builder/tests/__fixtures__/builder/foo/tsconfig.json rename to crates/project-builder/tests/__fixtures__/builder/baz/package.json diff --git a/crates/project-builder/tests/__fixtures__/builder/foo/package.json b/crates/project-builder/tests/__fixtures__/builder/foo/package.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/crates/project-builder/tests/__fixtures__/builder/foo/package.json @@ -0,0 +1 @@ +{} diff --git a/crates/project-builder/tests/__fixtures__/builder/qux/tsconfig.json b/crates/project-builder/tests/__fixtures__/builder/qux/tsconfig.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/crates/project-builder/tests/__fixtures__/builder/qux/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/crates/project-builder/tests/__fixtures__/langs/bun/moon.yml b/crates/project-builder/tests/__fixtures__/langs/bun/moon.yml index 7ac30045466..47cdd62df44 100644 --- a/crates/project-builder/tests/__fixtures__/langs/bun/moon.yml +++ b/crates/project-builder/tests/__fixtures__/langs/bun/moon.yml @@ -1,3 +1,3 @@ language: javascript type: application -platform: bun +platform: bun # deprecated diff --git a/crates/project-builder/tests/__fixtures__/langs/deno/moon.yml b/crates/project-builder/tests/__fixtures__/langs/deno/moon.yml index 866335d2bc2..abcce43db73 100644 --- a/crates/project-builder/tests/__fixtures__/langs/deno/moon.yml +++ b/crates/project-builder/tests/__fixtures__/langs/deno/moon.yml @@ -1,3 +1,3 @@ language: javascript type: application -platform: deno +platform: deno # deprecated diff --git a/crates/project-builder/tests/__fixtures__/langs/project-platform/moon.yml b/crates/project-builder/tests/__fixtures__/langs/project-platform/moon.yml index cce9d2705dc..7556b031681 100644 --- a/crates/project-builder/tests/__fixtures__/langs/project-platform/moon.yml +++ b/crates/project-builder/tests/__fixtures__/langs/project-platform/moon.yml @@ -1,5 +1,3 @@ -platform: node - tasks: node-a: command: noop diff --git a/crates/project-builder/tests/__fixtures__/langs/project-platform/package.json b/crates/project-builder/tests/__fixtures__/langs/project-platform/package.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/crates/project-builder/tests/__fixtures__/langs/project-platform/package.json @@ -0,0 +1 @@ +{} diff --git a/crates/project-builder/tests/project_builder_test.rs b/crates/project-builder/tests/project_builder_test.rs index de183914e34..9409f811a93 100644 --- a/crates/project-builder/tests/project_builder_test.rs +++ b/crates/project-builder/tests/project_builder_test.rs @@ -1,8 +1,8 @@ use moon_common::path::WorkspaceRelativePathBuf; use moon_common::Id; use moon_config::{ - ConfigLoader, DependencyConfig, DependencyScope, DependencySource, LanguageType, NodeConfig, - PlatformType, RustConfig, TaskArgs, TaskConfig, ToolchainConfig, + BunConfig, ConfigLoader, DenoConfig, DependencyConfig, DependencyScope, DependencySource, + LanguageType, NodeConfig, RustConfig, TaskArgs, TaskConfig, ToolchainConfig, }; use moon_file_group::FileGroup; use moon_project::Project; @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; // We need some top-level struct to hold the data used for lifetime refs. struct Stub { config_loader: ConfigLoader, + enabled_toolchains: Vec, toolchain_config: ToolchainConfig, workspace_root: PathBuf, id: Id, @@ -24,6 +25,8 @@ impl Stub { pub fn new(id: &str, root: &Path) -> Self { // Enable platforms so that detection works let toolchain_config = ToolchainConfig { + bun: Some(BunConfig::default()), + deno: Some(DenoConfig::default()), node: Some(NodeConfig::default()), rust: Some(RustConfig::default()), ..ToolchainConfig::default() @@ -31,6 +34,7 @@ impl Stub { Self { config_loader: ConfigLoader::default(), + enabled_toolchains: toolchain_config.get_enabled(), toolchain_config, workspace_root: root.to_path_buf(), id: Id::raw(id), @@ -44,6 +48,7 @@ impl Stub { &self.source, ProjectBuilderContext { config_loader: &self.config_loader, + enabled_toolchains: &self.enabled_toolchains, monorepo: true, root_project_id: None, toolchain_config: &self.toolchain_config, @@ -224,7 +229,7 @@ mod project_builder { #[tokio::test] async fn detects_from_env() { let sandbox = create_sandbox("builder"); - let project = build_project_without_inherited("foo", sandbox.path()).await; + let project = build_project_without_inherited("qux", sandbox.path()).await; assert_eq!(project.language, LanguageType::TypeScript); } @@ -234,7 +239,7 @@ mod project_builder { let project = build_lang_project("bash").await; assert_eq!(project.language, LanguageType::Bash); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -242,7 +247,7 @@ mod project_builder { let project = build_lang_project("batch").await; assert_eq!(project.language, LanguageType::Batch); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -250,12 +255,12 @@ mod project_builder { let project = build_lang_project("bun").await; assert_eq!(project.language, LanguageType::JavaScript); - assert_eq!(project.platform, PlatformType::Bun); + assert_eq!(project.toolchains, vec![Id::raw("system")]); // no configs let project = build_lang_project("bun-config").await; assert_eq!(project.language, LanguageType::JavaScript); - // assert_eq!(project.platform, PlatformType::Bun); + assert_eq!(project.toolchains, vec![Id::raw("bun")]); } #[tokio::test] @@ -263,12 +268,12 @@ mod project_builder { let project = build_lang_project("deno").await; assert_eq!(project.language, LanguageType::JavaScript); - assert_eq!(project.platform, PlatformType::Deno); + assert_eq!(project.toolchains, vec![Id::raw("system")]); // no configs let project = build_lang_project("deno-config").await; assert_eq!(project.language, LanguageType::TypeScript); - // assert_eq!(project.platform, PlatformType::Deno); + assert_eq!(project.toolchains, vec![Id::raw("deno")]); } #[tokio::test] @@ -276,12 +281,12 @@ mod project_builder { let project = build_lang_project("go").await; assert_eq!(project.language, LanguageType::Go); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); let project = build_lang_project("go-config").await; assert_eq!(project.language, LanguageType::Go); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -289,12 +294,12 @@ mod project_builder { let project = build_lang_project("js").await; assert_eq!(project.language, LanguageType::JavaScript); - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("system")]); // no configs let project = build_lang_project("js-config").await; assert_eq!(project.language, LanguageType::JavaScript); - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("node")]); } #[tokio::test] @@ -305,7 +310,7 @@ mod project_builder { project.language, LanguageType::Other("kotlin".try_into().unwrap()) ); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -313,12 +318,12 @@ mod project_builder { let project = build_lang_project("php").await; assert_eq!(project.language, LanguageType::Php); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); let project = build_lang_project("php-config").await; assert_eq!(project.language, LanguageType::Php); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -326,12 +331,12 @@ mod project_builder { let project = build_lang_project("python").await; assert_eq!(project.language, LanguageType::Python); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); let project = build_lang_project("python-config").await; assert_eq!(project.language, LanguageType::Python); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -339,12 +344,12 @@ mod project_builder { let project = build_lang_project("ruby").await; assert_eq!(project.language, LanguageType::Ruby); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); let project = build_lang_project("ruby-config").await; assert_eq!(project.language, LanguageType::Ruby); - assert_eq!(project.platform, PlatformType::System); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } #[tokio::test] @@ -352,12 +357,12 @@ mod project_builder { let project = build_lang_project("rust").await; assert_eq!(project.language, LanguageType::Rust); - assert_eq!(project.platform, PlatformType::Rust); + assert_eq!(project.toolchains, vec![Id::raw("rust")]); let project = build_lang_project("rust-config").await; assert_eq!(project.language, LanguageType::Rust); - assert_eq!(project.platform, PlatformType::Rust); + assert_eq!(project.toolchains, vec![Id::raw("rust")]); } #[tokio::test] @@ -365,12 +370,12 @@ mod project_builder { let project = build_lang_project("ts").await; assert_eq!(project.language, LanguageType::TypeScript); - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("system")]); let project = build_lang_project("ts-config").await; assert_eq!(project.language, LanguageType::TypeScript); - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("system")]); } } @@ -382,7 +387,7 @@ mod project_builder { let sandbox = create_sandbox("builder"); let project = build_project_without_inherited("baz", sandbox.path()).await; - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("node")]); } #[tokio::test] @@ -390,7 +395,7 @@ mod project_builder { let sandbox = create_sandbox("builder"); let project = build_project_without_inherited("bar", sandbox.path()).await; - assert_eq!(project.platform, PlatformType::Rust); + assert_eq!(project.toolchains, vec![Id::raw("rust")]); } #[tokio::test] @@ -398,7 +403,7 @@ mod project_builder { let sandbox = create_sandbox("builder"); let project = build_project_without_inherited("foo", sandbox.path()).await; - assert_eq!(project.platform, PlatformType::Node); + assert_eq!(project.toolchains, vec![Id::raw("node")]); } #[tokio::test] @@ -406,18 +411,18 @@ mod project_builder { let project = build_lang_project("project-platform").await; assert_eq!( - project.tasks.get("node-a").unwrap().platform, - PlatformType::Node + project.tasks.get("node-a").unwrap().toolchains, + vec![Id::raw("node")] ); assert_eq!( - project.tasks.get("node-b").unwrap().platform, - PlatformType::Node + project.tasks.get("node-b").unwrap().toolchains, + vec![Id::raw("node")] ); assert_eq!( - project.tasks.get("system").unwrap().platform, - PlatformType::System + project.tasks.get("system").unwrap().toolchains, + vec![Id::raw("system")] ); } } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 0189d9792de..e86919c6cb9 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -66,6 +66,9 @@ cacheable!( /// Includes internal tasks! pub task_targets: Vec, + /// Toolchains derived from the configured language. + pub toolchains: Vec, + /// The type of project. #[serde(rename = "type")] pub type_of: ProjectType, diff --git a/crates/task-runner/src/task_runner.rs b/crates/task-runner/src/task_runner.rs index e743833b483..56bb76c91ed 100644 --- a/crates/task-runner/src/task_runner.rs +++ b/crates/task-runner/src/task_runner.rs @@ -437,7 +437,7 @@ impl<'task> TaskRunner<'task> { // Hash platform fields trace!( task_target = self.task.target.as_str(), - toolchains = ?self.task.toolchains.iter().map(|t| t.as_str()).collect::>(), + toolchains = ?self.task.toolchains.iter().map(|tc| tc.as_str()).collect::>(), "Including toolchain specific fields in the hash" ); diff --git a/crates/toolchain/src/detect/project_toolchain.rs b/crates/toolchain/src/detect/project_toolchain.rs index 61a73b08e63..21e6a0baa41 100644 --- a/crates/toolchain/src/detect/project_toolchain.rs +++ b/crates/toolchain/src/detect/project_toolchain.rs @@ -5,7 +5,8 @@ use moon_config::LanguageType; use std::path::Path; pub fn detect_project_toolchains( - root: &Path, + workspace_root: &Path, + project_root: &Path, language: &LanguageType, enabled_toolchains: &[Id], ) -> Vec { @@ -18,23 +19,40 @@ pub fn detect_project_toolchains( (Id::raw("bun"), BUN), (Id::raw("node"), NODE), ]; + let mut found = false; + // Detect in project first + for (id, files) in &runtimes { + if has_language_files(project_root, files) { + toolchains.push(id.to_owned()); + found = true; + break; + } + } + + // Then in workspace for (id, files) in runtimes { - if enabled_toolchains.contains(&id) && has_language_files(root, files) { + if !found && has_language_files(workspace_root, files) { toolchains.push(id); - toolchains.extend(language.get_toolchain_ids()); break; } } + + toolchains.extend(language.get_toolchain_ids()); } other => { - let id = Id::raw(other.to_string()); - - if enabled_toolchains.contains(&id) { - toolchains.push(id); - } + toolchains.push(Id::raw(other.to_string())); } }; + let mut toolchains = toolchains + .into_iter() + .filter(|id| enabled_toolchains.contains(&id)) + .collect::>(); + + if toolchains.is_empty() { + toolchains.push(Id::raw("system")); + } + toolchains }