mod api;
mod commands;
mod config;
use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};
use commands::{issues, labels, projects, teams, users, cycles, comments, documents, search, sync, statuses, git, bulk, interactive};
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
pub enum OutputFormat {
#[default]
Table,
Json,
}
#[derive(Parser)]
#[command(name = "linear")]
#[command(about = "A powerful CLI for Linear.app", long_about = None)]
#[command(version)]
struct Cli {
#[arg(short, long, global = true, default_value = "table")]
output: OutputFormat,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
#[command(alias = "p")]
Projects {
#[command(subcommand)]
action: projects::ProjectCommands,
},
#[command(alias = "i")]
Issues {
#[command(subcommand)]
action: issues::IssueCommands,
},
#[command(alias = "l")]
Labels {
#[command(subcommand)]
action: labels::LabelCommands,
},
#[command(alias = "t")]
Teams {
#[command(subcommand)]
action: teams::TeamCommands,
},
#[command(alias = "u")]
Users {
#[command(subcommand)]
action: users::UserCommands,
},
#[command(alias = "c")]
Cycles {
#[command(subcommand)]
action: cycles::CycleCommands,
},
#[command(alias = "cm")]
Comments {
#[command(subcommand)]
action: comments::CommentCommands,
},
#[command(alias = "d")]
Documents {
#[command(subcommand)]
action: documents::DocumentCommands,
},
#[command(alias = "s")]
Search {
#[command(subcommand)]
action: search::SearchCommands,
},
#[command(alias = "sy")]
Sync {
#[command(subcommand)]
action: sync::SyncCommands,
},
#[command(alias = "st")]
Statuses {
#[command(subcommand)]
action: statuses::StatusCommands,
},
#[command(alias = "g")]
Git {
#[command(subcommand)]
action: git::GitCommands,
},
#[command(alias = "b")]
Bulk {
#[command(subcommand)]
action: bulk::BulkCommands,
},
#[command(alias = "int")]
Interactive,
Config {
#[command(subcommand)]
action: ConfigCommands,
},
}
#[derive(Subcommand)]
enum ConfigCommands {
SetKey {
key: String,
},
Show,
#[command(alias = "add")]
WorkspaceAdd {
name: String,
api_key: String,
},
#[command(alias = "list")]
WorkspaceList,
#[command(alias = "use")]
WorkspaceSwitch {
name: String,
},
#[command(alias = "current")]
WorkspaceCurrent,
#[command(alias = "rm")]
WorkspaceRemove {
name: String,
},
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let output = cli.output;
match cli.command {
Commands::Projects { action } => projects::handle(action, output).await?,
Commands::Issues { action } => issues::handle(action, output).await?,
Commands::Labels { action } => labels::handle(action, output).await?,
Commands::Teams { action } => teams::handle(action, output).await?,
Commands::Users { action } => users::handle(action).await?,
Commands::Cycles { action } => cycles::handle(action).await?,
Commands::Comments { action } => comments::handle(action).await?,
Commands::Documents { action } => documents::handle(action).await?,
Commands::Search { action } => search::handle(action).await?,
Commands::Sync { action } => sync::handle(action).await?,
Commands::Statuses { action } => statuses::handle(action).await?,
Commands::Git { action } => git::handle(action).await?,
Commands::Bulk { action } => bulk::handle(action).await?,
Commands::Interactive => interactive::run().await?,
Commands::Config { action } => match action {
ConfigCommands::SetKey { key } => {
config::set_api_key(&key)?;
println!("API key saved successfully!");
}
ConfigCommands::Show => {
config::show_config()?;
}
ConfigCommands::WorkspaceAdd { name, api_key } => {
config::workspace_add(&name, &api_key)?;
}
ConfigCommands::WorkspaceList => {
config::workspace_list()?;
}
ConfigCommands::WorkspaceSwitch { name } => {
config::workspace_switch(&name)?;
}
ConfigCommands::WorkspaceCurrent => {
config::workspace_current()?;
}
ConfigCommands::WorkspaceRemove { name } => {
config::workspace_remove(&name)?;
}
},
}
Ok(())
}