Skip to content

Commit

Permalink
feat: Show all available task with task list (#1286)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruben Arts <ruben.arts@hotmail.com>
Co-authored-by: Ruben Arts <ruben@prefix.dev>
Co-authored-by: Tim de Jager <tdejager89@gmail.com>
  • Loading branch information
4 people authored May 1, 2024
1 parent 621b732 commit f67351e
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 25 deletions.
4 changes: 4 additions & 0 deletions docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ You can modify this table using [`pixi task`](cli.md#task).
!!! note
Specify different tasks for different platforms using the [target](#the-target-table) table

!!! info
If you want to hide a task from showing up with `pixi task list` or `pixi info`, you can prefix the name with `_`.
For example, if you want to hide `depending`, you can rename it to `_depending`.

## The `system-requirements` table

The system requirements are used to define minimal system specifications used during dependency resolution.
Expand Down
12 changes: 11 additions & 1 deletion src/cli/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,17 @@ impl Display for EnvironmentInfo {
)?;
}
if !self.tasks.is_empty() {
let tasks_list = self.tasks.iter().map(|t| t.fancy_display()).format(", ");
let tasks_list = self
.tasks
.iter()
.filter_map(|t| {
if !t.as_str().starts_with('_') {
Some(t.fancy_display())
} else {
None
}
})
.format(", ");
writeln!(f, "{:>WIDTH$}: {}", bold.apply_to("Tasks"), tasks_list)?;
}
Ok(())
Expand Down
14 changes: 2 additions & 12 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,13 @@ pub async fn execute(args: Args) -> miette::Result<()> {
fn command_not_found<'p>(project: &'p Project, explicit_environment: Option<Environment<'p>>) {
let available_tasks: HashSet<TaskName> =
if let Some(explicit_environment) = explicit_environment {
explicit_environment
.tasks(Some(Platform::current()))
.into_iter()
.flat_map(|tasks| tasks.into_keys())
.map(ToOwned::to_owned)
.collect()
explicit_environment.get_filtered_tasks()
} else {
project
.environments()
.into_iter()
.filter(|env| verify_current_platform_has_required_virtual_packages(env).is_ok())
.flat_map(|env| {
env.tasks(Some(Platform::current()))
.into_iter()
.flat_map(|tasks| tasks.into_keys())
.map(ToOwned::to_owned)
})
.flat_map(|env| env.get_filtered_tasks())
.collect()
};

Expand Down
52 changes: 40 additions & 12 deletions src/cli/task.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use crate::project::manifest::EnvironmentName;
use crate::project::manifest::FeatureName;
use crate::project::virtual_packages::verify_current_platform_has_required_virtual_packages;
use crate::task::{quote, Alias, CmdArgs, Execute, Task, TaskName};
use crate::Project;
use clap::Parser;
use indexmap::IndexMap;
use itertools::Itertools;
use rattler_conda_types::Platform;
use std::collections::HashSet;
use std::error::Error;
use std::path::PathBuf;
use std::str::FromStr;
use toml_edit::{Array, Item, Table, Value};

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -135,17 +139,22 @@ impl From<AddArgs> for Task {
Self::Plain(cmd_args)
} else {
let cwd = value.cwd;
let mut env = IndexMap::new();
for (key, value) in value.env {
env.insert(key, value);
}
let env = if value.env.is_empty() {
None
} else {
let mut env = IndexMap::new();
for (key, value) in value.env {
env.insert(key, value);
}
Some(env)
};
Self::Execute(Execute {
cmd: CmdArgs::Single(cmd_args),
depends_on,
inputs: None,
outputs: None,
cwd,
env: Some(env),
env,
})
}
}
Expand Down Expand Up @@ -273,15 +282,34 @@ pub fn execute(args: Args) -> miette::Result<()> {
);
}
Operation::List(args) => {
let environment = project.environment_from_name_or_env_var(args.environment)?;
let tasks = environment
.tasks(Some(Platform::current()))?
.into_keys()
.collect_vec();
if tasks.is_empty() {
let explicit_environment = args
.environment
.map(|n| EnvironmentName::from_str(n.as_str()))
.transpose()?
.map(|n| {
project
.environment(&n)
.ok_or_else(|| miette::miette!("unknown environment '{n}'"))
})
.transpose()?;
let available_tasks: HashSet<TaskName> =
if let Some(explicit_environment) = explicit_environment {
explicit_environment.get_filtered_tasks()
} else {
project
.environments()
.into_iter()
.filter(|env| {
verify_current_platform_has_required_virtual_packages(env).is_ok()
})
.flat_map(|env| env.get_filtered_tasks())
.collect()
};

if available_tasks.is_empty() {
eprintln!("No tasks found",);
} else {
let formatted: String = tasks
let formatted: String = available_tasks
.iter()
.sorted()
.map(|name| {
Expand Down
40 changes: 40 additions & 0 deletions src/project/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::task::TaskName;
use crate::{task::Task, Project};
use itertools::Either;
use rattler_conda_types::Platform;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::{collections::HashMap, fmt::Debug};

Expand Down Expand Up @@ -116,6 +117,23 @@ impl<'p> Environment<'p> {
Ok(result)
}

/// Return all tasks available for the given environment
/// This will not return task prefixed with _
pub fn get_filtered_tasks(&self) -> HashSet<TaskName> {
self.tasks(Some(Platform::current()))
.into_iter()
.flat_map(|tasks| {
tasks.into_iter().filter_map(|(key, _)| {
if !key.as_str().starts_with('_') {
Some(key)
} else {
None
}
})
})
.map(ToOwned::to_owned)
.collect()
}
/// Returns the task with the given `name` and for the specified `platform` or an `UnknownTask`
/// which explains why the task was not available.
pub fn task(
Expand Down Expand Up @@ -321,6 +339,28 @@ mod tests {
.tasks(Some(Platform::Osx64))
.is_err())
}
#[test]
fn test_filtered_tasks() {
let manifest = Project::from_str(
Path::new("pixi.toml"),
r#"
[project]
name = "foobar"
channels = []
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[tasks]
foo = "echo foo"
_bar = "echo bar"
"#,
)
.unwrap();

let task = manifest.default_environment().get_filtered_tasks();

assert_eq!(task.len(), 1);
assert_eq!(task.contains(&"foo".into()), true);
}

fn format_dependencies(dependencies: Dependencies) -> String {
dependencies
Expand Down

0 comments on commit f67351e

Please sign in to comment.