mirror of https://github.com/astral-sh/ruff
[ty] Exit with `2` if there's any IO error (#21508)
Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
parent
c796a70ec9
commit
663f78e644
|
|
@ -67,7 +67,7 @@ jobs:
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@0aff03414da5d242e97a9f43fb502e085637a4a1"
|
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@e5c5f5b2d762af91b28490537fe0077334165693"
|
||||||
|
|
||||||
ecosystem-analyzer \
|
ecosystem-analyzer \
|
||||||
--repository ruff \
|
--repository ruff \
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ jobs:
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@0aff03414da5d242e97a9f43fb502e085637a4a1"
|
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@e5c5f5b2d762af91b28490537fe0077334165693"
|
||||||
|
|
||||||
ecosystem-analyzer \
|
ecosystem-analyzer \
|
||||||
--verbose \
|
--verbose \
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ mod python_version;
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
pub use args::Cli;
|
pub use args::Cli;
|
||||||
|
use ty_project::metadata::settings::TerminalSettings;
|
||||||
use ty_static::EnvVars;
|
use ty_static::EnvVars;
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
@ -21,7 +22,9 @@ use clap::{CommandFactory, Parser};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use crossbeam::channel as crossbeam_channel;
|
use crossbeam::channel as crossbeam_channel;
|
||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
use ruff_db::diagnostic::{Diagnostic, DisplayDiagnosticConfig, DisplayDiagnostics, Severity};
|
use ruff_db::diagnostic::{
|
||||||
|
Diagnostic, DiagnosticId, DisplayDiagnosticConfig, DisplayDiagnostics, Severity,
|
||||||
|
};
|
||||||
use ruff_db::files::File;
|
use ruff_db::files::File;
|
||||||
use ruff_db::max_parallelism;
|
use ruff_db::max_parallelism;
|
||||||
use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf};
|
use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf};
|
||||||
|
|
@ -193,6 +196,12 @@ pub enum ExitStatus {
|
||||||
InternalError = 101,
|
InternalError = 101,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExitStatus {
|
||||||
|
pub const fn is_internal_error(self) -> bool {
|
||||||
|
matches!(self, ExitStatus::InternalError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Termination for ExitStatus {
|
impl Termination for ExitStatus {
|
||||||
fn report(self) -> ExitCode {
|
fn report(self) -> ExitCode {
|
||||||
ExitCode::from(self as u8)
|
ExitCode::from(self as u8)
|
||||||
|
|
@ -334,11 +343,8 @@ impl MainLoop {
|
||||||
let diagnostics_count = result.len();
|
let diagnostics_count = result.len();
|
||||||
|
|
||||||
let mut stdout = self.printer.stream_for_details().lock();
|
let mut stdout = self.printer.stream_for_details().lock();
|
||||||
let max_severity = result
|
let exit_status =
|
||||||
.iter()
|
exit_status_from_diagnostics(&result, terminal_settings);
|
||||||
.map(Diagnostic::severity)
|
|
||||||
.max()
|
|
||||||
.unwrap_or(Severity::Info);
|
|
||||||
|
|
||||||
// Only render diagnostics if they're going to be displayed, since doing
|
// Only render diagnostics if they're going to be displayed, since doing
|
||||||
// so is expensive.
|
// so is expensive.
|
||||||
|
|
@ -359,25 +365,14 @@ impl MainLoop {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if max_severity.is_fatal() {
|
if exit_status.is_internal_error() {
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
"A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details."
|
"A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.watcher.is_none() {
|
if self.watcher.is_none() {
|
||||||
return Ok(match max_severity {
|
return Ok(exit_status);
|
||||||
Severity::Info => ExitStatus::Success,
|
|
||||||
Severity::Warning => {
|
|
||||||
if terminal_settings.error_on_warning {
|
|
||||||
ExitStatus::Failure
|
|
||||||
} else {
|
|
||||||
ExitStatus::Success
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Severity::Error => ExitStatus::Failure,
|
|
||||||
Severity::Fatal => ExitStatus::InternalError,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -410,6 +405,40 @@ impl MainLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exit_status_from_diagnostics(
|
||||||
|
diagnostics: &[Diagnostic],
|
||||||
|
terminal_settings: &TerminalSettings,
|
||||||
|
) -> ExitStatus {
|
||||||
|
if diagnostics.is_empty() {
|
||||||
|
return ExitStatus::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut max_severity = Severity::Info;
|
||||||
|
let mut io_error = false;
|
||||||
|
|
||||||
|
for diagnostic in diagnostics {
|
||||||
|
max_severity = max_severity.max(diagnostic.severity());
|
||||||
|
io_error = io_error || matches!(diagnostic.id(), DiagnosticId::Io);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !max_severity.is_fatal() && io_error {
|
||||||
|
return ExitStatus::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
match max_severity {
|
||||||
|
Severity::Info => ExitStatus::Success,
|
||||||
|
Severity::Warning => {
|
||||||
|
if terminal_settings.error_on_warning {
|
||||||
|
ExitStatus::Failure
|
||||||
|
} else {
|
||||||
|
ExitStatus::Success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Severity::Error => ExitStatus::Failure,
|
||||||
|
Severity::Fatal => ExitStatus::InternalError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A progress reporter for `ty check`.
|
/// A progress reporter for `ty check`.
|
||||||
struct IndicatifReporter {
|
struct IndicatifReporter {
|
||||||
collector: CollectReporter,
|
collector: CollectReporter,
|
||||||
|
|
|
||||||
|
|
@ -562,9 +562,9 @@ fn check_non_existing_path() -> anyhow::Result<()> {
|
||||||
|
|
||||||
assert_cmd_snapshot!(
|
assert_cmd_snapshot!(
|
||||||
case.command().arg("project/main.py").arg("project/tests"),
|
case.command().arg("project/main.py").arg("project/tests"),
|
||||||
@r###"
|
@r"
|
||||||
success: false
|
success: false
|
||||||
exit_code: 1
|
exit_code: 2
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
error[io]: `<temp_dir>/project/main.py`: No such file or directory (os error 2)
|
error[io]: `<temp_dir>/project/main.py`: No such file or directory (os error 2)
|
||||||
|
|
||||||
|
|
@ -574,7 +574,7 @@ fn check_non_existing_path() -> anyhow::Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
WARN No python files found under the given path(s)
|
WARN No python files found under the given path(s)
|
||||||
"###
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ cd ..
|
||||||
echo "Project selector: ${PRIMER_SELECTOR}"
|
echo "Project selector: ${PRIMER_SELECTOR}"
|
||||||
# Allow the exit code to be 0 or 1, only fail for actual mypy_primer crashes/bugs
|
# Allow the exit code to be 0 or 1, only fail for actual mypy_primer crashes/bugs
|
||||||
uvx \
|
uvx \
|
||||||
--from="git+https://github.com/hauntsaninja/mypy_primer@ab5d30e2d4ecdaf7d6cc89395c7130143d6d3c82" \
|
--from="git+https://github.com/hauntsaninja/mypy_primer@089ac1da83cf26aee9c98de412b7eb10e20b2212" \
|
||||||
mypy_primer \
|
mypy_primer \
|
||||||
--repo ruff \
|
--repo ruff \
|
||||||
--type-checker ty \
|
--type-checker ty \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue