Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs for Fall back to PEP 621 project.version #307

Merged
merged 10 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.9.6'
rev: 'v0.9.7'
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down Expand Up @@ -59,7 +59,7 @@ repos:
test.*
)$
- repo: https://github.com/jsh9/pydoclint
rev: 0.6.0
rev: 0.6.2
hooks:
- id: pydoclint
args:
Expand Down
12 changes: 10 additions & 2 deletions bumpversion/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from typing import TYPE_CHECKING, Any, Optional

from bumpversion.config.files import read_config_file
from bumpversion.config.files import get_pep621_info, read_config_file
from bumpversion.config.models import Config
from bumpversion.exceptions import ConfigurationError
from bumpversion.ui import get_indented_logger
Expand Down Expand Up @@ -32,6 +32,7 @@
"message": "Bump version: {current_version} → {new_version}",
"moveable_tags": [],
"commit_args": None,
"pep621_info": None,
"scm_info": None,
"parts": {},
"files": [],
Expand Down Expand Up @@ -84,6 +85,10 @@ def get_configuration(config_file: Optional[Pathlike] = None, **overrides: Any)
Config.model_rebuild()
config = Config(**config_dict) # type: ignore[arg-type]

# Get the PEP 621 project.version key from pyproject.toml, if possible
config.pep621_info = get_pep621_info(config_file)
logger.debug("config.pep621_info = %r", config.pep621_info)

# Get the information about the SCM
scm_info = SCMInfo(SCMConfig.from_config(config))
config.scm_info = scm_info
Expand Down Expand Up @@ -113,9 +118,12 @@ def check_current_version(config: Config) -> str:
ConfigurationError: If it can't find the current version
"""
current_version = config.current_version
pep621_info = config.pep621_info
scm_info = config.scm_info

if current_version is None and scm_info.current_version:
if current_version is None and pep621_info is not None and pep621_info.version:
return pep621_info.version
elif current_version is None and scm_info.current_version:
return scm_info.current_version
elif current_version and scm_info.current_version and current_version != scm_info.current_version:
logger.warning(
Expand Down
12 changes: 11 additions & 1 deletion bumpversion/config/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ def create_configuration(destination: str, prompt: bool) -> TOMLDocument:
if prompt:
allow_dirty_default = "(Y/n)" if config["allow_dirty"] else "(y/N)"
answers = questionary.form(
current_version=questionary.text("What is the current version?", default=config["current_version"]),
current_version=questionary.text(
"What is the current version?",
default=config["current_version"],
instruction=(
"If omitted, use the project.version key in pyproject.toml. "
"(Does not support dynamically set versions.)"
),
),
commit=questionary.confirm(
"Commit changes made when bumping to version control?", default=config["commit"]
),
Expand All @@ -45,6 +52,8 @@ def create_configuration(destination: str, prompt: bool) -> TOMLDocument:
config.update(answers)

for key, val in config.items():
if key == "current_version" and not val:
continue
destination_config["tool"]["bumpversion"][key] = val if val is not None else ""

return destination_config
Expand All @@ -71,6 +80,7 @@ def get_defaults_from_dest(destination: str) -> Tuple[dict, TOMLDocument]:
project_config = destination_config.get("project", {}).get("version")
config["current_version"] = config["current_version"] or project_config or "0.1.0"
del config["scm_info"]
del config["pep621_info"]
del config["parts"]
del config["files"]

Expand Down
62 changes: 61 additions & 1 deletion bumpversion/config/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import TYPE_CHECKING, Any, Dict, MutableMapping, Optional, Union

from bumpversion.config.files_legacy import read_ini_file
from bumpversion.config.models import PEP621Info
from bumpversion.ui import get_indented_logger, print_warning

if TYPE_CHECKING: # pragma: no-coverage
Expand All @@ -23,6 +24,42 @@
)


def get_pep621_info(config_file: Optional[Pathlike] = None) -> Optional[PEP621Info]:
"""Retrieve the PEP 621 `project` table.

At the moment, only the `project.version` key is handled. Additionally, if the
version is marked as dynamic, then it is explicitly returned as `None`.

Args:
config_file:
The configuration file to explicitly use. Per PEP 621, this file must be
named `pyproject.toml`.

Returns:
A `PEP621Info` structure, if given a `pyproject.toml` file to parse, else `None`.

"""
# We repeat the steps of read_config_file here, except hardcoded to TOML files, and
# without additional error reporting. Then we reimplement read_toml_file, but
# without limiting ourselves to the tool.bumpversion subtable.
if not config_file:
return None

config_path = Path(config_file)
if not config_path.exists():
return None

# PEP 621 explicitly requires pyproject.toml
if config_path.name != "pyproject.toml":
return None

import tomlkit

toml_data = tomlkit.parse(config_path.read_text(encoding="utf-8")).unwrap()
project = toml_data.get("project", {})
return PEP621Info(version=None if "version" in project.get("dynamic", []) else project.get("version"))


def find_config_file(explicit_file: Optional[Pathlike] = None) -> Union[Path, None]:
"""
Find the configuration file, if it exists.
Expand Down Expand Up @@ -139,7 +176,8 @@ def update_config_file(
logger.info("You must have a `.toml` suffix to update the config file: %s.", config_path)
return

# TODO: Eventually this should be transformed into another default "files_to_modify" entry
# TODO: Eventually this config (and datafile_config_pyprojecttoml below) should be
# transformed into another default "files_to_modify" entry
datafile_config = FileChange(
filename=str(config_path),
key_path="tool.bumpversion.current_version",
Expand All @@ -154,4 +192,26 @@ def update_config_file(

updater = DataFileUpdater(datafile_config, config.version_config.part_configs)
updater.update_file(current_version, new_version, context, dry_run)

# Keep PEP 621 `project.version` consistent with `tool.bumpversion.current_version`.
# (At least, if PEP 621 static `project.version` is in use at all.)
if (
config_path.name == "pyproject.toml"
and config.pep621_info is not None
and config.pep621_info.version is not None
):
datafile_config_pyprojecttoml = FileChange(
filename=str(config_path),
key_path="project.version",
search=config.search,
replace=config.replace,
regex=config.regex,
ignore_missing_version=True,
ignore_missing_file=True,
serialize=config.serialize,
parse=config.parse,
)
updater2 = DataFileUpdater(datafile_config_pyprojecttoml, config.version_config.part_configs)
updater2.update_file(current_version, new_version, context, dry_run)

logger.dedent()
9 changes: 9 additions & 0 deletions bumpversion/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import re
from collections import defaultdict
from dataclasses import dataclass
from itertools import chain
from typing import TYPE_CHECKING, Dict, List, MutableMapping, Optional, Tuple, Union

Expand Down Expand Up @@ -97,6 +98,7 @@ class Config(BaseSettings):
commit: bool
message: str
commit_args: Optional[str]
pep621_info: Optional[PEP621Info]
scm_info: Optional[SCMInfo]
parts: Dict[str, VersionComponentSpec]
moveable_tags: list[str] = Field(default_factory=list)
Expand Down Expand Up @@ -179,3 +181,10 @@ def version_spec(self, version: Optional[str] = None) -> "VersionSpec":
from bumpversion.versioning.models import VersionSpec

return VersionSpec(self.parts)


@dataclass
class PEP621Info:
"""PEP 621 info, in particular, the static version number."""

version: Optional[str]
Binary file added docs/assets/bump-my-version-logo.afdesign
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/assets/bump-my-version-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 23 additions & 1 deletion docs/assets/css/cards.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
.card-content-title {
margin-top: 0;
font-weight: 400;
font-size: 1.5rem;
font-size: 1.25rem;
line-height: 1.334;
letter-spacing: 0;
margin-bottom: 0.35em;
Expand Down Expand Up @@ -198,3 +198,25 @@
.card-divider hr {
margin: 0;
}

/*************
Cards - side icon
*/
.card-icon {
min-width: 1.2rem;
padding: 16px;
}
.card-icon .twemoji {
--md-icon-size: 3rem;

}

.card-icon p {
margin: 0;
}

.card-container.horizontal {
display: flex;
flex-direction: row;
/*align-items: center;*/
}
5 changes: 5 additions & 0 deletions docs/howtos/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- [Avoid incorrect replacements](avoid-incorrect-replacements.md)
- [Using Calendar Versioning (CalVer)](calver.md)
- [Custom version formats in different files](custom-version-formats-by-file.md)
- [Multiple replacements within the same file](multiple-replacements.md)
- [How to update a date in a file](update-a-date.md)
4 changes: 4 additions & 0 deletions docs/howtos/multiple-replacements.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ filename = "CHANGELOG.md"
search = "{current_version}...HEAD"
replace = "{current_version}...{new_version}"
```

??? note "Note: `project.version` in `pyproject.toml`"

This technique is **not** needed to keep `project.version` in `pyproject.toml` up-to-date if you are storing your Bump My Version configuration in `pyproject.toml` as well. Bump My Version will handle this case automatically.
62 changes: 39 additions & 23 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,45 @@ title: Bump My Version

# Bump My Version

Bump My Version's purpose is to:

- Work as a part of an automated build system
- Manage project versioning through the project's development life cycle
- Incrementing version numbers
- Serializing version numbers
- Parsing version numbers
- Support SemVer, CalVer, and other versioning schemes
- Modify project files as part of the project's development life cycle
- Work with the project's source control system
- Committing changes
- Tagging releases
- Reading version numbers from tags

## Installation

You can download and install the latest version of this software from the Python package index (PyPI) as follows:

```console
pip install --upgrade bump-my-version
```
<!--
## Bump My Version's purpose is to

::: grid wide-gap
::: card-container horizontal depth-0
::: card-icon
:fontawesome-solid-gear:
::: card-content
::: card-content-title
Work as a part of an automated build system.
Bump My Version works with automation workflows.

::: card-container horizontal depth-0
::: card-icon
:fontawesome-solid-magnifying-glass:
::: card-content
::: card-content-title
Search and replace data in project files
Update the version and metadata in your files when you increment your version.

::: card-container horizontal depth-0
::: card-icon
:fontawesome-solid-sliders:
::: card-content
::: card-content-title
Manage your project's versioning
- Increment and serialize version numbers
- Parsing version numbers
- Support SemVer, CalVer, and other versioning schemes

::: card-container horizontal depth-0
::: card-icon
:fontawesome-solid-code-commit:
::: card-content
::: card-content-title
Work with the project's source control system
- Committing changes
- Tagging releases
- Reading version numbers from tags

## Jump to section

::: grid wide-gap
Expand Down Expand Up @@ -82,4 +99,3 @@ pip install --upgrade bump-my-version
{ .card-content-title }

Want to understand the library better? Read our explanations behind the design.
-->
8 changes: 6 additions & 2 deletions docs/reference/configuration/global.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ If you have pre-commit hooks, add an option to turn off your pre-commit hooks. F
::: field-list

required
: **Yes**
: **Yes**

default
: `""`
Expand All @@ -94,7 +94,11 @@ If you have pre-commit hooks, add an option to turn off your pre-commit hooks. F
environment var
: `BUMPVERSION_CURRENT_VERSION`

The current version of the software package before bumping. A value for this is required.
The current version of the software package before bumping. A value for this is required, unless a fallback value is found.

!!! note

‡ If `pyproject.toml` exists, then `current_version` falls back to `project.version` in `pyproject.toml`. This only works if `project.version` is statically set.

## ignore_missing_files

Expand Down
14 changes: 12 additions & 2 deletions docs/tutorials/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

## Installation

You can download and install the latest version of this software from the Python package index (PyPI) as follows:
To install Bump My Version as an independent tool, use [uv](https://docs.astral.sh/uv/getting-started/installation/) to install it on your system.

```console
pip install --upgrade bump-my-version
uv tool install bump-my-version
```

## Create a default configuration
Expand Down Expand Up @@ -57,6 +57,16 @@ $ bump-my-version show-bump 1.2.3
╰─ patch ─ 1.2.4
```

## Get the new version in a script

If you want to get the new version within a script, you can use the [`show`](../../reference/cli/#bump-my-version-show) method.

```console title="Extract the new version"
$ bump-my-version show current_version
1.2.3
$ bump-my-version show --increment minor new_version
1.3.3
```

## Configure a file to modify when bumping

Expand Down
Loading
Loading