mirror of https://github.com/astral-sh/uv
Add `uv sync --check` flag (#12342)
## Summary Closes #12338 ## Test Plan `cargo test` --------- Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
parent
26d40cb8a5
commit
a80353de2b
|
|
@ -3285,6 +3285,15 @@ pub struct SyncArgs {
|
|||
value_parser = parse_maybe_string,
|
||||
)]
|
||||
pub python: Option<Maybe<String>>,
|
||||
|
||||
/// Check if the Python environment is synchronized with the project.
|
||||
///
|
||||
/// If the environment is not up to date, uv will exit with an error.
|
||||
#[arg(long, overrides_with("no_check"))]
|
||||
pub check: bool,
|
||||
|
||||
#[arg(long, overrides_with("check"), hide = true)]
|
||||
pub no_check: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
pub enum DryRun {
|
||||
/// The operation should execute in dry run mode.
|
||||
Enabled,
|
||||
/// The operation should execute in dry run mode and check if the current environment is
|
||||
/// synced.
|
||||
Check,
|
||||
/// The operation should execute in normal mode.
|
||||
#[default]
|
||||
Disabled,
|
||||
|
|
@ -19,6 +22,6 @@ impl DryRun {
|
|||
|
||||
/// Returns `true` if dry run mode is enabled.
|
||||
pub const fn enabled(&self) -> bool {
|
||||
matches!(self, DryRun::Enabled)
|
||||
matches!(self, DryRun::Enabled) || matches!(self, DryRun::Check)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ pub(crate) async fn install(
|
|||
.context("Failed to determine installation plan")?;
|
||||
|
||||
if dry_run.enabled() {
|
||||
report_dry_run(resolution, plan, modifications, start, printer)?;
|
||||
report_dry_run(dry_run, resolution, plan, modifications, start, printer)?;
|
||||
return Ok(Changelog::default());
|
||||
}
|
||||
|
||||
|
|
@ -665,6 +665,7 @@ pub(crate) fn report_target_environment(
|
|||
|
||||
/// Report on the results of a dry-run installation.
|
||||
fn report_dry_run(
|
||||
dry_run: DryRun,
|
||||
resolution: &Resolution,
|
||||
plan: Plan,
|
||||
modifications: Modifications,
|
||||
|
|
@ -788,6 +789,10 @@ fn report_dry_run(
|
|||
}
|
||||
}
|
||||
|
||||
if matches!(dry_run, DryRun::Check) {
|
||||
return Err(Error::OutdatedEnvironment);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -859,4 +864,7 @@ pub(crate) enum Error {
|
|||
|
||||
#[error(transparent)]
|
||||
Anyhow(#[from] anyhow::Error),
|
||||
|
||||
#[error("The environment is outdated; run `{}` to update the environment", "uv sync".cyan())]
|
||||
OutdatedEnvironment,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1075,6 +1075,8 @@ impl SyncSettings {
|
|||
package,
|
||||
script,
|
||||
python,
|
||||
check,
|
||||
no_check,
|
||||
} = args;
|
||||
let install_mirrors = filesystem
|
||||
.clone()
|
||||
|
|
@ -1086,10 +1088,17 @@ impl SyncSettings {
|
|||
filesystem,
|
||||
);
|
||||
|
||||
let check = flag(check, no_check).unwrap_or_default();
|
||||
let dry_run = if check {
|
||||
DryRun::Check
|
||||
} else {
|
||||
DryRun::from_args(dry_run)
|
||||
};
|
||||
|
||||
Self {
|
||||
locked,
|
||||
frozen,
|
||||
dry_run: DryRun::from_args(dry_run),
|
||||
dry_run,
|
||||
script,
|
||||
active: flag(active, no_active),
|
||||
extras: ExtrasSpecification::from_args(
|
||||
|
|
|
|||
|
|
@ -352,6 +352,68 @@ fn mixed_requires_python() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["iniconfig"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Running `uv sync --check` should fail.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--check"), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Discovered existing environment at: .venv
|
||||
Resolved 2 packages in [TIME]
|
||||
Would create lockfile at: uv.lock
|
||||
Would download 1 package
|
||||
Would install 1 package
|
||||
+ iniconfig==2.0.0
|
||||
error: The environment is outdated; run `uv sync` to update the environment
|
||||
"###);
|
||||
|
||||
// Sync the environment.
|
||||
uv_snapshot!(context.filters(), context.sync(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
"###);
|
||||
|
||||
assert!(context.temp_dir.child("uv.lock").exists());
|
||||
|
||||
// Running `uv sync --check` should pass now that the environment is up to date.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--check"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Discovered existing environment at: .venv
|
||||
Resolved 2 packages in [TIME]
|
||||
Found up-to-date lockfile at: uv.lock
|
||||
Audited 1 package in [TIME]
|
||||
Would make no changes
|
||||
"###);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sync development dependencies in a (legacy) non-project workspace root.
|
||||
#[test]
|
||||
fn sync_legacy_non_project_dev_dependencies() -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -1513,6 +1513,10 @@ uv sync [OPTIONS]
|
|||
<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-sync--check"><a href="#uv-sync--check"><code>--check</code></a></dt><dd><p>Check if the Python environment is synchronized with the project.</p>
|
||||
|
||||
<p>If the environment is not up to date, uv will exit with an error.</p>
|
||||
|
||||
</dd><dt id="uv-sync--color"><a href="#uv-sync--color"><code>--color</code></a> <i>color-choice</i></dt><dd><p>Control the use of color in output.</p>
|
||||
|
||||
<p>By default, uv will automatically detect support for colors when writing to a terminal.</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue