Skip to content

Commit

Permalink
internal: Add new toolchain settings to tasks, projects, and more. (#…
Browse files Browse the repository at this point in the history
…1757)

* Update task config.

* Polish.

* Update queries.

* Update builders.

* Fix config tests.

* Update tests.

* Update changelog.

* Update infer tasks.

* Fix task builder.

* Update manager.

* Rework runtime.

* Polish.

* Update action tests.

* Fix some tests.

* Polish.

* Polish.

* Improve output.

* Fix bun.

* Update snaps.

* Update docs.

* Fix lint.
  • Loading branch information
milesj authored Jan 1, 2025
1 parent 8331002 commit 3970a14
Show file tree
Hide file tree
Showing 155 changed files with 1,566 additions and 1,020 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,24 @@

## Unreleased

#### 💥 Breaking

- We've updated the task inheritance order to better reflect specificity. The biggest changes are
that deno/node/bun are now a higher priority than javascript/typescript, and stack is the lowest
priority. This should only affect users with very complex inheritance chains.

#### 🚀 Updates

- We are deprecating the concept of a task "platform", as this is required for the next step in
supporting WASM based toolchain plugins. Going forward, any reference to platform is now a
toolchain. The following changes have been made:
- Deprecated the `platform` task setting, use `toolchain` instead.
- Deprecated the `taskPlatform` query field, use `taskToolchain` instead.
- Deprecated the `--platform` option for `moon query tasks`, use `--toolchain` instead.
- Deprecated the `$taskPlatform` token, use `$taskToolchain` instead.
- Deprecated the top-level `platform` setting from `moon.yml`, use `toolchain.default` instead.
- Additionally, the toolchain can now be inferred from the top-level `language` setting and any
config files in the project/workspace root. This pattern is preferred when possible.
- Updated task option `runInCI` to support the values "always" (always run) and "affected" (only run
if affected, same as `true`).

Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 29 additions & 36 deletions crates/action-graph/src/action_graph_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use moon_action_context::{ActionContext, TargetState};
use moon_affected::{AffectedTracker, DownstreamScope, UpstreamScope};
use moon_common::path::WorkspaceRelativePathBuf;
use moon_common::{color, Id};
use moon_config::{PlatformType, TaskDependencyConfig};
use moon_config::TaskDependencyConfig;
use moon_platform::{PlatformManager, Runtime};
use moon_project::Project;
use moon_query::{build_query, Criteria};
Expand Down Expand Up @@ -112,16 +112,8 @@ impl<'app> ActionGraphBuilder<'app> {
self.indices.get(node)
}

pub fn get_runtime(
&self,
project: &Project,
platform_type: PlatformType,
allow_override: bool,
) -> Runtime {
if let Some(platform) = self
.platform_manager
.find(|p| p.get_type() == platform_type)
{
pub fn get_runtime(&self, project: &Project, toolchain: &Id, allow_override: bool) -> Runtime {
if let Ok(platform) = self.platform_manager.get_by_toolchain(toolchain) {
return platform.get_runtime_from_config(if allow_override {
Some(&project.config)
} else {
Expand Down Expand Up @@ -179,51 +171,52 @@ impl<'app> ActionGraphBuilder<'app> {
task: Option<&Task>,
) -> miette::Result<Option<NodeIndex>> {
let mut in_project = false;
let mut platform_type = task.map(|t| t.platform).unwrap_or_else(|| project.platform);

// If project is NOT in the package manager workspace, then we should
// install dependencies in the project, not the workspace root.
if let Ok(platform) = self.platform_manager.get(platform_type) {
if !platform.is_project_in_dependency_workspace(project.source.as_str())? {
in_project = true;

debug!(
"Project {} is not within the dependency manager workspace, dependencies will be installed within the project instead of the root",
color::id(&project.id),
);
}
}
let toolchains = task
.map(|t| &t.toolchains)
.unwrap_or_else(|| &project.toolchains);
let mut primary_toolchain = toolchains[0].to_owned();

// If Bun and Node.js are enabled, they will both attempt to install
// dependencies in the target root. We need to avoid this problem,
// so always prefer Node.js instead. Revisit in the future.
if matches!(platform_type, PlatformType::Bun)
if primary_toolchain == "bun"
&& self
.platform_manager
.enabled()
.any(|enabled_platform| matches!(enabled_platform, PlatformType::Node))
.any(|enabled_platform| enabled_platform == "node")
{
debug!(
"Already installing dependencies with {}, skipping a conflicting install from {}",
PlatformType::Node,
platform_type,
"Already installing dependencies with node, skipping a conflicting install from bun"
);

platform_type = PlatformType::Node;
primary_toolchain = Id::raw("node")
}

// If project is NOT in the package manager workspace, then we should
// install dependencies in the project, not the workspace root.
if let Ok(platform) = self.platform_manager.get_by_toolchain(&primary_toolchain) {
if !platform.is_project_in_dependency_workspace(project.source.as_str())? {
in_project = true;

debug!(
"Project {} is not within the dependency manager workspace, dependencies will be installed within the project instead of the root",
color::id(&project.id),
);
}
}

let node = if in_project {
ActionNode::install_project_deps(InstallProjectDepsNode {
project: project.id.to_owned(),
runtime: self.get_runtime(project, platform_type, true),
runtime: self.get_runtime(project, &primary_toolchain, true),
})
} else {
ActionNode::install_workspace_deps(InstallWorkspaceDepsNode {
runtime: self.get_runtime(project, platform_type, false),
runtime: self.get_runtime(project, &primary_toolchain, false),
})
};

if node.get_runtime().platform.is_system() {
if node.get_runtime().is_system() {
return Ok(None);
}

Expand Down Expand Up @@ -323,7 +316,7 @@ impl<'app> ActionGraphBuilder<'app> {
env,
interactive: task.is_interactive() || reqs.interactive,
persistent: task.is_persistent(),
runtime: self.get_runtime(project, task.platform, true),
runtime: self.get_runtime(project, &task.toolchains[0], true),
target: task.target.to_owned(),
id: None,
});
Expand Down Expand Up @@ -604,7 +597,7 @@ impl<'app> ActionGraphBuilder<'app> {
) -> miette::Result<NodeIndex> {
let node = ActionNode::sync_project(SyncProjectNode {
project: project.id.clone(),
runtime: self.get_runtime(project, project.platform, true),
runtime: self.get_runtime(project, &project.toolchains[0], true),
});

if let Some(index) = self.get_index_from_node(&node) {
Expand Down
Loading

0 comments on commit 3970a14

Please sign in to comment.