Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions crates/plotnik-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@ pub enum Command {
#[command(after_help = r#"EXAMPLES:
plotnik tree app.ts
plotnik tree app.ts --raw
plotnik tree app.ts --spans"#)]
plotnik tree -s 'let x = 1' -l javascript"#)]
Tree {
/// Source file to parse (use "-" for stdin)
#[arg(value_name = "SOURCE")]
source: PathBuf,
source_path: Option<PathBuf>,

/// Inline source text
#[arg(short = 's', long = "source", value_name = "TEXT")]
source_text: Option<String>,

/// Language (inferred from extension if not specified)
#[arg(short = 'l', long, value_name = "LANG")]
Expand Down
34 changes: 26 additions & 8 deletions crates/plotnik-cli/src/commands/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,28 @@ use arborium_tree_sitter as tree_sitter;
use plotnik_langs::Lang;

pub struct TreeArgs {
pub source_path: PathBuf,
pub source_path: Option<PathBuf>,
pub source_text: Option<String>,
pub lang: Option<String>,
pub raw: bool,
pub spans: bool,
}

pub fn run(args: TreeArgs) {
let lang = resolve_lang(&args.lang, &args.source_path);
let source = load_source(&args.source_path);
let source = match (&args.source_text, &args.source_path) {
(Some(text), None) => text.clone(),
(None, Some(path)) => load_source(path),
(Some(_), Some(_)) => {
eprintln!("error: cannot use both --source and positional SOURCE");
std::process::exit(1);
}
(None, None) => {
eprintln!("error: source required (positional or --source)");
std::process::exit(1);
}
};

let lang = resolve_lang(&args.lang, args.source_path.as_deref(), args.source_text.is_some());
let tree = lang.parse(&source);
print!("{}", dump_tree(&tree, &source, args.raw, args.spans));
}
Expand All @@ -33,27 +46,32 @@ fn load_source(path: &PathBuf) -> String {
})
}

fn resolve_lang(lang: &Option<String>, source_path: &Path) -> Lang {
fn resolve_lang(lang: &Option<String>, source_path: Option<&Path>, is_inline: bool) -> Lang {
if let Some(name) = lang {
return plotnik_langs::from_name(name).unwrap_or_else(|| {
eprintln!("error: unknown language: {}", name);
std::process::exit(1);
});
}

if source_path.as_os_str() != "-"
&& let Some(ext) = source_path.extension().and_then(|e| e.to_str())
if let Some(path) = source_path
&& path.as_os_str() != "-"
&& let Some(ext) = path.extension().and_then(|e| e.to_str())
{
return plotnik_langs::from_ext(ext).unwrap_or_else(|| {
eprintln!(
"error: cannot infer language from extension '.{}', use --lang",
"error: cannot infer language from extension '.{}', use -l/--lang",
ext
);
std::process::exit(1);
});
}

eprintln!("error: --lang is required (cannot infer from stdin)");
if is_inline {
eprintln!("error: -l/--lang is required when using inline source");
} else {
eprintln!("error: -l/--lang is required (cannot infer from stdin)");
}
std::process::exit(1);
}

Expand Down
6 changes: 4 additions & 2 deletions crates/plotnik-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ fn main() {

match cli.command {
Command::Tree {
source,
source_path,
source_text,
lang,
raw,
spans,
} => {
commands::tree::run(TreeArgs {
source_path: source,
source_path,
source_text,
lang,
raw,
spans,
Expand Down