Add file watcher

This commit is contained in:
Charles Marsh 2022-08-10 14:00:08 -04:00
parent 211849901c
commit a8e7a98300
2 changed files with 52 additions and 11 deletions

View File

@ -9,9 +9,11 @@ bincode = { version = "1.3.3" }
cacache = { version = "10.0.1" } cacache = { version = "10.0.1" }
chrono = { version = "0.4.21" } chrono = { version = "0.4.21" }
clap = { version = "3.2.16", features = ["derive"] } clap = { version = "3.2.16", features = ["derive"] }
clearscreen = "1.0.10"
colored = { version = "2.0.0" } colored = { version = "2.0.0" }
fern = { version = "0.6.1" } fern = { version = "0.6.1" }
log = { version = "0.4.17" } log = { version = "0.4.17" }
notify = "4.0.17"
rayon = { version = "1.5.3" } rayon = { version = "1.5.3" }
rustpython-parser = { git = "https://github.com/RustPython/RustPython.git", rev = "dff916d45c5d13074d21ad329a5ab68a6499426a" } rustpython-parser = { git = "https://github.com/RustPython/RustPython.git", rev = "dff916d45c5d13074d21ad329a5ab68a6499426a" }
serde = { version = "1.0.143", features = ["derive"] } serde = { version = "1.0.143", features = ["derive"] }

View File

@ -1,9 +1,11 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::time::Instant; use std::sync::mpsc::channel;
use std::time::{Duration, Instant};
use anyhow::Result; use anyhow::Result;
use clap::{Parser, ValueHint}; use clap::{Parser, ValueHint};
use log::{error, info}; use log::{debug, error};
use notify::{watcher, RecursiveMode, Watcher};
use rayon::prelude::*; use rayon::prelude::*;
use rust_python_linter::fs::collect_python_files; use rust_python_linter::fs::collect_python_files;
use rust_python_linter::linter::check_path; use rust_python_linter::linter::check_path;
@ -18,6 +20,8 @@ struct Cli {
files: Vec<PathBuf>, files: Vec<PathBuf>,
#[clap(short, long, action)] #[clap(short, long, action)]
verbose: bool, verbose: bool,
#[clap(short, long, action)]
watch: bool,
} }
fn set_up_logging(verbose: bool) -> Result<()> { fn set_up_logging(verbose: bool) -> Result<()> {
@ -42,16 +46,12 @@ fn set_up_logging(verbose: bool) -> Result<()> {
.map_err(|e| e.into()) .map_err(|e| e.into())
} }
fn main() -> Result<()> { fn run_once(files: &[PathBuf]) -> Result<()> {
let cli = Cli::parse();
set_up_logging(cli.verbose)?;
// Collect all the files to check. // Collect all the files to check.
let start = Instant::now(); let start = Instant::now();
let files: Vec<DirEntry> = cli.files.iter().flat_map(collect_python_files).collect(); let files: Vec<DirEntry> = files.iter().flat_map(collect_python_files).collect();
let duration = start.elapsed(); let duration = start.elapsed();
info!("Identified files to lint in: {:?}", duration); debug!("Identified files to lint in: {:?}", duration);
let start = Instant::now(); let start = Instant::now();
let messages: Vec<Message> = files let messages: Vec<Message> = files
@ -65,10 +65,12 @@ fn main() -> Result<()> {
.flatten() .flatten()
.collect(); .collect();
let duration = start.elapsed(); let duration = start.elapsed();
info!("Checked files in: {:?}", duration); debug!("Checked files in: {:?}", duration);
println!("Found {} error(s).", messages.len());
if !messages.is_empty() { if !messages.is_empty() {
println!("Found {} error(s)!", messages.len()); println!();
for message in messages { for message in messages {
println!("{}", message); println!("{}", message);
} }
@ -76,3 +78,40 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
fn main() -> Result<()> {
let cli = Cli::parse();
set_up_logging(cli.verbose)?;
if cli.watch {
clearscreen::clear()?;
println!("Starting linter in watch mode...");
println!();
run_once(&cli.files)?;
let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_secs(1))?;
for file in &cli.files {
watcher.watch(file, RecursiveMode::Recursive)?;
}
loop {
match rx.recv() {
Ok(_) => {
clearscreen::clear()?;
println!("File change detected...");
println!();
run_once(&cli.files)?
}
Err(e) => return Err(e.into()),
}
}
} else {
run_once(&cli.files)?;
}
Ok(())
}