mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Add support for --dry-run
mode in uv lock
(#7783)
Some checks are pending
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
Some checks are pending
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
This PR adds support for `uv lock --dry-run`, as described in issue #6408. One thing to note: this functionality, as implemented, isn't limited to `-U` (if someone adds a dependency to the project's `pyproject.toml`, the plan will include these changes). --------- Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
parent
ede47c0793
commit
98523e2014
12 changed files with 205 additions and 18 deletions
|
@ -2903,6 +2903,13 @@ pub struct LockArgs {
|
|||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "locked")]
|
||||
pub frozen: 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 = "frozen", conflicts_with = "locked")]
|
||||
pub dry_run: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
pub resolver: ResolverArgs,
|
||||
|
||||
|
|
|
@ -661,6 +661,7 @@ async fn lock_and_sync(
|
|||
let mut lock = project::lock::do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
project.workspace(),
|
||||
venv.interpreter(),
|
||||
settings.into(),
|
||||
|
@ -775,6 +776,7 @@ async fn lock_and_sync(
|
|||
lock = project::lock::do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
project.workspace(),
|
||||
venv.interpreter(),
|
||||
settings.into(),
|
||||
|
|
|
@ -95,6 +95,7 @@ pub(crate) async fn export(
|
|||
let lock = match do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
project.workspace(),
|
||||
&interpreter,
|
||||
settings.as_ref(),
|
||||
|
|
|
@ -70,10 +70,12 @@ impl LockResult {
|
|||
}
|
||||
|
||||
/// Resolve the project requirements into a lockfile.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub(crate) async fn lock(
|
||||
project_dir: &Path,
|
||||
locked: bool,
|
||||
frozen: bool,
|
||||
dry_run: bool,
|
||||
python: Option<String>,
|
||||
settings: ResolverSettings,
|
||||
python_preference: PythonPreference,
|
||||
|
@ -108,6 +110,7 @@ pub(crate) async fn lock(
|
|||
match do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
dry_run,
|
||||
&workspace,
|
||||
&interpreter,
|
||||
settings.as_ref(),
|
||||
|
@ -123,9 +126,25 @@ pub(crate) async fn lock(
|
|||
.await
|
||||
{
|
||||
Ok(lock) => {
|
||||
if let LockResult::Changed(Some(previous), lock) = &lock {
|
||||
report_upgrades(previous, lock, printer)?;
|
||||
if dry_run {
|
||||
let changed = if let LockResult::Changed(previous, lock) = &lock {
|
||||
report_upgrades(previous.as_ref(), lock, printer, dry_run)?
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if !changed {
|
||||
writeln!(
|
||||
printer.stderr(),
|
||||
"{}",
|
||||
"No lockfile changes detected".bold()
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
if let LockResult::Changed(Some(previous), lock) = &lock {
|
||||
report_upgrades(Some(previous), lock, printer, dry_run)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
Err(ProjectError::Operation(pip::operations::Error::Resolve(
|
||||
|
@ -152,9 +171,11 @@ pub(crate) async fn lock(
|
|||
}
|
||||
|
||||
/// Perform a lock operation, respecting the `--locked` and `--frozen` parameters.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub(super) async fn do_safe_lock(
|
||||
locked: bool,
|
||||
frozen: bool,
|
||||
dry_run: bool,
|
||||
workspace: &Workspace,
|
||||
interpreter: &Interpreter,
|
||||
settings: ResolverSettingsRef<'_>,
|
||||
|
@ -224,8 +245,10 @@ pub(super) async fn do_safe_lock(
|
|||
.await?;
|
||||
|
||||
// If the lockfile changed, write it to disk.
|
||||
if let LockResult::Changed(_, lock) = &result {
|
||||
commit(lock, workspace).await?;
|
||||
if !dry_run {
|
||||
if let LockResult::Changed(_, lock) = &result {
|
||||
commit(lock, workspace).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
|
@ -916,17 +939,28 @@ pub(crate) async fn read(workspace: &Workspace) -> Result<Option<Lock>, ProjectE
|
|||
}
|
||||
|
||||
/// Reports on the versions that were upgraded in the new lockfile.
|
||||
fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> anyhow::Result<()> {
|
||||
///
|
||||
/// Returns `true` if any upgrades were reported.
|
||||
fn report_upgrades(
|
||||
existing_lock: Option<&Lock>,
|
||||
new_lock: &Lock,
|
||||
printer: Printer,
|
||||
dry_run: bool,
|
||||
) -> anyhow::Result<bool> {
|
||||
let existing_packages: FxHashMap<&PackageName, BTreeSet<&Version>> =
|
||||
existing_lock.packages().iter().fold(
|
||||
FxHashMap::with_capacity_and_hasher(existing_lock.packages().len(), FxBuildHasher),
|
||||
|mut acc, package| {
|
||||
acc.entry(package.name())
|
||||
.or_default()
|
||||
.insert(package.version());
|
||||
acc
|
||||
},
|
||||
);
|
||||
if let Some(existing_lock) = existing_lock {
|
||||
existing_lock.packages().iter().fold(
|
||||
FxHashMap::with_capacity_and_hasher(existing_lock.packages().len(), FxBuildHasher),
|
||||
|mut acc, package| {
|
||||
acc.entry(package.name())
|
||||
.or_default()
|
||||
.insert(package.version());
|
||||
acc
|
||||
},
|
||||
)
|
||||
} else {
|
||||
FxHashMap::default()
|
||||
};
|
||||
|
||||
let new_distributions: FxHashMap<&PackageName, BTreeSet<&Version>> =
|
||||
new_lock.packages().iter().fold(
|
||||
|
@ -939,11 +973,13 @@ fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> a
|
|||
},
|
||||
);
|
||||
|
||||
let mut updated = false;
|
||||
for name in existing_packages
|
||||
.keys()
|
||||
.chain(new_distributions.keys())
|
||||
.collect::<BTreeSet<_>>()
|
||||
{
|
||||
updated = true;
|
||||
match (existing_packages.get(name), new_distributions.get(name)) {
|
||||
(Some(existing_versions), Some(new_versions)) => {
|
||||
if existing_versions != new_versions {
|
||||
|
@ -960,7 +996,7 @@ fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> a
|
|||
writeln!(
|
||||
printer.stderr(),
|
||||
"{} {name} {existing_versions} -> {new_versions}",
|
||||
"Updated".green().bold()
|
||||
if dry_run { "Update" } else { "Updated" }.green().bold()
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
@ -973,7 +1009,7 @@ fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> a
|
|||
writeln!(
|
||||
printer.stderr(),
|
||||
"{} {name} {existing_versions}",
|
||||
"Removed".red().bold()
|
||||
if dry_run { "Remove" } else { "Removed" }.red().bold()
|
||||
)?;
|
||||
}
|
||||
(None, Some(new_versions)) => {
|
||||
|
@ -985,7 +1021,7 @@ fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> a
|
|||
writeln!(
|
||||
printer.stderr(),
|
||||
"{} {name} {new_versions}",
|
||||
"Added".green().bold()
|
||||
if dry_run { "Add" } else { "Added" }.green().bold()
|
||||
)?;
|
||||
}
|
||||
(None, None) => {
|
||||
|
@ -994,5 +1030,5 @@ fn report_upgrades(existing_lock: &Lock, new_lock: &Lock, printer: Printer) -> a
|
|||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(updated)
|
||||
}
|
||||
|
|
|
@ -175,6 +175,7 @@ pub(crate) async fn remove(
|
|||
let lock = project::lock::do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
project.workspace(),
|
||||
venv.interpreter(),
|
||||
settings.as_ref().into(),
|
||||
|
|
|
@ -543,6 +543,7 @@ pub(crate) async fn run(
|
|||
let result = match project::lock::do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
project.workspace(),
|
||||
venv.interpreter(),
|
||||
settings.as_ref().into(),
|
||||
|
|
|
@ -112,6 +112,7 @@ pub(crate) async fn sync(
|
|||
let lock = match do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
target.workspace(),
|
||||
venv.interpreter(),
|
||||
settings.as_ref().into(),
|
||||
|
|
|
@ -67,6 +67,7 @@ pub(crate) async fn tree(
|
|||
let lock = project::lock::do_safe_lock(
|
||||
locked,
|
||||
frozen,
|
||||
false,
|
||||
&workspace,
|
||||
&interpreter,
|
||||
settings.as_ref(),
|
||||
|
|
|
@ -1352,6 +1352,7 @@ async fn run_project(
|
|||
project_dir,
|
||||
args.locked,
|
||||
args.frozen,
|
||||
args.dry_run,
|
||||
args.python,
|
||||
args.settings,
|
||||
globals.python_preference,
|
||||
|
|
|
@ -767,6 +767,7 @@ impl SyncSettings {
|
|||
pub(crate) struct LockSettings {
|
||||
pub(crate) locked: bool,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) dry_run: bool,
|
||||
pub(crate) python: Option<String>,
|
||||
pub(crate) refresh: Refresh,
|
||||
pub(crate) settings: ResolverSettings,
|
||||
|
@ -779,6 +780,7 @@ impl LockSettings {
|
|||
let LockArgs {
|
||||
locked,
|
||||
frozen,
|
||||
dry_run,
|
||||
resolver,
|
||||
build,
|
||||
refresh,
|
||||
|
@ -788,6 +790,7 @@ impl LockSettings {
|
|||
Self {
|
||||
locked,
|
||||
frozen,
|
||||
dry_run,
|
||||
python: python.and_then(Maybe::into_option),
|
||||
refresh: Refresh::from(refresh),
|
||||
settings: ResolverSettings::combine(resolver_options(resolver, build), filesystem),
|
||||
|
|
|
@ -16078,3 +16078,132 @@ fn lock_multiple_sources_extra() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lock_dry_run() -> 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 = [
|
||||
"anyio <3 ; python_version == '3.12'",
|
||||
"anyio >3, <4 ; python_version > '3.12'",
|
||||
"matplotlib==3.1.0"
|
||||
]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 12 packages in [TIME]
|
||||
"###);
|
||||
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"requests==2.25.1",
|
||||
"matplotlib==3.5.0"
|
||||
]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--dry-run"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 19 packages in [TIME]
|
||||
Remove anyio v2.2.0, v3.7.1
|
||||
Add certifi v2024.2.2
|
||||
Add chardet v4.0.0
|
||||
Add fonttools v4.50.0
|
||||
Update idna v3.6 -> v2.10
|
||||
Update matplotlib v3.1.0 -> v3.5.0
|
||||
Add packaging v24.0
|
||||
Add pillow v10.2.0
|
||||
Add requests v2.25.1
|
||||
Add setuptools v69.2.0
|
||||
Add setuptools-scm v8.0.4
|
||||
Remove sniffio v1.3.1
|
||||
Add typing-extensions v4.10.0
|
||||
Add urllib3 v1.26.18
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lock_dry_run_noop() -> 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 = [
|
||||
"anyio <3 ; python_version == '3.12'",
|
||||
"anyio >3, <4 ; python_version > '3.12'",
|
||||
]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--dry-run"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 5 packages in [TIME]
|
||||
Add anyio v2.2.0, v3.7.1
|
||||
Add idna v3.6
|
||||
Add project v0.1.0
|
||||
Add sniffio v1.3.1
|
||||
"###);
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 5 packages in [TIME]
|
||||
"###);
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--dry-run"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 5 packages in [TIME]
|
||||
No lockfile changes detected
|
||||
"###);
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--dry-run").arg("-U"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 5 packages in [TIME]
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1706,6 +1706,10 @@ uv lock [OPTIONS]
|
|||
|
||||
<p>See <code>--project</code> to only change the project root directory.</p>
|
||||
|
||||
</dd><dt><code>--dry-run</code></dt><dd><p>Perform a dry run, without writing the lockfile.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
|
||||
|
||||
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system’s configured time zone.</p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue