From 44010d69eadaedd535a102f084e8d9f06ad93b55 Mon Sep 17 00:00:00 2001 From: Patrick Thomson Date: Thu, 25 Feb 2021 10:24:54 -0500 Subject: [PATCH] Walk query files recursively in `tree-sitter test`. We were only walking one level of depth into the `queries/` folder during invocations of `test`, which made us attempt to open folders rather than recurse into them. We have to pull in the `walkdir` crate, which is required for cross-platform walking of directories. Fixes #938. --- Cargo.lock | 30 ++++++++++++++++++++++++++++++ cli/Cargo.toml | 5 +++-- cli/src/error.rs | 7 +++++++ cli/src/test.rs | 27 ++++++++++++++++----------- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef55cd19..c176ab77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -664,6 +664,15 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "0.3.3" @@ -869,6 +878,7 @@ dependencies = [ "tree-sitter", "tree-sitter-highlight", "tree-sitter-tags", + "walkdir", "webbrowser", ] @@ -969,6 +979,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "webbrowser" version = "0.5.1" @@ -1001,6 +1022,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 1f05f02c..ed50da75 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -20,12 +20,13 @@ harness = false [dependencies] ansi_term = "0.11" -cc = "^1.0.58" atty = "0.2" +cc = "^1.0.58" clap = "2.32" difference = "2.0" dirs = "2.0.2" glob = "0.3.0" +html-escape = "0.2.6" lazy_static = "1.2.0" libloading = "0.5" once_cell = "0.1.8" @@ -35,8 +36,8 @@ serde = "1.0" serde_derive = "1.0" smallbitvec = "2.3.0" tiny_http = "0.6" +walkdir = "2.3" webbrowser = "0.5.1" -html-escape = "0.2.6" [dependencies.tree-sitter] version = ">= 0.17.0" diff --git a/cli/src/error.rs b/cli/src/error.rs index 50374246..fd6a593e 100644 --- a/cli/src/error.rs +++ b/cli/src/error.rs @@ -2,6 +2,7 @@ use super::test_highlight; use std::fmt::Write; use std::io; use tree_sitter::{QueryError, QueryErrorKind}; +use walkdir; #[derive(Debug)] pub struct Error(pub Vec); @@ -121,3 +122,9 @@ impl From for Error { Error::new(error) } } + +impl From for Error { + fn from(error: walkdir::Error) -> Self { + Error::new(error.to_string()) + } +} diff --git a/cli/src/test.rs b/cli/src/test.rs index c8cfe89f..65301cc6 100644 --- a/cli/src/test.rs +++ b/cli/src/test.rs @@ -6,12 +6,14 @@ use lazy_static::lazy_static; use regex::bytes::{Regex as ByteRegex, RegexBuilder as ByteRegexBuilder}; use regex::Regex; use std::char; +use std::ffi::OsStr; use std::fmt::Write as FmtWrite; use std::fs; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::str; use tree_sitter::{Language, LogType, Parser, Query}; +use walkdir::WalkDir; lazy_static! { static ref HEADER_REGEX: ByteRegex = ByteRegexBuilder::new(r"^===+\r?\n([^=]*)\r?\n===+\r?\n") @@ -122,17 +124,20 @@ pub fn run_tests_at_path( pub fn check_queries_at_path(language: Language, path: &Path) -> Result<()> { if path.exists() { - for entry in fs::read_dir(path)? { - let entry = entry?; - let filepath = entry.file_name(); - let filepath = filepath.to_str().unwrap_or(""); - let hidden = filepath.starts_with("."); - if !hidden { - let content = fs::read_to_string(entry.path()).map_err(Error::wrap(|| { - format!("Error reading query file {:?}", entry.file_name()) - }))?; - Query::new(language, &content).map_err(|e| (filepath, e))?; - } + for entry in WalkDir::new(path) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| { + e.file_type().is_file() + && e.path().extension().and_then(OsStr::to_str) == Some("scm") + && !e.path().starts_with(".") + }) + { + let filepath = entry.file_name().to_str().unwrap_or(""); + let content = fs::read_to_string(entry.path()).map_err(Error::wrap(|| { + format!("Error reading query file {:?}", entry.file_name()) + }))?; + Query::new(language, &content).map_err(|e| (filepath, e))?; } } Ok(())