Sort tasks when listing

This commit is contained in:
Daniel Flanagan 2024-04-17 11:18:29 -05:00
parent c08929c765
commit 7dfcb2ad95
6 changed files with 129 additions and 55 deletions

View file

@ -1,5 +1,8 @@
use crate::prelude::*; use crate::cli::prelude::*;
use clap::{Args, Parser, Subcommand};
mod gitlab;
mod jira;
mod prelude;
// TODO: clap for CLI // TODO: clap for CLI
@ -23,32 +26,79 @@ pub struct Cli {
#[derive(Subcommand)] #[derive(Subcommand)]
pub enum Commands { pub enum Commands {
/// Run the interactive terminal user interface (TUI)
Ui(UiArgs),
/// Lists tasks with options for syncing /// Lists tasks with options for syncing
List(ListArgs), List(list::Args),
/// Sync local tasks with GitLab and Jira /// Sync local tasks with GitLab and Jira
Sync, Sync(sync::Args),
/// Interact with the associated tasks' Jira issues /// Run the interactive terminal user interface (TUI)
Jira(JiraArgs), #[command(subcommand)]
Ui(ui::Command),
/// Interact with the configured Jira endpoint
#[command(subcommand)]
Jira(jira::Command),
/// Interact with the configured GitLab endpoint
#[command(subcommand)]
Gitlab(gitlab::Command),
} }
#[derive(Args)] mod ui {
pub struct UiArgs {} use clap::Subcommand;
#[derive(Args, Debug)] #[derive(Subcommand)]
pub struct ListArgs { pub enum Command {}
#[arg(long, default_value_t = false)] }
mod list {
use crate::{cli::prelude::*, task::Task};
#[derive(Parser)]
pub struct Args {
/// Whether or not to sync before listing tasks
#[arg(short, long, default_value = None)]
pub sync: bool, pub sync: bool,
}
impl Args {
pub async fn list(&self) -> Result<()> {
let tasks = Arc::new(crate::tasks::Tasks::try_new()?);
if self.sync {
eprintln!("Syncing...");
tasks.sync().await?;
}
// TODO: if we _don't_ sync, check last sync time and let user know
// that things may have changed
let mut tasks: Vec<Task> = tasks.all()?.into_values().collect();
tasks.sort_unstable();
eprintln!("{} Tasks", tasks.len());
// TODO: make this generical? take a vec of vecs or something, scan each
// entry and their lengths and we can spit out a nice table with each
// "column" having equal length
for t in tasks {
println!("{t}");
}
Ok(())
}
}
} }
#[derive(Args, Debug)] mod sync {
pub struct JiraArgs { use crate::cli::prelude::*;
#[arg(short, long)]
pub key: String, #[derive(Parser)]
pub struct Args {}
impl Args {
pub async fn sync(&self) -> Result<()> {
eprintln!("Syncing...");
Arc::new(crate::tasks::Tasks::try_new()?).sync().await?;
eprintln!("Done!");
Ok(())
}
}
} }
impl Cli { impl Cli {
@ -57,39 +107,6 @@ impl Cli {
} }
} }
pub async fn sync() -> Result<()> {
eprintln!("Syncing...");
Arc::new(crate::tasks::Tasks::try_new()?).sync().await?;
eprintln!("Done!");
Ok(())
}
pub async fn list_tasks(args: &ListArgs) -> Result<()> {
let tasks = Arc::new(crate::tasks::Tasks::try_new()?);
if args.sync {
eprintln!("Syncing...");
tasks.sync().await?;
}
// TODO: if we _don't_ sync, check last sync time and let user know
// that things may have changed
let tasks = tasks.all()?;
eprintln!("{} Tasks", tasks.len());
// TODO: make this generical? take a vec of vecs or something, scan each
// entry and their lengths and we can spit out a nice table with each
// "column" having equal length
for (_, t) in tasks.iter() {
println!("{t}");
}
Ok(())
}
pub async fn jira(args: &JiraArgs) -> Result<()> {
let tasks = crate::tasks::Tasks::try_new()?;
let issue = tasks.jira.issue(&args.key).await?;
println!("{issue:?}");
Ok(())
}
#[test] #[test]
fn verify_cli() { fn verify_cli() {
use clap::CommandFactory; use clap::CommandFactory;

25
src/cli/gitlab.rs Normal file
View file

@ -0,0 +1,25 @@
use crate::cli::prelude::*;
#[derive(Subcommand)]
pub enum Command {
Me(MeArgs),
}
impl Command {
pub async fn exec(&self) -> Result<()> {
match self {
Command::Me(args) => args.me().await,
}
}
}
#[derive(Parser)]
pub struct MeArgs {}
impl MeArgs {
pub async fn me(&self) -> Result<()> {
let tasks = crate::tasks::Tasks::try_new()?;
println!("{:?}", tasks.gitlab.me().await?);
Ok(())
}
}

29
src/cli/jira.rs Normal file
View file

@ -0,0 +1,29 @@
use crate::cli::prelude::*;
#[derive(Subcommand)]
pub enum Command {
Issue(IssueArgs),
}
impl Command {
pub async fn exec(&self) -> Result<()> {
match self {
Command::Issue(args) => args.issue().await,
}
}
}
#[derive(Args)]
pub struct IssueArgs {
#[arg(short, long)]
pub key: String,
}
impl IssueArgs {
pub async fn issue(&self) -> Result<()> {
let tasks = crate::tasks::Tasks::try_new()?;
let issue = tasks.jira.issue(&self.key).await?;
println!("{issue:?}");
Ok(())
}
}

2
src/cli/prelude.rs Normal file
View file

@ -0,0 +1,2 @@
pub use crate::prelude::*;
pub use clap::{Args, Parser, Subcommand};

0
src/cli/ui.rs Normal file
View file

View file

@ -27,10 +27,11 @@ async fn main() -> Result<()> {
trace!("Starting..."); trace!("Starting...");
info!("Starting..."); info!("Starting...");
let result = match cli.command { let result = match cli.command {
Commands::Sync => cli::sync().await, Commands::Sync(args) => args.sync().await,
Commands::Ui(_args) => tui::run().await, Commands::Ui(_args) => tui::run().await,
Commands::List(args) => cli::list_tasks(&args).await, Commands::List(args) => args.list().await,
Commands::Jira(args) => cli::jira(&args).await, Commands::Jira(jira) => jira.exec().await,
Commands::Gitlab(gitlab) => gitlab.exec().await,
}; };
result result
} }