AutoGitSemVer 0.8.3__tar.gz → 0.9.0__tar.gz

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.
Files changed (43) hide show
  1. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.copier-answers.yml +1 -1
  2. autogitsemver-0.9.0/.gitignore +16 -0
  3. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/DEVELOPMENT.md +1 -1
  4. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/PKG-INFO +6 -4
  5. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/README.md +5 -3
  6. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/pyproject.toml +15 -4
  7. autogitsemver-0.9.0/src/AutoGitSemVer/__init__.py +17 -0
  8. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/scripts/UpdatePythonVersion.py +27 -13
  9. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/tests/scripts/UpdatePythonVersion_UnitTest.py +65 -9
  10. autogitsemver-0.9.0/uv.lock +903 -0
  11. autogitsemver-0.8.3/.gitignore +0 -21
  12. autogitsemver-0.8.3/src/AutoGitSemVer/__init__.py +0 -14
  13. autogitsemver-0.8.3/uv.lock +0 -714
  14. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/CODEOWNERS +0 -0
  15. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  16. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  18. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  19. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/actions/release_impl/action.yml +0 -0
  20. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/pull_request_template.md +0 -0
  21. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/release_sources.yaml +0 -0
  22. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/workflows/CICD.yml +0 -0
  23. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/workflows/CICD_impl.yml +0 -0
  24. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.github/workflows/codeql.yml +0 -0
  25. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.pre-commit-config.yaml +0 -0
  26. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/.python-version +0 -0
  27. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/CODE_OF_CONDUCT.md +0 -0
  28. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/CONTRIBUTING.md +0 -0
  29. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/GOVERNANCE.md +0 -0
  30. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/LICENSE +0 -0
  31. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/MAINTAINERS.md +0 -0
  32. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/SECURITY.md +0 -0
  33. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/minisign_key.pub +0 -0
  34. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/AutoGitSemVerSchema.json +0 -0
  35. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/EntryPoint.py +0 -0
  36. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/Lib.py +0 -0
  37. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/py.typed +0 -0
  38. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer/scripts/__init__.py +0 -0
  39. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/AutoGitSemVer.yaml +0 -0
  40. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/ConfigurationSchema/AutoGitSemVerSchema.SimpleSchema +0 -0
  41. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/src/ConfigurationSchema/README.md +0 -0
  42. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/tests/EntryPoint_UnitTest.py +0 -0
  43. {autogitsemver-0.8.3 → autogitsemver-0.9.0}/tests/Lib_UnitTest.py +0 -0
@@ -6,7 +6,7 @@
6
6
  # available at https://github.com/gt-sse-center/copier-UvScaffolding.
7
7
  #
8
8
 
9
- _commit: v0.2.0
9
+ _commit: v0.2.4
10
10
  _src_path: .
11
11
  author_email: github@DavidBrownell.com
12
12
  author_name: David Brownell
@@ -0,0 +1,16 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ .coverage
12
+ .DS_Store
13
+ .vscode
14
+ coverage.xml
15
+ minisign_key.pri
16
+ post_generation_instructions.html
@@ -19,7 +19,7 @@
19
19
  | Automated Testing | `uv run pytest` or<br/>`uv run pytest --no-cov` | Run automated tests using [pytest](https://docs.pytest.org/) and extract code coverage using [coverage](https://coverage.readthedocs.io/) based on settings in `pyproject.toml`. | :white_check_mark: | :white_check_mark: |
20
20
  | Semantic Version Generation | `uv run python -m AutoGitSemVer.scripts.UpdatePythonVersion ./src/AutoGitSemVer/__init__.py ./src` | Generate a new [Semantic Version](https://semver.org/) based on git commits using [AutoGitSemVer](https://github.com/davidbrownell/AutoGitSemVer). Version information is stored in `./src/AutoGitSemVer/__init__.py`. | | :white_check_mark: |
21
21
  | Python Package Creation | `uv build` | Create a python package using [uv](https://github.com/astral-sh/uv) based on settings in `pyproject.toml`. Generated packages will be written to `./dist`. | | :white_check_mark: |
22
- | Sign Artifacts | `uv run --with py-minisign python -c "import minisign; minisign.SecretKey.from_file(<temp_filename>).sign_file(<filename>, trusted_comment='<package_name> v<package_version>', drop_signature=True)` | Signs artifacts using [py-minisign](https://github.com/x13a/py-minisign). Note that the private key is stored as a [GitHub secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). | | :white_check_mark: |
22
+ | Sign Artifacts | `uv run python -c "import minisign; minisign.SecretKey.from_file(<temp_filename>).sign_file(<filename>, trusted_comment='<package_name> v<package_version>', drop_signature=True)` | Signs artifacts using [py-minisign](https://github.com/x13a/py-minisign). Note that the private key is stored as a [GitHub secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). | | :white_check_mark: |
23
23
  | Python Package Publishing | `uv publish` | Publish a python package to [PyPi](https://pypi.org/) using [uv](https://github.com/astral-sh/uv) based on settings in `pyproject.toml`. | | :white_check_mark: |
24
24
 
25
25
  ## Contributing Changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AutoGitSemVer
3
- Version: 0.8.3
3
+ Version: 0.9.0
4
4
  Summary: Add your description here
5
5
  Project-URL: Homepage, https://github.com/davidbrownell/AutoGitSemVer
6
6
  Project-URL: Documentation, https://github.com/davidbrownell/AutoGitSemVer
@@ -260,11 +260,13 @@ A simple example of a configuration file can be found [here](https://github.com/
260
260
  | Via [pip](https://pip.pypa.io/en/stable/) | `pip install AutoGitSemVer` |
261
261
 
262
262
  ### Verifying Signed Artifacts
263
- Artifacts are signed and validated using [py-minisign](https://github.com/x13a/py-minisign) and the public key in the file `./minisign_key.pub`.
263
+ Artifacts are signed and verified using [py-minisign](https://github.com/x13a/py-minisign) and the public key in the file `./minisign_key.pub`.
264
264
 
265
265
  To verify that an artifact is valid, visit [the latest release](https://github.com/davidbrownell/AutoGitSemVer/releases/latest) and download the `.minisign` signature file that corresponds to the artifact, then run the following command, replacing `<filename>` with the name of the artifact to be verified:
266
266
 
267
- `uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>')"`
267
+ ```shell
268
+ uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>'); print('The file has been verified.')"
269
+ ```
268
270
 
269
271
  ## Development
270
272
  Please visit [Contributing](https://github.com/davidbrownell/AutoGitSemVer/blob/main/CONTRIBUTING.md) and [Development](https://github.com/davidbrownell/AutoGitSemVer/blob/main/DEVELOPMENT.md) for information on contributing to this project.
@@ -282,4 +284,4 @@ Additional information can be found at these locations.
282
284
  | Security | [SECURITY.md](https://github.com/davidbrownell/AutoGitSemVer/blob/main/SECURITY.md) | Information about how to privately report security issues associated with this project. |
283
285
 
284
286
  ## License
285
- AutoGitSemVer is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
287
+ `AutoGitSemVer` is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
@@ -227,11 +227,13 @@ A simple example of a configuration file can be found [here](https://github.com/
227
227
  | Via [pip](https://pip.pypa.io/en/stable/) | `pip install AutoGitSemVer` |
228
228
 
229
229
  ### Verifying Signed Artifacts
230
- Artifacts are signed and validated using [py-minisign](https://github.com/x13a/py-minisign) and the public key in the file `./minisign_key.pub`.
230
+ Artifacts are signed and verified using [py-minisign](https://github.com/x13a/py-minisign) and the public key in the file `./minisign_key.pub`.
231
231
 
232
232
  To verify that an artifact is valid, visit [the latest release](https://github.com/davidbrownell/AutoGitSemVer/releases/latest) and download the `.minisign` signature file that corresponds to the artifact, then run the following command, replacing `<filename>` with the name of the artifact to be verified:
233
233
 
234
- `uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>')"`
234
+ ```shell
235
+ uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>'); print('The file has been verified.')"
236
+ ```
235
237
 
236
238
  ## Development
237
239
  Please visit [Contributing](https://github.com/davidbrownell/AutoGitSemVer/blob/main/CONTRIBUTING.md) and [Development](https://github.com/davidbrownell/AutoGitSemVer/blob/main/DEVELOPMENT.md) for information on contributing to this project.
@@ -249,4 +251,4 @@ Additional information can be found at these locations.
249
251
  | Security | [SECURITY.md](https://github.com/davidbrownell/AutoGitSemVer/blob/main/SECURITY.md) | Information about how to privately report security issues associated with this project. |
250
252
 
251
253
  ## License
252
- AutoGitSemVer is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
254
+ `AutoGitSemVer` is licensed under the <a href="https://choosealicense.com/licenses/MIT/" target="_blank">MIT</a> license.
@@ -13,6 +13,7 @@ dependencies = [
13
13
  "rtyaml>=1.0.0",
14
14
  "semantic-version>=2.10.0",
15
15
  ]
16
+
16
17
  dynamic = ["version"]
17
18
  classifiers = [
18
19
  "Development Status :: 4 - Beta",
@@ -52,16 +53,17 @@ build-backend = "hatchling.build"
52
53
  dev = [
53
54
  "dbrownell-commitemojis>=0.1.1",
54
55
  "pre-commit>=4.2.0",
55
- "pytest>=8.3.5",
56
- "pytest-cov>=6.1.1",
57
- "ruff>=0.11.9",
56
+ "py-minisign>=0.12.0",
57
+ "pytest>=8.4.1",
58
+ "pytest-cov>=6.2.1",
59
+ "ruff>=0.12.3",
58
60
  ]
59
61
 
60
62
  [tool.hatch.version]
61
63
  path = "src/AutoGitSemVer/__init__.py"
62
64
 
63
65
  [tool.pytest.ini_options]
64
- addopts = "--verbose -vv --capture=no --cov=AutoGitSemVer --cov-fail-under=90.0"
66
+ addopts = "--verbose -vv --capture=no --cov=AutoGitSemVer --cov-report term --cov-report xml:coverage.xml --cov-fail-under=90.0"
65
67
  python_files = [
66
68
  "**/*Test.py",
67
69
  ]
@@ -77,12 +79,21 @@ ignore = [
77
79
  "ANN003", # Missing type annotation for `**kwargs`
78
80
  "BLE001", # Do not catch blind exception: `Exception`
79
81
  "COM812", # Trailing comma missing
82
+ "D105", # Missing docstring in magic method
83
+ "D107", # Missing docstring in `__init__` method
80
84
  "D202", # No blank lines allowed after function docstring
81
85
  "E501", # Line too long
86
+ "FIX002", # Line contains TODO, consider resolving the issue
82
87
  "I001", # Import block is un-sorted or un-formatted
83
88
  "N802", # Function name `xxx` should be lowercase
84
89
  "N999", # Invalid module name
90
+ "RSE102", # Unnecessary parentheses on raise exception
85
91
  "S101", # Use of assert detected
92
+ "TC006", # Add quotes to type expression in `typing.cast()`
93
+ "TD002", # Missing author in TODO
94
+ "TD003", # Missing issue link for this TODO
95
+ "TRY002", # Create your own exception
96
+ "TRY300", # Consider moving this statement to an `else` block
86
97
  "UP032", # Use f-string instead of `format` call
87
98
  ]
88
99
 
@@ -0,0 +1,17 @@
1
+ # noqa: D104
2
+
3
+ # Wheel names will be generated according to this value. Do not manually modify this value; instead
4
+ # update it according to committed changes by running this command from the root of the repository:
5
+ #
6
+ # uv run python -m AutoGitSemVer.scripts.UpdatePythonVersion ./src/AutoGitSemVer/__init__.py ./src
7
+ #
8
+ __version__ = "0.9.0"
9
+
10
+
11
+ from .Lib import GenerateStyle, GetSemanticVersion, GetSemanticVersionResult
12
+
13
+ __all__ = [
14
+ "GenerateStyle",
15
+ "GetSemanticVersion",
16
+ "GetSemanticVersionResult",
17
+ ]
@@ -46,13 +46,13 @@ app = typer.Typer(
46
46
  # ----------------------------------------------------------------------
47
47
  @app.command("EntryPoint", help=__doc__, no_args_is_help=True)
48
48
  def EntryPoint(
49
- python_filename: Annotated[
49
+ filename: Annotated[
50
50
  Path,
51
51
  typer.Argument(
52
52
  dir_okay=False,
53
53
  exists=True,
54
54
  resolve_path=True,
55
- help="Name of the python file that contains the __version__ variable.",
55
+ help="Name of the python file that contains the __version__ variable or the pyproject.toml file that contains the version variable.",
56
56
  ),
57
57
  ],
58
58
  working_dir: Annotated[
@@ -76,7 +76,7 @@ def EntryPoint(
76
76
  with DoneManager.CreateCommandLine(
77
77
  flags=DoneManagerFlags.Create(verbose=verbose, debug=debug),
78
78
  ) as dm:
79
- working_dir = working_dir or python_filename.parent
79
+ working_dir = working_dir or filename.parent
80
80
 
81
81
  version = GetSemanticVersion(
82
82
  dm,
@@ -89,17 +89,31 @@ def EntryPoint(
89
89
 
90
90
  dm.WriteLine("")
91
91
 
92
- with dm.Nested(f"Updating '{python_filename}'...") as update_dm:
93
- with python_filename.open(encoding="utf-8") as f:
92
+ with dm.Nested(f"Updating '{filename}'...") as update_dm:
93
+ with filename.open(encoding="utf-8") as f:
94
94
  content = f.read()
95
95
 
96
- match = re.search(
97
- r"^(?P<prefix>\s*__version__\s*=\s*)(?P<quote>['\"])\S*?(?P=quote)(?P<newline>\r?\n)",
98
- content,
99
- flags=re.MULTILINE,
100
- )
96
+ if filename.suffix == ".py":
97
+ variable_name = "__version__"
98
+
99
+ regex = re.compile(
100
+ rf"^(?P<prefix>\s*{variable_name}\s*=\s*)(?P<quote>['\"])\S*?(?P=quote)(?P<newline>\r?\n)",
101
+ flags=re.MULTILINE,
102
+ )
103
+ elif filename.suffix == ".toml":
104
+ variable_name = "version"
105
+
106
+ regex = re.compile(
107
+ rf"^(?P<prefix>{variable_name}\s*=\s*)(?P<quote>['\"])\S*?(?P=quote)(?P<newline>\r?\n)",
108
+ flags=re.MULTILINE,
109
+ )
110
+ else:
111
+ error = f"'{filename}' is not a recognized file type."
112
+ raise Exception(error)
113
+
114
+ match = regex.search(content)
101
115
  if not match:
102
- update_dm.WriteError("A '__version__' variable was not found.\n")
116
+ update_dm.WriteError(f"A '{variable_name}' variable was not found.\n")
103
117
  return
104
118
 
105
119
  content = "".join(
@@ -114,7 +128,7 @@ def EntryPoint(
114
128
  ],
115
129
  )
116
130
 
117
- with python_filename.open("w", encoding="utf-8", newline=match.group("newline")) as f:
131
+ with filename.open("w", encoding="utf-8", newline=match.group("newline")) as f:
118
132
  f.write(content)
119
133
 
120
134
 
@@ -122,4 +136,4 @@ def EntryPoint(
122
136
  # ----------------------------------------------------------------------
123
137
  # ----------------------------------------------------------------------
124
138
  if __name__ == "__main__":
125
- app()
139
+ app() # pragma: no cover
@@ -18,15 +18,14 @@ import textwrap
18
18
  from pathlib import Path
19
19
  from unittest.mock import MagicMock as Mock, mock_open, patch
20
20
 
21
- import pytest
22
-
21
+ from click.testing import Result
23
22
  from typer.testing import CliRunner
24
23
  from AutoGitSemVer import GetSemanticVersionResult
25
24
  from AutoGitSemVer.scripts.UpdatePythonVersion import app
26
25
 
27
26
 
28
27
  # ----------------------------------------------------------------------
29
- def test_Default():
28
+ def test_Python():
30
29
  _Execute(
31
30
  textwrap.dedent(
32
31
  """\
@@ -46,7 +45,7 @@ def test_Default():
46
45
 
47
46
 
48
47
  # ----------------------------------------------------------------------
49
- def test_NoVersion():
48
+ def test_NoPythonVersion():
50
49
  _Execute(
51
50
  textwrap.dedent(
52
51
  """\
@@ -58,6 +57,53 @@ def test_NoVersion():
58
57
  )
59
58
 
60
59
 
60
+ # ----------------------------------------------------------------------
61
+ def test_Toml():
62
+ _Execute(
63
+ textwrap.dedent(
64
+ """\
65
+ # Line Before
66
+ version = ""
67
+ # Line After
68
+ """,
69
+ ),
70
+ textwrap.dedent(
71
+ """\
72
+ # Line Before
73
+ version = "1.2.3"
74
+ # Line After
75
+ """,
76
+ ),
77
+ file_extension=".toml",
78
+ )
79
+
80
+
81
+ # ----------------------------------------------------------------------
82
+ def test_NoTomlVersion():
83
+ _Execute(
84
+ textwrap.dedent(
85
+ """\
86
+ # No version in this file
87
+ """,
88
+ ),
89
+ "",
90
+ file_extension=".toml",
91
+ expected_failure=True,
92
+ )
93
+
94
+
95
+ # ----------------------------------------------------------------------
96
+ def test_UnsupportedFileType():
97
+ result = _Execute(
98
+ "",
99
+ "",
100
+ file_extension=".md",
101
+ expected_failure=True,
102
+ )
103
+ exception_message = str(result.exception)
104
+ assert "README.md' is not a recognized file type." in exception_message
105
+
106
+
61
107
  # ----------------------------------------------------------------------
62
108
  # ----------------------------------------------------------------------
63
109
  # ----------------------------------------------------------------------
@@ -65,8 +111,9 @@ def _Execute(
65
111
  original: str,
66
112
  expected: str,
67
113
  *,
114
+ file_extension: str = ".py",
68
115
  expected_failure: bool = False,
69
- ) -> str:
116
+ ) -> Result:
70
117
  # ----------------------------------------------------------------------
71
118
  def MyWrite(value):
72
119
  assert value == expected
@@ -86,11 +133,20 @@ def _Execute(
86
133
  ),
87
134
  patch.object(Path, "open", file_mock),
88
135
  ):
89
- result = CliRunner().invoke(app, [__file__])
136
+ if file_extension == ".py":
137
+ placeholder_filename = Path(__file__)
138
+ elif file_extension == ".toml":
139
+ placeholder_filename = Path(__file__).parent.parent.parent / "pyproject.toml"
140
+ elif file_extension == ".md":
141
+ placeholder_filename = Path(__file__).parent.parent.parent / "README.md"
142
+ else:
143
+ assert False, file_extension
144
+
145
+ result = CliRunner().invoke(app, [str(placeholder_filename)])
90
146
 
91
147
  if expected_failure:
92
- assert result.exit_code != 0
148
+ assert result.exit_code != 0, result.output
93
149
  else:
94
- assert result.exit_code == 0
150
+ assert result.exit_code == 0, result.output
95
151
 
96
- return result.output
152
+ return result