use std::path::PathBuf;
use clap::{Parser, Subcommand, ValueEnum};
use cartog_core::{EdgeKind, SymbolKind};
#[derive(Debug, Parser)]
#[command(name = "cartog")]
#[command(about = "Map your codebase. Navigate by graph, not grep.")]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
#[arg(long, global = true)]
pub json: bool,
#[arg(long, global = true)]
pub tokens: Option<u32>,
#[arg(long, global = true, value_name = "PATH", env = "CARTOG_DB")]
pub db: Option<PathBuf>,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum SymbolKindFilter {
Function,
Class,
Method,
Variable,
Import,
Interface,
Enum,
TypeAlias,
Trait,
Module,
Document,
All,
}
impl From<SymbolKindFilter> for SymbolKind {
fn from(f: SymbolKindFilter) -> Self {
match f {
SymbolKindFilter::Function => SymbolKind::Function,
SymbolKindFilter::Class => SymbolKind::Class,
SymbolKindFilter::Method => SymbolKind::Method,
SymbolKindFilter::Variable => SymbolKind::Variable,
SymbolKindFilter::Import => SymbolKind::Import,
SymbolKindFilter::Interface => SymbolKind::Interface,
SymbolKindFilter::Enum => SymbolKind::Enum,
SymbolKindFilter::TypeAlias => SymbolKind::TypeAlias,
SymbolKindFilter::Trait => SymbolKind::Trait,
SymbolKindFilter::Module => SymbolKind::Module,
SymbolKindFilter::Document => SymbolKind::Document,
SymbolKindFilter::All => unreachable!("All is not a single SymbolKind"),
}
}
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum EdgeKindFilter {
Calls,
Imports,
Inherits,
References,
Raises,
Implements,
TypeOf,
}
impl From<EdgeKindFilter> for EdgeKind {
fn from(f: EdgeKindFilter) -> Self {
match f {
EdgeKindFilter::Calls => EdgeKind::Calls,
EdgeKindFilter::Imports => EdgeKind::Imports,
EdgeKindFilter::Inherits => EdgeKind::Inherits,
EdgeKindFilter::References => EdgeKind::References,
EdgeKindFilter::Raises => EdgeKind::Raises,
EdgeKindFilter::Implements => EdgeKind::Implements,
EdgeKindFilter::TypeOf => EdgeKind::TypeOf,
}
}
}
#[derive(Debug, Subcommand)]
pub enum Command {
Index {
#[arg(default_value = ".")]
path: String,
#[arg(long)]
force: bool,
#[arg(long)]
no_lsp: bool,
},
Outline {
file: String,
},
Callees {
name: String,
},
Impact {
name: String,
#[arg(long, default_value = "3")]
depth: u32,
},
Refs {
name: String,
#[arg(long)]
kind: Option<EdgeKindFilter>,
},
Hierarchy {
name: String,
},
Deps {
file: String,
},
Stats,
Config,
Doctor,
Search {
query: String,
#[arg(long)]
kind: Option<SymbolKindFilter>,
#[arg(long)]
file: Option<String>,
#[arg(long, default_value = "30")]
limit: u32,
},
Map {
#[arg(long, default_value = "4000")]
tokens: u32,
},
Changes {
#[arg(long, default_value = "5")]
commits: u32,
#[arg(long)]
kind: Option<SymbolKindFilter>,
},
Watch {
#[arg(default_value = ".")]
path: String,
#[arg(long, default_value = "2")]
debounce: u64,
#[arg(long)]
rag: bool,
#[arg(long, default_value = "30")]
rag_delay: u64,
},
Serve {
#[arg(long)]
watch: bool,
#[arg(long)]
rag: bool,
},
#[command(subcommand)]
Rag(RagCommand),
}
#[derive(Debug, Subcommand)]
pub enum RagCommand {
Setup,
Index {
#[arg(default_value = ".")]
path: String,
#[arg(long)]
force: bool,
},
Search {
query: String,
#[arg(long)]
kind: Option<SymbolKindFilter>,
#[arg(long, default_value = "10")]
limit: u32,
},
}