0
# Poetry Dynamic Versioning
1
2
A Poetry plugin that enables dynamic versioning based on version control system tags. It automatically injects version information from VCS tags (like Git tags) into relevant project files during Poetry commands such as build, eliminating the need to manually edit and commit version changes.
3
4
## Package Information
5
6
- **Package Name**: poetry-dynamic-versioning
7
- **Language**: Python
8
- **Installation**: `pip install "poetry-dynamic-versioning[plugin]"`
9
- **Requirements**: Python 3.7+, Poetry 1.2.0+
10
11
## Core Imports
12
13
```python
14
import poetry_dynamic_versioning
15
```
16
17
For programmatic usage (internal API functions):
18
19
```python
20
from poetry_dynamic_versioning import (
21
_get_version,
22
_get_and_apply_version,
23
_get_config_from_path,
24
_validate_config
25
)
26
```
27
28
Note: These are internal functions (prefixed with `_`) and may change between versions. They are documented here as they provide the core functionality for programmatic usage.
29
30
## Basic Usage
31
32
### As Poetry Plugin
33
34
Configure in `pyproject.toml`:
35
36
```toml
37
[tool.poetry-dynamic-versioning]
38
enable = true
39
40
[build-system]
41
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
42
build-backend = "poetry_dynamic_versioning.backend"
43
```
44
45
Enable via CLI:
46
47
```bash
48
# Install plugin
49
poetry self add "poetry-dynamic-versioning[plugin]"
50
51
# Enable in project
52
poetry dynamic-versioning enable
53
54
# Apply versioning manually
55
poetry dynamic-versioning
56
57
# Show current version
58
poetry dynamic-versioning show
59
```
60
61
### Programmatic Usage
62
63
```python
64
from poetry_dynamic_versioning import _get_version, _get_config_from_path
65
from pathlib import Path
66
67
# Get configuration for current project
68
config = _get_config_from_path()
69
70
# Get dynamic version
71
version_string, version_obj = _get_version(config)
72
print(f"Dynamic version: {version_string}")
73
74
# Apply version to project files
75
from poetry_dynamic_versioning import _get_and_apply_version
76
project_name = _get_and_apply_version(retain=True, force=True)
77
```
78
79
## Architecture
80
81
Poetry Dynamic Versioning operates through several key components:
82
83
- **Plugin System**: Integrates with Poetry via ApplicationPlugin to hook into Poetry commands
84
- **Build Backend**: Provides PEP 517 compliant build backend by wrapping poetry.core.masonry.api
85
- **Version Detection**: Uses Dunamai library to extract version information from VCS tags
86
- **File Substitution**: Automatically updates version placeholders in source files during builds
87
- **State Management**: Tracks and reverts changes to maintain repository cleanliness
88
89
The plugin supports both Classic Poetry mode (`[tool.poetry]`) and PEP 621 mode (`[project]`), automatically detecting the appropriate configuration format.
90
91
## Capabilities
92
93
### Configuration Management
94
95
Load, validate, and merge configuration from pyproject.toml with comprehensive validation and default value handling. Supports complex configuration hierarchies including substitution patterns, file-specific settings, and VCS options.
96
97
```python { .api }
98
def _get_config(local: Mapping) -> _Config: ...
99
def _get_config_from_path(start: Optional[Path] = None) -> Mapping: ...
100
def _validate_config(config: Optional[Mapping] = None) -> Sequence[str]: ...
101
def _default_config() -> Mapping: ...
102
```
103
104
[Configuration](./configuration.md)
105
106
### Version Detection and Processing
107
108
Extract version information from version control systems using Dunamai, with support for custom patterns, formatting, and override mechanisms. Handles Git, Mercurial, and other VCS systems with extensive customization options.
109
110
```python { .api }
111
def _get_version(config: _Config, name: Optional[str] = None) -> Tuple[str, Version]: ...
112
def _get_version_from_file(config: _Config) -> Optional[str]: ...
113
def _get_override_version(name: Optional[str], env: Optional[Mapping] = None) -> Optional[str]: ...
114
```
115
116
[Version Detection](./version-detection.md)
117
118
### File Management and Substitution
119
120
Apply dynamic versions to project files with automatic backup and restoration. Supports pattern-based substitution in multiple file types with configurable folder structures and file-specific behaviors.
121
122
```python { .api }
123
def _get_and_apply_version(
124
pyproject_path: Optional[Path] = None,
125
retain: bool = False,
126
force: bool = False,
127
io: bool = True
128
) -> Optional[str]: ...
129
def _apply_version(
130
name: str,
131
version: str,
132
instance: Version,
133
config: _Config,
134
pyproject_path: Path,
135
mode: _Mode,
136
retain: bool = False
137
) -> None: ...
138
def _revert_version(retain: bool = False) -> None: ...
139
```
140
141
[File Management](./file-management.md)
142
143
### Plugin Integration
144
145
Poetry plugin classes and command handlers that integrate dynamic versioning into Poetry's command lifecycle with event-driven activation and cleanup.
146
147
```python { .api }
148
class DynamicVersioningPlugin(ApplicationPlugin):
149
def activate(self, application: Application) -> None: ...
150
151
class DynamicVersioningCommand(Command):
152
def handle(self) -> int: ...
153
154
def activate() -> None: ...
155
def deactivate() -> None: ...
156
```
157
158
[Plugin System](./plugin-system.md)
159
160
### CLI Interface
161
162
Command-line interface for standalone usage with subcommands for enabling configuration, showing versions, and applying dynamic versioning outside of Poetry command contexts.
163
164
```python { .api }
165
def main() -> None: ...
166
def enable() -> None: ...
167
def show() -> None: ...
168
def apply(*, standalone: bool) -> None: ...
169
```
170
171
**Main Script Entry Point:**
172
173
```python { .api }
174
# From poetry_dynamic_versioning.__main__ module
175
def main() -> None:
176
"""
177
Main entry point for the poetry-dynamic-versioning console script.
178
179
Parses command-line arguments, sets CLI mode, and dispatches to
180
appropriate CLI functions. Handles exceptions and exits with
181
appropriate error codes.
182
183
Used when package is executed as: python -m poetry_dynamic_versioning
184
"""
185
```
186
187
[CLI Interface](./cli-interface.md)
188
189
### Build Backend Integration
190
191
PEP 517 build backend that wraps poetry-core's masonry API with automatic dynamic versioning activation and cleanup for seamless integration with build tools.
192
193
```python { .api }
194
# From poetry_dynamic_versioning.backend module
195
# Re-exports all poetry.core.masonry.api functionality with patching
196
197
def activate() -> None:
198
"""
199
Activate build backend patching system.
200
201
Automatically called when backend is loaded. Checks configuration,
202
applies patches if enabled, and registers cleanup handlers.
203
"""
204
205
def deactivate() -> None:
206
"""
207
Deactivate patches and restore original state.
208
209
Called automatically on exit to ensure repository cleanliness
210
after build operations complete.
211
"""
212
```
213
214
The backend module automatically re-exports all functions from `poetry.core.masonry.api` while adding dynamic versioning capabilities through the patch system.
215
216
### Utility Functions
217
218
Internal utility functions that provide debugging, command execution, and project file discovery capabilities for advanced programmatic usage.
219
220
```python { .api }
221
def _debug(message: str) -> None:
222
"""
223
Print debug message to stderr if debug mode is enabled.
224
225
Parameters:
226
- message: Debug message to print
227
228
Debug mode is controlled by POETRY_DYNAMIC_VERSIONING_DEBUG environment variable.
229
"""
230
231
def _run_cmd(command: str, codes: Sequence[int] = (0,)) -> Tuple[int, str]:
232
"""
233
Execute shell command and return result.
234
235
Parameters:
236
- command: Shell command to execute
237
- codes: Acceptable exit codes (defaults to [0])
238
239
Returns:
240
Tuple[int, str]: Exit code and combined stdout/stderr output
241
242
Raises:
243
- RuntimeError: If command exits with unacceptable code
244
"""
245
246
def _escape_branch(value: Optional[str]) -> Optional[str]:
247
"""
248
Escape branch name for safe usage in version strings.
249
250
Parameters:
251
- value: Branch name to escape
252
253
Returns:
254
Optional[str]: Escaped branch name with non-alphanumeric characters removed
255
"""
256
257
def _format_timestamp(value: Optional[dt.datetime]) -> Optional[str]:
258
"""
259
Format datetime as timestamp string.
260
261
Parameters:
262
- value: Datetime to format
263
264
Returns:
265
Optional[str]: Formatted timestamp string (YYYYMMDDHHMMSS)
266
"""
267
268
def _find_higher_file(*names: str, start: Optional[Path] = None) -> Optional[Path]:
269
"""
270
Find file in current directory or parent directories.
271
272
Parameters:
273
- names: File names to search for
274
- start: Starting directory (defaults to current directory)
275
276
Returns:
277
Optional[Path]: Path to first found file, or None if not found
278
"""
279
280
def _get_pyproject_path(start: Optional[Path] = None) -> Optional[Path]:
281
"""
282
Find pyproject.toml file in directory tree.
283
284
Parameters:
285
- start: Starting directory (defaults to current directory)
286
287
Returns:
288
Optional[Path]: Path to pyproject.toml file, or None if not found
289
"""
290
291
def _get_pyproject_path_from_poetry(pyproject) -> Path:
292
"""
293
Extract pyproject.toml path from Poetry instance.
294
295
Parameters:
296
- pyproject: Poetry pyproject instance
297
298
Returns:
299
Path: Path to pyproject.toml file
300
301
Raises:
302
- RuntimeError: Unable to determine path from Poetry instance
303
"""
304
```
305
306
## Types
307
308
```python { .api }
309
class _Mode(Enum):
310
Classic = "classic"
311
Pep621 = "pep621"
312
313
class _ProjectState:
314
def __init__(
315
self,
316
path: Path,
317
original_version: Optional[str],
318
version: str,
319
mode: _Mode,
320
dynamic_array: Optional[tomlkit.items.Array],
321
substitutions: Optional[MutableMapping[Path, str]] = None,
322
) -> None: ...
323
324
class _State:
325
def __init__(self) -> None: ...
326
patched_core_poetry_create: bool
327
cli_mode: bool
328
projects: MutableMapping[str, _ProjectState]
329
```
330
331
## Environment Variables
332
333
- `POETRY_DYNAMIC_VERSIONING_BYPASS`: Override version globally
334
- `POETRY_DYNAMIC_VERSIONING_OVERRIDE`: Override specific packages (format: `pkg1=0.1.0,pkg2=0.2.0`)
335
- `POETRY_DYNAMIC_VERSIONING_DEBUG`: Enable debug output (set to `1`)
336
- `POETRY_DYNAMIC_VERSIONING_COMMANDS`: Comma-separated list of Poetry commands to activate on
337
- `POETRY_DYNAMIC_VERSIONING_COMMANDS_NO_IO`: Commands that shouldn't modify files (default: `version`)