mirror of https://github.com/astral-sh/ruff
Create a dependency graph
This commit is contained in:
parent
3b1b53dacf
commit
f5e1b54ffe
|
|
@ -1,3 +1,9 @@
|
|||
import os
|
||||
from multiprocessing import pool as fool
|
||||
from spr_platform import module
|
||||
from spr_platform.sub_module import other
|
||||
import spr_platform.sub_module
|
||||
|
||||
if (1, 2):
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use rustpython_parser::ast::{Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::parser;
|
||||
|
||||
use ::rust_python_linter::fs;
|
||||
use ::rust_python_linter::visitor::{walk_stmt, Visitor};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
struct ModuleImport {
|
||||
module_name: Option<String>,
|
||||
remote_name: Option<String>,
|
||||
local_name: Option<String>,
|
||||
lineno: usize,
|
||||
pragma: usize,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ImportVisitor {
|
||||
imports: Vec<ModuleImport>,
|
||||
}
|
||||
|
||||
// Inspired by: https://github.com/blais/snakefood/blob/f902c9a099f7c5bb75154a747bf098259211025d/lib/python/snakefood/find.py#L241
|
||||
impl Visitor for ImportVisitor {
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) {
|
||||
match &stmt.node {
|
||||
StmtKind::Import { names } => {
|
||||
for alias in names {
|
||||
self.imports.push(ModuleImport {
|
||||
module_name: Some(alias.name.clone()),
|
||||
remote_name: None,
|
||||
local_name: Some(
|
||||
alias.asname.clone().unwrap_or_else(|| alias.name.clone()),
|
||||
),
|
||||
lineno: stmt.location.row(),
|
||||
pragma: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
StmtKind::ImportFrom {
|
||||
module,
|
||||
names,
|
||||
level,
|
||||
} => {
|
||||
if let Some(module_name) = module {
|
||||
if module_name == "__future__" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for alias in names {
|
||||
if alias.name == "*" {
|
||||
self.imports.push(ModuleImport {
|
||||
module_name: module.clone(),
|
||||
remote_name: None,
|
||||
local_name: None,
|
||||
lineno: stmt.location.row(),
|
||||
pragma: *level,
|
||||
})
|
||||
} else {
|
||||
self.imports.push(ModuleImport {
|
||||
module_name: module.clone(),
|
||||
remote_name: Some(alias.name.clone()),
|
||||
local_name: Some(
|
||||
alias.asname.clone().unwrap_or_else(|| alias.name.clone()),
|
||||
),
|
||||
lineno: stmt.location.row(),
|
||||
pragma: *level,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
walk_stmt(self, stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_imports(python_ast: &Suite) -> Vec<ModuleImport> {
|
||||
python_ast
|
||||
.iter()
|
||||
.flat_map(|stmt| {
|
||||
let mut visitor: ImportVisitor = Default::default();
|
||||
visitor.visit_stmt(stmt);
|
||||
visitor.imports
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// What else is required here? Map from modules to files.
|
||||
let files = fs::iter_python_files(&PathBuf::from("resources/test/src"));
|
||||
for entry in files {
|
||||
// Read the file from disk.
|
||||
let contents = fs::read_file(entry.path())?;
|
||||
|
||||
// Run the parser.
|
||||
let python_ast = parser::parse_program(&contents)?;
|
||||
|
||||
// Collect imports.
|
||||
let imports = collect_imports(&python_ast);
|
||||
for import in imports {
|
||||
println!("{} imports: {:?}", entry.path().to_string_lossy(), import)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ use notify::{raw_watcher, RecursiveMode, Watcher};
|
|||
use rayon::prelude::*;
|
||||
use walkdir::DirEntry;
|
||||
|
||||
use ::rust_python_linter::fs::iter_python_files;
|
||||
use ::rust_python_linter::fs;
|
||||
use ::rust_python_linter::linter::check_path;
|
||||
use ::rust_python_linter::logging::set_up_logging;
|
||||
use ::rust_python_linter::message::Message;
|
||||
|
|
@ -33,7 +33,7 @@ struct Cli {
|
|||
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(iter_python_files).collect();
|
||||
let files: Vec<DirEntry> = files.iter().flat_map(fs::iter_python_files).collect();
|
||||
let duration = start.elapsed();
|
||||
debug!("Identified files to lint in: {:?}", duration);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ pub mod linter;
|
|||
pub mod logging;
|
||||
pub mod message;
|
||||
mod settings;
|
||||
mod visitor;
|
||||
pub mod visitor;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ pub fn check_path(path: &Path, mode: &cache::Mode) -> Result<Vec<Message>> {
|
|||
// Read the file from disk.
|
||||
let contents = fs::read_file(path)?;
|
||||
|
||||
// Run the linter.
|
||||
// Run the parser.
|
||||
let python_ast = parser::parse_program(&contents)?;
|
||||
|
||||
// Run the linter.
|
||||
let messages: Vec<Message> = check_ast(&python_ast)
|
||||
.into_iter()
|
||||
.chain(check_lines(&contents))
|
||||
|
|
|
|||
Loading…
Reference in New Issue