Coverage for src/pullapprove/trust/lockfiles.py: 100%
11 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-28 14:54 -0500
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-28 14:54 -0500
1"""Trust rule: package-manager lockfiles are tool-generated, not hand-edited."""
3from __future__ import annotations
5from pathlib import PurePosixPath
7from ..diff import DiffFile, DiffHunk
8from .labels import Trust
10# Package-manager lockfiles: regenerated by tooling, not hand-edited.
11LOCKFILE_NAMES = frozenset(
12 {
13 "package-lock.json",
14 "yarn.lock",
15 "pnpm-lock.yaml",
16 "Cargo.lock",
17 "Gemfile.lock",
18 "poetry.lock",
19 # go.sum is the tool-generated checksum lock; go.mod is the editable
20 # manifest (dependencies, replace directives, module path) — reviewer-
21 # relevant, so it is deliberately NOT trusted.
22 "go.sum",
23 "composer.lock",
24 "Pipfile.lock",
25 "bun.lockb",
26 "bun.lock",
27 "flake.lock",
28 "packages.lock.json",
29 "paket.lock",
30 "pdm.lock",
31 "uv.lock",
32 }
33)
36def _lockfile(file: DiffFile, hunk: DiffHunk) -> Trust | None:
37 if PurePosixPath(file.new_path).name not in LOCKFILE_NAMES:
38 return None
39 # A genuine lockfile is added or regenerated in place, never renamed from a
40 # non-lockfile. Renaming e.g. `secrets.py` -> `poetry.lock` would otherwise
41 # hide the whole file's hand-written content as "generated"; decline a move
42 # unless the source was itself a lockfile.
43 if file.is_move() and PurePosixPath(file.old_path).name not in LOCKFILE_NAMES:
44 return None
45 return Trust.LOCKFILE