Fix: checking multiple files (#126)

* fix: remove duplicates when checking multiple files

* fix: exit 1 when providing invalid file or patterns

* wip

* keep order of insertion, and works with options or flags in the middle

* alphabetical order

* remove useless type annotation

* return IndexSet directly instead of Vec

* remove .clone()
This commit is contained in:
Loïc Riegel 2025-02-24 09:24:27 +01:00 committed by GitHub
parent 7871d31c93
commit f0a44bf272
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 95 additions and 23 deletions

View file

@ -6,5 +6,8 @@
"[typescript]": { "[typescript]": {
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome" "editor.defaultFormatter": "biomejs.biome"
} },
"cSpell.words": [
"indexmap"
]
} }

25
Cargo.lock generated
View file

@ -166,6 +166,12 @@ dependencies = [
"windows", "windows",
] ]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]] [[package]]
name = "erg_common" name = "erg_common"
version = "0.6.53-nightly.2" version = "0.6.53-nightly.2"
@ -260,6 +266,12 @@ dependencies = [
"ahash", "ahash",
] ]
[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
@ -405,6 +417,16 @@ dependencies = [
"icu_properties", "icu_properties",
] ]
[[package]]
name = "indexmap"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
]
[[package]] [[package]]
name = "is-macro" name = "is-macro"
version = "0.3.7" version = "0.3.7"
@ -502,7 +524,7 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea0ed76adf7defc1a92240b5c36d5368cfe9251640dcce5bd2d0b7c1fd87aeb" checksum = "5ea0ed76adf7defc1a92240b5c36d5368cfe9251640dcce5bd2d0b7c1fd87aeb"
dependencies = [ dependencies = [
"hashbrown", "hashbrown 0.14.5",
"itertools", "itertools",
"libm", "libm",
"ryu", "ryu",
@ -733,6 +755,7 @@ dependencies = [
"erg_common", "erg_common",
"erg_compiler", "erg_compiler",
"glob", "glob",
"indexmap",
"pylyzer_core", "pylyzer_core",
] ]

View file

@ -54,6 +54,7 @@ pylyzer_core = { version = "0.0.81", path = "./crates/pylyzer_core" }
erg_common = { workspace = true } erg_common = { workspace = true }
els = { workspace = true } els = { workspace = true }
glob = "0.3.2" glob = "0.3.2"
indexmap = "2.7.1"
[dev-dependencies] [dev-dependencies]
erg_compiler = { workspace = true } erg_compiler = { workspace = true }

View file

@ -6,6 +6,7 @@ use erg_common::config::{ErgConfig, ErgMode};
use erg_common::io::Input; use erg_common::io::Input;
use erg_common::pathutil::project_entry_file_of; use erg_common::pathutil::project_entry_file_of;
use erg_common::switch_lang; use erg_common::switch_lang;
use indexmap::IndexSet;
use crate::copy::clear_cache; use crate::copy::clear_cache;
@ -49,7 +50,7 @@ OPTIONS
--clear-cache --clear-cache
--code/-c cmd --code/-c cmd
--dump-decl --dump-decl
--disable ", --disable feat ",
"simplified_chinese" => "simplified_chinese" =>
"\ "\
@ -67,7 +68,7 @@ OPTIONS
--clear-cache --clear-cache
--code/-c cmd --code/-c cmd
--dump-decl --dump-decl
--disable ", --disable feat ",
"traditional_chinese" => "traditional_chinese" =>
"\ "\
@ -85,7 +86,7 @@ OPTIONS
--clear-cache --clear-cache
--code/-c cmd --code/-c cmd
--dump-decl --dump-decl
--disable ", --disable feat ",
"english" => "english" =>
"\ "\
@ -103,7 +104,7 @@ OPTIONS
--clear-cache clear cache --clear-cache clear cache
--code/-c cmd program passed in as string --code/-c cmd program passed in as string
--dump-decl output type declaration file --dump-decl output type declaration file
--disable disable specified features", --disable feat disable specified features",
) )
} }
@ -213,21 +214,53 @@ For more information try `pylyzer --help`"
cfg cfg
} }
pub(crate) fn files_to_be_checked() -> Vec<PathBuf> { pub(crate) fn files_to_be_checked() -> IndexSet<Result<PathBuf, String>> {
let file_or_patterns = env::args() let mut file_or_patterns = vec![];
.skip(1) let mut args = env::args().skip(1);
.rev() while let Some(arg) = &args.next() {
.take_while(|arg| !arg.starts_with("-")); match arg.as_str() {
let mut files = vec![]; "--" => {
// Discard runtime args
break;
}
"--code" | "-c" | "--disable" | "--verbose" => {
// Skip options
let _ = &args.next();
continue;
}
file_or_pattern if file_or_pattern.starts_with("-") => {
// Skip flags
continue;
}
file_or_pattern => file_or_patterns.push(file_or_pattern.to_owned()),
}
}
let mut files = IndexSet::new();
for file_or_pattern in file_or_patterns { for file_or_pattern in file_or_patterns {
if PathBuf::from(&file_or_pattern).is_file() { if PathBuf::from(&file_or_pattern).is_file() {
files.push(PathBuf::from(&file_or_pattern)); files.insert(Ok(PathBuf::from(&file_or_pattern)));
} else { } else {
for entry in glob::glob(&file_or_pattern).expect("Failed to read glob pattern") { let entries = glob::glob(&file_or_pattern);
match entry { match entries {
Err(e) => eprintln!("err: {e}"), Err(_) => {
Ok(path) if path.is_file() => files.push(path), files.insert(Err(file_or_pattern));
_ => {} continue;
}
Ok(entries) => {
let mut entries = entries.into_iter().peekable();
if entries.peek().is_none() {
files.insert(Err(file_or_pattern));
}
for entry in entries {
match entry {
Err(e) => eprintln!("err: {e}"),
Ok(path) if path.is_file() => {
files.insert(Ok(path));
}
_ => {}
}
}
} }
} }
} }

View file

@ -4,6 +4,8 @@ mod copy;
use els::Server; use els::Server;
use erg_common::config::ErgMode; use erg_common::config::ErgMode;
use erg_common::spawn::exec_new_thread; use erg_common::spawn::exec_new_thread;
use erg_common::style::colors::RED;
use erg_common::style::RESET;
use pylyzer_core::{PythonAnalyzer, SimplePythonParser}; use pylyzer_core::{PythonAnalyzer, SimplePythonParser};
use crate::config::files_to_be_checked; use crate::config::files_to_be_checked;
@ -23,11 +25,21 @@ fn run() {
code = analyzer.run(); code = analyzer.run();
} else { } else {
for path in files { for path in files {
let cfg = cfg.inherit(path); match path {
let mut analyzer = PythonAnalyzer::new(cfg); Err(invalid_file_or_pattern) => {
let c = analyzer.run(); if code == 0 {
if c != 0 { code = 1;
code = 1; }
println!("{RED}Invalid file or pattern{RESET}: {invalid_file_or_pattern}");
}
Ok(path) => {
let cfg = cfg.inherit(path);
let mut analyzer = PythonAnalyzer::new(cfg);
let c = analyzer.run();
if c != 0 {
code = 1;
}
}
} }
} }
} }