mirror of https://github.com/astral-sh/ruff
Make cache configurable (#6)
This commit is contained in:
parent
0a034ddb57
commit
35d1d24399
|
|
@ -4,13 +4,15 @@ use std::time::{Duration, Instant};
|
|||
|
||||
use ::rust_python_linter::fs::collect_python_files;
|
||||
use ::rust_python_linter::linter::check_path;
|
||||
use ::rust_python_linter::logging::set_up_logging;
|
||||
use ::rust_python_linter::message::Message;
|
||||
use ::rust_python_linter::timestamped_println;
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, ValueHint};
|
||||
use colored::Colorize;
|
||||
use log::{debug, error};
|
||||
use notify::{watcher, RecursiveMode, Watcher};
|
||||
use rayon::prelude::*;
|
||||
use rust_python_linter::message::Message;
|
||||
use walkdir::DirEntry;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -23,44 +25,11 @@ struct Cli {
|
|||
verbose: bool,
|
||||
#[clap(short, long, action)]
|
||||
watch: bool,
|
||||
#[clap(short, long, action)]
|
||||
no_cache: bool,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! timestamped_println {
|
||||
($($arg:tt)*) => {
|
||||
println!(
|
||||
"[{}] {}",
|
||||
chrono::Local::now()
|
||||
.format("%H:%M:%S %p")
|
||||
.to_string()
|
||||
.dimmed(),
|
||||
format_args!($($arg)*)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn set_up_logging(verbose: bool) -> Result<()> {
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(if verbose {
|
||||
log::LevelFilter::Debug
|
||||
} else {
|
||||
log::LevelFilter::Info
|
||||
})
|
||||
.chain(std::io::stdout())
|
||||
.apply()
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
fn run_once(files: &[PathBuf]) -> Result<Vec<Message>> {
|
||||
fn run_once(files: &[PathBuf], cache: bool) -> Result<Vec<Message>> {
|
||||
// Collect all the files to check.
|
||||
let start = Instant::now();
|
||||
let files: Vec<DirEntry> = files.iter().flat_map(collect_python_files).collect();
|
||||
|
|
@ -71,7 +40,7 @@ fn run_once(files: &[PathBuf]) -> Result<Vec<Message>> {
|
|||
let messages: Vec<Message> = files
|
||||
.par_iter()
|
||||
.map(|entry| {
|
||||
check_path(entry.path()).unwrap_or_else(|e| {
|
||||
check_path(entry.path(), &cache.into()).unwrap_or_else(|e| {
|
||||
error!("Failed to check {}: {e:?}", entry.path().to_string_lossy());
|
||||
vec![]
|
||||
})
|
||||
|
|
@ -123,7 +92,7 @@ fn main() -> Result<()> {
|
|||
clearscreen::clear()?;
|
||||
timestamped_println!("Starting linter in watch mode...\n");
|
||||
|
||||
let messages = run_once(&cli.files)?;
|
||||
let messages = run_once(&cli.files, !cli.no_cache)?;
|
||||
report_continuously(&messages)?;
|
||||
|
||||
// Configure the file watcher.
|
||||
|
|
@ -140,14 +109,14 @@ fn main() -> Result<()> {
|
|||
clearscreen::clear()?;
|
||||
timestamped_println!("File change detected...\n");
|
||||
|
||||
let messages = run_once(&cli.files)?;
|
||||
let messages = run_once(&cli.files, !cli.no_cache)?;
|
||||
report_continuously(&messages)?;
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let messages = run_once(&cli.files)?;
|
||||
let messages = run_once(&cli.files, !cli.no_cache)?;
|
||||
report_once(&messages)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
48
src/cache.rs
48
src/cache.rs
|
|
@ -26,6 +26,42 @@ struct CheckResult {
|
|||
messages: Vec<Message>,
|
||||
}
|
||||
|
||||
pub enum Mode {
|
||||
ReadWrite,
|
||||
ReadOnly,
|
||||
WriteOnly,
|
||||
None,
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
fn allow_read(&self) -> bool {
|
||||
match self {
|
||||
Mode::ReadWrite => true,
|
||||
Mode::ReadOnly => true,
|
||||
Mode::WriteOnly => false,
|
||||
Mode::None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn allow_write(&self) -> bool {
|
||||
match self {
|
||||
Mode::ReadWrite => true,
|
||||
Mode::ReadOnly => false,
|
||||
Mode::WriteOnly => true,
|
||||
Mode::None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Mode {
|
||||
fn from(value: bool) -> Self {
|
||||
match value {
|
||||
true => Mode::ReadWrite,
|
||||
false => Mode::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cache_dir() -> &'static str {
|
||||
"./.cache"
|
||||
}
|
||||
|
|
@ -34,7 +70,11 @@ fn cache_key(path: &Path) -> Cow<str> {
|
|||
path.to_string_lossy()
|
||||
}
|
||||
|
||||
pub fn get(path: &Path) -> Option<Vec<Message>> {
|
||||
pub fn get(path: &Path, mode: &Mode) -> Option<Vec<Message>> {
|
||||
if !mode.allow_read() {
|
||||
return None;
|
||||
};
|
||||
|
||||
match cacache::read_sync(cache_dir(), cache_key(path)) {
|
||||
Ok(encoded) => match path.metadata() {
|
||||
Ok(m) => match bincode::deserialize::<CheckResult>(&encoded[..]) {
|
||||
|
|
@ -53,7 +93,11 @@ pub fn get(path: &Path) -> Option<Vec<Message>> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn set(path: &Path, messages: &[Message]) {
|
||||
pub fn set(path: &Path, messages: &[Message], mode: &Mode) {
|
||||
if !mode.allow_write() {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Ok(metadata) = path.metadata() {
|
||||
let check_result = CheckResultRef {
|
||||
metadata: &CacheMetadata {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
mod cache;
|
||||
mod checker;
|
||||
pub mod checker;
|
||||
pub mod fs;
|
||||
pub mod linter;
|
||||
pub mod logging;
|
||||
pub mod message;
|
||||
mod parser;
|
||||
mod visitor;
|
||||
pub mod parser;
|
||||
pub mod visitor;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use anyhow::Result;
|
|||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::cache::Mode;
|
||||
use crate::checker::check_ast;
|
||||
use crate::message::Message;
|
||||
use crate::{cache, parser};
|
||||
|
|
@ -20,9 +21,9 @@ struct CheckResult {
|
|||
messages: Vec<Message>,
|
||||
}
|
||||
|
||||
pub fn check_path(path: &Path) -> Result<Vec<Message>> {
|
||||
pub fn check_path(path: &Path, mode: &Mode) -> Result<Vec<Message>> {
|
||||
// Check the cache.
|
||||
if let Some(messages) = cache::get(path) {
|
||||
if let Some(messages) = cache::get(path, mode) {
|
||||
debug!("Cache hit for: {}", path.to_string_lossy());
|
||||
return Ok(messages);
|
||||
}
|
||||
|
|
@ -37,7 +38,7 @@ pub fn check_path(path: &Path) -> Result<Vec<Message>> {
|
|||
filename: path.to_string_lossy().to_string(),
|
||||
})
|
||||
.collect();
|
||||
cache::set(path, &messages);
|
||||
cache::set(path, &messages, mode);
|
||||
|
||||
Ok(messages)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
use anyhow::Result;
|
||||
use fern;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! timestamped_println {
|
||||
($($arg:tt)*) => {
|
||||
println!(
|
||||
"[{}] {}",
|
||||
chrono::Local::now()
|
||||
.format("%H:%M:%S %p")
|
||||
.to_string()
|
||||
.dimmed(),
|
||||
format_args!($($arg)*)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_up_logging(verbose: bool) -> Result<()> {
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(if verbose {
|
||||
log::LevelFilter::Debug
|
||||
} else {
|
||||
log::LevelFilter::Info
|
||||
})
|
||||
.chain(std::io::stdout())
|
||||
.apply()
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
Loading…
Reference in New Issue