Skip to content

Commit

Permalink
feat: Update task list console output (prefix-dev#1443)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruben Arts <[email protected]>
  • Loading branch information
vigneshmanick and ruben-arts authored May 28, 2024
1 parent e4e5bdc commit 8baa8ee
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ List all tasks in the project.
##### Options

- `--environment`(`-e`): the environment's tasks list, if non is provided the default tasks will be listed.
- `--summary`(`-s`): the output gets formatted to be machine parsable. (Used in the autocompletion of `pixi run`).
- `--summary`(`-s`): list the tasks per environment.

```shell
pixi task list
Expand Down
4 changes: 2 additions & 2 deletions src/cli/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn replace_bash_completion(script: &str) -> Cow<str> {
COMPREPLY=( $$(compgen -W "$${opts}" -- "$${cur}") )
return 0
elif [[ $${COMP_CWORD} -eq 2 ]]; then
local tasks=$$(pixi task list --summary 2> /dev/null)
local tasks=$$(pixi task list --machine-readable 2> /dev/null)
if [[ $$? -eq 0 ]]; then
COMPREPLY=( $$(compgen -W "$${tasks}" -- "$${cur}") )
return 0
Expand All @@ -73,7 +73,7 @@ fn replace_zsh_completion(script: &str) -> Cow<str> {
// NOTE THIS IS FORMATTED BY HAND
let zsh_replacement = r#"$1
local tasks
tasks=("$${(@s/ /)$$(pixi task list --summary 2> /dev/null)}")
tasks=("$${(@s/ /)$$(pixi task list --machine-readable 2> /dev/null)}")
if [[ -n "$$tasks" ]]; then
_values 'task' "$${tasks[@]}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ expression: result
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
elif [[ ${COMP_CWORD} -eq 2 ]]; then
local tasks=$(pixi task list --summary 2> /dev/null)
local tasks=$(pixi task list --machine-readable 2> /dev/null)
if [[ $? -eq 0 ]]; then
COMPREPLY=( $(compgen -W "${tasks}" -- "${cur}") )
return 0
Expand Down Expand Up @@ -46,4 +46,4 @@ expression: result
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )

;;

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ _arguments "${_arguments_options[@]}" \
;;
(run)
local tasks
tasks=("${(@s/ /)$(pixi task list --summary 2> /dev/null)}")
tasks=("${(@s/ /)$(pixi task list --machine-readable 2> /dev/null)}")

if [[ -n "$tasks" ]]; then
_values 'task' "${tasks[@]}"
Expand Down Expand Up @@ -45,4 +45,4 @@ _arguments "${_arguments_options[@]}" \
&& ret=0
;;


63 changes: 51 additions & 12 deletions src/cli/task.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::project::manifest::EnvironmentName;
use crate::project::manifest::FeatureName;
use crate::project::virtual_packages::verify_current_platform_has_required_virtual_packages;
use crate::project::Environment;
use crate::task::{quote, Alias, CmdArgs, Execute, Task, TaskName};
use crate::Project;
use clap::Parser;
Expand All @@ -9,6 +10,8 @@ use itertools::Itertools;
use rattler_conda_types::Platform;
use std::collections::HashSet;
use std::error::Error;
use std::io;
use std::io::{stdout, Write};
use std::path::PathBuf;
use std::str::FromStr;
use toml_edit::{Array, Item, Table, Value};
Expand All @@ -28,7 +31,7 @@ pub enum Operation {
#[clap(alias = "@")]
Alias(AliasArgs),

/// List all tasks
/// List all tasks in the project
#[clap(visible_alias = "ls", alias = "l")]
List(ListArgs),
}
Expand Down Expand Up @@ -107,10 +110,17 @@ pub struct AliasArgs {

#[derive(Parser, Debug, Clone)]
pub struct ListArgs {
/// Tasks available for this machine per environment
#[arg(long, short)]
pub summary: bool,

/// The environment the list should be generated for
/// Output the list of tasks from all environments in
/// machine readable format (space delimited)
/// this output is used for autocomplete by `pixi run`
#[arg(long, hide(true))]
pub machine_readable: bool,

/// The environment the list should be generated for.
/// If not specified, the default environment is used.
#[arg(long, short)]
pub environment: Option<String>,
Expand Down Expand Up @@ -182,6 +192,31 @@ pub struct Args {
pub manifest_path: Option<PathBuf>,
}

fn print_heading(value: &str) {
let bold = console::Style::new().bold();
eprintln!("{}\n{:-<2$}", bold.apply_to(value), "", value.len(),);
}

fn print_tasks_per_env(envs: Vec<Environment>) -> io::Result<()> {
let mut writer = tabwriter::TabWriter::new(stdout());
for env in envs {
let formatted: String = env
.get_filtered_tasks()
.iter()
.sorted()
.map(|name| name.fancy_display())
.join(", ");
writeln!(
writer,
"{}\t: {}",
env.name().fancy_display().bold(),
formatted
)?;
}
writer.flush()?;
Ok(())
}

pub fn execute(args: Args) -> miette::Result<()> {
let mut project = Project::load_or_else_discover(args.manifest_path.as_deref())?;
match args.operation {
Expand Down Expand Up @@ -309,20 +344,24 @@ pub fn execute(args: Args) -> miette::Result<()> {

if available_tasks.is_empty() {
eprintln!("No tasks found",);
} else if args.summary {
print_heading("Tasks per environment:");
print_tasks_per_env(project.environments()).expect("io error when printing tasks");
} else if args.machine_readable {
let unformatted: String = available_tasks
.iter()
.sorted()
.map(|name| name.as_str())
.join(" ");
eprintln!("{}", unformatted);
} else {
let formatted: String = available_tasks
.iter()
.sorted()
.map(|name| {
if args.summary {
format!("{} ", name.as_str(),)
} else {
format!("* {}\n", name.fancy_display().bold(),)
}
})
.collect();

println!("{}", formatted);
.map(|name| name.fancy_display())
.join(", ");
print_heading("Tasks that can run on this machine:");
eprintln!("{}", formatted);
}
}
};
Expand Down

0 comments on commit 8baa8ee

Please sign in to comment.