Skip to content

Commit fcd6dd1

Browse files
authored
Release v2.0.0
2 parents 5a9972c + 70c8393 commit fcd6dd1

22 files changed

+601
-326
lines changed

.bumper.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[tool.bumper]
2-
current_version = "1.0.0"
2+
current_version = "2.0.0"
3+
versioning_type = "semver"
34

45
[[tool.bumper.files]]
56
file = "./pyproject.toml"

.github/workflows/lint_test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ jobs:
1616
- uses: actions/checkout@v4
1717

1818
- name: Install uv
19-
uses: astral-sh/setup-uv@v5
19+
uses: astral-sh/setup-uv@v6
2020
with:
21-
version: "0.6.x"
21+
version: "0.7.x"
2222
enable-cache: true
2323
cache-dependency-glob: "uv.lock"
2424

@@ -45,9 +45,9 @@ jobs:
4545
- uses: actions/checkout@v4
4646

4747
- name: Install uv
48-
uses: astral-sh/setup-uv@v5
48+
uses: astral-sh/setup-uv@v6
4949
with:
50-
version: "0.6.x"
50+
version: "0.7.x"
5151
enable-cache: true
5252
cache-dependency-glob: "uv.lock"
5353

.github/workflows/pypi_release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jobs:
1919
- uses: actions/checkout@v4
2020

2121
- name: Install uv
22-
uses: astral-sh/setup-uv@v5
22+
uses: astral-sh/setup-uv@v6
2323
with:
24-
version: "0.6.x"
24+
version: "0.7.x"
2525
enable-cache: true
2626
cache-dependency-glob: "uv.lock"
2727

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ repos:
3535
- id: python-check-blanket-type-ignore
3636
- id: python-use-type-annotations
3737
- repo: https://github.com/astral-sh/ruff-pre-commit
38-
rev: v0.11.4
38+
rev: v0.11.8
3939
hooks:
4040
- id: ruff

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22
Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (`<major>`.`<minor>`.`<patch>`)
33

4+
## [v2.0.0]
5+
### Changed
6+
* #7 `versioning_type` is now a required configuration key for the `[tool.bumper]` table
7+
8+
### Added
9+
* #7 Add support for CalVer, specified as `<YYYY>.<0M>.<MICRO>`
10+
411
## [v1.0.0]
512
Initial release

README.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# bumper
2-
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sco1-bumper/1.0.0?logo=python&logoColor=FFD43B)](https://pypi.org/project/sco1-bumper/)
2+
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sco1-bumper/2.0.0?logo=python&logoColor=FFD43B)](https://pypi.org/project/sco1-bumper/)
33
[![PyPI](https://img.shields.io/pypi/v/sco1-bumper?logo=Python&logoColor=FFD43B)](https://pypi.org/project/sco1-bumper/)
44
[![PyPI - License](https://img.shields.io/pypi/l/sco1-bumper?color=magenta)](https://github.com/sco1/bumper/blob/main/LICENSE)
55
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sco1/bumper/main.svg)](https://results.pre-commit.ci/latest/github/sco1/bumper/main)
@@ -8,6 +8,12 @@ Automatically increment the project's version number.
88

99
Heavily inspired by [`bump2version`](https://github.com/c4urself/bump2version) and [`bumpversion`](https://github.com/peritus/bumpversion). While [`bump-my-version`](https://github.com/callowayproject/bump-my-version) is an excellent modern fork this functionality, I'd like a pared down version of the offered feature set for my personal projects.
1010

11+
## Supported Versioning Schemes
12+
* [Semantic Versioning (SemVer)](https://semver.org/#semantic-versioning-200)
13+
* Assumes `<MAJOR>.<MINOR>.<PATCH>`
14+
* [Calendar Versioning (CalVer)](https://calver.org/)
15+
* Assumes `<YYYY>.<0M>.<MICRO>`
16+
1117
## Installation
1218
Install from PyPi with your favorite `pip` invocation, e.g.:
1319

@@ -21,10 +27,10 @@ import cog
2127
from subprocess import PIPE, run
2228
out = run(["bumper", "--help"], stdout=PIPE, encoding="ascii")
2329
cog.out(
24-
f"```bash\n$ bumper --help\n{out.stdout.rstrip()}\n```"
30+
f"```\n$ bumper --help\n{out.stdout.rstrip()}\n```"
2531
)
2632
]]] -->
27-
```bash
33+
```
2834
$ bumper --help
2935
Usage: bumper [OPTIONS] COMMAND [ARGS]...
3036
@@ -42,7 +48,7 @@ Commands:
4248
### Required Fields
4349
#### `tool.bumper`
4450
* `current_version` - The current software version. This is automatically incremented when bumping.
45-
* **NOTE:** Only SemVer is supported
51+
* `versioning_type` - Versioning type to be used, accepted values are `"semver"` and `"calver"`
4652

4753
#### `tool.bumper.files`
4854
* `file` - Path to target file relative to the repository root
@@ -51,9 +57,22 @@ Commands:
5157
### Example Configuration
5258
The basic configuration looks something like the following:
5359

60+
#### SemVer
5461
```toml
5562
[tool.bumper]
5663
current_version = "0.1.0"
64+
versioning_type = "semver"
65+
66+
[[tool.bumper.files]]
67+
file = "./pyproject.toml"
68+
search = 'version = "{current_version}"'
69+
```
70+
71+
#### CalVer
72+
```toml
73+
[tool.bumper]
74+
current_version = "2025.01.0"
75+
versioning_type = "calver"
5776

5877
[[tool.bumper.files]]
5978
file = "./pyproject.toml"
@@ -65,6 +84,7 @@ Multiple replacements within the same file can also be specified:
6584
```toml
6685
[tool.bumper]
6786
current_version = "0.1.0"
87+
versioning_type = "semver"
6888

6989
[[tool.bumper.files]]
7090
file = "./pyproject.toml"
@@ -88,20 +108,29 @@ import cog
88108
from subprocess import PIPE, run
89109
out = run(["bumper", "bump", "--help"], stdout=PIPE, encoding="ascii")
90110
cog.out(
91-
f"```bash\n$ bumper bump --help\n{out.stdout.rstrip()}\n```"
111+
f"```\n$ bumper bump --help\n{out.stdout.rstrip()}\n```"
92112
)
93113
]]] -->
94-
```bash
114+
```
95115
$ bumper bump --help
96-
Usage: bumper bump [OPTIONS] BUMP_BY:{major|minor|patch}
116+
Usage: bumper bump [OPTIONS] BUMP_BY:{major|minor|patch|date}
97117
98118
Bump the requested version component.
99119
120+
Allowable `BUMP_BY` values differ based on the project's specified
121+
versioning type: SemVer - (major, minor, patch), CalVer - (date)
122+
123+
When using CalVer, if the user's current UTC month is the same as the
124+
current project version, then the Micro component is incremented. Otherwise,
125+
the date components are bumped to the user's current UTC month and Micro
126+
reset to `0`.
127+
100128
If `dry_run` is `True`, the requested diff will be displayed in the terminal
101129
& no file modifications will take place.
102130
103131
Arguments:
104-
BUMP_BY:{major|minor|patch} [required]
132+
BUMP_BY:{major|minor|patch|date}
133+
[required]
105134
106135
Options:
107136
--dry-run / --no-dry-run Preview the requested diff. [default: no-dry-run]
@@ -112,17 +141,17 @@ Options:
112141
### `bumper init`
113142
A small helper to initialize a starter `.bumper.toml` file that bumps the `version` field of your project's `pyproject.toml` file.
114143

115-
**NOTE:** This starter file is initialized at version `0.1.0`, so be sure to update this value with your current version number before using bumper.
144+
**NOTE:** Be sure to update the sample version with your current version number before bumping with bumper.
116145

117146
<!-- [[[cog
118147
import cog
119148
from subprocess import PIPE, run
120149
out = run(["bumper", "init", "--help"], stdout=PIPE, encoding="ascii")
121150
cog.out(
122-
f"```bash\n$ bumper init --help\n{out.stdout.rstrip()}\n```"
151+
f"```\n$ bumper init --help\n{out.stdout.rstrip()}\n```"
123152
)
124153
]]] -->
125-
```bash
154+
```
126155
$ bumper init --help
127156
Usage: bumper init [OPTIONS]
128157
@@ -133,6 +162,8 @@ Usage: bumper init [OPTIONS]
133162
configuration will be preserved.
134163
135164
Options:
165+
--versioning-type [semver|calver]
166+
[default: semver]
136167
--ignore-existing / --no-ignore-existing
137168
[default: no-ignore-existing]
138169
--help Show this message and exit.

bumper/bump.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import copy
2+
import datetime as dt
23
import difflib
34
from collections import defaultdict
45
from enum import StrEnum
@@ -10,19 +11,36 @@
1011

1112

1213
class BumpType(StrEnum): # noqa: D101
14+
# SemVer only
1315
MAJOR = "major"
1416
MINOR = "minor"
1517
PATCH = "patch"
1618

19+
# CalVer only
20+
DATE = "date"
21+
1722

1823
def _build_new_version(current_version: version.Version, bump_type: BumpType) -> version.Version:
19-
major, minor, patch = current_version.major, current_version.minor, current_version.micro
20-
if bump_type is BumpType.MAJOR:
21-
new_version = version.Version(f"{major+1}.0.0")
22-
elif bump_type is BumpType.MINOR:
23-
new_version = version.Version(f"{major}.{minor+1}.0")
24-
elif bump_type is BumpType.PATCH: # pragma: no branch
25-
new_version = version.Version(f"{major}.{minor}.{patch+1}")
24+
if bump_type == BumpType.DATE:
25+
utc_date = dt.datetime.now(dt.timezone.utc).date()
26+
version_year, version_month, version_micro = (
27+
current_version.major,
28+
current_version.minor,
29+
current_version.micro,
30+
)
31+
32+
if (version_year == utc_date.year) and (version_month == utc_date.month):
33+
new_version = version.Version(f"{version_year}.{version_month:02}.{version_micro+1}")
34+
else:
35+
new_version = version.Version(f"{utc_date.year}.{utc_date.month:02}.0")
36+
else:
37+
major, minor, patch = current_version.major, current_version.minor, current_version.micro
38+
if bump_type is BumpType.MAJOR:
39+
new_version = version.Version(f"{major+1}.0.0")
40+
elif bump_type is BumpType.MINOR:
41+
new_version = version.Version(f"{major}.{minor+1}.0")
42+
elif bump_type is BumpType.PATCH: # pragma: no branch
43+
new_version = version.Version(f"{major}.{minor}.{patch+1}")
2644

2745
return new_version
2846

@@ -42,10 +60,17 @@ def bump_ver(
4260
"""
4361
Bump the current version according to the provided rules in `files`.
4462
45-
**NOTE:** Ensure that the bumper configuration file is included in the rules passed to `files`.
46-
4763
If `dry_run` is `True`, files will not be modified and a per-file diff will be printed to the
4864
terminal instead.
65+
66+
If using CalVer (`bump_type` == `BumpType.DATE`), if the user's current UTC month is the same as
67+
the current project version, then the Micro component is incremented. Otherwise, the date
68+
components are bumped to the user's current UTC month and Micro reset to `0`.
69+
70+
NOTE: Ensure that the bumper configuration file is included in the rules passed to `files`.
71+
72+
NOTE: It is assumed that `bump_type` is appropriate for the project's configured versioning
73+
type.
4974
"""
5075
next_version = _build_new_version(current_version, bump_type)
5176
file_operations = _merge_bumpers(files) # Merge so we handle each file all at once

bumper/cli.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@
88
BumperConfigError,
99
BumperFile,
1010
ExistingConfigError,
11+
VersioningType,
1112
parse_config,
1213
write_default_config,
1314
)
1415

1516
bumper_cli = typer.Typer(add_completion=False)
1617

1718

18-
class ConfigNotFoundError(Exception): ... # noqa: D101
19-
20-
2119
def _abort_with_message(message: str, end: str = "\n") -> t.Never:
2220
print(message, end=end)
2321
raise typer.Abort()
@@ -31,35 +29,53 @@ def bump_ver_cmd(
3129
"""
3230
Bump the requested version component.
3331
32+
Allowable `BUMP_BY` values differ based on the project's specified versioning type: SemVer -
33+
(major, minor, patch), CalVer - (date)
34+
35+
When using CalVer, if the user's current UTC month is the same as the current project version,
36+
then the Micro component is incremented. Otherwise, the date components are bumped to the user's
37+
current UTC month and Micro reset to `0`.
38+
3439
If `dry_run` is `True`, the requested diff will be displayed in the terminal & no file
3540
modifications will take place.
3641
"""
3742
for cfg_path in CONFIG_PRIORITY:
3843
if cfg_path.exists():
3944
break
4045
else:
41-
raise ConfigNotFoundError("Configuration file could not be located.")
46+
_abort_with_message("Configuration file could not be located.")
4247

4348
try:
44-
current_version, files = parse_config(cfg_path)
49+
current_version, versioning_type, files = parse_config(cfg_path)
4550
except BumperConfigError as e:
4651
_abort_with_message(str(e))
4752

53+
# Check valid bump_by before we attempt to build a new version
54+
if versioning_type == VersioningType.SEMVER:
55+
if bump_by == BumpType.DATE:
56+
_abort_with_message("SemVer projects must bump by major, minor, or patch.")
57+
elif versioning_type == VersioningType.CALVER:
58+
if bump_by != BumpType.DATE:
59+
_abort_with_message("CalVer projects must bump by date.")
60+
4861
# Add in the bump configuration so it gets updated as well
4962
files.append(BumperFile(file=cfg_path, search='current_version = "{current_version}"'))
5063
bump_ver(current_version=current_version, files=files, bump_type=bump_by, dry_run=dry_run)
5164

5265

5366
@bumper_cli.command()
54-
def init(ignore_existing: bool = typer.Option(False)) -> None:
67+
def init(
68+
versioning_type: VersioningType = VersioningType.SEMVER,
69+
ignore_existing: bool = typer.Option(False),
70+
) -> None:
5571
"""
5672
Generate a default bumper configuration file.
5773
5874
If the `--ignore_existing` flag is set, any existing `.bumper.toml` file will be overwritten;
5975
this action is not reversible. Otherwise, the existing configuration will be preserved.
6076
"""
6177
try:
62-
write_default_config(ignore_existing)
78+
write_default_config(versioning_type=versioning_type, ignore_existing=ignore_existing)
6379
except ExistingConfigError as e:
6480
_abort_with_message(str(e))
6581

0 commit comments

Comments
 (0)