From a3499c19a6ff514419e4b1ea11769b646060c2b0 Mon Sep 17 00:00:00 2001 From: Manuel Barkhau Date: Thu, 15 Oct 2020 19:54:26 +0000 Subject: [PATCH] update defaults and tests --- README.md | 328 +++++++++--------- scripts/update_readme_examples.py | 8 +- setup.cfg | 10 +- setup.py | 2 +- src/pycalver2/cli.py | 2 +- src/pycalver2/config.py | 131 ++++--- src/pycalver2/vcs.py | 3 +- test/fixtures/project_a/README.md | 2 +- .../project_a/{pycalver.toml => calver.toml} | 6 +- test/fixtures/project_b/setup.cfg | 4 +- test/fixtures/project_b/setup.py | 7 +- test/fixtures/project_c/pyproject.toml | 2 +- test/fixtures/project_d/pyproject.toml | 2 +- test/test_cli.py | 65 ++-- test/test_config.py | 130 ++++--- test/test_rewrite.py | 3 +- test/util.py | 1 + 17 files changed, 400 insertions(+), 306 deletions(-) rename test/fixtures/project_a/{pycalver.toml => calver.toml} (79%) diff --git a/README.md b/README.md index 170efa2..6806f98 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ -# [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[1-9][0-9]{3})\.(?P1[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[1-9][0-9]{3})\.(?P1[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[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 - + ``` -$ 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. ``` - + - + ``` -$ 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. ``` - + ### 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=` | -| `PYTAG` | a, b, rc, post | `--release=` | -| `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=` | +| `PYTAG` | a, b, rc, post | `--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 - ¹ 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 - (?P + (?P v # "v" version prefix (?P\d{4}) - (?P\d{2}) ) (?P \. # "." 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=` 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. ``` diff --git a/scripts/update_readme_examples.py b/scripts/update_readme_examples.py index 9dc1a31..2c60bdf 100644 --- a/scripts/update_readme_examples.py +++ b/scripts/update_readme_examples.py @@ -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 '// {p; r /tmp/pycalver_help.txt' \ diff --git a/setup.cfg b/setup.cfg index 7de1c91..e63ac04 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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] diff --git a/setup.py b/setup.py index f0e5a54..f73329d 100644 --- a/setup.py +++ b/setup.py @@ -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", diff --git a/src/pycalver2/cli.py b/src/pycalver2/cli.py index 6fc4c26..e5b3ea2 100755 --- a/src/pycalver2/cli.py +++ b/src/pycalver2/cli.py @@ -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) diff --git a/src/pycalver2/config.py b/src/pycalver2/config.py index 16dbb77..e4f8587 100644 --- a/src/pycalver2/config.py +++ b/src/pycalver2/config.py @@ -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" diff --git a/src/pycalver2/vcs.py b/src/pycalver2/vcs.py index ab25193..29a9100 100644 --- a/src/pycalver2/vcs.py +++ b/src/pycalver2/vcs.py @@ -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 diff --git a/test/fixtures/project_a/README.md b/test/fixtures/project_a/README.md index ae141f2..34780a9 100644 --- a/test/fixtures/project_a/README.md +++ b/test/fixtures/project_a/README.md @@ -1,3 +1,3 @@ -# PyCalVer README Fixture +# Python CalVer README Fixture Current Version: v2016.0123-alpha diff --git a/test/fixtures/project_a/pycalver.toml b/test/fixtures/project_a/calver.toml similarity index 79% rename from test/fixtures/project_a/pycalver.toml rename to test/fixtures/project_a/calver.toml index 418cbb5..3b30ca6 100644 --- a/test/fixtures/project_a/pycalver.toml +++ b/test/fixtures/project_a/calver.toml @@ -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}"', ] diff --git a/test/fixtures/project_b/setup.cfg b/test/fixtures/project_b/setup.cfg index 36ed0b4..08158aa 100644 --- a/test/fixtures/project_b/setup.cfg +++ b/test/fixtures/project_b/setup.cfg @@ -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 = diff --git a/test/fixtures/project_b/setup.py b/test/fixtures/project_b/setup.py index d4082bb..942a85b 100644 --- a/test/fixtures/project_b/setup.py +++ b/test/fixtures/project_b/setup.py @@ -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", +) diff --git a/test/fixtures/project_c/pyproject.toml b/test/fixtures/project_c/pyproject.toml index e460fb7..aae94e8 100644 --- a/test/fixtures/project_c/pyproject.toml +++ b/test/fixtures/project_c/pyproject.toml @@ -1,4 +1,4 @@ -[pycalver] +[calver] current_version = "v2017q1.54321" version_pattern = "v{year}q{quarter}.{build_no}" commit = true diff --git a/test/fixtures/project_d/pyproject.toml b/test/fixtures/project_d/pyproject.toml index 65faaf4..c59dcaf 100644 --- a/test/fixtures/project_d/pyproject.toml +++ b/test/fixtures/project_d/pyproject.toml @@ -1,4 +1,4 @@ -[pycalver] +[calver] current_version = "v2017q1.54321" version_pattern = "vYYYYqQ.BUILD" commit = true diff --git a/test/test_cli.py b/test/test_cli.py index 4d968fc..ed244c5 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -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 diff --git a/test/test_config.py b/test/test_config.py index 33c79fe..c071944 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -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 diff --git a/test/test_rewrite.py b/test/test_rewrite.py index cec7bc7..9794ea0 100644 --- a/test/test_rewrite.py +++ b/test/test_rewrite.py @@ -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(): diff --git a/test/util.py b/test/util.py index d9d4f68..86d7a7a 100644 --- a/test/util.py +++ b/test/util.py @@ -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"], ]