mirror of https://github.com/astral-sh/ruff
Add JUnit xml output format (#968)
This commit is contained in:
parent
a0202e8eb2
commit
f5466fe720
|
|
@ -220,13 +220,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.22"
|
version = "0.4.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
|
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"time",
|
||||||
|
"wasm-bindgen",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -883,9 +886,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.1"
|
version = "1.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
|
@ -1220,6 +1223,12 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nextest-workspace-hack"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d906846a98739ed9d73d66e62c2641eef8321f1734b7a1156ab045a0248fb2b3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.24.2"
|
version = "0.24.2"
|
||||||
|
|
@ -1606,6 +1615,29 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-junit"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05b909fe9bf2abb1e3d6a97c9189a37c8105c61d03dca9ce6aace023e7d682bd"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"indexmap",
|
||||||
|
"nextest-workspace-hack",
|
||||||
|
"quick-xml",
|
||||||
|
"thiserror",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
|
|
@ -1835,6 +1867,7 @@ dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"path-absolutize",
|
"path-absolutize",
|
||||||
|
"quick-junit",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"ropey",
|
"ropey",
|
||||||
|
|
@ -2263,6 +2296,17 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-keccak"
|
name = "tiny-keccak"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
|
@ -2489,6 +2533,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
|
@ -2527,6 +2577,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ notify = { version = "4.0.17" }
|
||||||
num-bigint = { version = "0.4.3" }
|
num-bigint = { version = "0.4.3" }
|
||||||
once_cell = { version = "1.16.0" }
|
once_cell = { version = "1.16.0" }
|
||||||
path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix_paths_on_wasm"] }
|
path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix_paths_on_wasm"] }
|
||||||
|
quick-junit = "0.3.2"
|
||||||
rayon = { version = "1.5.3" }
|
rayon = { version = "1.5.3" }
|
||||||
regex = { version = "1.6.0" }
|
regex = { version = "1.6.0" }
|
||||||
ropey = { version = "1.5.0", features = ["cr_lines", "simd"], default-features = false }
|
ropey = { version = "1.5.0", features = ["cr_lines", "simd"], default-features = false }
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ Options:
|
||||||
--per-file-ignores <PER_FILE_IGNORES>
|
--per-file-ignores <PER_FILE_IGNORES>
|
||||||
List of mappings from file pattern to code to exclude
|
List of mappings from file pattern to code to exclude
|
||||||
--format <FORMAT>
|
--format <FORMAT>
|
||||||
Output serialization format for error messages [default: text] [possible values: text, json, grouped]
|
Output serialization format for error messages [default: text] [possible values: text, json, junit, grouped]
|
||||||
--show-source
|
--show-source
|
||||||
Show violations with source code
|
Show violations with source code
|
||||||
--show-files
|
--show-files
|
||||||
|
|
@ -1457,7 +1457,7 @@ line-length = 120
|
||||||
#### [`format`](#format)
|
#### [`format`](#format)
|
||||||
|
|
||||||
The style in which violation messages should be formatted: `"text"` (default), `"grouped"`
|
The style in which violation messages should be formatted: `"text"` (default), `"grouped"`
|
||||||
(group messages by file), or `"json"` (machine-readable).
|
(group messages by file), `"json"` (machine-readable), or `"junit"` (machine-readable XML).
|
||||||
|
|
||||||
**Default value**: `"text"`
|
**Default value**: `"text"`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::str::FromStr;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_parser::ast::Location;
|
use rustpython_parser::ast::Location;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum_macros::{AsRefStr, EnumIter, EnumString};
|
use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::autofix::Fix;
|
use crate::autofix::Fix;
|
||||||
|
|
@ -17,6 +17,7 @@ use crate::pyupgrade::types::Primitive;
|
||||||
EnumIter,
|
EnumIter,
|
||||||
EnumString,
|
EnumString,
|
||||||
Debug,
|
Debug,
|
||||||
|
Display,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
Eq,
|
Eq,
|
||||||
Clone,
|
Clone,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Result};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use walkdir::DirEntry;
|
use walkdir::DirEntry;
|
||||||
|
|
||||||
|
|
@ -61,6 +61,9 @@ pub fn explain(code: &CheckCode, format: SerializationFormat) -> Result<()> {
|
||||||
})?
|
})?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
SerializationFormat::Junit => {
|
||||||
|
bail!("`--explain` does not support junit format")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,50 @@ impl<'a> Printer<'a> {
|
||||||
)?
|
)?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
SerializationFormat::Junit => {
|
||||||
|
use quick_junit::{NonSuccessKind, Report, TestCase, TestCaseStatus, TestSuite};
|
||||||
|
|
||||||
|
// Group by filename.
|
||||||
|
let mut grouped_messages = BTreeMap::default();
|
||||||
|
for message in &diagnostics.messages {
|
||||||
|
grouped_messages
|
||||||
|
.entry(&message.filename)
|
||||||
|
.or_insert_with(Vec::new)
|
||||||
|
.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut report = Report::new("ruff");
|
||||||
|
for (filename, messages) in grouped_messages {
|
||||||
|
let mut test_suite = TestSuite::new(filename);
|
||||||
|
test_suite
|
||||||
|
.extra
|
||||||
|
.insert("package".to_string(), "org.ruff".to_string());
|
||||||
|
for message in messages {
|
||||||
|
let mut status = TestCaseStatus::non_success(NonSuccessKind::Failure);
|
||||||
|
status.set_message(message.kind.body());
|
||||||
|
status.set_description(format!(
|
||||||
|
"line {}, col {}, {}",
|
||||||
|
message.location.row(),
|
||||||
|
message.location.column(),
|
||||||
|
message.kind.body()
|
||||||
|
));
|
||||||
|
let mut case =
|
||||||
|
TestCase::new(format!("org.ruff.{}", message.kind.code()), status);
|
||||||
|
let file_path = Path::new(filename);
|
||||||
|
let file_stem = file_path.file_stem().unwrap().to_str().unwrap();
|
||||||
|
let classname = file_path.parent().unwrap().join(file_stem);
|
||||||
|
case.set_classname(classname.to_str().unwrap());
|
||||||
|
case.extra
|
||||||
|
.insert("line".to_string(), message.location.row().to_string());
|
||||||
|
case.extra
|
||||||
|
.insert("column".to_string(), message.location.column().to_string());
|
||||||
|
|
||||||
|
test_suite.add_test_case(case);
|
||||||
|
}
|
||||||
|
report.add_test_suite(test_suite);
|
||||||
|
}
|
||||||
|
println!("{}", report.to_string().unwrap());
|
||||||
|
}
|
||||||
SerializationFormat::Text => {
|
SerializationFormat::Text => {
|
||||||
self.pre_text(diagnostics);
|
self.pre_text(diagnostics);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,5 +148,6 @@ impl FromStr for PatternPrefixPair {
|
||||||
pub enum SerializationFormat {
|
pub enum SerializationFormat {
|
||||||
Text,
|
Text,
|
||||||
Json,
|
Json,
|
||||||
|
Junit,
|
||||||
Grouped,
|
Grouped,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue