uv-lock-report 0.12.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uv_lock_report/__init__.py +32 -0
- uv_lock_report/__main__.py +11 -0
- uv_lock_report/cli.py +41 -0
- uv_lock_report/models.py +430 -0
- uv_lock_report/report.py +68 -0
- uv_lock_report/tests/__init__.py +0 -0
- uv_lock_report/tests/conftest.py +125 -0
- uv_lock_report/tests/test_get_lockfiles.py +324 -0
- uv_lock_report/tests/test_lock_file_reporter.py +615 -0
- uv_lock_report/tests/test_lockfile.py +47 -0
- uv_lock_report/tests/test_lockfile_changes.py +71 -0
- uv_lock_report/tests/test_updated_package.py +11 -0
- uv_lock_report/tests/test_version_change_level.py +52 -0
- uv_lock_report-0.12.1.dist-info/METADATA +133 -0
- uv_lock_report-0.12.1.dist-info/RECORD +17 -0
- uv_lock_report-0.12.1.dist-info/WHEEL +4 -0
- uv_lock_report-0.12.1.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from uv_lock_report.models import LockfileChanges, OutputFormat, RequiresPythonChanges
|
|
2
|
+
|
|
3
|
+
from .conftest import (
|
|
4
|
+
ADDED_PACKAGES,
|
|
5
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_SIMPLE,
|
|
6
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_SIMPLE_WITH_LINK,
|
|
7
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_TABLE,
|
|
8
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_SIMPLE,
|
|
9
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_SIMPLE_WITH_LINK,
|
|
10
|
+
EXPECTED_LOCKFILE_CHANGES_FULL_TABLE,
|
|
11
|
+
REMOVED_PACKAGES,
|
|
12
|
+
UPDATED_PACKAGES,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestLockfileChanges:
|
|
17
|
+
def test_empty_markdown(self):
|
|
18
|
+
lfc = LockfileChanges(
|
|
19
|
+
requires_python=RequiresPythonChanges(old=None, new=None),
|
|
20
|
+
output_format=OutputFormat.TABLE,
|
|
21
|
+
show_learn_more_link=False,
|
|
22
|
+
)
|
|
23
|
+
assert lfc.markdown == "## uv Lockfile Report"
|
|
24
|
+
|
|
25
|
+
def test_full_markdown_table(self):
|
|
26
|
+
lfc = LockfileChanges(
|
|
27
|
+
requires_python=RequiresPythonChanges(old=None, new=None),
|
|
28
|
+
added=ADDED_PACKAGES,
|
|
29
|
+
updated=UPDATED_PACKAGES,
|
|
30
|
+
removed=REMOVED_PACKAGES,
|
|
31
|
+
output_format=OutputFormat.TABLE,
|
|
32
|
+
show_learn_more_link=False,
|
|
33
|
+
)
|
|
34
|
+
assert lfc.markdown == EXPECTED_LOCKFILE_CHANGES_FULL_TABLE
|
|
35
|
+
assert lfc.items == len(ADDED_PACKAGES) + len(UPDATED_PACKAGES) + len(
|
|
36
|
+
REMOVED_PACKAGES
|
|
37
|
+
)
|
|
38
|
+
assert lfc.model_dump() == EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_TABLE
|
|
39
|
+
|
|
40
|
+
def test_full_markdown_simple(self):
|
|
41
|
+
lfc = LockfileChanges(
|
|
42
|
+
requires_python=RequiresPythonChanges(old=None, new=None),
|
|
43
|
+
added=ADDED_PACKAGES,
|
|
44
|
+
updated=UPDATED_PACKAGES,
|
|
45
|
+
removed=REMOVED_PACKAGES,
|
|
46
|
+
output_format=OutputFormat.SIMPLE,
|
|
47
|
+
show_learn_more_link=False,
|
|
48
|
+
)
|
|
49
|
+
assert lfc.markdown == EXPECTED_LOCKFILE_CHANGES_FULL_SIMPLE
|
|
50
|
+
assert lfc.items == len(ADDED_PACKAGES) + len(UPDATED_PACKAGES) + len(
|
|
51
|
+
REMOVED_PACKAGES
|
|
52
|
+
)
|
|
53
|
+
assert lfc.model_dump() == EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_SIMPLE
|
|
54
|
+
|
|
55
|
+
def test_full_markdown_simple_with_learn_more_link(self):
|
|
56
|
+
lfc = LockfileChanges(
|
|
57
|
+
requires_python=RequiresPythonChanges(old=None, new=None),
|
|
58
|
+
added=ADDED_PACKAGES,
|
|
59
|
+
updated=UPDATED_PACKAGES,
|
|
60
|
+
removed=REMOVED_PACKAGES,
|
|
61
|
+
output_format=OutputFormat.SIMPLE,
|
|
62
|
+
show_learn_more_link=True,
|
|
63
|
+
)
|
|
64
|
+
assert lfc.markdown == EXPECTED_LOCKFILE_CHANGES_FULL_SIMPLE_WITH_LINK
|
|
65
|
+
assert lfc.items == len(ADDED_PACKAGES) + len(UPDATED_PACKAGES) + len(
|
|
66
|
+
REMOVED_PACKAGES
|
|
67
|
+
)
|
|
68
|
+
assert (
|
|
69
|
+
lfc.model_dump()
|
|
70
|
+
== EXPECTED_LOCKFILE_CHANGES_FULL_MODEL_DUMP_SIMPLE_WITH_LINK
|
|
71
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from uv_lock_report.models import UpdatedPackage
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestUpdatedPackage:
|
|
5
|
+
def test_valid_versions(self):
|
|
6
|
+
up = UpdatedPackage(name="steve", old_version="1.0.0", new_version="2.0.0")
|
|
7
|
+
assert up.model_dump() == {
|
|
8
|
+
"name": "steve",
|
|
9
|
+
"new_version": "2.0.0",
|
|
10
|
+
"old_version": "1.0.0",
|
|
11
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from uv_lock_report.models import VersionChangeLevel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestVersionChangeLevel:
|
|
7
|
+
"""Test the VersionChangeLevel enum and its gitmoji property."""
|
|
8
|
+
|
|
9
|
+
def test_major_gitmoji(self):
|
|
10
|
+
"""Test that MAJOR change level returns collision emoji."""
|
|
11
|
+
assert VersionChangeLevel.MAJOR.gitmoji == ":collision:"
|
|
12
|
+
|
|
13
|
+
def test_minor_gitmoji(self):
|
|
14
|
+
"""Test that MINOR change level returns sparkles emoji."""
|
|
15
|
+
assert VersionChangeLevel.MINOR.gitmoji == ":sparkles:"
|
|
16
|
+
|
|
17
|
+
def test_patch_gitmoji(self):
|
|
18
|
+
"""Test that PATCH change level returns hammer and wrench emoji."""
|
|
19
|
+
assert VersionChangeLevel.PATCH.gitmoji == ":hammer_and_wrench:"
|
|
20
|
+
|
|
21
|
+
def test_unknown_gitmoji(self):
|
|
22
|
+
"""Test that UNKNOWN change level returns question mark emoji."""
|
|
23
|
+
assert VersionChangeLevel.UNKNOWN.gitmoji == ":question:"
|
|
24
|
+
|
|
25
|
+
def test_all_levels_have_gitmoji(self):
|
|
26
|
+
"""Test that all VersionChangeLevel values have a gitmoji defined."""
|
|
27
|
+
for level in VersionChangeLevel:
|
|
28
|
+
# Should not raise NotImplementedError
|
|
29
|
+
emoji = level.gitmoji
|
|
30
|
+
assert isinstance(emoji, str)
|
|
31
|
+
assert emoji.startswith(":")
|
|
32
|
+
assert emoji.endswith(":")
|
|
33
|
+
|
|
34
|
+
def test_level_values(self):
|
|
35
|
+
"""Test that VersionChangeLevel enum values are correctly ordered."""
|
|
36
|
+
assert VersionChangeLevel.MAJOR == 0
|
|
37
|
+
assert VersionChangeLevel.MINOR == 1
|
|
38
|
+
assert VersionChangeLevel.PATCH == 2
|
|
39
|
+
assert VersionChangeLevel.UNKNOWN == 10
|
|
40
|
+
|
|
41
|
+
@pytest.mark.parametrize(
|
|
42
|
+
"level,expected_emoji",
|
|
43
|
+
[
|
|
44
|
+
(VersionChangeLevel.MAJOR, ":collision:"),
|
|
45
|
+
(VersionChangeLevel.MINOR, ":sparkles:"),
|
|
46
|
+
(VersionChangeLevel.PATCH, ":hammer_and_wrench:"),
|
|
47
|
+
(VersionChangeLevel.UNKNOWN, ":question:"),
|
|
48
|
+
],
|
|
49
|
+
)
|
|
50
|
+
def test_gitmoji_mapping(self, level, expected_emoji):
|
|
51
|
+
"""Parametrized test for all VersionChangeLevel to gitmoji mappings."""
|
|
52
|
+
assert level.gitmoji == expected_emoji
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: uv-lock-report
|
|
3
|
+
Version: 0.12.1
|
|
4
|
+
Summary: Parse and report package changes in uv.lock.
|
|
5
|
+
Project-URL: Homepage, https://github.com/mw-root/uv-lock-report
|
|
6
|
+
Project-URL: Source, https://github.com/mw-root/uv-lock-report
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Requires-Dist: packaging>=25.0
|
|
9
|
+
Requires-Dist: pydantic>=2.11.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
## uv Lock Report
|
|
13
|
+
|
|
14
|
+
[](https://codecov.io/gh/mw-root/uv-lock-report)
|
|
15
|
+
|
|
16
|
+
## Description
|
|
17
|
+
|
|
18
|
+
<!-- AUTO-DOC-DESCRIPTION:START - Do not remove or modify this section -->
|
|
19
|
+
|
|
20
|
+
Digests complex `uv.lock` diffs in Pull Requests and provides a
|
|
21
|
+
simple summary of dependency changes as a PR comment.
|
|
22
|
+
|
|
23
|
+
<!-- AUTO-DOC-DESCRIPTION:END -->
|
|
24
|
+
|
|
25
|
+
Pull Requests with lockfile changes can be difficult to evaluate at a quick glance
|
|
26
|
+
and diffs are usually hidden by default.
|
|
27
|
+
|
|
28
|
+
This GitHub Action transforms complex `uv.lock` diffs into a clean, easy-to-read report.
|
|
29
|
+
It analyzes the changes between your base and head lockfiles, then posts a formatted comment showing exactly which packages were added, updated, or removed—including version changes and their severity (major, minor, or patch).
|
|
30
|
+
|
|
31
|
+
No more parsing through hundreds of lines of TOML diffs to understand what changed.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Example Gitlab Actions Usage
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
name: uv Lockfile Report
|
|
38
|
+
|
|
39
|
+
on:
|
|
40
|
+
pull_request:
|
|
41
|
+
|
|
42
|
+
permissions:
|
|
43
|
+
contents: read
|
|
44
|
+
pull-requests: write
|
|
45
|
+
|
|
46
|
+
jobs:
|
|
47
|
+
report:
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v5
|
|
51
|
+
with:
|
|
52
|
+
fetch-depth: 0
|
|
53
|
+
|
|
54
|
+
- name: Report
|
|
55
|
+
uses: mw-root/uv-lock-report@v0.7.0
|
|
56
|
+
with:
|
|
57
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Inputs
|
|
61
|
+
|
|
62
|
+
<!-- AUTO-DOC-INPUT:START - Do not remove or modify this section -->
|
|
63
|
+
|
|
64
|
+
| INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
|
|
65
|
+
|----------------------|--------|----------|------------|-----------------------------------------------------------------|
|
|
66
|
+
| github-token | string | true | | GitHub Token |
|
|
67
|
+
| output-format | string | false | `"simple"` | The output format of the report. <br>One of: simple, table |
|
|
68
|
+
| show-learn-more-link | string | false | `"true"` | Whether to show a "Learn More" <br>link in the report comment. |
|
|
69
|
+
|
|
70
|
+
<!-- AUTO-DOC-INPUT:END -->
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
### Output Format Examples
|
|
75
|
+
|
|
76
|
+
The formatting can be chosen with the `output-format` input.
|
|
77
|
+
|
|
78
|
+
#### Simple Format ( Default )
|
|
79
|
+

|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
#### Table Format
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
## CLI Usage
|
|
86
|
+
|
|
87
|
+
You can also use `uv-lock-report` as a standalone CLI tool for local development or in custom CI/CD pipelines.
|
|
88
|
+
|
|
89
|
+
### Installation
|
|
90
|
+
|
|
91
|
+
Install the package using uv:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
uv build
|
|
95
|
+
pip install ./dist/uv_lock_report-0.1.0-py3-none-any.whl
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Usage
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv-lock-report --base-sha <git-sha> --base-path <path-to-base-lockfile> --output-path <output-file>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Arguments
|
|
105
|
+
|
|
106
|
+
- `--base-sha`: Git SHA of the base commit to compare against
|
|
107
|
+
- `--base-path`: Path to the base lockfile (usually `uv.lock`)
|
|
108
|
+
- `--output-path`: Path where the JSON report will be written
|
|
109
|
+
- `--output-format`: Output format (`table` or `simple`, default: `table`)
|
|
110
|
+
- `--show-learn-more-link`: Whether to show "Learn More" link (`true` or `false`, default: `true`)
|
|
111
|
+
|
|
112
|
+
#### Example
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Compare current uv.lock with the one from main branch
|
|
116
|
+
uv-lock-report \
|
|
117
|
+
--base-sha main \
|
|
118
|
+
--base-path uv.lock \
|
|
119
|
+
--output-path report.json \
|
|
120
|
+
--output-format table
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Testing the installation
|
|
124
|
+
|
|
125
|
+
You can test that the CLI is properly installed:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Test with a built wheel
|
|
129
|
+
uv run --with ./dist/uv_lock_report-0.1.0-py3-none-any.whl uv-lock-report --help
|
|
130
|
+
|
|
131
|
+
# Or run the included test script
|
|
132
|
+
uv run python test_cli_install.py
|
|
133
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
uv_lock_report/__init__.py,sha256=zKtnG7mL7xg1KILo66OgUMSbTVASEQziETf1boXqleY,653
|
|
2
|
+
uv_lock_report/__main__.py,sha256=TRR4lhwzvfRgbC7NgkLK3w8c9cxiBJrgIUpwZ7NszPM,211
|
|
3
|
+
uv_lock_report/cli.py,sha256=D0VdCQoa6Lu5PNHrlAQEFFH5-nHVkr3EZbm_UqrKWC8,1188
|
|
4
|
+
uv_lock_report/models.py,sha256=gsKUKaTNLuCW7jO4LAqRcefxVvU8iFBnAiI4smWXJHQ,13208
|
|
5
|
+
uv_lock_report/report.py,sha256=UtaMSpTB0Lx0imaT30Iu45fJYZdS9gDO7s8VXcSAow0,1779
|
|
6
|
+
uv_lock_report/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
uv_lock_report/tests/conftest.py,sha256=JlHtpwzC4fSeEU9flBjmuSRmztWa92symBmvTiiadNg,4267
|
|
8
|
+
uv_lock_report/tests/test_get_lockfiles.py,sha256=T0vMVhm3fey3BRUw4tPOnRKsakRFw9xM28a9bvfkyuA,12043
|
|
9
|
+
uv_lock_report/tests/test_lock_file_reporter.py,sha256=v2eMQJSHDkS19OClEpwPcZlT1zQxtRntQo90gtGhfhQ,22846
|
|
10
|
+
uv_lock_report/tests/test_lockfile.py,sha256=yyoKh7XsgSSPriO2-LSHt3J04zOJd6fGKZNQbboNgrg,1372
|
|
11
|
+
uv_lock_report/tests/test_lockfile_changes.py,sha256=8lHcHGGNkFwzk5MKATBFRZPjb0CfMJvkUujGYuFIsWk,2742
|
|
12
|
+
uv_lock_report/tests/test_updated_package.py,sha256=YXqPdE7rgj71IEl35iWwoPCEse0a8STn5bO1t4-EAT4,343
|
|
13
|
+
uv_lock_report/tests/test_version_change_level.py,sha256=x5mhdMTb7fLqtw-6Bz_0tgatefE7jTo3DitCsXUUnqY,2034
|
|
14
|
+
uv_lock_report-0.12.1.dist-info/METADATA,sha256=FwSEZbaplW752PXC-ptU9sh5WTbnCOoXLyiJ5RcXOs0,3958
|
|
15
|
+
uv_lock_report-0.12.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
uv_lock_report-0.12.1.dist-info/entry_points.txt,sha256=li0cGnt4Tj1WfCUcoycxuq-AGJNsYy6GXUM-anRvf30,59
|
|
17
|
+
uv_lock_report-0.12.1.dist-info/RECORD,,
|