Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/uv-resolver/src/exclude_newer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,9 @@ impl ExcludeNewer {
match (&self.global, &other.global) {
(Some(self_global), Some(other_global)) => {
if let Some(change) = compare_exclude_newer_value(self_global, other_global) {
return Some(ExcludeNewerChange::GlobalChanged(change));
if !change.is_relative_timestamp_change() {
return Some(ExcludeNewerChange::GlobalChanged(change));
}
}
}
(None, Some(global)) => {
Expand Down
21 changes: 16 additions & 5 deletions crates/uv-resolver/src/lock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1161,10 +1161,18 @@ impl Lock {
if !exclude_newer.is_empty() {
// Always serialize global exclude-newer as a string
if let Some(global) = &exclude_newer.global {
options_table.insert("exclude-newer", value(global.to_string()));
// Serialize the original span if present
if let Some(span) = global.span() {
// When a relative span is present, write a no-op timestamp
// for backwards compatibility with older versions of uv that
// don't understand `exclude-newer-span`.
Comment thread
zanieb marked this conversation as resolved.
Outdated
let mut noop = value("0001-01-01T00:00:00Z");
if let Item::Value(ref mut v) = noop {
v.decor_mut().set_suffix(" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.");
}
options_table.insert("exclude-newer", noop);
options_table.insert("exclude-newer-span", value(span.to_string()));
} else {
options_table.insert("exclude-newer", value(global.to_string()));
}
}

Expand Down Expand Up @@ -2349,10 +2357,13 @@ struct ExcludeNewerWire {

impl From<ExcludeNewerWire> for ExcludeNewer {
fn from(wire: ExcludeNewerWire) -> Self {
let global = match (wire.exclude_newer, wire.exclude_newer_span) {
(Some(timestamp), span) => Some(ExcludeNewerValue::new(timestamp, span)),
(None, Some(span)) => Some(ExcludeNewerValue::new(Timestamp::UNIX_EPOCH, Some(span))),
(None, None) => None,
};
Self {
global: wire
.exclude_newer
.map(|timestamp| ExcludeNewerValue::new(timestamp, wire.exclude_newer_span)),
global,
package: wire.exclude_newer_package,
}
}
Expand Down
20 changes: 9 additions & 11 deletions crates/uv/tests/it/lock_exclude_newer_relative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn lock_exclude_newer_relative() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3W"

[[package]]
Expand Down Expand Up @@ -116,7 +116,7 @@ fn lock_exclude_newer_relative() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-17T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P2W"

[[package]]
Expand Down Expand Up @@ -165,7 +165,7 @@ fn lock_exclude_newer_relative() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-05-18T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P2W"

[[package]]
Expand Down Expand Up @@ -560,7 +560,7 @@ fn lock_exclude_newer_relative_pyproject() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3W"

[[package]]
Expand Down Expand Up @@ -714,7 +714,7 @@ fn lock_exclude_newer_relative_global_and_package() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3W"

[options.exclude-newer-package]
Expand Down Expand Up @@ -907,7 +907,7 @@ fn lock_exclude_newer_relative_global_and_package() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3W"

[options.exclude-newer-package]
Expand Down Expand Up @@ -1235,7 +1235,7 @@ fn lock_exclude_newer_relative_no_timestamp_in_lockfile() -> Result<()> {
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3W"

[[package]]
Expand All @@ -1260,7 +1260,7 @@ fn lock_exclude_newer_relative_no_timestamp_in_lockfile() -> Result<()> {
"#);

// Manually remove the exclude-newer timestamp from the lockfile, leaving the span.
let lock = lock.replace("exclude-newer = \"2024-04-10T00:00:00Z\"\n", "");
let lock = lock.replace("exclude-newer = \"0001-01-01T00:00:00Z\" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.\n", "");
context.temp_dir.child("uv.lock").write_str(&lock)?;

// The lockfile now has no exclude-newer, but `pyproject.toml` still configures one,
Expand All @@ -1274,19 +1274,17 @@ fn lock_exclude_newer_relative_no_timestamp_in_lockfile() -> Result<()> {
----- stdout -----

----- stderr -----
Resolving despite existing lockfile due to addition of global exclude newer 2024-04-10T00:00:00Z
Resolved 2 packages in [TIME]
");

// The lockfile should have exclude-newer restored.
// The lockfile retains the span but no timestamp since no re-resolution occurred.
Comment thread
zanieb marked this conversation as resolved.
Outdated
let lock = context.read("uv.lock");
assert_snapshot!(lock, @r#"
version = 1
revision = 3
requires-python = ">=3.12"

[options]
exclude-newer = "2024-04-10T00:00:00Z"
exclude-newer-span = "P3W"

[[package]]
Expand Down
Loading