update defaults and tests

This commit is contained in:
Manuel Barkhau 2020-10-15 19:54:26 +00:00
parent 5f66a42c17
commit a3499c19a6
17 changed files with 400 additions and 306 deletions

328
README.md
View file

@ -5,9 +5,9 @@
</div>
# [PyCalVer: Automatic Calendar Versioning][url_repo]
# [Python CalVer: Automatic Calendar Versioning][url_repo]
PyCalVer is a CLI-tool to search and replace all version strings in your project files ([calver][url_calver_org], [semver][url_semver_org] or otherwise). PyCalVer has support for
Python CalVer provides the CLI command `calver`. You can use it to search and update version strings in your project files. It has a flexible pattern syntax to support many version string schemes ([calver][url_calver_org], [semver][url_semver_org] or otherwise). PyCalVer features:
- Configurable version patterns
- Git, Mercurial or no VCS
@ -22,7 +22,7 @@ Project/Repo:
[![MIT License][img_license]][url_license]
[![Supported Python Versions][img_pyversions]][url_pyversions]
[![PyCalVer v202010.1041-beta][img_version]][url_version]
[![CalVer v2020.1041-beta][img_version]][url_version]
[![PyPI Releases][img_pypi]][url_pypi]
[![PyPI Downloads][img_downloads]][url_downloads]
@ -62,7 +62,7 @@ Code Quality/CI:
[img_downloads]: https://pepy.tech/badge/pycalver/month
[url_downloads]: https://pepy.tech/project/pycalver
[img_version]: https://img.shields.io/static/v1.svg?label=PyCalVer&message=v202010.1041-beta&color=blue
[img_version]: https://img.shields.io/static/v1.svg?label=CalVer&message=v2020.1041-beta&color=blue
[url_version]: https://pypi.org/project/pycalver/
[img_pypi]: https://img.shields.io/badge/PyPI-wheels-green.svg
@ -72,8 +72,6 @@ Code Quality/CI:
[url_pyversions]: https://pypi.python.org/pypi/pycalver
[](TOC)
- [PyCalVer: Automatic Calendar Versioning](#pycalver-automatic-calendar-versioning)
@ -109,7 +107,7 @@ Code Quality/CI:
### Search and Replace
With PyCalVer, you only configure a single `version_pattern` which is then used
With `calver`, you configure a single `version_pattern` which is then used to
1. Search for version strings in your project files
2. Replace these occurrences with an updated/bumped version number.
@ -117,11 +115,11 @@ With PyCalVer, you only configure a single `version_pattern` which is then used
Your configuration might look something like this:
```
[pycalver]
current_version = "2020.9"
version_pattern = "YYYY.MM"
[calver]
current_version = "2020.9.0"
version_pattern = "YYYY.MM.PATCH"
[pycalver:file_patterns]
[calver:file_patterns]
src/mymodule/__init__.py
__version__ = "{version}"
src/mymodule/__main__.py
@ -130,22 +128,22 @@ setup.py
version="{version}",
```
> Throughout the examples, we use the `--date` argument. Without this argument PyCalVer will just use the current date. We use it here so that you can easily reproduce the examples.
> Throughout the examples, we use the `--date` argument. Without this argument `calver` will just use the current UTC date. We use it here so that you can easily reproduce the examples.
Using this configuration, the output of `pycalver bump --dry` might look something like this:
Using this configuration, the output of `calver bump --dry` might look something like this:
```diff
$ pycalver bump --date 2020-10-01 --dry
$ calver bump --date 2020-10-21 --dry
INFO - fetching tags from remote (to turn off use: -n / --no-fetch)
INFO - Old Version: 2020.9
INFO - New Version: 2020.10
INFO - Old Version: 2020.9.0
INFO - New Version: 2020.10.0
--- setup.py
+++ setup.py
@@ -63,7 +63,7 @@
setuptools.setup(
name="mymodule",
- version="2020.9",
+ version="2020.10",
- version="2020.9.0",
+ version="2020.10.0",
description=description,
long_description=long_description,
@ -153,8 +151,8 @@ INFO - New Version: 2020.10
+++ src/mymodule/__init__.py
@@ -3,3 +3,3 @@
-__version__ = "2020.9"
+__version__ = "2020.10"
-__version__ = "2020.9.0"
+__version__ = "2020.10.0"
--- src/mymodule/__main__.py
@ -162,8 +160,8 @@ INFO - New Version: 2020.10
@@ -101,7 +101,7 @@
@click.group()
-@click.version_option(version="2020.9")
+@click.version_option(version="2020.10")
-@click.version_option(version="2020.9.0")
+@click.version_option(version="2020.10.0")
@click.help_option()
@click.option('-v', '--verbose', count=True, help="Control log level. -vv for debug level.")
```
@ -182,22 +180,22 @@ If PyCalVer does not serve your purposes, you may wish to look at the [bump2vers
### Testing a version pattern
You can validate a pattern and how it is incremented using `pycalver test`.
You can validate a pattern and how it is incremented using `calver test`.
```shell
$ pycalver test --date 2018-09-22 '2018.37' 'YYYY.WW'
New Version: 2018.38
PEP440 : 2018.38
$ calver test --date 2020-09-22 '2020.37' 'YYYY.WW'
New Version: 2020.38
PEP440 : 2020.38
$ pycalver test --date 2018-09-22 '2018.37' 'YYYY.MM' # expected to fail
ERROR - Incomplete match '2018.3' for version string '2018.37' with pattern 'YYYY.MM'/'(?P<year_y>[1-9][0-9]{3})\.(?P<month>1[0-2]|[1-9])'
ERROR - Version did not change: '2018.37'. Invalid version and/or pattern 'YYYY.MM'.
$ calver test --date 2020-09-22 '2020.37' 'YYYY.MM' # expected to fail because 37 is not valid for part MM
ERROR - Incomplete match '2020.3' for version string '2020.37' with pattern 'YYYY.MM'/'(?P<year_y>[1-9][0-9]{3})\.(?P<month>1[0-2]|[1-9])'
ERROR - Invalid version '2020.37' and/or pattern 'YYYY.MM'.
```
This illustrates that each pattern is internally translated to a regular expression which must match your version string. The `--verbose` flag shows a slightly more readable form.
```shell
$ pycalver test --date 2018-09-22 'v2018.37' 'YYYY.WW' --verbose
$ calver test --date 2018-09-22 'v2018.37' 'YYYY.WW' --verbose
INFO - Using pattern YYYY.WW
INFO - regex = re.compile(r"""
(?P<year_y>[1-9][0-9]{3})
@ -215,30 +213,30 @@ In other words, you don't specify regular expressions manually, they are generat
You can do tradition SemVer without any kind of calendar component if you like.
```shell
$ pycalver test '1.2.3' 'MAJOR.MINOR.PATCH' --patch
$ calver test '1.2.3' 'MAJOR.MINOR.PATCH' --patch
New Version: 1.2.4
PEP440 : 1.2.4
$ pycalver test '1.2.3' 'MAJOR.MINOR.PATCH' --minor
$ calver test '1.2.3' 'MAJOR.MINOR.PATCH' --minor
New Version: 1.3.0
PEP440 : 1.3.0
$ pycalver test '1.2.3' 'MAJOR.MINOR.PATCH' --major
$ calver test '1.2.3' 'MAJOR.MINOR.PATCH' --major
New Version: 2.0.0
PEP440 : 2.0.0
```
These are the same CLI flags as are accepted by the `pycalver bump` command.
These are the same CLI flags as are accepted by the `calver bump` command.
In the context of a CalVer version, a typical use would be to include a `PATCH` part in your version pattern, so that you can create multiple releases in the same month.
```shell
$ pycalver test --date 2018-09-22 '2018.9.0' 'YYYY.MM.PATCH'
$ calver test --date 2018-09-22 '2018.9.0' 'YYYY.MM.PATCH'
ERROR - Invalid arguments or pattern, version did not change.
ERROR - Version did not change: '2018.9.0'. Invalid version and/or pattern 'YYYY.MM.PATCH'.
INFO - Perhaps try: pycalver test --patch
INFO - Perhaps try: calver test --patch
$ pycalver test --date 2018-09-22 '2018.9.0' 'YYYY.MM.PATCH' --patch
$ calver test --date 2018-09-22 '2018.9.0' 'YYYY.MM.PATCH' --patch
New Version: 2018.9.1
PEP440 : 2018.9.1
```
@ -246,7 +244,7 @@ PEP440 : 2018.9.1
The `PATCH` part will roll over back to zero when leading parts change (in this case the year and month).
```shell
$ pycalver test --date 2018-10-22 '2018.9.1' 'YYYY.MM.PATCH'
$ calver test --date 2018-10-22 '2018.9.1' 'YYYY.MM.PATCH'
New Version: 2018.10.0
PEP440 : 2018.10.0
```
@ -254,54 +252,55 @@ PEP440 : 2018.10.0
This will happen even if you use the `--patch` argument, so that your first release of the month has a `PATCH` of 0 instead of 1.
```shell
$ pycalver test --date 2018-10-22 '2018.9.1' 'YYYY.MM.PATCH' --patch
$ calver test --date 2018-10-22 '2018.9.1' 'YYYY.MM.PATCH' --patch
New Version: 2018.10.0
PEP440 : 2018.10.0
```
### Auto Incrementing Parts: `BUILD`/`INC0`/`INC1`
### Auto Increment Parts: `BUILD`/`INC0`/`INC1`
The following parts are incremented automatically, and do not use/require a CLI flag: `BUILD`/`INC0`/`INC1`. This means you can just do `pycalver bump` without any further CLI flags and special cases, which can simplify your build scripts.
The following parts are incremented automatically, and do not use/require a CLI flag: `BUILD`/`INC0`/`INC1`. This means you can just do `calver bump` without any further CLI flags and special cases, which can simplify your build scripts.
```shell
$ pycalver test --date 2018-09-22 '2018.9.1' 'YYYY.MM.INC0'
$ calver test --date 2018-09-22 '2018.9.1' 'YYYY.MM.INC0'
New Version: 2018.9.2
PEP440 : 2018.9.2
$ pycalver test --date 2018-10-22 '2018.9.2' 'YYYY.MM.INC0'
$ calver test --date 2018-10-22 '2018.9.2' 'YYYY.MM.INC0'
New Version: 2018.10.0
PEP440 : 2018.10.0
$ pycalver test --date 2018-10-22 '2018.9.2' 'YYYY.MM.INC1'
$ calver test --date 2018-10-22 '2018.9.2' 'YYYY.MM.INC1'
New Version: 2018.10.1
PEP440 : 2018.10.1
```
If it is rare for you to make multiple releases within a given period, you can make such a part optional using the `[PART]` syntax with square braces:
If it is rare for you to make multiple releases within a given period, you can make such a part optional using the `[PART]` syntax with square brackets:
```shell
$ pycalver test --date 2018-09-22 '2018.9' 'YYYY.MM[.INC0]'
$ calver test --date 2018-09-22 '2018.9' 'YYYY.MM[.INC0]'
New Version: 2018.9.1
PEP440 : 2018.9.1
$ pycalver test --date 2018-10-22 '2018.9.1' 'YYYY.MM[.INC0]'
$ calver test --date 2018-10-22 '2018.9.1' 'YYYY.MM[.INC0]'
New Version: 2018.10
PEP440 : 2018.10
```
If the extra `INC0` part is needed, it is added. If the date rolls over and it's no longer needed, it is omitted. Any literal text enclosed in the braces (such as a separator) will also be added or omitted as needed.
If the extra `INC0` part is needed, it is added. If the date rolls over and it's no longer needed, it is omitted. Any literal text enclosed in the brackets (such as a separator) will also be added or omitted as needed.
### Persistent Parts: `BUILD`/`RELEASE`/`PYTAG`
The `BUILD` and `RELEASE` parts are not reset. Instead they are carried forward.
```shell
$ pycalver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]'
$ calver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]'
New Version: 201809.1052-beta
PEP440 : 201809.1052b0
$ pycalver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]' --release rc
$ calver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]' --release rc
New Version: 201809.1052-rc
PEP440 : 201809.1052rc0
```
@ -309,17 +308,24 @@ PEP440 : 201809.1052rc0
To remove a release tag, mark it as final with `--release final`.
```shell
$ pycalver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]' --release final
$ calver test --date 2018-09-22 '201809.1051-beta' 'YYYY0M.BUILD[-RELEASE]' --release final
New Version: 201809.1052
PEP440 : 201809.1052
```
### Searching for Patterns with `grep`
Using `pycalver grep`, you can search for occurrences of a version pattern in your project files.
When searching for a pattern, There are some limitations to keep in mind:
1. A version string cannot span multiple lines.
2. There is no mechanism for escaping parts.
3. Brackets `[]` can be escaped with backslash.
Using `calver grep`, you can search for occurrences of a version pattern in your project files.
```shell
$ pycalver grep '__version__ = "YYYY.MM[-RELEASENUM]"' src/module/__init__.py
$ calver grep '__version__ = "YYYY.MM[-RELEASENUM]"' src/module/__init__.py
src/module/__init__.py
3:
4: __version__ = "2020.9-beta1"
@ -336,7 +342,7 @@ When you write your configuration, you can avoid repeating your version pattern
Applied to the above example, you can instead use this:
```shell
$ pycalver grep --version-pattern "YYYY.MM[-RELEASENUM]" '__version__ = "{version}"' src/module/__init__.py
$ calver grep --version-pattern "YYYY.MM[-RELEASENUM]" '__version__ = "{version}"' src/module/__init__.py
src/module/__init__.py
3:
4: __version__ = "2020.9-beta1"
@ -346,12 +352,12 @@ src/module/__init__.py
The corresponding configuration would look like this.
```ini
[pycalver]
[calver]
current_version = "2020.9-beta1"
version_pattern = "YYYY.MM[-RELEASENUM]"
...
[pycalver:file_patterns]
[calver:file_patterns]
src/module/__init__.py
__version__ = "{version}"
...
@ -360,7 +366,7 @@ src/module/__init__.py
If your pattern produces non PEP440 version numbers, you may wish to use the placeholder `{pep440_version}` in your search pattern and specify your `--version-pattern` separately.
```shell
$ pycalver grep --version-pattern "YYYY.MM[-RELEASENUM]" 'version="{pep440_version}"' setup.py
$ calver grep --version-pattern "YYYY.MM[-RELEASENUM]" 'version="{pep440_version}"' setup.py
setup.py
65: url="https://github.com/org/project",
66: version="2020.9b1",
@ -374,7 +380,7 @@ The placeholder `{version}` matches `2020.9-beta1`, while the placeholder `{pep4
As a further illustration of how the search and replace works, you might want use a file pattern entry to keep the year of your copyright header up to date.
```
$ python -m pycalver grep 'Copyright (c) 2018-YYYY' src/mymodule/*.py | head
$ calver grep 'Copyright (c) 2018-YYYY' src/mymodule/*.py | head
src/mymodule/__init__.py
3:
4: # Copyright (c) 2018-2020 Vandelay Industries - All rights reserved.
@ -389,7 +395,7 @@ src/mymodule/config.py
The corresponding configuration for this pattern would look like this.
```ini
[pycalver:file_patterns]
[calver:file_patterns]
...
src/mymodule/*.py
Copyright (c) 2018-YYYY Vandelay Industries - All rights reserved.
@ -400,11 +406,11 @@ src/mymodule/*.py
### Command Line
<!-- BEGIN pycalver --help -->
<!-- BEGIN calver --help -->
```
$ pycalver --help
Usage: pycalver [OPTIONS] COMMAND [ARGS]...
$ calver --help
Usage: calver [OPTIONS] COMMAND [ARGS]...
Automatically update PyCalVer version strings in all project files.
@ -416,18 +422,18 @@ Options:
Commands:
bump Increment the current version string and update project files.
grep Search file(s) for a version pattern.
init Initialize [pycalver] configuration.
init Initialize [calver] configuration.
show Show current version of your project.
test Increment a version number for demo purposes.
```
<!-- END pycalver --help -->
<!-- END calver --help -->
<!-- BEGIN pycalver bump --help -->
<!-- BEGIN calver bump --help -->
```
$ pycalver bump --help
Usage: pycalver bump [OPTIONS]
$ calver bump --help
Usage: calver bump [OPTIONS]
Increment the current version string and update project files.
@ -455,7 +461,7 @@ Options:
--help Show this message and exit.
```
<!-- END pycalver bump --help -->
<!-- END calver bump --help -->
### Part Overview
@ -464,21 +470,21 @@ Options:
[url_calver_org_scheme]: https://calver.org/#scheme
| part | range / example(s) | comment |
|-----------|---------------------------|--------------------------------------------|
| `YYYY` | 2019, 2020... | Full year, based on `strftime('%Y')` |
| `YY` | 18, 19..99, 0, 1 | Short year, based on `int(strftime('%y'))` |
| `MM` | 9, 10, 11, 12 | Month, based on `int(strftime('%m'))` |
| `DD` | 1, 2, 3..31 | Day, based on `int(strftime('%d'))` |
| `MAJOR` | 0..9, 10..99, 100.. | `pycalver bump --major` |
| `MINOR` | 0..9, 10..99, 100.. | `pycalver bump --minor` |
| `PATCH` | 0..9, 10..99, 100.. | `pycalver bump --patch` |
| `RELEASE` | alpha, beta, rc, post | `--release=<tag>` |
| `PYTAG` | a, b, rc, post | `--release=<tag>` |
| `NUM` | 0, 1, 2... | `-r/--release-num` |
| `BUILD` | 1001, 1002 .. 1999, 22000 | build number (maintains lexical order) |
| `INC0` | 0, 1, 2... | 0-based auto incrementing number |
| `INC1` | 1, 2... | 1-based auto incrementing number |
| part | range / example(s) | comment |
|---------|---------------------------|--------------------------------------------|
| `YYYY` | 2019, 2020... | Full year, based on `strftime('%Y')` |
| `YY` | 18, 19..99, 0, 1 | Short year, based on `int(strftime('%y'))` |
| `MM` | 9, 10, 11, 12 | Month, based on `int(strftime('%m'))` |
| `DD` | 1, 2, 3..31 | Day, based on `int(strftime('%d'))` |
| `MAJOR` | 0..9, 10..99, 100.. | `calver bump --major` |
| `MINOR` | 0..9, 10..99, 100.. | `calver bump --minor` |
| `PATCH` | 0..9, 10..99, 100.. | `calver bump --patch` |
| `TAG` | alpha, beta, rc, post | `--tag=<tag>` |
| `PYTAG` | a, b, rc, post | `--tag=<tag>` |
| `NUM` | 0, 1, 2... | `-r/--release-num` |
| `BUILD` | 1001, 1002 .. 1999, 22000 | build number (maintains lexical order) |
| `INC0` | 0, 1, 2... | 0-based auto incrementing number |
| `INC1` | 1, 2... | 1-based auto incrementing number |
The following are also available, but you should review the [Normalization Caveats](#normalization-caveats) before you decide to use them.
@ -565,7 +571,7 @@ If you wish to avoid this, you should use a pattern which maintains lexicographi
<!-- END pattern_examples -->
- ¹ If `PATCH > 9`
- ² For `2100` YY produces `00`...
- ² For the year 2100, the part `YY` will produce 0
### Week Numbering
@ -603,20 +609,22 @@ number would run backwards if it was created around New Year.
## Configuration
The fastest way to setup the configuration for project is to use `pycalver init`.
### Configuration Setup
The fastest way to setup the configuration for project is to use `calver init`.
```shell
$ pip install pycalver
$ pip install python-calver
...
Installing collected packages: click pathlib2 typing toml pycalver
Successfully installed pycalver-202010.1041b0
Installing collected packages: click lexid pathlib2 typing toml python-calver
Successfully installed python-calver-2020.1041b0
$ cd myproject
~/myproject/
$ pycalver init --dry
Exiting because of '-d/--dry'. Would have written to pycalver.toml:
$ calver init --dry
Exiting because of '-d/--dry'. Would have written to calver.toml:
[pycalver]
[calver]
current_version = "v202010.1001-alpha"
version_pattern = "vYYYY0M.BUILD[-RELEASE]"
commit_message = "bump version to {new_version}"
@ -624,41 +632,39 @@ Exiting because of '-d/--dry'. Would have written to pycalver.toml:
tag = true
push = true
[pycalver.file_patterns]
[calver.file_patterns]
"README.md" = [
"{version}",
"{pep440_version}",
]
"pycalver.toml" = [
"calver.toml" = [
'current_version = "{version}"',
]
```
If you already have configuration file in your project (such as a `setup.cfg` file), then `pycalver init` will update that file instead.
If you already have configuration file in your project (such as a `setup.cfg` file), then `calver init` will update that file instead.
```
~/myproject
$ pycalver init
$ calver init
Updated setup.cfg
```
Your `setup.cfg` may now look something like this:
```ini
# setup.cfg
[pycalver]
current_version = "v201902.1001-alpha"
version_pattern = "vYYYY0M.BUILD[-RELEASE]"
[calver]
current_version = "2019.1001-alpha"
version_pattern = "YYYY.BUILD[-RELEASE]"
commit_message = "bump version to {new_version}"
commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
setup.cfg =
current_version = "{version}"
setup.py =
"{version}",
"{pep440_version}",
README.md =
{version}
@ -749,28 +755,28 @@ INFO - New Version: v201902.1002-beta
@@ -11,7 +11,7 @@
[![Supported Python Versions][pyversions_img]][pyversions_ref]
-[![Version v201901.1001-beta][version_img]][version_ref]
+[![Version v201902.1002-beta][version_img]][version_ref]
-[![Version 2019.1001-beta][version_img]][version_ref]
+[![Version 2019.1002-beta][version_img]][version_ref]
[![PyPI Releases][pypi_img]][pypi_ref]
--- src/mymodule_v1/__init__.py
+++ src/mymodule_v1/__init__.py
@@ -1,1 +1,1 @@
-__version__ = "v201901.1001-beta"
+__version__ = "v201902.1002-beta"
-__version__ = "2019.1001-beta"
+__version__ = "2019.1002-beta"
--- src/mymodule_v2/__init__.py
+++ src/mymodule_v2/__init__.py
@@ -1,1 +1,1 @@
-__version__ = "v201901.1001-beta"
+__version__ = "v201902.1002-beta"
-__version__ = "2019.1001-beta"
+__version__ = "2019.1002-beta"
--- setup.py
+++ setup.py
@@ -44,7 +44,7 @@
name="myproject",
- version="201901.1001b0",
+ version="201902.1002b0",
- version="2019.1001b0",
+ version="2019.1002b0",
license="MIT",
```
@ -1022,26 +1028,25 @@ The PyCalVer format for version strings has three parts:
```
o Year and Month of Release
| o Sequential Build Number
| | o Release Tag (optional)
| | |
---+--- --+-- --+--
v202010 .1001 -beta
o Year of Release
| o Sequential Build Number
| | o Release Tag (optional)
| | |
--+-- --+-- --+--
v2020 .1001 -beta
```
Some examples:
```
v201711.0001-alpha
v201712.0027-beta
v201801.0031
v201801.0032-post
2017.1001-alpha
2017.1027-beta
2018.1031
2018.1032-post
...
v202207.18133
v202207.18134
2022.28133
2022.28134
```
This format was chosen in part to be distinctive from
@ -1071,14 +1076,13 @@ These version strings can be parsed with the following regular expression:
```python
import re
# https://regex101.com/r/fnj60p/10
# https://regex101.com/r/fnj60p/14
PYCALVER_PATTERN = r"""
\b
(?P<pycalver>
(?P<vYYYY0M>
(?P<vYYYY>
v # "v" version prefix
(?P<year>\d{4})
(?P<month>\d{2})
)
(?P<build>
\. # "." build nr prefix
@ -1092,30 +1096,28 @@ PYCALVER_PATTERN = r"""
"""
PYCALVER_REGEX = re.compile(PYCALVER_PATTERN, flags=re.VERBOSE)
version_str = "v201712.0001-alpha"
version_str = "v2017.1001-alpha"
version_match = PYCALVER_REGEX.match(version_str)
assert version_match.groupdict() == {
"pycalver" : "v201712.0001-alpha",
"vYYYY0M" : "v201712",
"pycalver" : "v2017.1001-alpha",
"vYYYY0M" : "v2017",
"year" : "2017",
"month" : "12",
"build" : ".0001",
"build_no" : "0001",
"build" : ".1001",
"build_no" : "1001",
"release" : "-alpha",
"release_tag": "alpha",
}
version_str = "v201712.0033"
version_str = "v201712.1033"
version_match = PYCALVER_REGEX.match(version_str)
assert version_match.groupdict() == {
"pycalver" : "v201712.0033",
"vYYYY0M" : "v201712",
"pycalver" : "v2017.1033",
"vYYYY" : "v2017",
"year" : "2017",
"month" : "12",
"build" : ".0033",
"build_no" : "0033",
"build" : ".1033",
"build_no" : "1033",
"release" : None,
"release_tag": None,
}
@ -1124,12 +1126,12 @@ assert version_match.groupdict() == {
### Incrementing Behaviour
To see how version strings are incremented, we can use
`pycalver test`:
`calver test`:
```shell
$ pycalver test v201801.1033-beta
New Version: v201902.1034-beta
PEP440 : 201902.1034b0
$ calver test v2018.1033-beta
New Version: v2019.1034-beta
PEP440 : 2019.1034b0
```
This is the simple case:
@ -1141,13 +1143,13 @@ This is the simple case:
You can explicitly update the release tag by using the `--release=<tag>` argument:
```shell
$ pycalver test v201801.1033-alpha --release=beta
New Version: v201902.1034-beta
PEP440 : 201902.1034b0
$ calver test v2018.1033-alpha --release=beta
New Version: v2019.1034-beta
PEP440 : 2019.1034b0
$ pycalver test v201902.1034-beta --release=final
New Version: v201902.1035
PEP440 : 201902.1035
$ calver test v2019.1034-beta --release=final
New Version: v2019.1035
PEP440 : 2019.1035
```
To maintain lexical ordering of version numbers, the version number is padded with extra zeros using [Lexical Ids][url_pypi_lexid].
@ -1326,20 +1328,20 @@ package which included the bug, they only have to do `pip install --upgrade
Perhaps a timeline will illustrate more clearly:
```
v202008.1665 # last stable release
v202008.1666-beta # pre release for testers
v201901.1667 # final release after testing
v2020.1665 # last stable release
v2020.1666-beta # pre release for testers
v2019.1667 # final release after testing
# bug is discovered which effects v202008.1666-beta and v201901.1667
# bug is discovered which effects v2020.1666-beta and v2019.1667
v201901.1668-beta # fix is issued for testers
v201901.1669 # fix is issued everybody
v2019.1668-beta # fix is issued for testers
v2019.1669 # fix is issued everybody
# Alternatively, revert before fixing
v201901.1668 # same as v202008.1665
v201901.1669-beta # reintroduce change from v202008.1666-beta + fix
v201901.1670 # final release after testing
v2019.1668 # same as v2020.1665
v2019.1669-beta # reintroduce change from v2020.1666-beta + fix
v2019.1670 # final release after testing
```
In the absolute worst case, a change is discovered to break backward
@ -1362,18 +1364,18 @@ package will perhaps have 99% overlap to the previous one and the old one
may eventually be abandoned.
```
mypkg v202008.1665 # last stable release
mypkg v202008.1666-rc # pre release for testers
mypkg v201901.1667 # final release after testing period
mypkg v2020.1665 # last stable release
mypkg v2020.1666-rc # pre release for testers
mypkg v2019.1667 # final release after testing period
# bug is discovered in v202008.1666-beta and v201901.1667
# bug is discovered in v2020.1666-beta and v2019.1667
mypkg v201901.1668 # same as v202008.1665
mypkg v2019.1668 # same as v2020.1665
# new package is created with compatibility breaking code
mypkg2 v201901.1669 # same as v201901.1667
mypkg v201901.1669 # updated readme, declaring support
mypkg2 v2019.1669 # same as v2019.1667
mypkg v2019.1669 # updated readme, declaring support
# level for mypkg, pointing to mypgk2
# and documenting how to upgrade.
```

View file

@ -184,8 +184,8 @@ def pattern_examples():
old_content = io.open("README.md").read()
new_content = old_content
new_content = update_md_code_output(new_content, "pycalver --help")
new_content = update_md_code_output(new_content, "pycalver bump --help")
new_content = update_md_code_output(new_content, "calver --help")
new_content = update_md_code_output(new_content, "calver bump --help")
new_content = update(new_content, "pattern_examples", pattern_examples())
new_content = update(new_content, "weeknum_example" , weeknum_example())
@ -199,8 +199,8 @@ else:
fobj.write(new_content)
# @printf '\n```\n$$ pycalver --help\n' > /tmp/pycalver_help.txt
# @$(DEV_ENV)/bin/pycalver --help >> /tmp/pycalver_help.txt
# @printf '\n```\n$$ calver --help\n' > /tmp/pycalver_help.txt
# @$(DEV_ENV)/bin/calver --help >> /tmp/pycalver_help.txt
# @printf '```\n\n' >> /tmp/pycalver_help.txt
# sed -i -ne '/<!-- BEGIN pycalver --help -->/ {p; r /tmp/pycalver_help.txt' \

View file

@ -88,7 +88,7 @@ exclude =
addopts = --doctest-modules
[pycalver]
[calver]
current_version = "v2020.1041-beta"
version_pattern = "vYYYY.BUILD[-TAG]"
commit_message = "bump {old_version} -> {new_version}"
@ -96,7 +96,7 @@ commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
bootstrapit.sh =
PACKAGE_VERSION="{version}"
setup.cfg =
@ -114,9 +114,9 @@ LICENSE =
license.header =
Copyright (c) 2018-YYYY
README.md =
\[PyCalVer {version}\]
img.shields.io/static/v1.svg?label=PyCalVer&message={version}&color=blue
Successfully installed pycalver-{pep440_version}
\[CalVer {version}\]
img.shields.io/static/v1.svg?label=CalVer&message={version}&color=blue
Successfully installed python-calver-{pep440_version}
[tool:pylint]

View file

@ -58,7 +58,7 @@ if any(arg.startswith("bdist") for arg in sys.argv):
setuptools.setup(
name="pycalver2",
name="python-calver",
license="MIT",
author="Manuel Barkhau",
author_email="mbarkhau@gmail.com",

View file

@ -539,7 +539,7 @@ def _try_bump(
'-d', "--dry", default=False, is_flag=True, help="Display diff of changes, don't rewrite files."
)
def init(verbose: int = 0, dry: bool = False) -> None:
"""Initialize [pycalver] configuration."""
"""Initialize [calver] configuration."""
_configure_logging(verbose=max(_VERBOSE, verbose))
ctx, cfg = config.init(project_path=".", cfg_missing_ok=True)

View file

@ -32,7 +32,7 @@ PatternsByFile = typ.Dict[str, typ.List[Pattern]]
FilePatternsItem = typ.Tuple[str, typ.List[Pattern]]
SUPPORTED_CONFIGS = ["setup.cfg", "pyproject.toml", "pycalver.toml"]
SUPPORTED_CONFIGS = ["setup.cfg", "pyproject.toml", "pycalver.toml", "calver.toml"]
DEFAULT_COMMIT_MESSAGE = "bump version to {new_version}"
@ -47,6 +47,33 @@ class ProjectContext(typ.NamedTuple):
vcs_type : typ.Optional[str]
def _parse_config_and_format(path: pl.Path) -> typ.Tuple[pl.Path, str, str]:
if (path / "pycalver.toml").exists():
config_filepath = path / "pycalver.toml"
config_format = 'toml'
elif (path / "calver.toml").exists():
config_filepath = path / "calver.toml"
config_format = 'toml'
elif (path / "pyproject.toml").exists():
config_filepath = path / "pyproject.toml"
config_format = 'toml'
elif (path / "setup.cfg").exists():
config_filepath = path / "setup.cfg"
config_format = 'cfg'
else:
# fallback to creating a new calver.toml
config_filepath = path / "calver.toml"
config_format = 'toml'
if config_filepath.is_absolute():
config_rel_path = str(config_filepath.relative_to(path.absolute()))
else:
config_rel_path = str(config_filepath)
config_filepath = pl.Path.cwd() / config_filepath
return (config_filepath, config_rel_path, config_format)
def init_project_ctx(project_path: typ.Union[str, pl.Path, None] = ".") -> ProjectContext:
"""Initialize ProjectContext from a path."""
if isinstance(project_path, pl.Path):
@ -57,25 +84,7 @@ def init_project_ctx(project_path: typ.Union[str, pl.Path, None] = ".") -> Proje
# assume it's a str/unicode
path = pl.Path(project_path)
if (path / "pycalver.toml").exists():
config_filepath = path / "pycalver.toml"
config_format = 'toml'
elif (path / "pyproject.toml").exists():
config_filepath = path / "pyproject.toml"
config_format = 'toml'
elif (path / "setup.cfg").exists():
config_filepath = path / "setup.cfg"
config_format = 'cfg'
else:
# fallback to creating a new pycalver.toml
config_filepath = path / "pycalver.toml"
config_format = 'toml'
if config_filepath.is_absolute():
config_rel_path = str(config_filepath.relative_to(path.absolute()))
else:
config_rel_path = str(config_filepath)
config_filepath = pl.Path.cwd() / config_filepath
config_filepath, config_rel_path, config_format = _parse_config_and_format(path)
vcs_type: typ.Optional[str]
@ -137,10 +146,14 @@ def _debug_str(cfg: Config) -> str:
def _parse_cfg_file_patterns(
cfg_parser: configparser.RawConfigParser,
) -> typ.Iterable[FileRawPatternsItem]:
if not cfg_parser.has_section("pycalver:file_patterns"):
return
file_pattern_items: typ.List[typ.Tuple[str, str]]
file_pattern_items: typ.List[typ.Tuple[str, str]] = cfg_parser.items("pycalver:file_patterns")
if cfg_parser.has_section("pycalver:file_patterns"):
file_pattern_items = cfg_parser.items("pycalver:file_patterns")
elif cfg_parser.has_section("calver:file_patterns"):
file_pattern_items = cfg_parser.items("calver:file_patterns")
else:
return
for filepath, patterns_str in file_pattern_items:
maybe_patterns = (line.strip() for line in patterns_str.splitlines())
@ -175,10 +188,13 @@ def _parse_cfg(cfg_buffer: typ.IO[str]) -> RawConfig:
else:
cfg_parser.readfp(cfg_buffer) # python2 compat
if not cfg_parser.has_section("pycalver"):
raise ValueError("Missing [pycalver] section.")
raw_cfg: RawConfig = dict(cfg_parser.items("pycalver"))
raw_cfg: RawConfig
if cfg_parser.has_section("pycalver"):
raw_cfg = dict(cfg_parser.items("pycalver"))
elif cfg_parser.has_section("calver"):
raw_cfg = dict(cfg_parser.items("calver"))
else:
raise ValueError("Missing [calver] section.")
for option, default_val in BOOL_OPTIONS.items():
val: OptionVal = raw_cfg.get(option, default_val)
@ -194,8 +210,15 @@ def _parse_cfg(cfg_buffer: typ.IO[str]) -> RawConfig:
def _parse_toml(cfg_buffer: typ.IO[str]) -> RawConfig:
raw_full_cfg: typ.Any = toml.load(cfg_buffer)
raw_cfg : RawConfig = raw_full_cfg.get('pycalver', {})
raw_full_cfg: typ.Any = toml.load(cfg_buffer)
raw_cfg : RawConfig
if 'pycalver' in raw_full_cfg:
raw_cfg = raw_full_cfg['pycalver']
elif 'calver' in raw_full_cfg:
raw_cfg = raw_full_cfg['calver']
else:
raw_cfg = {}
for option, default_val in BOOL_OPTIONS.items():
raw_cfg[option] = raw_cfg.get(option, default_val)
@ -284,7 +307,7 @@ def _validate_version_with_pattern(
if invalid_chars:
errmsg = (
f"Invalid character(s) '{invalid_chars.group(1)}'"
f' in pycalver.version_pattern = "{version_pattern}"'
f' in version_pattern = "{version_pattern}"'
)
raise ValueError(errmsg)
if not v2version.is_valid_week_pattern(version_pattern):
@ -321,10 +344,10 @@ def _parse_config(raw_cfg: RawConfig) -> Config:
push = raw_cfg['push'] = False
if tag and not commit:
raise ValueError("pycalver.commit = true required if pycalver.tag = true")
raise ValueError("commit=True required if tag=True")
if push and not commit:
raise ValueError("pycalver.commit = true required if pycalver.push = true")
raise ValueError("commit=True required if push=True")
cfg = Config(
current_version=current_version,
@ -351,26 +374,26 @@ def _parse_current_version_default_pattern(raw_cfg: RawConfig, raw_cfg_text: str
if line.strip() == "[pycalver]":
is_pycalver_section = True
elif line.strip() == "[calver]":
is_pycalver_section = True
elif line and line[0] == "[" and line[-1] == "]":
is_pycalver_section = False
raise ValueError("Could not parse pycalver.current_version")
raise ValueError("Could not parse 'current_version'")
def _set_raw_config_defaults(raw_cfg: RawConfig) -> None:
if 'current_version' in raw_cfg:
if not isinstance(raw_cfg['current_version'], str):
err = f"Invalid type for pycalver.current_version = {raw_cfg['current_version']}"
raise TypeError(err)
else:
raise ValueError("Missing 'pycalver.current_version'")
if 'version_pattern' not in raw_cfg:
raise TypeError("Missing version_pattern")
elif not isinstance(raw_cfg['version_pattern'], str):
err = f"Invalid type for version_pattern = {raw_cfg['version_pattern']}"
raise TypeError(err)
if 'version_pattern' in raw_cfg:
if not isinstance(raw_cfg['version_pattern'], str):
err = f"Invalid type for pycalver.version_pattern = {raw_cfg['version_pattern']}"
raise TypeError(err)
else:
raw_cfg['version_pattern'] = "{pycalver}"
if 'current_version' not in raw_cfg:
raise ValueError("Missing 'current_version' configuration")
elif not isinstance(raw_cfg['current_version'], str):
err = f"Invalid type for current_version = {raw_cfg['current_version']}"
raise TypeError(err)
if 'file_patterns' not in raw_cfg:
raw_cfg['file_patterns'] = {}
@ -426,7 +449,7 @@ def init(
DEFAULT_CONFIGPARSER_BASE_TMPL = """
[pycalver]
[calver]
current_version = "{initial_version}"
version_pattern = "vYYYY.BUILD[-TAG]"
commit_message = "bump version {{old_version}} -> {{new_version}}"
@ -434,7 +457,7 @@ commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
""".lstrip()
@ -466,7 +489,7 @@ README.md =
DEFAULT_TOML_BASE_TMPL = """
[pycalver]
[calver]
current_version = "{initial_version}"
version_pattern = "vYYYY.BUILD[-TAG]"
commit_message = "bump version {{old_version}} -> {{new_version}}"
@ -474,7 +497,7 @@ commit = true
tag = true
push = true
[pycalver.file_patterns]
[calver.file_patterns]
""".lstrip()
@ -485,6 +508,13 @@ DEFAULT_TOML_PYCALVER_STR = """
""".lstrip()
DEFAULT_TOML_CALVER_STR = """
"calver.toml" = [
'current_version = "{version}"',
]
""".lstrip()
DEFAULT_TOML_PYPROJECT_STR = """
"pyproject.toml" = [
'current_version = "{version}"',
@ -542,6 +572,7 @@ def default_config(ctx: ProjectContext) -> str:
default_pattern_strs_by_filename = {
"pyproject.toml": DEFAULT_TOML_PYPROJECT_STR,
"pycalver.toml" : DEFAULT_TOML_PYCALVER_STR,
"calver.toml" : DEFAULT_TOML_CALVER_STR,
"setup.py" : DEFAULT_TOML_SETUP_PY_STR,
"README.rst" : DEFAULT_TOML_README_RST_STR,
"README.md" : DEFAULT_TOML_README_MD_STR,
@ -561,7 +592,7 @@ def default_config(ctx: ProjectContext) -> str:
if ctx.config_format == 'cfg':
cfg_str += DEFAULT_CONFIGPARSER_SETUP_CFG_STR
if ctx.config_format == 'toml':
cfg_str += DEFAULT_TOML_PYCALVER_STR
cfg_str += DEFAULT_TOML_CALVER_STR
cfg_str += "\n"

View file

@ -4,9 +4,10 @@
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
# SPDX-License-Identifier: MIT
#
# pycalver/vcs.py (this file) is based on code from the
# pycalver2/vcs.py (this file) is based on code from the
# bumpversion project: https://github.com/peritus/bumpversion
# Copyright (c) 2013-2014 Filip Noetzel - MIT License
"""Minimal Git and Mercirial API.
If terminology for similar concepts differs between git and

View file

@ -1,3 +1,3 @@
# PyCalVer README Fixture
# Python CalVer README Fixture
Current Version: v2016.0123-alpha

View file

@ -1,12 +1,12 @@
[pycalver]
[calver]
current_version = "v2017.0123-alpha"
version_pattern = "vYYYY.BUILD[-TAG]"
commit = true
tag = true
push = true
[pycalver.file_patterns]
"pycalver.toml" = [
[calver.file_patterns]
"calver.toml" = [
'current_version = "{version}"',
]

View file

@ -1,11 +1,11 @@
[pycalver]
[calver]
current_version = v201307.0456-beta
version_pattern = {pycalver}
commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
setup.cfg =
current_version = {version}
setup.py =

View file

@ -1,3 +1,8 @@
import setuptools
setuptools.setup(name="mylib", license="MIT", version="201307.456b0", keywords="awesome library")
setuptools.setup(
name="mylib",
license="MIT",
version="201307.456b0",
keywords="awesome library",
)

View file

@ -1,4 +1,4 @@
[pycalver]
[calver]
current_version = "v2017q1.54321"
version_pattern = "v{year}q{quarter}.{build_no}"
commit = true

View file

@ -1,4 +1,4 @@
[pycalver]
[calver]
current_version = "v2017q1.54321"
version_pattern = "vYYYYqQ.BUILD"
commit = true

View file

@ -42,7 +42,7 @@ license_file = LICENSE
universal = 1
"""
PYCALVER_TOML_FIXTURE = """
CALVER_TOML_FIXTURE = """
"""
PYPROJECT_TOML_FIXTURE = """
@ -51,11 +51,11 @@ requires = ["setuptools", "wheel"]
"""
ENV = {
'GIT_AUTHOR_NAME' : "pycalver_tester",
'GIT_COMMITTER_NAME' : "pycalver_tester",
'GIT_AUTHOR_EMAIL' : "pycalver_tester@nowhere.com",
'GIT_COMMITTER_EMAIL': "pycalver_tester@nowhere.com",
'HGUSER' : "pycalver_tester",
'GIT_AUTHOR_NAME' : "calver_tester",
'GIT_COMMITTER_NAME' : "calver_tester",
'GIT_AUTHOR_EMAIL' : "calver_tester@nowhere.com",
'GIT_COMMITTER_EMAIL': "calver_tester@nowhere.com",
'HGUSER' : "calver_tester",
'PATH' : os.environ['PATH'],
}
@ -64,11 +64,11 @@ def shell(*cmd):
return sp.check_output(cmd, env=ENV)
DEBUG_LOG = 0
ECHO_CAPLOG = os.getenv('ECHO_CAPLOG') == "1"
def _debug_records(caplog):
if DEBUG_LOG:
if ECHO_CAPLOG:
print()
for record in caplog.records:
print(record)
@ -233,7 +233,11 @@ def _add_project_files(*files):
if "pycalver.toml" in files:
with pl.Path("pycalver.toml").open(mode="wt", encoding="utf-8") as fobj:
fobj.write(PYCALVER_TOML_FIXTURE)
fobj.write(CALVER_TOML_FIXTURE)
if "calver.toml" in files:
with pl.Path("calver.toml").open(mode="wt", encoding="utf-8") as fobj:
fobj.write(CALVER_TOML_FIXTURE)
if "pyproject.toml" in files:
with pl.Path("pyproject.toml").open(mode="wt", encoding="utf-8") as fobj:
@ -269,14 +273,14 @@ def test_novcs_nocfg_init(runner, caplog):
# dry mode test
result = runner.invoke(cli.cli, ['init', "-vv", "--dry"])
assert result.exit_code == 0
assert not os.path.exists("pycalver.toml")
assert not os.path.exists("calver.toml")
# non dry mode
result = runner.invoke(cli.cli, ['init', "-vv"])
assert result.exit_code == 0
assert os.path.exists("pycalver.toml")
with pl.Path("pycalver.toml").open(mode="r", encoding="utf-8") as fobj:
assert os.path.exists("calver.toml")
with pl.Path("calver.toml").open(mode="r", encoding="utf-8") as fobj:
cfg_content = fobj.read()
base_str = config.DEFAULT_TOML_BASE_TMPL.format(initial_version=config._initial_version())
@ -318,9 +322,10 @@ def test_novcs_setupcfg_init(runner):
assert f"PEP440 : {config._initial_version_pep440()}\n" in result.output
def test_novcs_pyproject_init(runner):
def test_novcs_pyproject_init(runner, caplog):
_add_project_files("README.md", "pyproject.toml")
result = runner.invoke(cli.cli, ['init', "-vv"])
_debug_records(caplog)
assert result.exit_code == 0
with pl.Path("pyproject.toml").open(mode="r", encoding="utf-8") as fobj:
@ -368,7 +373,7 @@ def test_git_init(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
@ -387,7 +392,7 @@ def test_hg_init(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
@ -408,7 +413,7 @@ def test_v1_git_tag_eval(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
@ -434,7 +439,7 @@ def test_hg_tag_eval(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
@ -458,7 +463,7 @@ def test_novcs_bump(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
@ -494,12 +499,12 @@ def test_git_bump(runner, caplog, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
shell("git", "add", "pycalver.toml")
shell("git", "add", "calver.toml")
shell("git", "commit", "-m", "initial commit")
result = runner.invoke(cli.cli, ['bump', "-vv"])
@ -522,12 +527,12 @@ def test_hg_bump(runner, version_pattern, cur_version, cur_pep440):
assert result.exit_code == 0
_update_config_val(
"pycalver.toml",
"calver.toml",
version_pattern=version_pattern,
current_version='"' + cur_version + '"',
)
shell("hg", "add", "pycalver.toml")
shell("hg", "add", "calver.toml")
shell("hg", "commit", "-m", "initial commit")
result = runner.invoke(cli.cli, ['bump', "-vv"])
@ -551,9 +556,9 @@ def test_empty_git_bump(runner, caplog):
with pl.Path("setup.cfg").open(mode="r") as fobj:
default_cfg_data = fobj.read()
assert "[pycalver]\n" in default_cfg_data
assert "[calver]\n" in default_cfg_data
assert "\ncurrent_version = " in default_cfg_data
assert "\n[pycalver:file_patterns]\n" in default_cfg_data
assert "\n[calver:file_patterns]\n" in default_cfg_data
assert "\nsetup.cfg =\n" in default_cfg_data
result = runner.invoke(cli.cli, ['bump'])
@ -573,9 +578,9 @@ def test_empty_hg_bump(runner, caplog):
with pl.Path("setup.cfg").open(mode="r") as fobj:
default_cfg_text = fobj.read()
assert "[pycalver]\n" in default_cfg_text
assert "[calver]\n" in default_cfg_text
assert "\ncurrent_version = " in default_cfg_text
assert "\n[pycalver:file_patterns]\n" in default_cfg_text
assert "\n[calver:file_patterns]\n" in default_cfg_text
assert "\nsetup.cfg =\n" in default_cfg_text
result = runner.invoke(cli.cli, ['bump'])
@ -899,11 +904,11 @@ def test_get_latest_vcs_version_tag(runner):
result = runner.invoke(cli.cli, ['init', "-vv"])
assert result.exit_code == 0
_update_config_val("pycalver.toml", push="false")
_update_config_val("pycalver.toml", current_version='"0.1.8"')
_update_config_val("pycalver.toml", version_pattern='"MAJOR.MINOR.PATCH"')
_update_config_val("calver.toml", push="false")
_update_config_val("calver.toml", current_version='"0.1.8"')
_update_config_val("calver.toml", version_pattern='"MAJOR.MINOR.PATCH"')
_vcs_init("git", files=["pycalver.toml"])
_vcs_init("git", files=["calver.toml"])
result = runner.invoke(cli.cli, ['bump', "--patch"])
assert result.exit_code == 0

View file

@ -15,7 +15,8 @@ from pycalver2 import config
PYCALVER_TOML_FIXTURE_1 = """
[pycalver]
current_version = "v201808.0123-alpha"
current_version = "v2020.1003-alpha"
version_pattern = "vYYYY.BUILD[-TAG]"
commit = true
tag = true
push = true
@ -35,6 +36,9 @@ PYCALVER_TOML_FIXTURE_2 = """
[pycalver]
current_version = "1.2.3"
version_pattern = "{semver}"
commit = false
tag = false
push = false
[pycalver.file_patterns]
"README.md" = [
@ -46,15 +50,34 @@ version_pattern = "{semver}"
]
"""
CALVER_TOML_FIXTURE_3 = """
[calver]
current_version = "v201808.0123-alpha"
version_pattern = "vYYYY0M.BUILD[-TAG]"
commit = true
tag = true
push = true
[calver.file_patterns]
"README.md" = [
"{version}",
"{pep440_version}",
]
"calver.toml" = [
'current_version = "{version}"',
]
"""
SETUP_CFG_FIXTURE = """
[pycalver]
[calver]
current_version = "v201808.0456-beta"
version_pattern = "vYYYY0M.BUILD[-TAG]"
commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
setup.py =
{version}
{pep440_version}
@ -64,7 +87,7 @@ setup.cfg =
NEW_PATTERN_CFG_FIXTURE = """
[pycalver]
[calver]
current_version = "v201808.1456-beta"
version_pattern = "vYYYY0M.BUILD[-TAG]"
commit_message = "bump version to {new_version}"
@ -72,7 +95,7 @@ commit = True
tag = True
push = True
[pycalver:file_patterns]
[calver:file_patterns]
setup.py =
{version}
{pep440_version}
@ -103,17 +126,18 @@ def test_parse_toml_1():
raw_cfg = config._parse_toml(buf)
cfg = config._parse_config(raw_cfg)
assert cfg.current_version == "v201808.0123-alpha"
assert cfg.version_pattern == "{pycalver}"
assert cfg.current_version == "v2020.1003-alpha"
assert cfg.version_pattern == "vYYYY.BUILD[-TAG]"
assert cfg.commit is True
assert cfg.tag is True
assert cfg.push is True
assert "pycalver.toml" in cfg.file_patterns
files = set(cfg.file_patterns)
assert "pycalver.toml" in files
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath["README.md" ] == ["{pycalver}", "{pep440_pycalver}"]
assert raw_patterns_by_filepath["pycalver.toml"] == ['current_version = "{pycalver}"']
raw_patterns_by_path = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_path["README.md" ] == ["vYYYY.BUILD[-TAG]", "YYYY.BLD[PYTAGNUM]"]
assert raw_patterns_by_path["pycalver.toml"] == ['current_version = "vYYYY.BUILD[-TAG]"']
def test_parse_toml_2():
@ -130,9 +154,29 @@ def test_parse_toml_2():
assert "pycalver.toml" in cfg.file_patterns
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath["README.md" ] == ["{semver}", "{semver}"]
assert raw_patterns_by_filepath["pycalver.toml"] == ['current_version = "{semver}"']
raw_patterns_by_path = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_path["README.md" ] == ["{semver}", "{semver}"]
assert raw_patterns_by_path["pycalver.toml"] == ['current_version = "{semver}"']
def test_parse_toml_3():
buf = mk_buf(CALVER_TOML_FIXTURE_3)
raw_cfg = config._parse_toml(buf)
cfg = config._parse_config(raw_cfg)
assert cfg.current_version == "v201808.0123-alpha"
assert cfg.version_pattern == "vYYYY0M.BUILD[-TAG]"
assert cfg.commit is True
assert cfg.tag is True
assert cfg.push is True
files = set(cfg.file_patterns)
assert "calver.toml" in files
raw_patterns_by_path = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_path["README.md" ] == ["vYYYY0M.BUILD[-TAG]", "YYYY0M.BLD[PYTAGNUM]"]
assert raw_patterns_by_path["calver.toml"] == ['current_version = "vYYYY0M.BUILD[-TAG]"']
def test_parse_v1_cfg():
@ -146,11 +190,12 @@ def test_parse_v1_cfg():
assert cfg.tag is True
assert cfg.push is True
assert "setup.cfg" in cfg.file_patterns
files = set(cfg.file_patterns)
assert "setup.cfg" in files
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath["setup.py" ] == ["{pycalver}", "{pep440_pycalver}"]
assert raw_patterns_by_filepath["setup.cfg"] == ['current_version = "{pycalver}"']
raw_patterns_by_path = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_path["setup.py" ] == ["vYYYY0M.BUILD[-TAG]", "YYYY0M.BLD[PYTAGNUM]"]
assert raw_patterns_by_path["setup.cfg"] == ['current_version = "vYYYY0M.BUILD[-TAG]"']
def test_parse_v2_cfg():
@ -164,16 +209,14 @@ def test_parse_v2_cfg():
assert cfg.tag is True
assert cfg.push is True
assert "setup.py" in cfg.file_patterns
assert "setup.cfg" in cfg.file_patterns
files = set(cfg.file_patterns)
assert "setup.py" in files
assert "setup.cfg" in files
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath["setup.py"] == [
"vYYYY0M.BUILD[-TAG]",
"YYYY0M.BLD[PYTAGNUM]",
]
assert raw_patterns_by_filepath["setup.cfg"] == ['current_version = "vYYYY0M.BUILD[-TAG]"']
assert raw_patterns_by_filepath["src/project/*.py"] == ["Copyright (c) 2018-YYYY"]
raw_patterns_by_path = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_path["setup.py"] == ["vYYYY0M.BUILD[-TAG]", "YYYY0M.BLD[PYTAGNUM]"]
assert raw_patterns_by_path["setup.cfg"] == ['current_version = "vYYYY0M.BUILD[-TAG]"']
assert raw_patterns_by_path["src/project/*.py"] == ["Copyright (c) 2018-YYYY"]
def test_parse_default_toml():
@ -204,8 +247,8 @@ def test_parse_default_cfg():
def test_parse_project_toml():
project_path = util.FIXTURES_DIR / "project_a"
config_path = util.FIXTURES_DIR / "project_a" / "pycalver.toml"
config_rel_path = "pycalver.toml"
config_path = util.FIXTURES_DIR / "project_a" / "calver.toml"
config_rel_path = "calver.toml"
with config_path.open() as fobj:
config_data = fobj.read()
@ -224,7 +267,8 @@ def test_parse_project_toml():
assert cfg.tag is True
assert cfg.push is True
assert set(cfg.file_patterns.keys()) == {"pycalver.toml", "README.md"}
files = set(cfg.file_patterns.keys())
assert files == {"calver.toml", "README.md"}
def test_parse_project_cfg():
@ -258,25 +302,26 @@ def test_parse_project_cfg():
def test_parse_toml_file(tmpdir):
project_path = tmpdir.mkdir("minimal")
setup_cfg = project_path.join("pycalver.toml")
setup_cfg.write(PYCALVER_TOML_FIXTURE_1)
setup_cfg_rel_path = "pycalver.toml"
cfg_file = project_path.join("pycalver.toml")
cfg_file.write(PYCALVER_TOML_FIXTURE_1)
cfg_file_rel_path = "pycalver.toml"
ctx = config.init_project_ctx(project_path)
assert ctx == config.ProjectContext(project_path, setup_cfg, setup_cfg_rel_path, 'toml', None)
assert ctx == config.ProjectContext(project_path, cfg_file, cfg_file_rel_path, 'toml', None)
cfg = config.parse(ctx)
assert cfg
assert cfg.current_version == "v201808.0123-alpha"
assert cfg.current_version == "v2020.1003-alpha"
assert cfg.version_pattern == "vYYYY.BUILD[-TAG]"
assert cfg.tag is True
assert cfg.commit is True
assert cfg.push is True
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath == {
"README.md" : ["{pycalver}", "{pep440_pycalver}"],
"pycalver.toml": ['current_version = "{pycalver}"'],
"README.md" : ["vYYYY.BUILD[-TAG]", "YYYY.BLD[PYTAGNUM]"],
"pycalver.toml": ['current_version = "vYYYY.BUILD[-TAG]"'],
}
@ -294,6 +339,8 @@ def test_parse_default_pattern():
assert cfg
assert cfg.current_version == "v2017q1.54321"
# assert cfg.version_pattern == "vYYYYqQ.BUILD"
assert cfg.version_pattern == "v{year}q{quarter}.{build_no}"
assert cfg.commit is True
assert cfg.tag is True
assert cfg.push is True
@ -317,14 +364,15 @@ def test_parse_cfg_file(tmpdir):
assert cfg
assert cfg.current_version == "v201808.0456-beta"
assert cfg.version_pattern == "vYYYY0M.BUILD[-TAG]"
assert cfg.tag is True
assert cfg.commit is True
assert cfg.push is True
raw_patterns_by_filepath = _parse_raw_patterns_by_filepath(cfg)
assert raw_patterns_by_filepath == {
"setup.py" : ["{pycalver}", "{pep440_pycalver}"],
"setup.cfg": ['current_version = "{pycalver}"'],
"setup.py" : ["vYYYY0M.BUILD[-TAG]", "YYYY0M.BLD[PYTAGNUM]"],
"setup.cfg": ['current_version = "vYYYY0M.BUILD[-TAG]"'],
}
@ -358,7 +406,7 @@ def test_parse_missing_version(tmpdir):
setup_path.write(
"\n".join(
(
"[pycalver]",
"[calver]",
# f"current_version = v201808.1001-dev",
"commit = False",
)
@ -374,7 +422,7 @@ def test_parse_missing_version(tmpdir):
def test_parse_invalid_version(tmpdir):
setup_path = tmpdir.mkdir("fail").join("setup.cfg")
setup_path.write("\n".join(("[pycalver]", "current_version = 0.1.0", "commit = False")))
setup_path.write("\n".join(("[calver]", "current_version = 0.1.0", "commit = False")))
ctx = config.init_project_ctx(setup_path)
assert ctx

View file

@ -95,13 +95,14 @@ def test_v1_rewrite_final():
def test_iter_file_paths():
with util.Project(project="a") as project:
ctx = config.init_project_ctx(project.dir)
assert ctx
cfg = config.parse(ctx)
assert cfg
_paths_and_patterns = rewrite.iter_path_patterns_items(cfg.file_patterns)
file_paths = {str(file_path) for file_path, patterns in _paths_and_patterns}
assert file_paths == {"pycalver.toml", "README.md"}
assert file_paths == {"calver.toml", "README.md"}
def test_iter_file_globs():

View file

@ -29,6 +29,7 @@ FIXTURE_PATH_PARTS = [
["setup.cfg"],
["setup.py"],
["pycalver.toml"],
["calver.toml"],
["src", "module_v1", "__init__.py"],
["src", "module_v2", "__init__.py"],
]