use crate::task::Task;
use console::truncate_str;
use eyre::Result;
use itertools::Itertools;
use tabled::Tabled;
use crate::config::{Config, Settings};
use crate::file::display_path;
use crate::ui::{style, table};
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)]
pub struct TaskLs {
#[clap(long, alias = "no-headers", verbatim_doc_comment)]
pub no_header: bool,
#[clap(long, verbatim_doc_comment)]
pub hidden: bool,
}
impl TaskLs {
pub fn run(self) -> Result<()> {
let config = Config::try_get()?;
let settings = Settings::try_get()?;
settings.ensure_experimental()?;
let rows = config
.tasks()
.iter()
.filter(|(n, t)| *n == &t.name) .map(|(_, t)| t)
.sorted()
.filter(|t| self.hidden || !t.hide)
.map(|t| t.into())
.collect::<Vec<Row>>();
let mut table = tabled::Table::new(rows);
table::default_style(&mut table, self.no_header);
rtxprintln!("{table}");
Ok(())
}
}
#[derive(Tabled)]
#[tabled(rename_all = "PascalCase")]
struct Row {
name: String,
description: String,
source: String,
}
impl From<&Task> for Row {
fn from(task: &Task) -> Self {
Self {
name: style::nbold(&task.name).bright().to_string(),
description: style::nblue(truncate(&task.description, 40)).to_string(),
source: display_path(&task.config_source),
}
}
}
fn first_line(s: &str) -> &str {
s.lines().next().unwrap_or_default()
}
fn truncate(s: &str, len: usize) -> String {
first_line(&truncate_str(s, len, "…")).to_string()
}
static AFTER_LONG_HELP: &str = color_print::cstr!(
r#"<bold><underline>Examples:</underline></bold>
$ <bold>rtx task ls</bold>
"#
);
#[cfg(test)]
mod tests {
use std::env;
#[test]
fn test_task_ls() {
assert_cli_snapshot!("t", "--no-headers", @r###"
configtask ~/config/config.toml
filetask This is a test build script ~/cwd/.rtx/tasks/filetask
lint ~/config/config.toml
test ~/config/config.toml
"###);
}
}