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.
@@ -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
+ [![codecov](https://codecov.io/gh/mw-root/uv-lock-report/graph/badge.svg?token=QQFK62PQ8G)](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
+ ![Example Comment](images/uv-lock-report-simple-comment.png "Simple Format")
80
+
81
+
82
+ #### Table Format
83
+ ![Example Comment](images/uv-lock-report-table-comment.png "Table Format")
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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ uv-lock-report = uv_lock_report.cli:main