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 clap::{Args, Parser, Subcommand};
use crate::cli::prelude::*;
mod gitlab;
mod jira;
mod prelude;
// TODO: clap for CLI
@ -23,32 +26,79 @@ pub struct Cli {
#[derive(Subcommand)]
pub enum Commands {
/// Run the interactive terminal user interface (TUI)
Ui(UiArgs),
/// Lists tasks with options for syncing
List(ListArgs),
List(list::Args),
/// Sync local tasks with GitLab and Jira
Sync,
Sync(sync::Args),
/// Interact with the associated tasks' Jira issues
Jira(JiraArgs),
/// Run the interactive terminal user interface (TUI)
#[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)]
pub struct UiArgs {}
mod ui {
use clap::Subcommand;
#[derive(Args, Debug)]
pub struct ListArgs {
#[arg(long, default_value_t = false)]
pub sync: bool,
#[derive(Subcommand)]
pub enum Command {}
}
#[derive(Args, Debug)]
pub struct JiraArgs {
#[arg(short, long)]
pub key: String,
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,
}
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(())
}
}
}
mod sync {
use crate::cli::prelude::*;
#[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 {
@ -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]
fn verify_cli() {
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...");
info!("Starting...");
let result = match cli.command {
Commands::Sync => cli::sync().await,
Commands::Sync(args) => args.sync().await,
Commands::Ui(_args) => tui::run().await,
Commands::List(args) => cli::list_tasks(&args).await,
Commands::Jira(args) => cli::jira(&args).await,
Commands::List(args) => args.list().await,
Commands::Jira(jira) => jira.exec().await,
Commands::Gitlab(gitlab) => gitlab.exec().await,
};
result
}