mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-24 20:28:06 +02:00
Refactor codebase for consistent indentation and formatting
- Standardized spacing and indentation across multiple modules for improved readability. - Reorganized `patterns` and `utils` imports for consistency. - Updated `NyxError` and `NyxResult` related implementations to maintain consistent formatting. - Enhanced readability in AST patterns for better clarity and maintainability.
This commit is contained in:
parent
b3870997d7
commit
14a549ac39
26 changed files with 1314 additions and 1221 deletions
|
|
@ -1,13 +1,9 @@
|
|||
use std::{env, fs};
|
||||
use console::style;
|
||||
use crate::errors::NyxResult;
|
||||
use crate::utils::get_project_info;
|
||||
use console::style;
|
||||
use std::{env, fs};
|
||||
|
||||
pub fn handle(
|
||||
project: Option<String>,
|
||||
all: bool,
|
||||
config_dir: &std::path::Path,
|
||||
) -> NyxResult<()> {
|
||||
pub fn handle(project: Option<String>, all: bool, config_dir: &std::path::Path) -> NyxResult<()> {
|
||||
if all {
|
||||
println!("{}", style("Cleaning all indexes...").cyan().bold());
|
||||
if config_dir.exists() {
|
||||
|
|
@ -19,9 +15,17 @@ pub fn handle(
|
|||
let db_path = config_dir.join(format!("{}.sqlite", proj_name));
|
||||
if db_path.exists() {
|
||||
fs::remove_file(&db_path)?;
|
||||
println!("{} {}", style("✔ Cleaned index for").green(), style(&proj_name).white().bold());
|
||||
println!(
|
||||
"{} {}",
|
||||
style("✔ Cleaned index for").green(),
|
||||
style(&proj_name).white().bold()
|
||||
);
|
||||
} else {
|
||||
println!("{} {}", style("✖ No index found for").red(), style(&proj_name).white().bold());
|
||||
println!(
|
||||
"{} {}",
|
||||
style("✖ No index found for").red(),
|
||||
style(&proj_name).white().bold()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let current_dir = env::current_dir()?;
|
||||
|
|
@ -29,11 +33,19 @@ pub fn handle(
|
|||
|
||||
if db_path.exists() {
|
||||
fs::remove_file(&db_path)?;
|
||||
println!("{} {}", style("✔ Cleaned index for").green(), style(&project_name).white().bold());
|
||||
println!(
|
||||
"{} {}",
|
||||
style("✔ Cleaned index for").green(),
|
||||
style(&project_name).white().bold()
|
||||
);
|
||||
} else {
|
||||
println!("{} {}", style("✖ No index found for current project").red(), style(&project_name).white().bold());
|
||||
println!(
|
||||
"{} {}",
|
||||
style("✖ No index found for current project").red(),
|
||||
style(&project_name).white().bold()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
use std::fs;
|
||||
use std::process::exit;
|
||||
use bytesize::ByteSize;
|
||||
use chrono::{DateTime, Local};
|
||||
use console::style;
|
||||
use crate::cli::IndexAction;
|
||||
use crate::database::index::{Indexer, IssueRow};
|
||||
use crate::errors::NyxResult;
|
||||
use crate::patterns::Severity;
|
||||
use crate::utils::Config;
|
||||
use crate::utils::project::get_project_info;
|
||||
use crate::walk::spawn_senders;
|
||||
use bytesize::ByteSize;
|
||||
use chrono::{DateTime, Local};
|
||||
use console::style;
|
||||
use rayon::prelude::*;
|
||||
use crate::errors::NyxResult;
|
||||
use std::fs;
|
||||
use std::process::exit;
|
||||
|
||||
pub fn handle(
|
||||
action: IndexAction,
|
||||
|
|
@ -24,10 +24,18 @@ pub fn handle(
|
|||
|
||||
if force || !db_path.exists() {
|
||||
build_index(&project_name, &build_path, &db_path, config)?;
|
||||
println!("✔ {} {}", style("Index built:" ).green(), style(db_path.display()).white().bold());
|
||||
println!(
|
||||
"✔ {} {}",
|
||||
style("Index built:").green(),
|
||||
style(db_path.display()).white().bold()
|
||||
);
|
||||
exit(0);
|
||||
} else {
|
||||
println!("{} {}", style("↩ Index already exists").yellow(), style("(use --force to rebuild)").dim());
|
||||
println!(
|
||||
"{} {}",
|
||||
style("↩ Index already exists").yellow(),
|
||||
style("(use --force to rebuild)").dim()
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -36,18 +44,34 @@ pub fn handle(
|
|||
let (project_name, db_path) = get_project_info(&status_path, database_dir)?;
|
||||
|
||||
println!("{}", style("Project status").blue().bold().underlined());
|
||||
println!(" {:14} {}", style("Project"), style(&project_name).white().bold());
|
||||
println!(" {:14} {}", style("Index path"), style(db_path.display()).underlined());
|
||||
println!(" {:14} {}", style("Exists"), style(db_path.exists()).bold());
|
||||
println!(
|
||||
" {:14} {}",
|
||||
style("Project"),
|
||||
style(&project_name).white().bold()
|
||||
);
|
||||
println!(
|
||||
" {:14} {}",
|
||||
style("Index path"),
|
||||
style(db_path.display()).underlined()
|
||||
);
|
||||
println!(
|
||||
" {:14} {}",
|
||||
style("Exists"),
|
||||
style(db_path.exists()).bold()
|
||||
);
|
||||
|
||||
if db_path.exists() {
|
||||
let meta = fs::metadata(&db_path)?;
|
||||
let size = ByteSize::b(meta.len());
|
||||
let mtime: DateTime<Local> = meta.modified()?.into();
|
||||
println!(" {:14} {}", style("Size"), size);
|
||||
println!(" {:14} {}", style("Modified"), mtime.format("%Y-%m-%d %H:%M:%S"));
|
||||
println!(" {:14} {}", style("Size"), size);
|
||||
println!(
|
||||
" {:14} {}",
|
||||
style("Modified"),
|
||||
mtime.format("%Y-%m-%d %H:%M:%S")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +85,7 @@ pub fn build_index(
|
|||
) -> NyxResult<()> {
|
||||
tracing::debug!("Building index for: {}", project_name);
|
||||
fs::File::create(db_path)?;
|
||||
|
||||
|
||||
let pool = Indexer::init(db_path)?;
|
||||
{
|
||||
let idx = Indexer::from_pool(project_name, &pool)?;
|
||||
|
|
@ -69,34 +93,39 @@ pub fn build_index(
|
|||
}
|
||||
|
||||
tracing::debug!("Cleaned index for: {}", project_name);
|
||||
|
||||
|
||||
let rx = spawn_senders(project_path, config);
|
||||
let paths: Vec<_> = rx.into_iter().flatten().collect();
|
||||
|
||||
paths.into_par_iter().try_for_each(|path| -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let issues = crate::commands::scan::run_rules_on_file(&path, config)?;
|
||||
let mut idx = Indexer::from_pool(project_name, &pool)?;
|
||||
let file_id = idx.upsert_file(&path)?;
|
||||
|
||||
let rows: Vec<IssueRow> = issues.iter().map(|d| IssueRow {
|
||||
rule_id: d.id.as_ref(),
|
||||
severity: match d.severity {
|
||||
Severity::High => "HIGH",
|
||||
Severity::Medium => "MEDIUM",
|
||||
Severity::Low => "LOW",
|
||||
},
|
||||
line: d.line as i64,
|
||||
col: d.col as i64,
|
||||
}).collect();
|
||||
|
||||
idx.replace_issues(file_id, rows)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
paths.into_par_iter().try_for_each(
|
||||
|path| -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let issues = crate::commands::scan::run_rules_on_file(&path, config)?;
|
||||
let mut idx = Indexer::from_pool(project_name, &pool)?;
|
||||
let file_id = idx.upsert_file(&path)?;
|
||||
|
||||
let rows: Vec<IssueRow> = issues
|
||||
.iter()
|
||||
.map(|d| IssueRow {
|
||||
rule_id: d.id.as_ref(),
|
||||
severity: match d.severity {
|
||||
Severity::High => "HIGH",
|
||||
Severity::Medium => "MEDIUM",
|
||||
Severity::Low => "LOW",
|
||||
},
|
||||
line: d.line as i64,
|
||||
col: d.col as i64,
|
||||
})
|
||||
.collect();
|
||||
|
||||
idx.replace_issues(file_id, rows)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
{
|
||||
let idx = Indexer::from_pool(project_name, &pool)?;
|
||||
idx.vacuum()?;
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
use std::fs;
|
||||
use crate::errors::NyxResult;
|
||||
use bytesize::ByteSize;
|
||||
use chrono::{DateTime, Local};
|
||||
use console::style;
|
||||
use crate::errors::NyxResult;
|
||||
use std::fs;
|
||||
|
||||
pub fn handle(
|
||||
verbose: bool,
|
||||
database_dir: &std::path::Path,
|
||||
) -> NyxResult<()> {
|
||||
pub fn handle(verbose: bool, database_dir: &std::path::Path) -> NyxResult<()> {
|
||||
println!("{}", style("Indexed projects").blue().bold().underlined());
|
||||
|
||||
if !database_dir.exists() {
|
||||
|
|
@ -21,18 +18,29 @@ pub fn handle(
|
|||
continue;
|
||||
}
|
||||
|
||||
let name = path.file_stem().and_then(|s| s.to_str()).unwrap_or("unknown");
|
||||
let name = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("unknown");
|
||||
println!(" {}", style(name).white().bold());
|
||||
|
||||
if verbose {
|
||||
let meta = fs::metadata(&path)?;
|
||||
let size = ByteSize::b(meta.len());
|
||||
let mtime: DateTime<Local> = meta.modified()?.into();
|
||||
println!(" {:10} {}", style("Path"), style(path.display()).underlined());
|
||||
println!(" {:10} {}", style("Size"), size);
|
||||
println!(" {:10} {}", style("Modified"), mtime.format("%Y-%m-%d %H:%M:%S"));
|
||||
println!(
|
||||
" {:10} {}",
|
||||
style("Path"),
|
||||
style(path.display()).underlined()
|
||||
);
|
||||
println!(" {:10} {}", style("Size"), size);
|
||||
println!(
|
||||
" {:10} {}",
|
||||
style("Modified"),
|
||||
mtime.format("%Y-%m-%d %H:%M:%S")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,35 @@
|
|||
pub mod scan;
|
||||
pub mod clean;
|
||||
pub mod index;
|
||||
pub mod list;
|
||||
pub mod clean;
|
||||
pub mod scan;
|
||||
|
||||
use crate::cli::Commands;
|
||||
use std::path::Path;
|
||||
use crate::errors::NyxResult;
|
||||
use crate::patterns::Severity;
|
||||
use crate::utils::config::Config;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn handle_command(
|
||||
command: Commands,
|
||||
database_dir: &Path,
|
||||
config: &mut Config
|
||||
config: &mut Config,
|
||||
) -> NyxResult<()> {
|
||||
match command {
|
||||
Commands::Scan { path, no_index, rebuild_index, format, high_only } => {
|
||||
if high_only { config.scanner.min_severity = Severity::High };
|
||||
|
||||
Commands::Scan {
|
||||
path,
|
||||
no_index,
|
||||
rebuild_index,
|
||||
format,
|
||||
high_only,
|
||||
} => {
|
||||
if high_only {
|
||||
config.scanner.min_severity = Severity::High
|
||||
};
|
||||
|
||||
scan::handle(&path, no_index, rebuild_index, format, database_dir, config)
|
||||
}
|
||||
Commands::Index { action } => {
|
||||
index::handle(action, database_dir, config)
|
||||
}
|
||||
Commands::List { verbose } => {
|
||||
list::handle(verbose, database_dir)
|
||||
}
|
||||
Commands::Clean { project, all } => {
|
||||
clean::handle(project, all, database_dir)
|
||||
}
|
||||
Commands::Index { action } => index::handle(action, database_dir, config),
|
||||
Commands::List { verbose } => list::handle(verbose, database_dir),
|
||||
Commands::Clean { project, all } => clean::handle(project, all, database_dir),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
use crate::utils::project::get_project_info;
|
||||
use console::style;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use r2d2::Pool;
|
||||
use r2d2_sqlite::SqliteConnectionManager;
|
||||
use crate::database::index::{IssueRow, Indexer};
|
||||
pub(crate) use crate::ast::run_rules_on_file;
|
||||
use crate::database::index::{Indexer, IssueRow};
|
||||
use crate::errors::NyxResult;
|
||||
use crate::patterns::Severity;
|
||||
use crate::utils::config::Config;
|
||||
use crate::utils::project::get_project_info;
|
||||
use crate::walk::spawn_senders;
|
||||
use console::style;
|
||||
use dashmap::DashMap;
|
||||
use r2d2::Pool;
|
||||
use r2d2_sqlite::SqliteConnectionManager;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use dashmap::DashMap;
|
||||
use crate::errors::NyxResult;
|
||||
pub(crate) use crate::ast::run_rules_on_file;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
type DynError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
||||
|
|
@ -37,14 +37,18 @@ pub fn handle(
|
|||
let scan_path = Path::new(path).canonicalize()?;
|
||||
let (project_name, db_path) = get_project_info(&scan_path, database_dir)?;
|
||||
|
||||
println!("{} {}...\n", style("Checking").green().bold(), &project_name);
|
||||
|
||||
println!(
|
||||
"{} {}...\n",
|
||||
style("Checking").green().bold(),
|
||||
&project_name
|
||||
);
|
||||
|
||||
let diags: Vec<Diag> = if no_index {
|
||||
scan_filesystem(&scan_path, config)?
|
||||
} else {
|
||||
if rebuild_index || !db_path.exists() {
|
||||
tracing::debug!("Scanning filesystem index filesystem");
|
||||
crate::commands::index::build_index(&project_name,&scan_path, &db_path, config)?;
|
||||
crate::commands::index::build_index(&project_name, &scan_path, &db_path, config)?;
|
||||
}
|
||||
|
||||
let pool = Indexer::init(&db_path)?;
|
||||
|
|
@ -53,9 +57,7 @@ pub fn handle(
|
|||
|
||||
tracing::debug!("Found {:?} issues.", diags.len());
|
||||
|
||||
if format == "console"
|
||||
|| (format.is_empty() && config.output.default_format == "console")
|
||||
{
|
||||
if format == "console" || (format.is_empty() && config.output.default_format == "console") {
|
||||
tracing::debug!("Printing to console");
|
||||
let mut grouped: BTreeMap<&str, Vec<&Diag>> = BTreeMap::new();
|
||||
for d in &diags {
|
||||
|
|
@ -65,16 +67,23 @@ pub fn handle(
|
|||
for (path, issues) in &grouped {
|
||||
println!("{}", style(path).blue().underlined());
|
||||
for d in issues {
|
||||
println!(" {:>4}:{:<4} [{}] {}",
|
||||
d.line, d.col, d.severity, style(&d.id).bold());
|
||||
println!(
|
||||
" {:>4}:{:<4} [{}] {}",
|
||||
d.line,
|
||||
d.col,
|
||||
d.severity,
|
||||
style(&d.id).bold()
|
||||
);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
println!("{} '{}' generated {} issues.",
|
||||
style("warning").yellow().bold(),
|
||||
style(project_name).white().bold(),
|
||||
style(diags.len()).bold());
|
||||
println!(
|
||||
"{} '{}' generated {} issues.",
|
||||
style("warning").yellow().bold(),
|
||||
style(project_name).white().bold(),
|
||||
style(diags.len()).bold()
|
||||
);
|
||||
println!("\t"); // TODO: Add individual counts for different warning levels
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -84,22 +93,16 @@ pub fn handle(
|
|||
// Scanning helpers
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
fn scan_filesystem(
|
||||
root: &Path,
|
||||
cfg: &Config,
|
||||
) -> NyxResult<Vec<Diag>> {
|
||||
fn scan_filesystem(root: &Path, cfg: &Config) -> NyxResult<Vec<Diag>> {
|
||||
let rx = spawn_senders(root, cfg);
|
||||
let acc = Mutex::new(Vec::new());
|
||||
|
||||
rx.into_iter()
|
||||
.flatten()
|
||||
.par_bridge()
|
||||
.try_for_each(|path| {
|
||||
let mut local = run_rules_on_file(&path, cfg)?;
|
||||
acc.lock().unwrap().append(&mut local);
|
||||
Ok::<(), DynError>(())
|
||||
})?;
|
||||
|
||||
rx.into_iter().flatten().par_bridge().try_for_each(|path| {
|
||||
let mut local = run_rules_on_file(&path, cfg)?;
|
||||
acc.lock().unwrap().append(&mut local);
|
||||
Ok::<(), DynError>(())
|
||||
})?;
|
||||
|
||||
Ok(acc.into_inner()?)
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +111,6 @@ pub fn scan_with_index_parallel(
|
|||
pool: Arc<Pool<SqliteConnectionManager>>,
|
||||
cfg: &Config,
|
||||
) -> NyxResult<Vec<Diag>> {
|
||||
|
||||
let files = {
|
||||
let idx = Indexer::from_pool(project, &pool)?;
|
||||
idx.get_files(project)?
|
||||
|
|
@ -117,40 +119,48 @@ pub fn scan_with_index_parallel(
|
|||
// ① Collect per-path Vec<Diag> without a global mutex
|
||||
let diag_map: DashMap<String, Vec<Diag>> = DashMap::new();
|
||||
|
||||
files.into_par_iter()
|
||||
.for_each_init(
|
||||
// ② A single Indexer per Rayon worker thread
|
||||
|| Indexer::from_pool(project, &pool).expect("db pool"),
|
||||
|idx, path| {
|
||||
let needs_scan = idx.should_scan(&path).unwrap_or(true);
|
||||
files.into_par_iter().for_each_init(
|
||||
// ② A single Indexer per Rayon worker thread
|
||||
|| Indexer::from_pool(project, &pool).expect("db pool"),
|
||||
|idx, path| {
|
||||
let needs_scan = idx.should_scan(&path).unwrap_or(true);
|
||||
|
||||
let mut diags = if needs_scan {
|
||||
let d = run_rules_on_file(&path, cfg).unwrap_or_default();
|
||||
let file_id = idx.upsert_file(&path).unwrap_or_default();
|
||||
idx.replace_issues(
|
||||
file_id,
|
||||
d.iter().map(|d| IssueRow {
|
||||
rule_id: &d.id,
|
||||
severity: d.severity.as_db_str(),
|
||||
line: d.line as i64,
|
||||
col: d.col as i64,
|
||||
}),
|
||||
).ok();
|
||||
d
|
||||
} else {
|
||||
idx.get_issues_from_file(&path).unwrap_or_default()
|
||||
};
|
||||
if !diags.is_empty() {
|
||||
diag_map.entry(path.to_string_lossy().to_string())
|
||||
let mut diags = if needs_scan {
|
||||
let d = run_rules_on_file(&path, cfg).unwrap_or_default();
|
||||
let file_id = idx.upsert_file(&path).unwrap_or_default();
|
||||
idx.replace_issues(
|
||||
file_id,
|
||||
d.iter().map(|d| IssueRow {
|
||||
rule_id: &d.id,
|
||||
severity: d.severity.as_db_str(),
|
||||
line: d.line as i64,
|
||||
col: d.col as i64,
|
||||
}),
|
||||
)
|
||||
.ok();
|
||||
d
|
||||
} else {
|
||||
idx.get_issues_from_file(&path).unwrap_or_default()
|
||||
};
|
||||
if !diags.is_empty() {
|
||||
diag_map
|
||||
.entry(path.to_string_lossy().to_string())
|
||||
.or_default()
|
||||
.append(&mut diags);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Optional, heavy: only vacuum on --rebuild-index
|
||||
// if rebuild { idx.vacuum()?; }
|
||||
|
||||
// flatten
|
||||
let mut diags: Vec<Diag> = diag_map.into_iter().flat_map(|(_, v)| v).collect();
|
||||
|
||||
if let Some(max) = cfg.output.max_results {
|
||||
diags.truncate(max as usize);
|
||||
}
|
||||
|
||||
// Flatten
|
||||
Ok(diag_map.into_iter().flat_map(|(_, v)| v).collect())
|
||||
Ok(diags)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue