tinysemver 2.0.7__tar.gz → 2.0.8__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.
- {tinysemver-2.0.7/tinysemver.egg-info → tinysemver-2.0.8}/PKG-INFO +1 -1
- {tinysemver-2.0.7 → tinysemver-2.0.8}/pyproject.toml +1 -1
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver/tinysemver.py +47 -22
- {tinysemver-2.0.7 → tinysemver-2.0.8/tinysemver.egg-info}/PKG-INFO +1 -1
- {tinysemver-2.0.7 → tinysemver-2.0.8}/LICENSE +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/README.md +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/setup.cfg +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver/__init__.py +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver.egg-info/SOURCES.txt +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver.egg-info/dependency_links.txt +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver.egg-info/entry_points.txt +0 -0
- {tinysemver-2.0.7 → tinysemver-2.0.8}/tinysemver.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinysemver
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.8
|
|
4
4
|
Summary: Tiny Semantic Versioning (SemVer) library, that doesn't depend on 300K lines of JavaScript
|
|
5
5
|
Author-email: Ash Vardanian <1983160+ashvardanian@users.noreply.github.com>, Guillaume de Rouville <31691250+grouville@users.noreply.github.com>
|
|
6
6
|
License: Apache License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tinysemver"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.8"
|
|
8
8
|
description = "Tiny Semantic Versioning (SemVer) library, that doesn't depend on 300K lines of JavaScript"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -47,14 +47,14 @@ import argparse
|
|
|
47
47
|
import subprocess
|
|
48
48
|
import re
|
|
49
49
|
import os
|
|
50
|
-
from typing import List, Tuple, Literal, Union, Optional
|
|
50
|
+
from typing import List, Tuple, Literal, Union, Optional, NamedTuple
|
|
51
51
|
from datetime import datetime
|
|
52
52
|
import traceback
|
|
53
53
|
|
|
54
54
|
SemVer = Tuple[int, int, int]
|
|
55
55
|
BumpType = Literal["major", "minor", "patch"]
|
|
56
56
|
PathLike = Union[str, os.PathLike]
|
|
57
|
-
|
|
57
|
+
Commit = NamedTuple("Commit", [("hash", str), ("message", str)])
|
|
58
58
|
|
|
59
59
|
class NoNewCommitsError(Exception):
|
|
60
60
|
"""Raised when no new commits are found since the last tag."""
|
|
@@ -75,7 +75,8 @@ def get_last_tag(repository_path: PathLike) -> str:
|
|
|
75
75
|
return result.stdout.strip().decode("utf-8")
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
|
|
79
|
+
def get_commits_since_tag(repository_path: PathLike, tag: str) -> List[Commit]:
|
|
79
80
|
"""Get commit hashes and messages since the specified Git tag."""
|
|
80
81
|
result = subprocess.run(
|
|
81
82
|
["git", "log", f"{tag}..HEAD", "--no-merges", "--pretty=format:%h:%s"],
|
|
@@ -88,8 +89,8 @@ def get_commits_since_tag(repository_path: PathLike, tag: str) -> Tuple[List[str
|
|
|
88
89
|
|
|
89
90
|
lines = result.stdout.strip().decode("utf-8").split("\n")
|
|
90
91
|
hashes = [line.partition(":")[0] for line in lines if line.strip()]
|
|
91
|
-
|
|
92
|
-
return hashes,
|
|
92
|
+
messages = [line.partition(":")[2] for line in lines if line.strip()]
|
|
93
|
+
return [Commit(h, m) for h, m in zip(hashes, messages)]
|
|
93
94
|
|
|
94
95
|
|
|
95
96
|
def parse_version(tag: str) -> SemVer:
|
|
@@ -119,27 +120,45 @@ def normalize_verbs(verbs: Union[str, List[str]], defaults: List[str]) -> List[s
|
|
|
119
120
|
|
|
120
121
|
|
|
121
122
|
def group_commits(
|
|
122
|
-
commits: List[
|
|
123
|
+
commits: List[Commit],
|
|
123
124
|
major_verbs: List[str],
|
|
124
125
|
minor_verbs: List[str],
|
|
125
126
|
patch_verbs: List[str],
|
|
126
|
-
) -> Tuple[List[
|
|
127
|
+
) -> Tuple[List[Commit], List[Commit], List[Commit]]:
|
|
127
128
|
"""Group commits into major, minor, and patch categories based on keywords to simplify future `BumpType` resolution."""
|
|
128
129
|
major_commits = []
|
|
129
130
|
minor_commits = []
|
|
130
131
|
patch_commits = []
|
|
131
132
|
|
|
132
133
|
for commit in commits:
|
|
133
|
-
if any(commit_starts_with_verb(commit, verb) for verb in major_verbs):
|
|
134
|
+
if any(commit_starts_with_verb(commit.message, verb) for verb in major_verbs):
|
|
134
135
|
major_commits.append(commit)
|
|
135
|
-
if any(commit_starts_with_verb(commit, verb) for verb in minor_verbs):
|
|
136
|
+
if any(commit_starts_with_verb(commit.message, verb) for verb in minor_verbs):
|
|
136
137
|
minor_commits.append(commit)
|
|
137
|
-
if any(commit_starts_with_verb(commit, verb) for verb in patch_verbs):
|
|
138
|
+
if any(commit_starts_with_verb(commit.message, verb) for verb in patch_verbs):
|
|
138
139
|
patch_commits.append(commit)
|
|
139
140
|
|
|
140
141
|
return major_commits, minor_commits, patch_commits
|
|
141
142
|
|
|
142
143
|
|
|
144
|
+
def convert_commits_to_message(
|
|
145
|
+
major_commits: List[Commit],
|
|
146
|
+
minor_commits: List[Commit],
|
|
147
|
+
patch_commits: List[Commit],
|
|
148
|
+
) -> str:
|
|
149
|
+
"""Turns the different commits (major, minor, patch) into a single message."""
|
|
150
|
+
message = ""
|
|
151
|
+
|
|
152
|
+
if len(major_commits):
|
|
153
|
+
message += f"\n### Major\n\n" + "\n".join(f"- {c.message} ({c.hash})" for c in major_commits) + "\n"
|
|
154
|
+
if len(minor_commits):
|
|
155
|
+
message += f"\n### Minor\n\n" + "\n".join(f"- {c.message} ({c.hash})" for c in minor_commits) + "\n"
|
|
156
|
+
if len(patch_commits):
|
|
157
|
+
message += f"\n### Patch\n\n" + "\n".join(f"- {c.message} ({c.hash})" for c in patch_commits) + "\n"
|
|
158
|
+
|
|
159
|
+
return message
|
|
160
|
+
|
|
161
|
+
|
|
143
162
|
def bump_version(version: SemVer, bump_type: BumpType) -> SemVer:
|
|
144
163
|
"""Bump the version based on the specified bump type (major, minor, patch)."""
|
|
145
164
|
major, minor, patch = version
|
|
@@ -162,6 +181,9 @@ def create_tag(
|
|
|
162
181
|
github_repository: Optional[str] = None,
|
|
163
182
|
push: bool = False,
|
|
164
183
|
create_release: bool = False,
|
|
184
|
+
major_commits: List[Commit] = None,
|
|
185
|
+
minor_commits: List[Commit] = None,
|
|
186
|
+
patch_commits: List[Commit] = None,
|
|
165
187
|
) -> None:
|
|
166
188
|
"""Create a new Git tag and optionally push it to a remote GitHub repository."""
|
|
167
189
|
|
|
@@ -172,7 +194,10 @@ def create_tag(
|
|
|
172
194
|
env["GIT_AUTHOR_NAME"] = user_name
|
|
173
195
|
env["GIT_AUTHOR_EMAIL"] = user_email
|
|
174
196
|
env["GITHUB_TOKEN"] = github_token
|
|
197
|
+
|
|
175
198
|
message = f"Release: {tag} [skip ci]"
|
|
199
|
+
message += convert_commits_to_message(major_commits or [], minor_commits or [], patch_commits or [])
|
|
200
|
+
|
|
176
201
|
subprocess.run(["git", "add", "-A"], cwd=repository_path)
|
|
177
202
|
subprocess.run(["git", "commit", "-m", message], cwd=repository_path, env=env)
|
|
178
203
|
|
|
@@ -408,19 +433,19 @@ def bump(
|
|
|
408
433
|
if verbose:
|
|
409
434
|
print(f"Current version: {current_version[0]}.{current_version[1]}.{current_version[2]}")
|
|
410
435
|
|
|
411
|
-
|
|
412
|
-
if not len(
|
|
436
|
+
commits = get_commits_since_tag(repository_path, last_tag)
|
|
437
|
+
if not len(commits):
|
|
413
438
|
raise NoNewCommitsError(f"No new commits since the last {last_tag} tag")
|
|
414
439
|
|
|
415
440
|
if verbose:
|
|
416
|
-
print(f"? Commits since last tag: {len(
|
|
417
|
-
for hash, commit in
|
|
441
|
+
print(f"? Commits since last tag: {len(commits)}")
|
|
442
|
+
for hash, commit in commits:
|
|
418
443
|
print(f"# {hash}: {commit}")
|
|
419
444
|
|
|
420
|
-
major_commits, minor_commits, patch_commits = group_commits(
|
|
445
|
+
major_commits, minor_commits, patch_commits = group_commits(commits, major_verbs, minor_verbs, patch_verbs)
|
|
421
446
|
assert (
|
|
422
447
|
len(major_commits) + len(minor_commits) + len(patch_commits)
|
|
423
|
-
), "No commit categories found to bump the version: " + ", ".join(
|
|
448
|
+
), "No commit categories found to bump the version: " + ", ".join(map(lambda c: c[1], commits))
|
|
424
449
|
|
|
425
450
|
if len(major_commits):
|
|
426
451
|
bump_type = "major"
|
|
@@ -439,17 +464,14 @@ def bump(
|
|
|
439
464
|
if changelog_file:
|
|
440
465
|
now = datetime.now()
|
|
441
466
|
changes = f"\n## {now:%B %d, %Y}: v{new_version_str}\n"
|
|
442
|
-
|
|
443
|
-
changes += f"\n### Major\n\n" + "\n".join(f"- {c}" for c in major_commits) + "\n"
|
|
444
|
-
if len(minor_commits):
|
|
445
|
-
changes += f"\n### Minor\n\n" + "\n".join(f"- {c}" for c in minor_commits) + "\n"
|
|
446
|
-
if len(patch_commits):
|
|
447
|
-
changes += f"\n### Patch\n\n" + "\n".join(f"- {c}" for c in patch_commits) + "\n"
|
|
467
|
+
changes += convert_commits_to_message(major_commits, minor_commits, patch_commits)
|
|
448
468
|
|
|
449
469
|
print(f"Will update file: {changelog_file}")
|
|
450
470
|
if verbose:
|
|
451
471
|
changes_lines = changes.count("\n") + 1
|
|
452
472
|
print(f"? Appending {changes_lines} lines")
|
|
473
|
+
for line in changes.split("\n"):
|
|
474
|
+
print(f"+ {line}")
|
|
453
475
|
|
|
454
476
|
if not dry_run:
|
|
455
477
|
with open(changelog_file, "a") as file:
|
|
@@ -479,6 +501,9 @@ def bump(
|
|
|
479
501
|
github_repository=github_repository,
|
|
480
502
|
push=push,
|
|
481
503
|
create_release=create_release,
|
|
504
|
+
major_commits=major_commits,
|
|
505
|
+
minor_commits=minor_commits,
|
|
506
|
+
patch_commits=patch_commits,
|
|
482
507
|
)
|
|
483
508
|
|
|
484
509
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinysemver
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.8
|
|
4
4
|
Summary: Tiny Semantic Versioning (SemVer) library, that doesn't depend on 300K lines of JavaScript
|
|
5
5
|
Author-email: Ash Vardanian <1983160+ashvardanian@users.noreply.github.com>, Guillaume de Rouville <31691250+grouville@users.noreply.github.com>
|
|
6
6
|
License: Apache License
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|