Running uv lock --check with outdated lockfile will print that --check was passed, instead of --locked (#16322)

Hello,

# Summary

This PR fixes the confusing error message when running `uv lock --check`
with an outdated lockfile.

Previously, the error message incorrectly stated that `--locked` was
provided, even when the user used `--check`.

Now, the error message correctly indicates which flag was used: either
`--check` or `--locked`.

This closes #14105.

# Test plan

- I updated the existing integration test (`check_outdated_lock` in
`lock.rs`) to verify the new error message includes the correct flag.
- I ran existing tests to ensure I have no introduced regressions for
other commands.
This commit is contained in:
Charles-Meldhine Madi Mnemoi 2025-10-21 19:46:10 +02:00 committed by GitHub
parent 509a1e8ff6
commit 225bffbb6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 194 additions and 105 deletions

View file

@ -3719,20 +3719,34 @@ pub struct LockArgs {
/// missing or needs to be updated, uv will exit with an error.
///
/// Equivalent to `--locked`.
#[arg(long, alias = "locked", env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check_exists", "upgrade"])]
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check_exists", "upgrade", "locked"])]
pub check: bool,
/// Check if the lockfile is up-to-date.
///
/// Asserts that the `uv.lock` would remain unchanged after a resolution. If the lockfile is
/// missing or needs to be updated, uv will exit with an error.
///
/// Equivalent to `--check`.
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check_exists", "upgrade", "check"], hide = true)]
pub locked: bool,
/// Assert that a `uv.lock` exists without checking if it is up-to-date.
///
/// Equivalent to `--frozen`.
#[arg(long, alias = "frozen", env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "check")]
#[arg(long, alias = "frozen", env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check", "locked"])]
pub check_exists: bool,
/// Perform a dry run, without writing the lockfile.
///
/// In dry-run mode, uv will resolve the project's dependencies and report on the resulting
/// changes, but will not write the lockfile to disk.
#[arg(long, conflicts_with = "check_exists", conflicts_with = "check")]
#[arg(
long,
conflicts_with = "check_exists",
conflicts_with = "check",
conflicts_with = "locked"
)]
pub dry_run: bool,
/// Lock the specified Python script, rather than the current project.

View file

@ -59,13 +59,13 @@ use crate::commands::project::{
use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
use crate::commands::{ExitStatus, ScriptPath, diagnostics, project};
use crate::printer::Printer;
use crate::settings::ResolverInstallerSettings;
use crate::settings::{LockCheck, ResolverInstallerSettings};
/// Add one or more packages to the project requirements.
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn add(
project_dir: &Path,
locked: bool,
lock_check: LockCheck,
frozen: bool,
active: Option<bool>,
no_sync: bool,
@ -177,9 +177,9 @@ pub(crate) async fn add(
"`--package` is a no-op for Python scripts with inline metadata, which always run in isolation"
);
}
if locked {
if let LockCheck::Enabled(lock_check) = lock_check {
warn_user_once!(
"`--locked` is a no-op for Python scripts with inline metadata, which always run in isolation"
"`{lock_check}` is a no-op for Python scripts with inline metadata, which always run in isolation"
);
}
if frozen {
@ -728,7 +728,7 @@ pub(crate) async fn add(
&edits,
lock_state,
sync_state,
locked,
lock_check,
no_install_project,
no_install_workspace,
no_install_local,
@ -959,7 +959,7 @@ async fn lock_and_sync(
edits: &[DependencyEdit],
lock_state: UniversalState,
sync_state: PlatformState,
locked: bool,
lock_check: LockCheck,
no_install_project: bool,
no_install_workspace: bool,
no_install_local: bool,
@ -977,8 +977,8 @@ async fn lock_and_sync(
preview: Preview,
) -> Result<(), ProjectError> {
let mut lock = project::lock::LockOperation::new(
if locked {
LockMode::Locked(target.interpreter())
if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(target.interpreter(), lock_check)
} else {
LockMode::Write(target.interpreter())
},
@ -1099,8 +1099,8 @@ async fn lock_and_sync(
// If the file was modified, we have to lock again, though the only expected change is
// the addition of the minimum version specifiers.
lock = project::lock::LockOperation::new(
if locked {
LockMode::Locked(target.interpreter())
if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(target.interpreter(), lock_check)
} else {
LockMode::Write(target.interpreter())
},

View file

@ -30,7 +30,7 @@ use crate::commands::project::{
};
use crate::commands::{ExitStatus, OutputWriter, diagnostics};
use crate::printer::Printer;
use crate::settings::ResolverSettings;
use crate::settings::{LockCheck, ResolverSettings};
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
@ -65,7 +65,7 @@ pub(crate) async fn export(
extras: ExtrasSpecification,
groups: DependencyGroups,
editable: Option<EditableMode>,
locked: bool,
lock_check: LockCheck,
frozen: bool,
include_annotations: bool,
include_header: bool,
@ -172,8 +172,8 @@ pub(crate) async fn export(
// Determine the lock mode.
let mode = if frozen {
LockMode::Frozen
} else if locked {
LockMode::Locked(interpreter.as_ref().unwrap())
} else if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(interpreter.as_ref().unwrap(), lock_check)
} else if matches!(target, ExportTarget::Script(_))
&& !LockTarget::from(&target).lock_path().is_file()
{

View file

@ -49,7 +49,7 @@ use crate::commands::project::{
use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
use crate::commands::{ExitStatus, ScriptPath, diagnostics, pip};
use crate::printer::Printer;
use crate::settings::ResolverSettings;
use crate::settings::{LockCheck, LockCheckSource, ResolverSettings};
/// The result of running a lock operation.
#[derive(Debug, Clone)]
@ -81,7 +81,7 @@ impl LockResult {
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn lock(
project_dir: &Path,
locked: bool,
lock_check: LockCheck,
frozen: bool,
dry_run: DryRun,
refresh: Refresh,
@ -177,8 +177,8 @@ pub(crate) async fn lock(
.into_interpreter(),
};
if locked {
LockMode::Locked(&interpreter)
if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(&interpreter, lock_check)
} else if dry_run.enabled() {
LockMode::DryRun(&interpreter)
} else {
@ -257,7 +257,7 @@ pub(super) enum LockMode<'env> {
/// Perform a resolution, but don't write the lockfile to disk.
DryRun(&'env Interpreter),
/// Error if the lockfile is not up-to-date with the project requirements.
Locked(&'env Interpreter),
Locked(&'env Interpreter, LockCheckSource),
/// Use the existing lockfile without performing a resolution.
Frozen,
}
@ -336,7 +336,7 @@ impl<'env> LockOperation<'env> {
.ok_or_else(|| ProjectError::MissingLockfile)?;
Ok(LockResult::Unchanged(existing))
}
LockMode::Locked(interpreter) => {
LockMode::Locked(interpreter, lock_source) => {
// Read the existing lockfile.
let existing = target
.read()
@ -367,6 +367,7 @@ impl<'env> LockOperation<'env> {
return Err(ProjectError::LockMismatch(
prev.map(Box::new),
Box::new(cur),
lock_source,
));
}

View file

@ -57,7 +57,9 @@ use crate::commands::project::install_target::InstallTarget;
use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
use crate::commands::{capitalize, conjunction, pip};
use crate::printer::Printer;
use crate::settings::{InstallerSettingsRef, ResolverInstallerSettings, ResolverSettings};
use crate::settings::{
InstallerSettingsRef, LockCheckSource, ResolverInstallerSettings, ResolverSettings,
};
pub(crate) mod add;
pub(crate) mod environment;
@ -76,9 +78,9 @@ pub(crate) mod version;
#[derive(thiserror::Error, Debug)]
pub(crate) enum ProjectError {
#[error(
"The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`."
"The lockfile at `uv.lock` needs to be updated, but `{2}` was provided. To update the lockfile, run `uv lock`."
)]
LockMismatch(Option<Box<Lock>>, Box<Lock>),
LockMismatch(Option<Box<Lock>>, Box<Lock>, LockCheckSource),
#[error(
"Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`."

View file

@ -36,13 +36,13 @@ use crate::commands::project::{
};
use crate::commands::{ExitStatus, diagnostics, project};
use crate::printer::Printer;
use crate::settings::ResolverInstallerSettings;
use crate::settings::{LockCheck, ResolverInstallerSettings};
/// Remove one or more packages from the project requirements.
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn remove(
project_dir: &Path,
locked: bool,
lock_check: LockCheck,
frozen: bool,
active: Option<bool>,
no_sync: bool,
@ -70,9 +70,9 @@ pub(crate) async fn remove(
"`--package` is a no-op for Python scripts with inline metadata, which always run in isolation"
);
}
if locked {
if let LockCheck::Enabled(lock_check) = lock_check {
warn_user_once!(
"`--locked` is a no-op for Python scripts with inline metadata, which always run in isolation"
"`{lock_check}` is a no-op for Python scripts with inline metadata, which always run in isolation",
);
}
if frozen {
@ -291,8 +291,8 @@ pub(crate) async fn remove(
.ok();
// Determine the lock mode.
let mode = if locked {
LockMode::Locked(target.interpreter())
let mode = if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(target.interpreter(), lock_check)
} else {
LockMode::Write(target.interpreter())
};

View file

@ -73,7 +73,7 @@ use crate::commands::project::{
use crate::commands::reporters::PythonDownloadReporter;
use crate::commands::{ExitStatus, diagnostics, project};
use crate::printer::Printer;
use crate::settings::{ResolverInstallerSettings, ResolverSettings};
use crate::settings::{LockCheck, ResolverInstallerSettings, ResolverSettings};
/// Run a command.
#[allow(clippy::fn_params_excessive_bools)]
@ -83,7 +83,7 @@ pub(crate) async fn run(
command: Option<RunCommand>,
requirements: Vec<RequirementsSource>,
show_resolution: bool,
locked: bool,
lock_check: LockCheck,
frozen: bool,
active: Option<bool>,
no_sync: bool,
@ -264,8 +264,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
// Determine the lock mode.
let mode = if frozen {
LockMode::Frozen
} else if locked {
LockMode::Locked(environment.interpreter())
} else if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(environment.interpreter(), lock_check)
} else {
LockMode::Write(environment.interpreter())
};
@ -356,9 +356,9 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Some(environment.into_interpreter())
} else {
// If no lockfile is found, warn against `--locked` and `--frozen`.
if locked {
if let LockCheck::Enabled(lock_check) = lock_check {
warn_user!(
"No lockfile found for Python script (ignoring `--locked`); run `{}` to generate a lockfile",
"No lockfile found for Python script (ignoring `{lock_check}`); run `{}` to generate a lockfile",
"uv lock --script".green(),
);
}
@ -588,8 +588,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
for flag in groups.history().as_flags_pretty() {
warn_user!("`{flag}` has no effect when used alongside `--no-project`");
}
if locked {
warn_user!("`--locked` has no effect when used alongside `--no-project`");
if let LockCheck::Enabled(lock_check) = lock_check {
warn_user!("`{lock_check}` has no effect when used alongside `--no-project`");
}
if frozen {
warn_user!("`--frozen` has no effect when used alongside `--no-project`");
@ -605,8 +605,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
for flag in groups.history().as_flags_pretty() {
warn_user!("`{flag}` has no effect when used outside of a project");
}
if locked {
warn_user!("`--locked` has no effect when used outside of a project");
if let LockCheck::Enabled(lock_check) = lock_check {
warn_user!("`{lock_check}` has no effect when used outside of a project",);
}
if no_sync {
warn_user!("`--no-sync` has no effect when used outside of a project");
@ -740,8 +740,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
// Determine the lock mode.
let mode = if frozen {
LockMode::Frozen
} else if locked {
LockMode::Locked(venv.interpreter())
} else if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(venv.interpreter(), lock_check)
} else if isolated {
LockMode::DryRun(venv.interpreter())
} else {

View file

@ -50,13 +50,15 @@ use crate::commands::project::{
};
use crate::commands::{ExitStatus, diagnostics};
use crate::printer::Printer;
use crate::settings::{InstallerSettingsRef, ResolverInstallerSettings, ResolverSettings};
use crate::settings::{
InstallerSettingsRef, LockCheck, LockCheckSource, ResolverInstallerSettings, ResolverSettings,
};
/// Sync the project environment.
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn sync(
project_dir: &Path,
locked: bool,
lock_check: LockCheck,
frozen: bool,
dry_run: DryRun,
active: Option<bool>,
@ -217,9 +219,9 @@ pub(crate) async fn sync(
));
}
if locked {
if let LockCheck::Enabled(lock_check) = lock_check {
return Err(anyhow::anyhow!(
"`uv sync --locked` requires a script lockfile; run `{}` to lock the script",
"`uv sync {lock_check}` requires a script lockfile; run `{}` to lock the script",
format!("uv lock --script {}", script.path.user_display()).green(),
));
}
@ -304,8 +306,8 @@ pub(crate) async fn sync(
// Determine the lock mode.
let mode = if frozen {
LockMode::Frozen
} else if locked {
LockMode::Locked(environment.interpreter())
} else if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(environment.interpreter(), lock_check)
} else if dry_run.enabled() {
LockMode::DryRun(environment.interpreter())
} else {
@ -338,16 +340,18 @@ pub(crate) async fn sync(
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(ProjectError::LockMismatch(prev, cur)) => {
Err(ProjectError::LockMismatch(prev, cur, lock_source)) => {
if dry_run.enabled() {
// The lockfile is mismatched, but we're in dry-run mode. We should proceed with the
// sync operation, but exit with a non-zero status.
Outcome::LockMismatch(prev, cur)
Outcome::LockMismatch(prev, cur, lock_source)
} else {
writeln!(
printer.stderr(),
"{}",
ProjectError::LockMismatch(prev, cur).to_string().bold()
ProjectError::LockMismatch(prev, cur, lock_source)
.to_string()
.bold()
)?;
return Ok(ExitStatus::Failure);
}
@ -415,11 +419,13 @@ pub(crate) async fn sync(
match outcome {
Outcome::Success(..) => Ok(ExitStatus::Success),
Outcome::LockMismatch(prev, cur) => {
Outcome::LockMismatch(prev, cur, lock_source) => {
writeln!(
printer.stderr(),
"{}",
ProjectError::LockMismatch(prev, cur).to_string().bold()
ProjectError::LockMismatch(prev, cur, lock_source)
.to_string()
.bold()
)?;
Ok(ExitStatus::Failure)
}
@ -433,7 +439,7 @@ enum Outcome {
/// The `lock` operation was successful.
Success(LockResult),
/// The `lock` operation successfully resolved, but failed due to a mismatch (e.g., with `--locked`).
LockMismatch(Option<Box<Lock>>, Box<Lock>),
LockMismatch(Option<Box<Lock>>, Box<Lock>, LockCheckSource),
}
impl Outcome {
@ -444,7 +450,7 @@ impl Outcome {
LockResult::Changed(_, lock) => lock,
LockResult::Unchanged(lock) => lock,
},
Self::LockMismatch(_prev, cur) => cur,
Self::LockMismatch(_prev, cur, _lock_source) => cur,
}
}
}
@ -1272,7 +1278,7 @@ impl From<(&LockTarget<'_>, &LockMode<'_>, &Outcome)> for LockReport {
LockResult::Unchanged(..) => match mode {
// When `--frozen` is used, we don't check the lockfile
LockMode::Frozen => LockAction::Use,
LockMode::DryRun(_) | LockMode::Locked(_) | LockMode::Write(_) => {
LockMode::DryRun(_) | LockMode::Locked(_, _) | LockMode::Write(_) => {
LockAction::Check
}
},

View file

@ -29,6 +29,7 @@ use crate::commands::project::{
use crate::commands::reporters::LatestVersionReporter;
use crate::commands::{ExitStatus, diagnostics};
use crate::printer::Printer;
use crate::settings::LockCheck;
use crate::settings::ResolverSettings;
/// Run a command.
@ -36,7 +37,7 @@ use crate::settings::ResolverSettings;
pub(crate) async fn tree(
project_dir: &Path,
groups: DependencyGroups,
locked: bool,
lock_check: LockCheck,
frozen: bool,
universal: bool,
depth: u8,
@ -125,8 +126,8 @@ pub(crate) async fn tree(
// Determine the lock mode.
let mode = if frozen {
LockMode::Frozen
} else if locked {
LockMode::Locked(interpreter.as_ref().unwrap())
} else if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(interpreter.as_ref().unwrap(), lock_check)
} else if matches!(target, LockTarget::Script(_)) && !target.lock_path().is_file() {
// If we're locking a script, avoid creating a lockfile if it doesn't already exist.
LockMode::DryRun(interpreter.as_ref().unwrap())

View file

@ -38,7 +38,7 @@ use crate::commands::project::{
};
use crate::commands::{ExitStatus, diagnostics, project};
use crate::printer::Printer;
use crate::settings::ResolverInstallerSettings;
use crate::settings::{LockCheck, ResolverInstallerSettings};
/// Display version information for uv itself (`uv self version`)
pub(crate) fn self_version(
@ -63,7 +63,7 @@ pub(crate) async fn project_version(
package: Option<PackageName>,
explicit_project: bool,
dry_run: bool,
locked: bool,
lock_check: LockCheck,
frozen: bool,
active: Option<bool>,
no_sync: bool,
@ -297,7 +297,7 @@ pub(crate) async fn project_version(
Box::pin(lock_and_sync(
project,
project_dir,
locked,
lock_check,
frozen,
active,
no_sync,
@ -502,7 +502,7 @@ async fn print_frozen_version(
async fn lock_and_sync(
project: VirtualProject,
project_dir: &Path,
locked: bool,
lock_check: LockCheck,
frozen: bool,
active: Option<bool>,
no_sync: bool,
@ -579,8 +579,8 @@ async fn lock_and_sync(
};
// Determine the lock mode.
let mode = if locked {
LockMode::Locked(target.interpreter())
let mode = if let LockCheck::Enabled(lock_check) = lock_check {
LockMode::Locked(target.interpreter(), lock_check)
} else {
LockMode::Write(target.interpreter())
};

View file

@ -1844,7 +1844,7 @@ async fn run_project(
command,
requirements,
args.show_resolution || globals.verbose > 0,
args.locked,
args.lock_check,
args.frozen,
args.active,
args.no_sync,
@ -1895,7 +1895,7 @@ async fn run_project(
Box::pin(commands::sync(
project_dir,
args.locked,
args.lock_check,
args.frozen,
args.dry_run,
args.active,
@ -1951,7 +1951,7 @@ async fn run_project(
Box::pin(commands::lock(
project_dir,
args.locked,
args.lock_check,
args.frozen,
args.dry_run,
args.refresh,
@ -2056,7 +2056,7 @@ async fn run_project(
Box::pin(commands::add(
project_dir,
args.locked,
args.lock_check,
args.frozen,
args.active,
args.no_sync,
@ -2114,7 +2114,7 @@ async fn run_project(
Box::pin(commands::remove(
project_dir,
args.locked,
args.lock_check,
args.frozen,
args.active,
args.no_sync,
@ -2158,7 +2158,7 @@ async fn run_project(
args.package,
explicit_project,
args.dry_run,
args.locked,
args.lock_check,
args.frozen,
args.active,
args.no_sync,
@ -2195,7 +2195,7 @@ async fn run_project(
Box::pin(commands::tree(
project_dir,
args.groups,
args.locked,
args.lock_check,
args.frozen,
args.universal,
args.depth,
@ -2249,7 +2249,7 @@ async fn run_project(
args.extras,
args.groups,
args.editable,
args.locked,
args.lock_check,
args.frozen,
args.include_annotations,
args.include_header,

View file

@ -347,10 +347,37 @@ impl InitSettings {
}
}
/// The source of a lock check operation.
#[derive(Debug, Clone, Copy)]
pub(crate) enum LockCheckSource {
/// The user invoked `uv <command> --locked`
Locked,
/// The user invoked `uv <command> --check`
Check,
}
impl std::fmt::Display for LockCheckSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Locked => write!(f, "--locked"),
Self::Check => write!(f, "--check"),
}
}
}
// Has lock check been enabled?
#[derive(Debug, Clone, Copy)]
pub(crate) enum LockCheck {
/// Lockfile check is enabled.
Enabled(LockCheckSource),
/// Lockfile check is disabled.
Disabled,
}
/// The resolved settings to use for a `run` invocation.
#[derive(Debug, Clone)]
pub(crate) struct RunSettings {
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) extras: ExtrasSpecification,
pub(crate) groups: DependencyGroups,
@ -439,7 +466,11 @@ impl RunSettings {
.unwrap_or_default();
Self {
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
extras: ExtrasSpecification::from_args(
extra.unwrap_or_default(),
@ -1263,7 +1294,7 @@ impl PythonPinSettings {
#[allow(clippy::struct_excessive_bools, dead_code)]
#[derive(Debug, Clone)]
pub(crate) struct SyncSettings {
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) dry_run: DryRun,
pub(crate) script: Option<PathBuf>,
@ -1345,10 +1376,15 @@ impl SyncSettings {
} else {
DryRun::from_args(dry_run)
};
let lock_check = if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
};
Self {
output_format,
locked,
lock_check,
frozen,
dry_run,
script,
@ -1401,7 +1437,7 @@ impl SyncSettings {
#[allow(clippy::struct_excessive_bools, dead_code)]
#[derive(Debug, Clone)]
pub(crate) struct LockSettings {
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) dry_run: DryRun,
pub(crate) script: Option<PathBuf>,
@ -1421,6 +1457,7 @@ impl LockSettings {
) -> Self {
let LockArgs {
check,
locked,
check_exists,
dry_run,
script,
@ -1435,8 +1472,16 @@ impl LockSettings {
.map(|fs| fs.install_mirrors.clone())
.unwrap_or_default();
let lock_check = if check {
LockCheck::Enabled(LockCheckSource::Check)
} else if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
};
Self {
locked: check,
lock_check,
frozen: check_exists,
dry_run: DryRun::from_args(dry_run),
script,
@ -1454,7 +1499,7 @@ impl LockSettings {
#[allow(clippy::struct_excessive_bools, dead_code)]
#[derive(Debug, Clone)]
pub(crate) struct AddSettings {
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) active: Option<bool>,
pub(crate) no_sync: bool,
@ -1603,7 +1648,11 @@ impl AddSettings {
let bounds = bounds.or(filesystem.as_ref().and_then(|fs| fs.add.add_bounds));
Self {
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
active: flag(active, no_active, "active"),
no_sync,
@ -1646,7 +1695,7 @@ impl AddSettings {
#[allow(clippy::struct_excessive_bools, dead_code)]
#[derive(Debug, Clone)]
pub(crate) struct RemoveSettings {
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) active: Option<bool>,
pub(crate) no_sync: bool,
@ -1707,7 +1756,11 @@ impl RemoveSettings {
.collect();
Self {
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
active: flag(active, no_active, "active"),
no_sync,
@ -1737,7 +1790,7 @@ pub(crate) struct VersionSettings {
pub(crate) short: bool,
pub(crate) output_format: VersionFormat,
pub(crate) dry_run: bool,
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) active: Option<bool>,
pub(crate) no_sync: bool,
@ -1785,7 +1838,11 @@ impl VersionSettings {
short,
output_format,
dry_run,
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
active: flag(active, no_active, "active"),
no_sync,
@ -1807,7 +1864,7 @@ impl VersionSettings {
#[derive(Debug, Clone)]
pub(crate) struct TreeSettings {
pub(crate) groups: DependencyGroups,
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) universal: bool,
pub(crate) depth: u8,
@ -1870,7 +1927,11 @@ impl TreeSettings {
only_group,
all_groups,
),
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
universal,
depth: tree.depth,
@ -1906,7 +1967,7 @@ pub(crate) struct ExportSettings {
pub(crate) hashes: bool,
pub(crate) install_options: InstallOptions,
pub(crate) output_file: Option<PathBuf>,
pub(crate) locked: bool,
pub(crate) lock_check: LockCheck,
pub(crate) frozen: bool,
pub(crate) include_annotations: bool,
pub(crate) include_header: bool,
@ -2001,7 +2062,11 @@ impl ExportSettings {
no_emit_package,
),
output_file,
locked,
lock_check: if locked {
LockCheck::Enabled(LockCheckSource::Locked)
} else {
LockCheck::Disabled
},
frozen,
include_annotations: flag(annotate, no_annotate, "annotate").unwrap_or(true),
include_header: flag(header, no_header, "header").unwrap_or(true),

View file

@ -13193,7 +13193,7 @@ fn check_outdated_lock() -> Result<()> {
----- stderr -----
Resolved 2 packages in [TIME]
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
The lockfile at `uv.lock` needs to be updated, but `--check` was provided. To update the lockfile, run `uv lock`.
");
Ok(())
}

View file

@ -7780,7 +7780,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -7894,7 +7894,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -8008,7 +8008,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -8122,7 +8122,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -8236,7 +8236,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -8352,7 +8352,7 @@ fn preview_features() {
short: false,
output_format: Text,
dry_run: false,
locked: false,
lock_check: Disabled,
frozen: false,
active: None,
no_sync: false,
@ -9596,7 +9596,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,
@ -9715,7 +9715,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,
@ -9857,7 +9857,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,
@ -9974,7 +9974,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,
@ -10081,7 +10081,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,
@ -10189,7 +10189,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
),
}
LockSettings {
locked: false,
lock_check: Disabled,
frozen: false,
dry_run: Disabled,
script: None,

View file

@ -1634,7 +1634,7 @@ uv lock [OPTIONS]
<p>May also be set with the <code>UV_INSECURE_HOST</code> environment variable.</p></dd><dt id="uv-lock--cache-dir"><a href="#uv-lock--cache-dir"><code>--cache-dir</code></a> <i>cache-dir</i></dt><dd><p>Path to the cache directory.</p>
<p>Defaults to <code>$XDG_CACHE_HOME/uv</code> or <code>$HOME/.cache/uv</code> on macOS and Linux, and <code>%LOCALAPPDATA%\uv\cache</code> on Windows.</p>
<p>To view the location of the cache directory, run <code>uv cache dir</code>.</p>
<p>May also be set with the <code>UV_CACHE_DIR</code> environment variable.</p></dd><dt id="uv-lock--check"><a href="#uv-lock--check"><code>--check</code></a>, <code>--locked</code></dt><dd><p>Check if the lockfile is up-to-date.</p>
<p>May also be set with the <code>UV_CACHE_DIR</code> environment variable.</p></dd><dt id="uv-lock--check"><a href="#uv-lock--check"><code>--check</code></a></dt><dd><p>Check if the lockfile is up-to-date.</p>
<p>Asserts that the <code>uv.lock</code> would remain unchanged after a resolution. If the lockfile is missing or needs to be updated, uv will exit with an error.</p>
<p>Equivalent to <code>--locked</code>.</p>
<p>May also be set with the <code>UV_LOCKED</code> environment variable.</p></dd><dt id="uv-lock--check-exists"><a href="#uv-lock--check-exists"><code>--check-exists</code></a>, <code>--frozen</code></dt><dd><p>Assert that a <code>uv.lock</code> exists without checking if it is up-to-date.</p>