Skip to content

Commit 8c06373

Browse files
authored
Fix uv lock check header comparison (#2317)
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
1 parent 5cfbb54 commit 8c06373

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/hatch/env/lockers/uv.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@
1212
from hatch.env.virtual import VirtualEnvironment
1313

1414

15+
_UV_GENERATED_HEADER = "# This file was autogenerated by uv via the following command:"
16+
_UV_COMMAND_PREFIX = "# "
17+
18+
19+
def _strip_uv_generated_header(contents: str) -> str:
20+
lines = contents.splitlines(keepends=True)
21+
if not lines or lines[0].rstrip("\r\n") != _UV_GENERATED_HEADER:
22+
return contents
23+
24+
index = 1
25+
while index < len(lines) and lines[index].startswith(_UV_COMMAND_PREFIX):
26+
index += 1
27+
28+
return "".join(lines[index:])
29+
30+
1531
class UvLocker(LockerInterface):
1632
PLUGIN_NAME = "uv"
1733

@@ -140,7 +156,7 @@ def in_sync(
140156
existing = output_path.read_text(encoding="utf-8")
141157
fresh = temp_path.read_text(encoding="utf-8")
142158

143-
return existing == fresh
159+
return _strip_uv_generated_header(existing) == _strip_uv_generated_header(fresh)
144160

145161
@classmethod
146162
def apply_lock(cls, environment: EnvironmentInterface, lock_path: Path) -> None:

tests/cli/env/test_lock.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import tomli_w
55

66
from hatch.config.constants import ConfigEnvVars
7+
from hatch.env.lockers.uv import UvLocker
78
from hatch.project.core import Project
89
from hatch.utils.toml import load_toml_file
910

@@ -372,6 +373,46 @@ def test_check_exists(hatch, helpers, temp_dir, config_file):
372373
assert "Lockfile is up to date" in result.output
373374

374375

376+
def test_uv_in_sync_ignores_autogenerated_command_header(helpers, monkeypatch, temp_dir):
377+
lock_path = temp_dir / "pylock.toml"
378+
lock_body = helpers.dedent(
379+
"""
380+
lock-version = "1.0"
381+
created-by = "uv"
382+
383+
[[packages]]
384+
name = "click"
385+
version = "8.4.1"
386+
"""
387+
)
388+
lock_path.write_text(
389+
helpers.dedent(
390+
"""
391+
# This file was autogenerated by uv via the following command:
392+
# uv pip compile /tmp/requirements.txt --output-file /project/pylock.toml
393+
"""
394+
)
395+
+ lock_body,
396+
encoding="utf-8",
397+
)
398+
399+
def generate(_cls, _environment, _dependencies, output_path, **_kwargs):
400+
output_path.write_text(
401+
helpers.dedent(
402+
"""
403+
# This file was autogenerated by uv via the following command:
404+
# uv pip compile /tmp/tmpabc/requirements.txt --output-file /tmp/tmpabc/pylock.toml
405+
"""
406+
)
407+
+ lock_body,
408+
encoding="utf-8",
409+
)
410+
411+
monkeypatch.setattr(UvLocker, "generate", classmethod(generate))
412+
413+
assert UvLocker.in_sync(object(), [], lock_path)
414+
415+
375416
@pytest.mark.usefixtures("mock_locker")
376417
def test_check_lockfile_stale(hatch, helpers, temp_dir, config_file):
377418
config_file.model.template.plugins["default"]["tests"] = False

0 commit comments

Comments
 (0)