mirror of https://github.com/astral-sh/ruff
Add a check for long lines
This commit is contained in:
parent
4a67c8d44b
commit
943a0de62b
|
|
@ -1493,7 +1493,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-python-linter"
|
||||
version = "0.0.8"
|
||||
version = "0.0.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rust-python-linter"
|
||||
version = "0.0.8"
|
||||
version = "0.0.9"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
"""Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
"""
|
||||
|
|
@ -85,7 +85,7 @@ pub fn check_ast(python_ast: &Suite) -> Vec<Check> {
|
|||
mod tests {
|
||||
use rustpython_parser::ast::{Alias, Location, Stmt, StmtKind};
|
||||
|
||||
use crate::checker::Checker;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::Check;
|
||||
use crate::checks::CheckKind::ImportStarUsage;
|
||||
use crate::visitor::Visitor;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::checks::Check;
|
||||
use crate::checks::CheckKind::LineTooLong;
|
||||
|
||||
pub fn check_lines(contents: &str) -> Vec<Check> {
|
||||
contents
|
||||
.lines()
|
||||
.enumerate()
|
||||
.filter_map(|(row, line)| {
|
||||
if line.len() > 79 {
|
||||
Some(Check {
|
||||
kind: LineTooLong,
|
||||
location: Location::new(row + 1, 79 + 1),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ pub enum CheckKind {
|
|||
DuplicateArgumentName,
|
||||
ImportStarUsage,
|
||||
IfTuple,
|
||||
LineTooLong,
|
||||
}
|
||||
|
||||
impl CheckKind {
|
||||
|
|
@ -15,6 +16,7 @@ impl CheckKind {
|
|||
CheckKind::DuplicateArgumentName => "F831",
|
||||
CheckKind::IfTuple => "F634",
|
||||
CheckKind::ImportStarUsage => "F403",
|
||||
CheckKind::LineTooLong => "E501",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +26,7 @@ impl CheckKind {
|
|||
CheckKind::DuplicateArgumentName => "Duplicate argument name in function definition",
|
||||
CheckKind::IfTuple => "If test is a tuple, which is always `True`",
|
||||
CheckKind::ImportStarUsage => "Unable to detect undefined names",
|
||||
CheckKind::LineTooLong => "Line too long (> 79 characters)",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
src/fs.rs
14
src/fs.rs
|
|
@ -1,5 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
fn is_not_hidden(entry: &DirEntry) -> bool {
|
||||
|
|
@ -18,3 +20,11 @@ pub fn iter_python_files(path: &PathBuf) -> impl Iterator<Item = DirEntry> {
|
|||
.filter_map(|entry| entry.ok())
|
||||
.filter(|entry| entry.path().to_string_lossy().ends_with(".py"))
|
||||
}
|
||||
|
||||
pub fn read_file(path: &Path) -> Result<String> {
|
||||
let file = File::open(path)?;
|
||||
let mut buf_reader = BufReader::new(file);
|
||||
let mut contents = String::new();
|
||||
buf_reader.read_to_string(&mut contents)?;
|
||||
Ok(contents)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
mod cache;
|
||||
pub mod checker;
|
||||
pub mod check_ast;
|
||||
mod check_lines;
|
||||
mod checks;
|
||||
pub mod fs;
|
||||
pub mod linter;
|
||||
pub mod logging;
|
||||
pub mod message;
|
||||
mod parser;
|
||||
mod visitor;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ use std::path::Path;
|
|||
|
||||
use anyhow::Result;
|
||||
use log::debug;
|
||||
use rustpython_parser::parser;
|
||||
|
||||
use crate::checker::check_ast;
|
||||
use crate::check_ast::check_ast;
|
||||
use crate::check_lines::check_lines;
|
||||
use crate::message::Message;
|
||||
use crate::{cache, parser};
|
||||
use crate::{cache, fs};
|
||||
|
||||
pub fn check_path(path: &Path, mode: &cache::Mode) -> Result<Vec<Message>> {
|
||||
// Check the cache.
|
||||
|
|
@ -14,10 +16,14 @@ pub fn check_path(path: &Path, mode: &cache::Mode) -> Result<Vec<Message>> {
|
|||
return Ok(messages);
|
||||
}
|
||||
|
||||
// Read the file from disk.
|
||||
let contents = fs::read_file(path)?;
|
||||
|
||||
// Run the linter.
|
||||
let python_ast = parser::parse(path)?;
|
||||
let python_ast = parser::parse_program(&contents)?;
|
||||
let messages: Vec<Message> = check_ast(&python_ast)
|
||||
.into_iter()
|
||||
.chain(check_lines(&contents))
|
||||
.map(|check| Message {
|
||||
kind: check.kind,
|
||||
location: check.location,
|
||||
|
|
@ -37,7 +43,7 @@ mod tests {
|
|||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::cache;
|
||||
use crate::checks::CheckKind::{DuplicateArgumentName, IfTuple, ImportStarUsage};
|
||||
use crate::checks::CheckKind::{DuplicateArgumentName, IfTuple, ImportStarUsage, LineTooLong};
|
||||
use crate::linter::check_path;
|
||||
use crate::message::Message;
|
||||
|
||||
|
|
@ -116,4 +122,23 @@ mod tests {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_too_long() -> Result<()> {
|
||||
let actual = check_path(
|
||||
&Path::new("./resources/test/src/line_too_long.py"),
|
||||
&cache::Mode::None,
|
||||
)?;
|
||||
let expected = vec![Message {
|
||||
kind: LineTooLong,
|
||||
location: Location::new(3, 80),
|
||||
filename: "./resources/test/src/line_too_long.py".to_string(),
|
||||
}];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 1..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,13 @@ impl fmt::Display for Message {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}{}{}{}{}\t{}\t{}",
|
||||
"{}{}{}{}{}{} {} {}",
|
||||
self.filename.white().bold(),
|
||||
":".cyan(),
|
||||
self.location.row(),
|
||||
":".cyan(),
|
||||
self.location.column(),
|
||||
":".cyan(),
|
||||
self.location.row(),
|
||||
self.kind.code().red().bold(),
|
||||
self.kind.body()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use rustpython_parser::ast::Suite;
|
||||
use rustpython_parser::parser;
|
||||
|
||||
pub fn parse(path: &Path) -> Result<Suite> {
|
||||
let file = File::open(path)?;
|
||||
let mut buf_reader = BufReader::new(file);
|
||||
let mut contents = String::new();
|
||||
buf_reader.read_to_string(&mut contents)?;
|
||||
parser::parse_program(&contents).map_err(|e| e.into())
|
||||
}
|
||||
Loading…
Reference in New Issue