Accept a paths file to most CLI subcommands
This commit is contained in:
parent
32bb2e5add
commit
91a715799e
2 changed files with 68 additions and 49 deletions
111
cli/src/main.rs
111
cli/src/main.rs
|
|
@ -53,11 +53,12 @@ fn run() -> error::Result<()> {
|
|||
.subcommand(
|
||||
SubCommand::with_name("parse")
|
||||
.about("Parse files")
|
||||
.arg(Arg::with_name("paths-file").long("paths").takes_value(true))
|
||||
.arg(
|
||||
Arg::with_name("path")
|
||||
Arg::with_name("paths")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
.required(true),
|
||||
.required(false),
|
||||
)
|
||||
.arg(Arg::with_name("scope").long("scope").takes_value(true))
|
||||
.arg(Arg::with_name("debug").long("debug").short("d"))
|
||||
|
|
@ -79,17 +80,18 @@ fn run() -> error::Result<()> {
|
|||
SubCommand::with_name("query")
|
||||
.about("Search files using a syntax tree query")
|
||||
.arg(Arg::with_name("query-path").index(1).required(true))
|
||||
.arg(Arg::with_name("paths-file").long("paths").takes_value(true))
|
||||
.arg(
|
||||
Arg::with_name("path")
|
||||
Arg::with_name("paths")
|
||||
.index(2)
|
||||
.multiple(true)
|
||||
.required(true),
|
||||
.required(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("beg>:<end")
|
||||
Arg::with_name("byte-range")
|
||||
.help("The range of byte offsets in which the query will be executed")
|
||||
.long("byte-range")
|
||||
.takes_value(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name("scope").long("scope").takes_value(true))
|
||||
.arg(Arg::with_name("captures").long("captures").short("c")),
|
||||
|
|
@ -99,11 +101,11 @@ fn run() -> error::Result<()> {
|
|||
.arg(Arg::with_name("quiet").long("quiet").short("q"))
|
||||
.arg(Arg::with_name("time").long("quiet").short("t"))
|
||||
.arg(Arg::with_name("scope").long("scope").takes_value(true))
|
||||
.arg(Arg::with_name("paths-file").long("paths").takes_value(true))
|
||||
.arg(
|
||||
Arg::with_name("inputs")
|
||||
Arg::with_name("paths")
|
||||
.help("The source file to use")
|
||||
.index(1)
|
||||
.required(true)
|
||||
.multiple(true),
|
||||
),
|
||||
)
|
||||
|
|
@ -122,11 +124,12 @@ fn run() -> error::Result<()> {
|
|||
.subcommand(
|
||||
SubCommand::with_name("highlight")
|
||||
.about("Highlight a file")
|
||||
.arg(Arg::with_name("paths-file").long("paths").takes_value(true))
|
||||
.arg(
|
||||
Arg::with_name("path")
|
||||
Arg::with_name("paths")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
.required(true),
|
||||
.required(false),
|
||||
)
|
||||
.arg(Arg::with_name("scope").long("scope").takes_value(true))
|
||||
.arg(Arg::with_name("html").long("html").short("h"))
|
||||
|
|
@ -225,7 +228,9 @@ fn run() -> error::Result<()> {
|
|||
let timeout = matches
|
||||
.value_of("timeout")
|
||||
.map_or(0, |t| u64::from_str_radix(t, 10).unwrap());
|
||||
let paths = collect_paths(matches.values_of("path").unwrap())?;
|
||||
|
||||
let paths = collect_paths(matches.value_of("paths-file"), matches.values_of("paths"))?;
|
||||
|
||||
let max_path_length = paths.iter().map(|p| p.chars().count()).max().unwrap();
|
||||
let mut has_error = false;
|
||||
loader.find_all_languages(&config.parser_directories)?;
|
||||
|
|
@ -251,28 +256,23 @@ fn run() -> error::Result<()> {
|
|||
}
|
||||
} else if let Some(matches) = matches.subcommand_matches("query") {
|
||||
let ordered_captures = matches.values_of("captures").is_some();
|
||||
let paths = matches
|
||||
.values_of("path")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(Path::new)
|
||||
.collect::<Vec<&Path>>();
|
||||
let paths = collect_paths(matches.value_of("paths-file"), matches.values_of("paths"))?;
|
||||
loader.find_all_languages(&config.parser_directories)?;
|
||||
let language = select_language(
|
||||
&mut loader,
|
||||
paths[0],
|
||||
Path::new(&paths[0]),
|
||||
¤t_dir,
|
||||
matches.value_of("scope"),
|
||||
)?;
|
||||
let query_path = Path::new(matches.value_of("query-path").unwrap());
|
||||
let range = matches.value_of("beg>:<end").map(|br| {
|
||||
let range = matches.value_of("byte-range").map(|br| {
|
||||
let r: Vec<&str> = br.split(":").collect();
|
||||
(r[0].parse().unwrap(), r[1].parse().unwrap())
|
||||
});
|
||||
query::query_files_at_paths(language, paths, query_path, ordered_captures, range)?;
|
||||
} else if let Some(matches) = matches.subcommand_matches("tags") {
|
||||
loader.find_all_languages(&config.parser_directories)?;
|
||||
let paths = collect_paths(matches.values_of("inputs").unwrap())?;
|
||||
let paths = collect_paths(matches.value_of("paths-file"), matches.values_of("paths"))?;
|
||||
tags::generate_tags(
|
||||
&loader,
|
||||
matches.value_of("scope"),
|
||||
|
|
@ -285,7 +285,7 @@ fn run() -> error::Result<()> {
|
|||
loader.find_all_languages(&config.parser_directories)?;
|
||||
|
||||
let time = matches.is_present("time");
|
||||
let paths = collect_paths(matches.values_of("path").unwrap())?;
|
||||
let paths = collect_paths(matches.value_of("paths-file"), matches.values_of("paths"))?;
|
||||
let html_mode = matches.is_present("html");
|
||||
if html_mode {
|
||||
println!("{}", highlight::HTML_HEADER);
|
||||
|
|
@ -358,39 +358,58 @@ fn run() -> error::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_paths<'a>(paths: impl Iterator<Item = &'a str>) -> error::Result<Vec<String>> {
|
||||
let mut result = Vec::new();
|
||||
fn collect_paths<'a>(
|
||||
paths_file: Option<&str>,
|
||||
paths: Option<impl Iterator<Item = &'a str>>,
|
||||
) -> error::Result<Vec<String>> {
|
||||
if let Some(paths_file) = paths_file {
|
||||
return Ok(fs::read_to_string(paths_file)
|
||||
.map_err(Error::wrap(|| {
|
||||
format!("Failed to read paths file {}", paths_file)
|
||||
}))?
|
||||
.trim()
|
||||
.split_ascii_whitespace()
|
||||
.map(String::from)
|
||||
.collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
let mut incorporate_path = |path: &str, positive| {
|
||||
if positive {
|
||||
result.push(path.to_string());
|
||||
} else {
|
||||
if let Some(index) = result.iter().position(|p| p == path) {
|
||||
result.remove(index);
|
||||
if let Some(paths) = paths {
|
||||
let mut result = Vec::new();
|
||||
|
||||
let mut incorporate_path = |path: &str, positive| {
|
||||
if positive {
|
||||
result.push(path.to_string());
|
||||
} else {
|
||||
if let Some(index) = result.iter().position(|p| p == path) {
|
||||
result.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
for mut path in paths {
|
||||
let mut positive = true;
|
||||
if path.starts_with("!") {
|
||||
positive = false;
|
||||
path = path.trim_start_matches("!");
|
||||
}
|
||||
for mut path in paths {
|
||||
let mut positive = true;
|
||||
if path.starts_with("!") {
|
||||
positive = false;
|
||||
path = path.trim_start_matches("!");
|
||||
}
|
||||
|
||||
if Path::new(path).exists() {
|
||||
incorporate_path(path, positive);
|
||||
} else {
|
||||
let paths =
|
||||
glob(path).map_err(Error::wrap(|| format!("Invalid glob pattern {:?}", path)))?;
|
||||
for path in paths {
|
||||
if let Some(path) = path?.to_str() {
|
||||
incorporate_path(path, positive);
|
||||
if Path::new(path).exists() {
|
||||
incorporate_path(path, positive);
|
||||
} else {
|
||||
let paths = glob(path)
|
||||
.map_err(Error::wrap(|| format!("Invalid glob pattern {:?}", path)))?;
|
||||
for path in paths {
|
||||
if let Some(path) = path?.to_str() {
|
||||
incorporate_path(path, positive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
Ok(result)
|
||||
|
||||
Err(Error::new("Must provide one or more paths".to_string()))
|
||||
}
|
||||
|
||||
fn select_language(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use tree_sitter::{Language, Node, Parser, Query, QueryCursor};
|
|||
|
||||
pub fn query_files_at_paths(
|
||||
language: Language,
|
||||
paths: Vec<&Path>,
|
||||
paths: Vec<String>,
|
||||
query_path: &Path,
|
||||
ordered_captures: bool,
|
||||
range: Option<(usize, usize)>,
|
||||
|
|
@ -29,9 +29,9 @@ pub fn query_files_at_paths(
|
|||
parser.set_language(language).map_err(|e| e.to_string())?;
|
||||
|
||||
for path in paths {
|
||||
writeln!(&mut stdout, "{}", path.to_str().unwrap())?;
|
||||
writeln!(&mut stdout, "{}", path)?;
|
||||
|
||||
let source_code = fs::read(path).map_err(Error::wrap(|| {
|
||||
let source_code = fs::read(&path).map_err(Error::wrap(|| {
|
||||
format!("Error reading source file {:?}", path)
|
||||
}))?;
|
||||
let text_callback = |n: Node| &source_code[n.byte_range()];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue