Skip to content

Commit

Permalink
Update task config.
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Dec 17, 2024
1 parent 6e9a499 commit a796501
Show file tree
Hide file tree
Showing 24 changed files with 245 additions and 125 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions crates/app/src/commands/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ pub async fn project(session: CliSession, args: ProjectArgs) -> AppResult {
console.print_entry("Root", color::path(&project.root))?;
}

if let Some(toolchain) = &project.toolchain {
console.print_entry("Toolchain", toolchain)?;
}

if project.platform.is_javascript() {
console.print_entry("Platform", format!("{}", &project.platform))?;
}
Expand Down
4 changes: 4 additions & 0 deletions crates/app/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ pub struct QueryTasksArgs {
#[arg(long, help = "Filter tasks with the provided script", help_heading = HEADING_FILTERS)]
script: Option<String>,

#[arg(long, help = "Filter tasks that belong to a toolchain", help_heading = HEADING_FILTERS)]
toolchain: Option<String>,

#[arg(long = "type", help = "Filter projects of this type", help_heading = HEADING_FILTERS)]
type_of: Option<String>,
}
Expand All @@ -362,6 +365,7 @@ pub async fn tasks(session: CliSession, args: QueryTasksArgs) -> AppResult {
platform: args.platform,
project: args.project,
script: args.script,
toolchain: args.toolchain,
type_of: args.type_of,
..QueryTasksOptions::default()
};
Expand Down
1 change: 1 addition & 0 deletions crates/app/src/commands/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub async fn task(session: CliSession, args: TaskArgs) -> AppResult {

console.print_entry("Task", color::id(&args.target.task_id))?;
console.print_entry("Project", color::id(&project.id))?;
console.print_entry("Toolchains", task.toolchains.join(", "))?;
console.print_entry("Platform", format!("{}", &task.platform))?;
console.print_entry("Type", format!("{}", &task.type_of))?;

Expand Down
8 changes: 8 additions & 0 deletions crates/app/src/queries/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct QueryTasksOptions {
pub platform: Option<String>,
pub project: Option<String>,
pub script: Option<String>,
pub toolchain: Option<String>,
#[serde(rename = "type")]
pub type_of: Option<String>,
}
Expand All @@ -45,6 +46,7 @@ fn load_with_regex(
let platform_regex = convert_to_regex("platform", &options.platform)?;
let project_regex = convert_to_regex("project", &options.project)?;
let script_regex = convert_to_regex("script", &options.script)?;
let toolchain_regex = convert_to_regex("toolchain", &options.toolchain)?;
let type_regex = convert_to_regex("type", &options.type_of)?;
let mut filtered = vec![];

Expand Down Expand Up @@ -79,6 +81,12 @@ fn load_with_regex(
}
}

if let Some(regex) = &toolchain_regex {
if !task.toolchains.iter().any(|tc| regex.is_match(&tc)) {
continue;
}
}

if let Some(regex) = &type_regex {
if !regex.is_match(&task.type_of.to_string()) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion crates/config/src/inherited_tasks_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ impl InheritedTasksManager {

// Only modify tasks for `tasks/*.*` files instead of `tasks.*`,
// as the latter will be globbed alongside toolchain/workspace configs.
// We also don't know what platform each of the tasks should be yet.
// We also don't know what toolchain each of the tasks should be yet.
if let Some(tasks) = &mut managed_config.tasks {
for (task_id, task) in tasks.iter_mut() {
if lookup != "*" {
Expand Down
23 changes: 22 additions & 1 deletion crates/config/src/language_platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ pub enum LanguageType {

impl LanguageType {
pub fn other(id: &str) -> Result<LanguageType, IdError> {
Ok(LanguageType::Other(Id::new(id)?))
Ok(Self::Other(Id::new(id)?))
}

pub fn get_toolchain_ids(&self) -> Vec<Id> {
match self {
Self::Bash | Self::Batch | Self::Unknown => vec![Id::raw("system")],
Self::TypeScript => vec![Id::raw("typescript"), Id::raw("javascript")],
Self::Other(id) => vec![id.to_owned()],
other => vec![Id::raw(other.to_string().to_lowercase())],
}
}
}

Expand Down Expand Up @@ -93,6 +102,18 @@ impl PlatformType {
pub fn is_unknown(&self) -> bool {
matches!(self, PlatformType::Unknown)
}

pub fn get_toolchain_ids(&self) -> Vec<Id> {
match self {
PlatformType::Bun => vec![Id::raw("bun"), Id::raw("javascript")],
PlatformType::Deno => vec![Id::raw("deno"), Id::raw("javascript")],
PlatformType::Node => vec![Id::raw("node"), Id::raw("javascript")],
PlatformType::Python => vec![Id::raw("python")],
PlatformType::Rust => vec![Id::raw("rust")],
PlatformType::System => vec![Id::raw("system")],
PlatformType::Unknown => vec![],
}
}
}

#[cfg(test)]
Expand Down
8 changes: 7 additions & 1 deletion crates/config/src/project/task_config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::language_platform::PlatformType;
use crate::project::{PartialTaskOptionsConfig, TaskOptionsConfig};
use crate::shapes::{InputPath, OutputPath};
use crate::shapes::{InputPath, OneOrMany, OutputPath};
use moon_common::{cacheable, Id};
use moon_target::{Target, TargetScope};
use rustc_hash::FxHashMap;
Expand Down Expand Up @@ -222,6 +222,7 @@ cacheable!(
/// The platform in which the task will be ran in. The platform determines
/// available binaries, lookup paths, and more. When not provided, will
/// be automatically detected.
#[deprecated(note = "Use `toolchain` instead.")]
pub platform: PlatformType,

/// The preset to apply for the task. Will inherit default options.
Expand All @@ -232,6 +233,11 @@ cacheable!(
/// arguments, merging, or inheritance.
pub script: Option<String>,

/// The toolchain(s) in which the task will be ran in. The toolchain determines
/// available binaries, lookup paths, and more. When not provided, will
/// be automatically detected.
pub toolchain: OneOrMany<Id>,

/// The type of task, primarily used for categorical reasons. When not provided,
/// will be automatically determined.
#[serde(rename = "type")]
Expand Down
7 changes: 7 additions & 0 deletions crates/config/src/shapes/poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ impl<T: Schematic> Default for OneOrMany<T> {
}

impl<T: Schematic + Clone> OneOrMany<T> {
pub fn is_empty(&self) -> bool {
match self {
Self::One(item) => false,
Self::Many(list) => list.is_empty(),
}
}

pub fn to_list(&self) -> Vec<T> {
match self {
Self::One(item) => vec![item.to_owned()],
Expand Down
26 changes: 26 additions & 0 deletions crates/config/src/toolchain_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,32 @@ pub struct ToolchainConfig {
}

impl ToolchainConfig {
pub fn get_enabled(&self) -> Vec<Id> {
let mut tools = self.toolchains.keys().cloned().collect::<Vec<_>>();

if self.bun.is_some() {
tools.push(Id::raw("bun"));
}

if self.deno.is_some() {
tools.push(Id::raw("deno"));
}

if self.node.is_some() {
tools.push(Id::raw("node"));
}

if self.python.is_some() {
tools.push(Id::raw("python"))
}

if self.rust.is_some() {
tools.push(Id::raw("rust"));
}

tools
}

pub fn get_enabled_platforms(&self) -> Vec<PlatformType> {
let mut tools = vec![];

Expand Down
2 changes: 1 addition & 1 deletion crates/project-builder/src/project_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ impl<'app> ProjectBuilder<'app> {
let mut tasks_builder = TasksBuilder::new(
self.id,
self.source,
&self.platform,
&self.language,
TasksBuilderContext {
monorepo: self.context.monorepo,
toolchain_config: self.context.toolchain_config,
Expand Down
10 changes: 7 additions & 3 deletions crates/project/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ cacheable!(
pub language: LanguageType,

/// Default platform to run tasks against.
#[deprecated]
pub platform: PlatformType,

/// The technology stack of the project.
pub stack: StackType,

/// Absolute path to the project's root folder.
pub root: PathBuf,

/// The technology stack of the project.
pub stack: StackType,

/// Relative path from the workspace root to the project root.
/// Is the RHS of the `projects` setting.
pub source: WorkspaceRelativePathBuf,
Expand All @@ -64,6 +65,9 @@ cacheable!(
/// Includes internal tasks!
pub task_targets: Vec<Target>,

/// Default toolchain to run tasks against.
pub toolchain: Option<Id>,

/// The type of project.
#[serde(rename = "type")]
pub type_of: ProjectType,
Expand Down
1 change: 1 addition & 0 deletions crates/query/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum Field<'l> {
Tag(FieldValues<'l>),
Task(FieldValues<'l>),
TaskPlatform(Vec<PlatformType>),
TaskToolchain(FieldValues<'l>),
TaskType(Vec<TaskType>),
}

Expand Down
46 changes: 26 additions & 20 deletions crates/task-builder/src/tasks_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use crate::tasks_builder_error::TasksBuilderError;
use moon_common::path::{is_root_level_source, WorkspaceRelativePath};
use moon_common::{color, supports_pkl_configs, Id};
use moon_config::{
is_glob_like, InheritedTasksConfig, InputPath, PlatformType, ProjectConfig,
is_glob_like, InheritedTasksConfig, InputPath, LanguageType, ProjectConfig,
ProjectWorkspaceInheritedTasksConfig, TaskArgs, TaskConfig, TaskDependency,
TaskDependencyConfig, TaskMergeStrategy, TaskOptionRunInCI, TaskOptionsConfig, TaskOutputStyle,
TaskPreset, TaskType, ToolchainConfig,
};
use moon_target::Target;
use moon_task::{Task, TaskOptions};
use moon_task_args::parse_task_args;
use moon_toolchain::detect::detect_task_platform;
use moon_toolchain::detect::detect_task_toolchains;
use rustc_hash::{FxHashMap, FxHashSet};
use std::collections::BTreeMap;
use std::hash::Hash;
Expand Down Expand Up @@ -72,10 +72,11 @@ pub struct TasksBuilderContext<'proj> {
#[derive(Debug)]
pub struct TasksBuilder<'proj> {
context: TasksBuilderContext<'proj>,
enabled_toolchains: Vec<Id>,

project_id: &'proj Id,
project_env: FxHashMap<&'proj str, &'proj str>,
project_platform: &'proj PlatformType,
project_language: &'proj LanguageType,
project_source: &'proj WorkspaceRelativePath,

// Global settings for tasks to inherit
Expand All @@ -94,14 +95,15 @@ impl<'proj> TasksBuilder<'proj> {
pub fn new(
project_id: &'proj Id,
project_source: &'proj WorkspaceRelativePath,
project_platform: &'proj PlatformType,
project_language: &'proj LanguageType,
context: TasksBuilderContext<'proj>,
) -> Self {
Self {
enabled_toolchains: context.toolchain_config.get_enabled(),
context,
project_id,
project_env: FxHashMap::default(),
project_platform,
project_language,
project_source,
implicit_deps: vec![],
implicit_inputs: vec![],
Expand Down Expand Up @@ -384,10 +386,16 @@ impl<'proj> TasksBuilder<'proj> {
);
}

// Backwards compat
#[allow(deprecated)]
if !config.platform.is_unknown() {
task.platform = config.platform;
}

if !config.toolchain.is_empty() {
task.toolchains = config.toolchain.to_list();
}

if config.description.is_some() {
task.description = config.description.clone();
}
Expand Down Expand Up @@ -424,7 +432,7 @@ impl<'proj> TasksBuilder<'proj> {
// If a script, wipe out inherited arguments, and extract the first command
if let Some(script) = &task.script {
task.args.clear();
task.platform = PlatformType::System;
task.toolchains = vec![Id::raw("system")];

if let Some(i) = script.find(' ') {
task.command = script[0..i].to_owned();
Expand Down Expand Up @@ -460,21 +468,19 @@ impl<'proj> TasksBuilder<'proj> {
);
}

if task.platform.is_unknown() {
let platform = detect_task_platform(
// Backwards compat for when the user has explicitly configured
// the deprecated `platform` setting
#[allow(deprecated)]
if !task.platform.is_unknown() && task.toolchains.is_empty() {
task.toolchains = task.platform.get_toolchain_ids();
}

if task.toolchains.is_empty() {
task.toolchains = detect_task_toolchains(
&task.command,
&self.context.toolchain_config.get_enabled_platforms(),
&self.project_language,
&self.enabled_toolchains,
);

task.platform = if platform.is_unknown() {
if self.project_platform.is_unknown() {
PlatformType::System
} else {
self.project_platform.to_owned()
}
} else {
platform
};
}

task.type_of = if !task.outputs.is_empty() {
Expand All @@ -489,7 +495,7 @@ impl<'proj> TasksBuilder<'proj> {

if task.options.shell.is_none() {
// Windows requires a shell for path resolution to work correctly
if cfg!(windows) || task.platform.is_system() || task.script.is_some() {
if cfg!(windows) || task.is_system_toolchain() || task.script.is_some() {
task.options.shell = Some(true);
}

Expand Down
2 changes: 2 additions & 0 deletions crates/task-expander/src/token_expander.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ impl<'graph> TokenExpander<'graph> {
"target" => Cow::Borrowed(task.target.as_str()),
"task" => Cow::Borrowed(task.id.as_str()),
"taskPlatform" => Cow::Owned(task.platform.to_string()),
"taskToolchain" => Cow::Borrowed(task.toolchains[0].as_str()),
"taskToolchains" => Cow::Owned(task.toolchains.join(",")),
"taskType" => Cow::Owned(task.type_of.to_string()),
// Datetime
"date" => Cow::Owned(now_timestamp().format("%F").to_string()),
Expand Down
Loading

0 comments on commit a796501

Please sign in to comment.