mirror of
https://github.com/TECHNOFAB11/bumpver.git
synced 2025-12-12 14:30:09 +01:00
wip: add v2 module placeholders
This commit is contained in:
parent
7962a7cb9f
commit
669e8944e9
27 changed files with 1361 additions and 393 deletions
|
|
@ -1,9 +1,9 @@
|
|||
Individual files contain the following tag instead of the full license text.
|
||||
|
||||
This file is part of the pycalver project
|
||||
https://gitlab.com/mbarkhau/pycalver
|
||||
https://github.com/mbarkhau/pycalver
|
||||
|
||||
Copyright (c) 2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
This enables machine processing of license information based on the SPDX
|
||||
|
|
|
|||
2
makefile
2
makefile
|
|
@ -61,3 +61,5 @@ test_compat: $(COMPAT_TEST_FILES)
|
|||
ENABLE_BACKTRACE=0 PYTHONPATH="" ENV=$${ENV-dev} \
|
||||
$${env_py} -m pytest --verbose compat_test/; \
|
||||
done;
|
||||
|
||||
rm -rf compat_test/
|
||||
|
|
|
|||
183
pycalver1k.svg
183
pycalver1k.svg
|
|
@ -14,8 +14,8 @@
|
|||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0 (b51213c273, 2020-08-10)"
|
||||
sodipodi:docname="pycalver_1k.svg"
|
||||
inkscape:export-filename="C:\Users\ManuelBarkhau\Dropbox\projects\pycalver\pycalver_128.png"
|
||||
sodipodi:docname="pycalver1k.svg"
|
||||
inkscape:export-filename="/home/mbarkhau/foss/pycalver/pycalver1k2_128.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
x2="17.63979"
|
||||
y2="282.83472"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0831145,0,0,1.325042,-1.407405,-355.71527)" />
|
||||
gradientTransform="matrix(1.0541065,0,0,0.87055183,-0.916204,-223.64659)" />
|
||||
<mask
|
||||
maskUnits="userSpaceOnUse"
|
||||
id="mask1129">
|
||||
|
|
@ -201,6 +201,59 @@
|
|||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask
|
||||
maskUnits="userSpaceOnUse"
|
||||
id="mask1129-3">
|
||||
<g
|
||||
id="g1145-6"
|
||||
transform="translate(-1.5416733,-2.3386129)">
|
||||
<rect
|
||||
y="267.51743"
|
||||
x="-0.8018086"
|
||||
height="9.5214758"
|
||||
width="38.553631"
|
||||
id="rect1131-7"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#aa8800;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
|
||||
<g
|
||||
transform="translate(0.07525963,4.2889947)"
|
||||
id="g1137-5"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
|
||||
<ellipse
|
||||
cy="268.73132"
|
||||
cx="10.111843"
|
||||
id="ellipse1133-3"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
rx="2.2523122"
|
||||
ry="2.629046" />
|
||||
<rect
|
||||
y="263.9899"
|
||||
x="8.7405252"
|
||||
height="6.5171237"
|
||||
width="2.7426364"
|
||||
id="rect1135-5"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(16.669414,4.2889947)"
|
||||
id="g1143-6"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
|
||||
<ellipse
|
||||
cy="268.73132"
|
||||
cx="10.111843"
|
||||
id="ellipse1139-2"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
rx="2.2523122"
|
||||
ry="2.629046" />
|
||||
<rect
|
||||
y="263.9899"
|
||||
x="8.7405252"
|
||||
height="6.5171237"
|
||||
width="2.7426364"
|
||||
id="rect1141-9"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" />
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
|
|
@ -209,11 +262,11 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="9.2734375"
|
||||
inkscape:cx="56.807022"
|
||||
inkscape:cy="64"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="61.591322"
|
||||
inkscape:cy="64.987937"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer5"
|
||||
inkscape:current-layer="layer8"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="2512"
|
||||
|
|
@ -250,44 +303,76 @@
|
|||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="gradient"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:url(#linearGradient1165-3);fill-opacity:1;stroke:#000000;stroke-width:1.52114;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect815"
|
||||
width="30.280628"
|
||||
height="20.917326"
|
||||
x="1.7930192"
|
||||
y="10.965927" />
|
||||
id="layer6"
|
||||
inkscape:label="bg"
|
||||
style="display:inline">
|
||||
<path
|
||||
id="rect880"
|
||||
style="display:inline;fill:#ffffff;stroke-width:7.16557"
|
||||
d="m 1.585409,3.7099638 30.618783,-0.052171 0.725957,0.7967657 -0.0046,27.3188725 -0.528162,0.557572 L 1.1974464,32.32312 0.94904837,32.088188 0.93651797,4.3514519 Z"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="text"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="gradient"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:url(#linearGradient1165-3);fill-opacity:1;stroke:#000000;stroke-width:1.21634;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect815"
|
||||
width="29.469652"
|
||||
height="13.742671"
|
||||
x="2.1985073"
|
||||
y="17.262745" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="text bottom"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-263.13332)"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
style="display:inline">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.2889px;line-height:0.85;font-family:Monoid;-inkscape-font-specification:Monoid;letter-spacing:-0.111125px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="3.0023723"
|
||||
y="283.79349"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.8167px;line-height:0.85;font-family:Monoid;-inkscape-font-specification:Monoid;letter-spacing:-0.111125px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="2.2388713"
|
||||
y="292.59897"
|
||||
id="text859"><tspan
|
||||
sodipodi:role="line"
|
||||
x="3.0023723"
|
||||
y="283.79349"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.2889px;font-family:'Iosevka Term SS05';-inkscape-font-specification:'Iosevka Term SS05 Bold';stroke-width:0.264583"
|
||||
id="tspan886"><tspan
|
||||
dy="0.58999997"
|
||||
id="tspan884"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.2889px;font-family:'Iosevka Term SS05';-inkscape-font-specification:'Iosevka Term SS05 Bold';stroke-width:0.264583">v2020</tspan></tspan><tspan
|
||||
x="2.2388713"
|
||||
y="292.59897"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.8167px;font-family:'Iosevka Term SS05';-inkscape-font-specification:'Iosevka Term SS05 Bold';stroke-width:0.264583"
|
||||
id="tspan953">2020</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="frame top"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect815-0"
|
||||
width="30.546177"
|
||||
height="13.588312"
|
||||
x="1.6602445"
|
||||
y="-15.922193"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer8"
|
||||
inkscape:label="text top"
|
||||
style="display:inline">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:16.9333px;line-height:1.25;font-family:sans-serif;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="4.7286582"
|
||||
y="13.507061"
|
||||
id="text921"><tspan
|
||||
sodipodi:role="line"
|
||||
x="3.0023723"
|
||||
y="293.7308"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.2889px;font-family:'Iosevka Term SS05';-inkscape-font-specification:'Iosevka Term SS05 Bold';stroke-width:0.264583"
|
||||
id="tspan953">.1001</tspan></text>
|
||||
id="tspan919"
|
||||
x="4.7286582"
|
||||
y="13.507061"
|
||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:16.9333px;font-family:'Iosevka Fixed SS05';-inkscape-font-specification:'Iosevka Fixed SS05 Medium';fill:#ffffff;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none">ver</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
|
|
@ -297,10 +382,17 @@
|
|||
<rect
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#aa8800;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect1398"
|
||||
width="31.802925"
|
||||
width="30.684868"
|
||||
height="0.76833469"
|
||||
x="1.0316887"
|
||||
y="10.203551" />
|
||||
x="1.5910856"
|
||||
y="16.622082" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="top frame"
|
||||
sodipodi:insensitive="true"
|
||||
style="display:none">
|
||||
<rect
|
||||
style="display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.32913;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="rect900"
|
||||
|
|
@ -309,27 +401,28 @@
|
|||
x="3.5457754"
|
||||
y="268.57437"
|
||||
clip-path="none"
|
||||
mask="url(#mask1129)"
|
||||
transform="matrix(1.0938376,0,0,0.89104584,-1.5990177,-235.29985)" />
|
||||
mask="url(#mask1129-3)"
|
||||
transform="matrix(1.0545213,0,0,0.89332824,-0.92322741,-236.38373)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="pegs"
|
||||
style="display:inline">
|
||||
style="display:none"
|
||||
sodipodi:insensitive="true">
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#aa8800;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="rect1400"
|
||||
width="1.5874993"
|
||||
height="5.499999"
|
||||
x="7.0579548"
|
||||
y="1.2687082" />
|
||||
x="7.3927369"
|
||||
y="1.7978847" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#aa8800;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
|
||||
id="rect1400-6"
|
||||
width="1.5874993"
|
||||
height="5.499999"
|
||||
x="25.221212"
|
||||
y="1.39138" />
|
||||
x="24.886431"
|
||||
y="1.7978847" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 17 KiB |
BIN
pycalver1k2_128.png
Normal file
BIN
pycalver1k2_128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
|
|
@ -12,3 +12,4 @@ typing; python_version < "3.5"
|
|||
click
|
||||
toml
|
||||
six
|
||||
lexid
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
import sys
|
||||
|
||||
print(sys.version)
|
||||
95
setup.py
95
setup.py
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import os
|
||||
|
|
@ -26,48 +26,11 @@ install_requires = [
|
|||
]
|
||||
|
||||
|
||||
package_dir = {"": "src"}
|
||||
|
||||
|
||||
if any(arg.startswith("bdist") for arg in sys.argv):
|
||||
try:
|
||||
import lib3to6
|
||||
package_dir = lib3to6.fix(package_dir)
|
||||
except ImportError:
|
||||
if sys.version_info < (3, 6):
|
||||
raise
|
||||
else:
|
||||
sys.stderr.write((
|
||||
"WARNING: Creating non-universal bdist of pycalver, "
|
||||
"this should only be used for development.\n"
|
||||
))
|
||||
|
||||
|
||||
long_description = "\n\n".join((read("README.md"), read("CHANGELOG.md")))
|
||||
|
||||
|
||||
setuptools.setup(
|
||||
name="pycalver",
|
||||
license="MIT",
|
||||
author="Manuel Barkhau",
|
||||
author_email="mbarkhau@gmail.com",
|
||||
url="https://gitlab.com/mbarkhau/pycalver",
|
||||
version="202007.36",
|
||||
keywords="version versioning bumpversion calver",
|
||||
description="CalVer for python libraries.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=['pycalver'],
|
||||
package_dir=package_dir,
|
||||
install_requires=install_requires,
|
||||
entry_points="""
|
||||
[console_scripts]
|
||||
pycalver=pycalver.cli:cli
|
||||
""",
|
||||
zip_safe=True,
|
||||
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Environment :: Console",
|
||||
"Environment :: Other Environment",
|
||||
|
|
@ -84,5 +47,53 @@ setuptools.setup(
|
|||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Topic :: Software Development :: Libraries",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
],
|
||||
]
|
||||
|
||||
package_dir = {"": "src"}
|
||||
|
||||
|
||||
is_lib3to6_fix_required = (
|
||||
any(arg.startswith("bdist") for arg in sys.argv)
|
||||
and (
|
||||
"Programming Language :: Python :: 2.7" in classifiers
|
||||
or "Programming Language :: Python :: 2" in classifiers
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if is_lib3to6_fix_required:
|
||||
try:
|
||||
import lib3to6
|
||||
package_dir = lib3to6.fix(package_dir)
|
||||
except ImportError:
|
||||
if sys.version_info < (3, 6):
|
||||
raise
|
||||
else:
|
||||
sys.stderr.write((
|
||||
"WARNING: Creating non-universal bdist of pycalver, "
|
||||
"this should only be used for development.\n"
|
||||
))
|
||||
|
||||
|
||||
setuptools.setup(
|
||||
name="pycalver",
|
||||
license="MIT",
|
||||
author="Manuel Barkhau",
|
||||
author_email="mbarkhau@gmail.com",
|
||||
url="https://gitlab.com/mbarkhau/pycalver",
|
||||
version="202007.36",
|
||||
keywords="version versioning bumpversion calver",
|
||||
description="CalVer for python libraries.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages("src/"),
|
||||
package_dir=package_dir,
|
||||
install_requires=install_requires,
|
||||
entry_points="""
|
||||
[console_scripts]
|
||||
pycalver=pycalver.cli:cli
|
||||
""",
|
||||
python_requires=">=2.7",
|
||||
zip_safe=True,
|
||||
classifiers=classifiers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""PyCalVer: CalVer for Python Packages."""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
__main__ module for PyCalVer.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
CLI module for PyCalVer.
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ def _parse_config(raw_cfg: RawConfig) -> Config:
|
|||
version_str: str = raw_cfg['current_version']
|
||||
version_str = raw_cfg['current_version'] = version_str.strip("'\" ")
|
||||
|
||||
# TODO (mb 2020-09-06): new style pattern by default
|
||||
# version_pattern: str = raw_cfg.get('version_pattern', "vYYYY0M.BUILD[-TAG]")
|
||||
version_pattern: str = raw_cfg.get('version_pattern', "{pycalver}")
|
||||
version_pattern = raw_cfg['version_pattern'] = version_pattern.strip("'\" ")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,169 +0,0 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""A scheme for lexically ordered numerical ids.
|
||||
|
||||
Throughout the sequence this expression remains true, whether you
|
||||
are dealing with integers or strings:
|
||||
|
||||
older_id < newer_id
|
||||
|
||||
The left most character/digit is only used to maintain lexical
|
||||
order, so that the position in the sequence is maintained in the
|
||||
remaining digits.
|
||||
|
||||
sequence_pos = int(idval[1:], 10)
|
||||
|
||||
lexical sequence_pos
|
||||
0 0
|
||||
11 1
|
||||
12 2
|
||||
...
|
||||
19 9
|
||||
220 20
|
||||
221 21
|
||||
...
|
||||
298 98
|
||||
299 99
|
||||
3300 300
|
||||
3301 301
|
||||
...
|
||||
3998 998
|
||||
3999 999
|
||||
44000 4000
|
||||
44001 4001
|
||||
...
|
||||
899999998 99999998
|
||||
899999999 99999999
|
||||
9900000000 900000000
|
||||
9900000001 900000001
|
||||
...
|
||||
9999999998 999999998
|
||||
9999999999 999999999 # maximum value
|
||||
|
||||
You can add leading zeros to delay the expansion and/or increase
|
||||
the maximum possible value.
|
||||
|
||||
lexical sequence_pos
|
||||
0001 1
|
||||
0002 2
|
||||
0003 3
|
||||
...
|
||||
0999 999
|
||||
11000 1000
|
||||
11001 1001
|
||||
11002 1002
|
||||
...
|
||||
19998 9998
|
||||
19999 9999
|
||||
220000 20000
|
||||
220001 20001
|
||||
...
|
||||
899999999998 99999999998
|
||||
899999999999 99999999999
|
||||
9900000000000 900000000000
|
||||
9900000000001 900000000001
|
||||
...
|
||||
9999999999998 999999999998
|
||||
9999999999999 999999999999 # maximum value
|
||||
|
||||
This scheme is useful when you just want an ordered sequence of
|
||||
numbers, but the numbers don't have any particular meaning or
|
||||
arithmetical relation. The only relation they have to each other
|
||||
is that numbers generated later in the sequence are greater than
|
||||
ones generated earlier.
|
||||
"""
|
||||
|
||||
|
||||
MINIMUM_ID = "0"
|
||||
|
||||
|
||||
def next_id(prev_id: str) -> str:
|
||||
"""Generate next lexical id.
|
||||
|
||||
Increments by one and adds padding if required.
|
||||
|
||||
>>> next_id("0098")
|
||||
'0099'
|
||||
>>> next_id("0099")
|
||||
'0100'
|
||||
>>> next_id("0999")
|
||||
'11000'
|
||||
>>> next_id("11000")
|
||||
'11001'
|
||||
"""
|
||||
|
||||
num_digits = len(prev_id)
|
||||
|
||||
if prev_id.count("9") == num_digits:
|
||||
raise OverflowError("max lexical version reached: " + prev_id)
|
||||
|
||||
_prev_id_val = int(prev_id, 10)
|
||||
_maybe_next_id_val = int(_prev_id_val) + 1
|
||||
_maybe_next_id_str = f"{_maybe_next_id_val:0{num_digits}}"
|
||||
|
||||
_is_padding_ok = prev_id[0] == _maybe_next_id_str[0]
|
||||
_next_id_str: str
|
||||
|
||||
if _is_padding_ok:
|
||||
_next_id_str = _maybe_next_id_str
|
||||
else:
|
||||
_next_id_str = str(_maybe_next_id_val * 11)
|
||||
return _next_id_str
|
||||
|
||||
|
||||
def ord_val(lex_id: str) -> int:
|
||||
"""Parse the ordinal value of a lexical id.
|
||||
|
||||
The ordinal value is the position in the sequence,
|
||||
from repeated calls to next_id.
|
||||
|
||||
>>> ord_val("0098")
|
||||
98
|
||||
>>> ord_val("0099")
|
||||
99
|
||||
>>> ord_val("0100")
|
||||
100
|
||||
>>> ord_val("11000")
|
||||
1000
|
||||
>>> ord_val("11001")
|
||||
1001
|
||||
"""
|
||||
if len(lex_id) == 1:
|
||||
return int(lex_id, 10)
|
||||
else:
|
||||
return int(lex_id[1:], 10)
|
||||
|
||||
|
||||
def _main() -> None:
|
||||
_curr_id = "01"
|
||||
print(f"{'lexical':<13} {'numerical':>12}")
|
||||
|
||||
while True:
|
||||
print(f"{_curr_id:<13} {ord_val(_curr_id):>12}")
|
||||
_next_id = next_id(_curr_id)
|
||||
|
||||
if _next_id.count("9") == len(_next_id):
|
||||
# all nines, we're done
|
||||
print(f"{_next_id:<13} {ord_val(_next_id):>12}")
|
||||
break
|
||||
|
||||
if _next_id[0] != _curr_id[0] and len(_curr_id) > 1:
|
||||
print(f"{_next_id:<13} {ord_val(_next_id):>12}")
|
||||
_next_id = next_id(_next_id)
|
||||
print(f"{_next_id:<13} {ord_val(_next_id):>12}")
|
||||
_next_id = next_id(_next_id)
|
||||
|
||||
print("...")
|
||||
|
||||
# skip ahead
|
||||
_next_id = _next_id[:1] + "9" * (len(_next_id) - 2) + "8"
|
||||
|
||||
_curr_id = _next_id
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
_main()
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Parse PyCalVer strings from files."""
|
||||
|
||||
|
|
@ -22,6 +22,8 @@ class PatternMatch(typ.NamedTuple):
|
|||
|
||||
PatternMatches = typ.Iterable[PatternMatch]
|
||||
|
||||
RegexpPatterns = typ.List[typ.Pattern[str]]
|
||||
|
||||
|
||||
def _iter_for_pattern(lines: typ.List[str], pattern: str) -> PatternMatches:
|
||||
# The pattern is escaped, so that everything besides the format
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Compose Regular Expressions from Patterns.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Rewrite files, updating occurences of version strings."""
|
||||
|
||||
|
|
@ -13,8 +13,9 @@ import logging
|
|||
|
||||
import pathlib2 as pl
|
||||
|
||||
from . import parse
|
||||
from . import config
|
||||
from pycalver import parse
|
||||
from pycalver import config
|
||||
|
||||
from . import version
|
||||
from . import patterns
|
||||
|
||||
|
|
@ -53,6 +54,28 @@ class NoPatternMatch(Exception):
|
|||
"""
|
||||
|
||||
|
||||
class RewrittenFileData(typ.NamedTuple):
|
||||
"""Container for line-wise content of rewritten files."""
|
||||
|
||||
path : str
|
||||
line_sep : str
|
||||
old_lines: typ.List[str]
|
||||
new_lines: typ.List[str]
|
||||
|
||||
|
||||
def iter_file_paths(
|
||||
file_patterns: config.PatternsByGlob,
|
||||
) -> typ.Iterable[typ.Tuple[pl.Path, config.Patterns]]:
|
||||
for globstr, pattern_strs in file_patterns.items():
|
||||
file_paths = glob.glob(globstr)
|
||||
if not any(file_paths):
|
||||
errmsg = f"No files found for path/glob '{globstr}'"
|
||||
raise IOError(errmsg)
|
||||
for file_path_str in file_paths:
|
||||
file_path = pl.Path(file_path_str)
|
||||
yield (file_path, pattern_strs)
|
||||
|
||||
|
||||
def rewrite_lines(
|
||||
pattern_strs: typ.List[str], new_vinfo: version.VersionInfo, old_lines: typ.List[str]
|
||||
) -> typ.List[str]:
|
||||
|
|
@ -88,15 +111,6 @@ def rewrite_lines(
|
|||
return new_lines
|
||||
|
||||
|
||||
class RewrittenFileData(typ.NamedTuple):
|
||||
"""Container for line-wise content of rewritten files."""
|
||||
|
||||
path : str
|
||||
line_sep : str
|
||||
old_lines: typ.List[str]
|
||||
new_lines: typ.List[str]
|
||||
|
||||
|
||||
def rfd_from_content(
|
||||
pattern_strs: typ.List[str], new_vinfo: version.VersionInfo, content: str
|
||||
) -> RewrittenFileData:
|
||||
|
|
@ -122,19 +136,6 @@ def rfd_from_content(
|
|||
return RewrittenFileData("<path>", line_sep, old_lines, new_lines)
|
||||
|
||||
|
||||
def _iter_file_paths(
|
||||
file_patterns: config.PatternsByGlob,
|
||||
) -> typ.Iterable[typ.Tuple[pl.Path, config.Patterns]]:
|
||||
for globstr, pattern_strs in file_patterns.items():
|
||||
file_paths = glob.glob(globstr)
|
||||
if not any(file_paths):
|
||||
errmsg = f"No files found for path/glob '{globstr}'"
|
||||
raise IOError(errmsg)
|
||||
for file_path_str in file_paths:
|
||||
file_path = pl.Path(file_path_str)
|
||||
yield (file_path, pattern_strs)
|
||||
|
||||
|
||||
def iter_rewritten(
|
||||
file_patterns: config.PatternsByGlob, new_vinfo: version.VersionInfo
|
||||
) -> typ.Iterable[RewrittenFileData]:
|
||||
|
|
@ -144,23 +145,23 @@ def iter_rewritten(
|
|||
>>> new_vinfo = version.parse_version_info("v201809.0123")
|
||||
>>> rewritten_datas = iter_rewritten(file_patterns, new_vinfo)
|
||||
>>> rfd = list(rewritten_datas)[0]
|
||||
>>> assert rfd.new_lines == [
|
||||
>>> expected = [
|
||||
... '# This file is part of the pycalver project',
|
||||
... '# https://gitlab.com/mbarkhau/pycalver',
|
||||
... '# https://github.com/mbarkhau/pycalver',
|
||||
... '#',
|
||||
... '# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License',
|
||||
... '# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License',
|
||||
... '# SPDX-License-Identifier: MIT',
|
||||
... '"""PyCalVer: CalVer for Python Packages."""',
|
||||
... '',
|
||||
... '__version__ = "v201809.0123"',
|
||||
... '',
|
||||
... ]
|
||||
>>>
|
||||
>>> assert rfd.new_lines[:len(expected)] == expected
|
||||
'''
|
||||
|
||||
fobj: typ.IO[str]
|
||||
|
||||
for file_path, pattern_strs in _iter_file_paths(file_patterns):
|
||||
for file_path, pattern_strs in iter_file_paths(file_patterns):
|
||||
with file_path.open(mode="rt", encoding="utf-8") as fobj:
|
||||
content = fobj.read()
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ def diff(new_vinfo: version.VersionInfo, file_patterns: config.PatternsByGlob) -
|
|||
full_diff = ""
|
||||
fobj: typ.IO[str]
|
||||
|
||||
for file_path, pattern_strs in sorted(_iter_file_paths(file_patterns)):
|
||||
for file_path, pattern_strs in sorted(iter_file_paths(file_patterns)):
|
||||
with file_path.open(mode="rt", encoding="utf-8") as fobj:
|
||||
content = fobj.read()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# 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
|
||||
|
|
@ -15,11 +15,14 @@ mercurial, then the git terms are used. For example "fetch"
|
|||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import typing as typ
|
||||
import logging
|
||||
import tempfile
|
||||
import subprocess as sp
|
||||
|
||||
from pycalver import config
|
||||
|
||||
logger = logging.getLogger("pycalver.vcs")
|
||||
|
||||
|
||||
|
|
@ -179,3 +182,57 @@ def get_vcs_api() -> VCSAPI:
|
|||
return vcs_api
|
||||
|
||||
raise OSError("No such directory .git/ or .hg/ ")
|
||||
|
||||
|
||||
# cli helper methods
|
||||
|
||||
|
||||
def assert_not_dirty(vcs_api: VCSAPI, filepaths: typ.Set[str], allow_dirty: bool) -> None:
|
||||
dirty_files = vcs_api.status(required_files=filepaths)
|
||||
|
||||
if dirty_files:
|
||||
logger.warning(f"{vcs_api.name} working directory is not clean. Uncomitted file(s):")
|
||||
for dirty_file in dirty_files:
|
||||
logger.warning(" " + dirty_file)
|
||||
|
||||
if not allow_dirty and dirty_files:
|
||||
sys.exit(1)
|
||||
|
||||
dirty_pattern_files = set(dirty_files) & filepaths
|
||||
if dirty_pattern_files:
|
||||
logger.error("Not commiting when pattern files are dirty:")
|
||||
for dirty_file in dirty_pattern_files:
|
||||
logger.warning(" " + dirty_file)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def commit(
|
||||
cfg : config.Config,
|
||||
vcs_api : VCSAPI,
|
||||
filepaths : typ.Set[str],
|
||||
new_version : str,
|
||||
commit_message: str,
|
||||
) -> None:
|
||||
for filepath in filepaths:
|
||||
vcs_api.add(filepath)
|
||||
|
||||
vcs_api.commit(commit_message)
|
||||
|
||||
if cfg.commit and cfg.tag:
|
||||
vcs_api.tag(new_version)
|
||||
|
||||
if cfg.commit and cfg.tag and cfg.push:
|
||||
vcs_api.push(new_version)
|
||||
|
||||
|
||||
def get_tags(fetch: bool) -> typ.List[str]:
|
||||
try:
|
||||
vcs_api = get_vcs_api()
|
||||
logger.debug(f"vcs found: {vcs_api.name}")
|
||||
if fetch:
|
||||
logger.info("fetching tags from remote (to turn off use: -n / --no-fetch)")
|
||||
vcs_api.fetch()
|
||||
return vcs_api.ls_tags()
|
||||
except OSError:
|
||||
logger.debug("No vcs found")
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://gitlab.com/mbarkhau/pycalver
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Functions related to version string manipulation."""
|
||||
|
||||
|
|
@ -9,9 +9,9 @@ import typing as typ
|
|||
import logging
|
||||
import datetime as dt
|
||||
|
||||
import lexid
|
||||
import pkg_resources
|
||||
|
||||
from . import lex_id
|
||||
from . import patterns
|
||||
|
||||
logger = logging.getLogger("pycalver.version")
|
||||
|
|
@ -482,7 +482,7 @@ def incr(
|
|||
else:
|
||||
logger.warning(f"Version appears to be from the future '{old_version}'")
|
||||
|
||||
cur_vinfo = cur_vinfo._replace(bid=lex_id.next_id(cur_vinfo.bid))
|
||||
cur_vinfo = cur_vinfo._replace(bid=lexid.next_id(cur_vinfo.bid))
|
||||
|
||||
if major:
|
||||
cur_vinfo = cur_vinfo._replace(major=cur_vinfo.major + 1, minor=0, patch=0)
|
||||
|
|
|
|||
8
src/pycalver2/__init__.py
Normal file
8
src/pycalver2/__init__.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""PyCalVer: CalVer for Python Packages."""
|
||||
|
||||
__version__ = "v202007.1036"
|
||||
53
src/pycalver2/cli.py
Normal file
53
src/pycalver2/cli.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env python
|
||||
# This file is part of the pycalver project
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
CLI module for PyCalVer.
|
||||
|
||||
Provided subcommands: show, test, init, bump
|
||||
"""
|
||||
import typing as typ
|
||||
import logging
|
||||
|
||||
import pycalver2.rewrite as v2rewrite
|
||||
import pycalver2.version as v2version
|
||||
from pycalver import config
|
||||
|
||||
logger = logging.getLogger("pycalver2.cli")
|
||||
|
||||
|
||||
def update_cfg_from_vcs(cfg: config.Config, all_tags: typ.List[str]) -> config.Config:
|
||||
version_tags = [tag for tag in all_tags if v2version.is_valid(tag, cfg.version_pattern)]
|
||||
if not version_tags:
|
||||
logger.debug("no vcs tags found")
|
||||
return cfg
|
||||
|
||||
version_tags.sort(reverse=True)
|
||||
logger.debug(f"found {len(version_tags)} tags: {version_tags[:2]}")
|
||||
latest_version_tag = version_tags[0]
|
||||
latest_version_pep440 = v2version.to_pep440(latest_version_tag)
|
||||
if latest_version_tag <= cfg.current_version:
|
||||
return cfg
|
||||
|
||||
logger.info(f"Working dir version : {cfg.current_version}")
|
||||
logger.info(f"Latest version from VCS tag: {latest_version_tag}")
|
||||
return cfg._replace(
|
||||
current_version=latest_version_tag,
|
||||
pep440_version=latest_version_pep440,
|
||||
)
|
||||
|
||||
|
||||
def rewrite(
|
||||
cfg : config.Config,
|
||||
new_version: str,
|
||||
) -> None:
|
||||
new_vinfo = v2version.parse_version_info(new_version, cfg.version_pattern)
|
||||
v2rewrite.rewrite(cfg.file_patterns, new_vinfo)
|
||||
|
||||
|
||||
def get_diff(cfg: config.Config, new_version: str) -> str:
|
||||
new_vinfo = v2version.parse_version_info(new_version, cfg.version_pattern)
|
||||
return v2rewrite.diff(new_vinfo, cfg.file_patterns)
|
||||
205
src/pycalver2/patterns.py
Normal file
205
src/pycalver2/patterns.py
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Compose Regular Expressions from Patterns.
|
||||
|
||||
>>> version_info = PYCALVER_RE.match("v201712.0123-alpha").groupdict()
|
||||
>>> assert version_info == {
|
||||
... "pycalver" : "v201712.0123-alpha",
|
||||
... "vYYYYMM" : "v201712",
|
||||
... "year" : "2017",
|
||||
... "month" : "12",
|
||||
... "build" : ".0123",
|
||||
... "build_no" : "0123",
|
||||
... "release" : "-alpha",
|
||||
... "release_tag" : "alpha",
|
||||
... }
|
||||
>>>
|
||||
>>> version_info = PYCALVER_RE.match("v201712.0033").groupdict()
|
||||
>>> assert version_info == {
|
||||
... "pycalver" : "v201712.0033",
|
||||
... "vYYYYMM" : "v201712",
|
||||
... "year" : "2017",
|
||||
... "month" : "12",
|
||||
... "build" : ".0033",
|
||||
... "build_no" : "0033",
|
||||
... "release" : None,
|
||||
... "release_tag": None,
|
||||
... }
|
||||
"""
|
||||
|
||||
import re
|
||||
import typing as typ
|
||||
|
||||
# https://regex101.com/r/fnj60p/10
|
||||
PYCALVER_PATTERN = r"""
|
||||
\b
|
||||
(?P<pycalver>
|
||||
(?P<vYYYYMM>
|
||||
v # "v" version prefix
|
||||
(?P<year>\d{4})
|
||||
(?P<month>\d{2})
|
||||
)
|
||||
(?P<build>
|
||||
\. # "." build nr prefix
|
||||
(?P<build_no>\d{4,})
|
||||
)
|
||||
(?P<release>
|
||||
\- # "-" release prefix
|
||||
(?P<release_tag>alpha|beta|dev|rc|post)
|
||||
)?
|
||||
)(?:\s|$)
|
||||
"""
|
||||
|
||||
PYCALVER_RE: typ.Pattern[str] = re.compile(PYCALVER_PATTERN, flags=re.VERBOSE)
|
||||
|
||||
|
||||
PATTERN_ESCAPES = [
|
||||
("\u005c", "\u005c\u005c"),
|
||||
("-" , "\u005c-"),
|
||||
("." , "\u005c."),
|
||||
("+" , "\u005c+"),
|
||||
("*" , "\u005c*"),
|
||||
("?" , "\u005c?"),
|
||||
("{" , "\u005c{"),
|
||||
("}" , "\u005c}"),
|
||||
("[" , "\u005c["),
|
||||
("]" , "\u005c]"),
|
||||
("(" , "\u005c("),
|
||||
(")" , "\u005c)"),
|
||||
]
|
||||
|
||||
# NOTE (mb 2020-09-04): These are depricated in favour of explicit patterns
|
||||
COMPOSITE_PART_PATTERNS = {
|
||||
'pep440_pycalver': r"{year}{month}\.{BID}(?:{pep440_tag})?",
|
||||
'pycalver' : r"v{year}{month}\.{bid}(?:-{tag})?",
|
||||
'calver' : r"v{year}{month}",
|
||||
'semver' : r"{MAJOR}\.{MINOR}\.{PATCH}",
|
||||
'release_tag' : r"{tag}",
|
||||
'build' : r"\.{bid}",
|
||||
'release' : r"(?:-{tag})?",
|
||||
# depricated
|
||||
'pep440_version': r"{year}{month}\.{BID}(?:{pep440_tag})?",
|
||||
}
|
||||
|
||||
|
||||
PART_PATTERNS = {
|
||||
# recommended (based on calver.org)
|
||||
'YYYY': r"[1-9]\d{3}",
|
||||
'YY' : r"\d{1,2}",
|
||||
'0Y' : r"\d{2}",
|
||||
'Q' : r"[1-4]",
|
||||
'MM' : r"(?:[1-9]|1[0-2])",
|
||||
'0M' : r"(?:0[1-9]|1[0-2])",
|
||||
'DD' : r"([1-9]|[1-2][0-9]|3[0-1])",
|
||||
'0D' : r"(0[1-9]|[1-2][0-9]|3[0-1])",
|
||||
'JJJ' : r"(?:[1-9]\d|[1-9]|[1-2]\d\d|3[0-5][0-9]|36[0-6])",
|
||||
'00J' : r"(?:[0-2]\d\d|3[0-5][0-9]|36[0-6])",
|
||||
'WW' : r"(?:[1-9]|[1-4]\d|5[0-2])",
|
||||
'0W' : r"(?:[0-4]\d|5[0-2])",
|
||||
'UU' : r"(?:[1-9]|[0-4]\d|5[0-2])",
|
||||
'0U' : r"(?:[0-4]\d|5[0-2])",
|
||||
'VV' : r"(?:[1-9]|[1-4]\d|5[0-3])",
|
||||
'0V' : r"(?:[0-4]\d|5[0-3])",
|
||||
'GGGG': r"[1-9]\d{3}",
|
||||
'GG' : r"\d{1,2}",
|
||||
'0G' : r"\d{2}",
|
||||
# non calver parts
|
||||
'MAJOR': r"\d+",
|
||||
'MINOR': r"\d+",
|
||||
'PATCH': r"\d+",
|
||||
'MICRO': r"\d+",
|
||||
'BUILD': r"\d+",
|
||||
'TAG' : r"(?:alpha|beta|dev|rc|post|final)",
|
||||
'PYTAG': r"(?:a|b|dev|rc|post)?\d*",
|
||||
# supported (but legacy)
|
||||
'year' : r"\d{4}",
|
||||
'month' : r"(?:0[0-9]|1[0-2])",
|
||||
'month_short': r"(?:1[0-2]|[1-9])",
|
||||
'build_no' : r"\d{4,}",
|
||||
'pep440_tag' : r"(?:a|b|dev|rc|post)?\d*",
|
||||
'tag' : r"(?:alpha|beta|dev|rc|post|final)",
|
||||
'yy' : r"\d{2}",
|
||||
'yyyy' : r"\d{4}",
|
||||
'quarter' : r"[1-4]",
|
||||
'iso_week' : r"(?:[0-4]\d|5[0-3])",
|
||||
'us_week' : r"(?:[0-4]\d|5[0-3])",
|
||||
'dom' : r"(0[1-9]|[1-2][0-9]|3[0-1])",
|
||||
'dom_short' : r"([1-9]|[1-2][0-9]|3[0-1])",
|
||||
'doy' : r"(?:[0-2]\d\d|3[0-5][0-9]|36[0-6])",
|
||||
'doy_short' : r"(?:[0-2]\d\d|3[0-5][0-9]|36[0-6])",
|
||||
'bid' : r"\d{4,}",
|
||||
# dropped support (never documented)
|
||||
# 'BID' : r"[1-9]\d*",
|
||||
# 'MM' : r"\d{2,}",
|
||||
# 'MMM' : r"\d{3,}",
|
||||
# 'MMMM' : r"\d{4,}",
|
||||
# 'MMMMM' : r"\d{5,}",
|
||||
# 'PP' : r"\d{2,}",
|
||||
# 'PPP' : r"\d{3,}",
|
||||
# 'PPPP' : r"\d{4,}",
|
||||
# 'PPPPP' : r"\d{5,}",
|
||||
# 'BB' : r"[1-9]\d{1,}",
|
||||
# 'BBB' : r"[1-9]\d{2,}",
|
||||
# 'BBBB' : r"[1-9]\d{3,}",
|
||||
# 'BBBBB' : r"[1-9]\d{4,}",
|
||||
# 'BBBBBB' : r"[1-9]\d{5,}",
|
||||
# 'BBBBBBB' : r"[1-9]\d{6,}",
|
||||
}
|
||||
|
||||
|
||||
FULL_PART_FORMATS = {
|
||||
'pep440_pycalver': "{year}{month:02}.{BID}{pep440_tag}",
|
||||
'pycalver' : "v{year}{month:02}.{bid}{release}",
|
||||
'calver' : "v{year}{month:02}",
|
||||
'semver' : "{MAJOR}.{MINOR}.{PATCH}",
|
||||
'release_tag' : "{tag}",
|
||||
'build' : ".{bid}",
|
||||
# NOTE (mb 2019-01-04): since release is optional, it
|
||||
# is treated specially in version.format
|
||||
# 'release' : "-{tag}",
|
||||
'month' : "{month:02}",
|
||||
'month_short': "{month}",
|
||||
'build_no' : "{bid}",
|
||||
'iso_week' : "{iso_week:02}",
|
||||
'us_week' : "{us_week:02}",
|
||||
'dom' : "{dom:02}",
|
||||
'doy' : "{doy:03}",
|
||||
'dom_short' : "{dom}",
|
||||
'doy_short' : "{doy}",
|
||||
# depricated
|
||||
'pep440_version': "{year}{month:02}.{BID}{pep440_tag}",
|
||||
'version' : "v{year}{month:02}.{bid}{release}",
|
||||
}
|
||||
|
||||
|
||||
def _replace_pattern_parts(pattern: str) -> str:
|
||||
for part_name, part_pattern in PART_PATTERNS.items():
|
||||
named_part_pattern = f"(?P<{part_name}>{part_pattern})"
|
||||
placeholder = "\u005c{" + part_name + "\u005c}"
|
||||
pattern = pattern.replace(placeholder, named_part_pattern)
|
||||
return pattern
|
||||
|
||||
|
||||
def compile_pattern_str(pattern: str) -> str:
|
||||
for char, escaped in PATTERN_ESCAPES:
|
||||
pattern = pattern.replace(char, escaped)
|
||||
|
||||
return _replace_pattern_parts(pattern)
|
||||
|
||||
|
||||
def compile_pattern(pattern: str) -> typ.Pattern[str]:
|
||||
pattern_str = compile_pattern_str(pattern)
|
||||
return re.compile(pattern_str)
|
||||
|
||||
|
||||
def _init_composite_patterns() -> None:
|
||||
for part_name, part_pattern in COMPOSITE_PART_PATTERNS.items():
|
||||
part_pattern = part_pattern.replace("{", "\u005c{").replace("}", "\u005c}")
|
||||
pattern_str = _replace_pattern_parts(part_pattern)
|
||||
PART_PATTERNS[part_name] = pattern_str
|
||||
|
||||
|
||||
_init_composite_patterns()
|
||||
175
src/pycalver2/rewrite.py
Normal file
175
src/pycalver2/rewrite.py
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Rewrite files, updating occurences of version strings."""
|
||||
|
||||
import io
|
||||
import typing as typ
|
||||
import logging
|
||||
|
||||
from pycalver import parse
|
||||
from pycalver import config
|
||||
from pycalver import rewrite as v1rewrite
|
||||
from pycalver2 import version
|
||||
from pycalver2 import patterns
|
||||
|
||||
logger = logging.getLogger("pycalver2.rewrite")
|
||||
|
||||
|
||||
def rewrite_lines(
|
||||
pattern_strs: typ.List[str], new_vinfo: version.VersionInfo, old_lines: typ.List[str]
|
||||
) -> typ.List[str]:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Replace occurances of pattern_strs in old_lines with new_vinfo.
|
||||
|
||||
>>> new_vinfo = version.parse_version_info("v201811.0123-beta")
|
||||
>>> pattern_strs = ['__version__ = "{pycalver}"']
|
||||
>>> rewrite_lines(pattern_strs, new_vinfo, ['__version__ = "v201809.0002-beta"'])
|
||||
['__version__ = "v201811.0123-beta"']
|
||||
|
||||
>>> pattern_strs = ['__version__ = "{pep440_version}"']
|
||||
>>> rewrite_lines(pattern_strs, new_vinfo, ['__version__ = "201809.2b0"'])
|
||||
['__version__ = "201811.123b0"']
|
||||
"""
|
||||
new_lines = old_lines[:]
|
||||
found_patterns = set()
|
||||
|
||||
re_patterns = [patterns.compile_pattern(p) for p in pattern_strs]
|
||||
for match in parse.iter_matches(old_lines, re_patterns):
|
||||
found_patterns.add(match.pattern)
|
||||
replacement = version.format_version(new_vinfo, match.pattern)
|
||||
span_l, span_r = match.span
|
||||
new_line = match.line[:span_l] + replacement + match.line[span_r:]
|
||||
new_lines[match.lineno] = new_line
|
||||
|
||||
non_matched_patterns = set(pattern_strs) - found_patterns
|
||||
if non_matched_patterns:
|
||||
for non_matched_pattern in non_matched_patterns:
|
||||
logger.error(f"No match for pattern '{non_matched_pattern}'")
|
||||
compiled_pattern_str = patterns.compile_pattern_str(non_matched_pattern)
|
||||
logger.error(f"Pattern compiles to regex '{compiled_pattern_str}'")
|
||||
raise v1rewrite.NoPatternMatch("Invalid pattern(s)")
|
||||
else:
|
||||
return new_lines
|
||||
|
||||
|
||||
def rfd_from_content(
|
||||
pattern_strs: typ.List[str], new_vinfo: version.VersionInfo, content: str
|
||||
) -> v1rewrite.RewrittenFileData:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
r"""Rewrite pattern occurrences with version string.
|
||||
|
||||
>>> new_vinfo = version.parse_version_info("v201809.0123")
|
||||
>>> pattern_strs = ['__version__ = "{pycalver}"']
|
||||
>>> content = '__version__ = "v201809.0001-alpha"'
|
||||
>>> rfd = rfd_from_content(pattern_strs, new_vinfo, content)
|
||||
>>> rfd.new_lines
|
||||
['__version__ = "v201809.0123"']
|
||||
>>>
|
||||
>>> new_vinfo = version.parse_version_info("v1.2.3", "v{semver}")
|
||||
>>> pattern_strs = ['__version__ = "v{semver}"']
|
||||
>>> content = '__version__ = "v1.2.2"'
|
||||
>>> rfd = rfd_from_content(pattern_strs, new_vinfo, content)
|
||||
>>> rfd.new_lines
|
||||
['__version__ = "v1.2.3"']
|
||||
"""
|
||||
line_sep = v1rewrite.detect_line_sep(content)
|
||||
old_lines = content.split(line_sep)
|
||||
new_lines = rewrite_lines(pattern_strs, new_vinfo, old_lines)
|
||||
return v1rewrite.RewrittenFileData("<path>", line_sep, old_lines, new_lines)
|
||||
|
||||
|
||||
def iter_rewritten(
|
||||
file_patterns: config.PatternsByGlob, new_vinfo: version.VersionInfo
|
||||
) -> typ.Iterable[v1rewrite.RewrittenFileData]:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
r'''Iterate over files with version string replaced.
|
||||
|
||||
>>> file_patterns = {"src/pycalver/__init__.py": ['__version__ = "{pycalver}"']}
|
||||
>>> new_vinfo = version.parse_version_info("v201809.0123")
|
||||
>>> rewritten_datas = iter_rewritten(file_patterns, new_vinfo)
|
||||
>>> rfd = list(rewritten_datas)[0]
|
||||
>>> assert rfd.new_lines == [
|
||||
... '# This file is part of the pycalver project',
|
||||
... '# https://gitlab.com/mbarkhau/pycalver',
|
||||
... '#',
|
||||
... '# Copyright (c) 2019 Manuel Barkhau (mbarkhau@gmail.com) - MIT License',
|
||||
... '# SPDX-License-Identifier: MIT',
|
||||
... '"""PyCalVer: CalVer for Python Packages."""',
|
||||
... '',
|
||||
... '__version__ = "v201809.0123"',
|
||||
... '',
|
||||
... ]
|
||||
>>>
|
||||
'''
|
||||
|
||||
fobj: typ.IO[str]
|
||||
|
||||
for file_path, pattern_strs in v1rewrite.iter_file_paths(file_patterns):
|
||||
with file_path.open(mode="rt", encoding="utf-8") as fobj:
|
||||
content = fobj.read()
|
||||
|
||||
rfd = rfd_from_content(pattern_strs, new_vinfo, content)
|
||||
yield rfd._replace(path=str(file_path))
|
||||
|
||||
|
||||
def diff(new_vinfo: version.VersionInfo, file_patterns: config.PatternsByGlob) -> str:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
r"""Generate diffs of rewritten files.
|
||||
|
||||
>>> new_vinfo = version.parse_version_info("v201809.0123")
|
||||
>>> file_patterns = {"src/pycalver/__init__.py": ['__version__ = "{pycalver}"']}
|
||||
>>> diff_str = diff(new_vinfo, file_patterns)
|
||||
>>> lines = diff_str.split("\n")
|
||||
>>> lines[:2]
|
||||
['--- src/pycalver/__init__.py', '+++ src/pycalver/__init__.py']
|
||||
>>> assert lines[6].startswith('-__version__ = "v2')
|
||||
>>> assert not lines[6].startswith('-__version__ = "v201809.0123"')
|
||||
>>> lines[7]
|
||||
'+__version__ = "v201809.0123"'
|
||||
"""
|
||||
|
||||
full_diff = ""
|
||||
fobj: typ.IO[str]
|
||||
|
||||
for file_path, pattern_strs in sorted(v1rewrite.iter_file_paths(file_patterns)):
|
||||
with file_path.open(mode="rt", encoding="utf-8") as fobj:
|
||||
content = fobj.read()
|
||||
|
||||
try:
|
||||
rfd = rfd_from_content(pattern_strs, new_vinfo, content)
|
||||
except v1rewrite.NoPatternMatch:
|
||||
# pylint:disable=raise-missing-from ; we support py2, so not an option
|
||||
errmsg = f"No patterns matched for '{file_path}'"
|
||||
raise v1rewrite.NoPatternMatch(errmsg)
|
||||
|
||||
rfd = rfd._replace(path=str(file_path))
|
||||
lines = v1rewrite.diff_lines(rfd)
|
||||
if len(lines) == 0:
|
||||
errmsg = f"No patterns matched for '{file_path}'"
|
||||
raise v1rewrite.NoPatternMatch(errmsg)
|
||||
|
||||
full_diff += "\n".join(lines) + "\n"
|
||||
|
||||
full_diff = full_diff.rstrip("\n")
|
||||
return full_diff
|
||||
|
||||
|
||||
def rewrite(file_patterns: config.PatternsByGlob, new_vinfo: version.VersionInfo) -> None:
|
||||
"""Rewrite project files, updating each with the new version."""
|
||||
fobj: typ.IO[str]
|
||||
|
||||
for file_data in iter_rewritten(file_patterns, new_vinfo):
|
||||
new_content = file_data.line_sep.join(file_data.new_lines)
|
||||
with io.open(file_data.path, mode="wt", encoding="utf-8") as fobj:
|
||||
fobj.write(new_content)
|
||||
590
src/pycalver2/version.py
Normal file
590
src/pycalver2/version.py
Normal file
|
|
@ -0,0 +1,590 @@
|
|||
# This file is part of the pycalver project
|
||||
# https://github.com/mbarkhau/pycalver
|
||||
#
|
||||
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""Functions related to version string manipulation."""
|
||||
|
||||
import typing as typ
|
||||
import logging
|
||||
import datetime as dt
|
||||
|
||||
import lexid
|
||||
import pkg_resources
|
||||
|
||||
from . import patterns
|
||||
|
||||
logger = logging.getLogger("pycalver.version")
|
||||
|
||||
|
||||
# The test suite may replace this.
|
||||
TODAY = dt.datetime.utcnow().date()
|
||||
|
||||
|
||||
PATTERN_PART_FIELDS = {
|
||||
'YYYY' : 'year_y',
|
||||
'YY' : 'year_y',
|
||||
'0Y' : 'year_y',
|
||||
'Q' : 'quarter',
|
||||
'MM' : 'month',
|
||||
'0M' : 'month',
|
||||
'DD' : 'dom',
|
||||
'0D' : 'dom',
|
||||
'JJJ' : 'doy',
|
||||
'00J' : 'doy',
|
||||
'MAJOR': 'major',
|
||||
'MINOR': 'minor',
|
||||
'PATCH': 'patch',
|
||||
'MICRO': 'patch',
|
||||
'BUILD': 'bid',
|
||||
'TAG' : 'tag',
|
||||
'PYTAG': 'pytag',
|
||||
'WW' : 'week_w',
|
||||
'0W' : 'week_w',
|
||||
'UU' : 'week_u',
|
||||
'0U' : 'week_u',
|
||||
'VV' : 'week_v',
|
||||
'0V' : 'week_v',
|
||||
'GGGG' : 'year_g',
|
||||
'GG' : 'year_g',
|
||||
'0G' : 'year_g',
|
||||
}
|
||||
|
||||
ID_FIELDS_BY_PART = {
|
||||
'MAJOR': 'major',
|
||||
'MINOR': 'minor',
|
||||
'PATCH': 'patch',
|
||||
'MICRO': 'patch',
|
||||
}
|
||||
|
||||
|
||||
ZERO_VALUES = {
|
||||
'major': "0",
|
||||
'minor': "0",
|
||||
'patch': "0",
|
||||
'TAG' : "final",
|
||||
'PYTAG': "",
|
||||
}
|
||||
|
||||
|
||||
class CalendarInfo(typ.NamedTuple):
|
||||
"""Container for calendar components of version strings."""
|
||||
|
||||
year_y : int
|
||||
year_g : int
|
||||
quarter: int
|
||||
month : int
|
||||
dom : int
|
||||
doy : int
|
||||
week_w : int
|
||||
week_u : int
|
||||
week_v : int
|
||||
|
||||
|
||||
def _date_from_doy(year: int, doy: int) -> dt.date:
|
||||
"""Parse date from year and day of year (1 indexed).
|
||||
|
||||
>>> cases = [
|
||||
... (2016, 1), (2016, 31), (2016, 31 + 1), (2016, 31 + 29), (2016, 31 + 30),
|
||||
... (2017, 1), (2017, 31), (2017, 31 + 1), (2017, 31 + 28), (2017, 31 + 29),
|
||||
... ]
|
||||
>>> dates = [_date_from_doy(year, month) for year, month in cases]
|
||||
>>> assert [(d.month, d.day) for d in dates] == [
|
||||
... (1, 1), (1, 31), (2, 1), (2, 29), (3, 1),
|
||||
... (1, 1), (1, 31), (2, 1), (2, 28), (3, 1),
|
||||
... ]
|
||||
"""
|
||||
return dt.date(year, 1, 1) + dt.timedelta(days=doy - 1)
|
||||
|
||||
|
||||
def _quarter_from_month(month: int) -> int:
|
||||
"""Calculate quarter (1 indexed) from month (1 indexed).
|
||||
|
||||
>>> [_quarter_from_month(month) for month in range(1, 13)]
|
||||
[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
|
||||
"""
|
||||
return ((month - 1) // 3) + 1
|
||||
|
||||
|
||||
def cal_info(date: dt.date = None) -> CalendarInfo:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Generate calendar components for current date.
|
||||
|
||||
>>> from datetime import date
|
||||
|
||||
>>> c = cal_info(date(2019, 1, 5))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
(2019, 1, 1, 5, 5, 0, 0)
|
||||
|
||||
>>> c = cal_info(date(2019, 1, 6))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
(2019, 1, 1, 6, 6, 0, 1)
|
||||
|
||||
>>> c = cal_info(date(2019, 1, 7))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
(2019, 1, 1, 7, 7, 1, 1)
|
||||
|
||||
>>> c = cal_info(date(2019, 4, 7))
|
||||
>>> (c.year_y, c.quarter, c.month, c.dom, c.doy, c.iso_week, c.us_week)
|
||||
(2019, 2, 4, 7, 97, 13, 14)
|
||||
"""
|
||||
if date is None:
|
||||
date = TODAY
|
||||
|
||||
kwargs = {
|
||||
'year_y' : date.year,
|
||||
'year_g' : int(date.strftime("%G"), base=10),
|
||||
'quarter': _quarter_from_month(date.month),
|
||||
'month' : date.month,
|
||||
'dom' : date.day,
|
||||
'doy' : int(date.strftime("%j"), base=10),
|
||||
'week_w' : int(date.strftime("%W"), base=10),
|
||||
'week_u' : int(date.strftime("%U"), base=10),
|
||||
'week_v' : int(date.strftime("%V"), base=10),
|
||||
}
|
||||
|
||||
return CalendarInfo(**kwargs)
|
||||
|
||||
|
||||
class VersionInfo(typ.NamedTuple):
|
||||
"""Container for parsed version string."""
|
||||
|
||||
year_y : typ.Optional[int]
|
||||
year_g : typ.Optional[int]
|
||||
quarter: typ.Optional[int]
|
||||
month : typ.Optional[int]
|
||||
dom : typ.Optional[int]
|
||||
doy : typ.Optional[int]
|
||||
week_w : typ.Optional[int]
|
||||
week_u : typ.Optional[int]
|
||||
week_v : typ.Optional[int]
|
||||
major : int
|
||||
minor : int
|
||||
patch : int
|
||||
bid : str
|
||||
tag : str
|
||||
pytag : str
|
||||
|
||||
|
||||
FieldKey = str
|
||||
MatchGroupKey = str
|
||||
MatchGroupStr = str
|
||||
|
||||
PatternGroups = typ.Dict[MatchGroupKey, MatchGroupStr]
|
||||
FieldValues = typ.Dict[FieldKey , MatchGroupStr]
|
||||
|
||||
|
||||
def _parse_field_values(field_values: FieldValues) -> VersionInfo:
|
||||
fvals = field_values
|
||||
tag = fvals.get('tag')
|
||||
if tag is None:
|
||||
tag = "final"
|
||||
|
||||
tag = TAG_ALIASES.get(tag, tag)
|
||||
assert tag is not None
|
||||
# TODO (mb 2020-09-06): parts of course
|
||||
pytag = "TODO"
|
||||
|
||||
bid = fvals['bid'] if 'bid' in fvals else "1001"
|
||||
|
||||
year_y = int(fvals['year_y']) if 'year_y' in fvals else None
|
||||
year_g = int(fvals['year_g']) if 'year_g' in fvals else None
|
||||
doy = int(fvals['doy' ]) if 'doy' in fvals else None
|
||||
|
||||
date: typ.Optional[dt.date] = None
|
||||
|
||||
month: typ.Optional[int] = None
|
||||
dom : typ.Optional[int] = None
|
||||
|
||||
week_w: typ.Optional[int] = None
|
||||
week_u: typ.Optional[int] = None
|
||||
week_v: typ.Optional[int] = None
|
||||
|
||||
if year_y and doy:
|
||||
date = _date_from_doy(year_y, doy)
|
||||
month = date.month
|
||||
dom = date.day
|
||||
else:
|
||||
month = int(fvals['month']) if 'month' in fvals else None
|
||||
dom = int(fvals['dom' ]) if 'dom' in fvals else None
|
||||
|
||||
quarter = int(fvals['quarter']) if 'quarter' in fvals else None
|
||||
if quarter is None and month:
|
||||
quarter = _quarter_from_month(month)
|
||||
|
||||
if year_y and month and dom:
|
||||
date = dt.date(year_y, month, dom)
|
||||
|
||||
if date:
|
||||
# derive all fields from other previous values
|
||||
doy = int(date.strftime("%j"), base=10)
|
||||
week_w = int(date.strftime("%W"), base=10)
|
||||
week_u = int(date.strftime("%U"), base=10)
|
||||
week_v = int(date.strftime("%V"), base=10)
|
||||
year_g = int(date.strftime("%G"), base=10)
|
||||
|
||||
major = int(fvals['major']) if 'major' in fvals else 0
|
||||
minor = int(fvals['minor']) if 'minor' in fvals else 0
|
||||
patch = int(fvals['patch']) if 'patch' in fvals else 0
|
||||
|
||||
return VersionInfo(
|
||||
year_y=year_y,
|
||||
year_g=year_g,
|
||||
quarter=quarter,
|
||||
month=month,
|
||||
dom=dom,
|
||||
doy=doy,
|
||||
week_w=week_w,
|
||||
week_u=week_u,
|
||||
week_v=week_v,
|
||||
major=major,
|
||||
minor=minor,
|
||||
patch=patch,
|
||||
bid=bid,
|
||||
tag=tag,
|
||||
pytag=pytag,
|
||||
)
|
||||
|
||||
|
||||
def _is_calver(nfo: typ.Union[CalendarInfo, VersionInfo]) -> bool:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Check pattern for any calendar based parts.
|
||||
|
||||
>>> _is_calver(cal_info())
|
||||
True
|
||||
|
||||
>>> vnfo = _parse_version_info({'year': "2018", 'month': "11", 'bid': "0018"})
|
||||
>>> _is_calver(vnfo)
|
||||
True
|
||||
|
||||
>>> vnfo = _parse_version_info({'MAJOR': "1", 'MINOR': "023", 'PATCH': "45"})
|
||||
>>> _is_calver(vnfo)
|
||||
False
|
||||
"""
|
||||
for field in CalendarInfo._fields:
|
||||
maybe_val: typ.Any = getattr(nfo, field, None)
|
||||
if isinstance(maybe_val, int):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
TAG_ALIASES: typ.Dict[str, str] = {
|
||||
'a' : "alpha",
|
||||
'b' : "beta",
|
||||
'pre': "rc",
|
||||
}
|
||||
|
||||
|
||||
PEP440_TAGS: typ.Dict[str, str] = {
|
||||
'alpha': "a",
|
||||
'beta' : "b",
|
||||
'final': "",
|
||||
'rc' : "rc",
|
||||
'dev' : "dev",
|
||||
'post' : "post",
|
||||
}
|
||||
|
||||
|
||||
VersionInfoKW = typ.Dict[str, typ.Union[str, int, None]]
|
||||
|
||||
|
||||
class PatternError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def _parse_pattern_groups(pattern_groups: PatternGroups) -> FieldValues:
|
||||
for part_name in pattern_groups.keys():
|
||||
is_valid_part_name = (
|
||||
part_name in patterns.COMPOSITE_PART_PATTERNS or part_name in PATTERN_PART_FIELDS
|
||||
)
|
||||
if not is_valid_part_name:
|
||||
err_msg = f"Invalid part '{part_name}'"
|
||||
raise PatternError(err_msg)
|
||||
|
||||
field_value_items = [
|
||||
(field_name, pattern_groups[part_name])
|
||||
for part_name, field_name in PATTERN_PART_FIELDS.items()
|
||||
if part_name in pattern_groups.keys()
|
||||
]
|
||||
|
||||
all_fields = [field_name for field_name, _ in field_value_items]
|
||||
unique_fields = set(all_fields)
|
||||
duplicate_fields = [f for f in unique_fields if all_fields.count(f) > 1]
|
||||
|
||||
if any(duplicate_fields):
|
||||
err_msg = f"Multiple parts for same field {duplicate_fields}."
|
||||
raise PatternError(err_msg)
|
||||
|
||||
return dict(field_value_items)
|
||||
|
||||
|
||||
def _parse_version_info(pattern_groups: PatternGroups) -> VersionInfo:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Parse normalized VersionInfo from groups of a matched pattern.
|
||||
|
||||
>>> vnfo = _parse_version_info({'year': "2018", 'month': "11", 'bid': "0099"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.quarter, vnfo.bid, vnfo.tag)
|
||||
(2018, 11, 4, '0099', 'final')
|
||||
|
||||
>>> vnfo = _parse_version_info({'year': "2018", 'doy': "11", 'bid': "099", 'tag': "b"})
|
||||
>>> (vnfo.year_y, vnfo.month, vnfo.dom, vnfo.bid, vnfo.tag)
|
||||
(2018, 1, 11, '099', 'beta')
|
||||
|
||||
>>> vnfo = _parse_version_info({'MAJOR': "1", 'MINOR': "23", 'PATCH': "45"})
|
||||
>>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
(1, 23, 45)
|
||||
|
||||
>>> vnfo = _parse_version_info({'MAJOR': "1", 'MMM': "023", 'PPPP': "0045"})
|
||||
>>> (vnfo.major, vnfo.minor, vnfo.patch)
|
||||
(1, 23, 45)
|
||||
"""
|
||||
field_values = _parse_pattern_groups(pattern_groups)
|
||||
return _parse_field_values(field_values)
|
||||
|
||||
|
||||
def parse_version_info(version_str: str, pattern: str = "{pycalver}") -> VersionInfo:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Parse normalized VersionInfo.
|
||||
|
||||
>>> vnfo = parse_version_info("v201712.0033-beta", pattern="{pycalver}")
|
||||
>>> assert vnfo == _parse_version_info({'year': 2017, 'month': 12, 'bid': "0033", 'tag': "beta"})
|
||||
|
||||
>>> vnfo = parse_version_info("1.23.456", pattern="{semver}")
|
||||
>>> assert vnfo == _parse_version_info({'MAJOR': "1", 'MINOR': "23", 'PATCH': "456"})
|
||||
"""
|
||||
regex = patterns.compile_pattern(pattern)
|
||||
match = regex.match(version_str)
|
||||
if match is None:
|
||||
err_msg = (
|
||||
f"Invalid version string '{version_str}' for pattern '{pattern}'/'{regex.pattern}'"
|
||||
)
|
||||
raise PatternError(err_msg)
|
||||
|
||||
return _parse_version_info(match.groupdict())
|
||||
|
||||
|
||||
def is_valid(version_str: str, pattern: str = "{pycalver}") -> bool:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Check if a version matches a pattern.
|
||||
|
||||
>>> is_valid("v201712.0033-beta", pattern="{pycalver}")
|
||||
True
|
||||
>>> is_valid("v201712.0033-beta", pattern="{semver}")
|
||||
False
|
||||
>>> is_valid("1.2.3", pattern="{semver}")
|
||||
True
|
||||
>>> is_valid("v201712.0033-beta", pattern="{semver}")
|
||||
False
|
||||
"""
|
||||
try:
|
||||
parse_version_info(version_str, pattern)
|
||||
return True
|
||||
except PatternError:
|
||||
return False
|
||||
|
||||
|
||||
TemplateKwargs = typ.Dict[str, typ.Union[str, int, None]]
|
||||
|
||||
|
||||
def _derive_template_kwargs(vinfo: VersionInfo) -> TemplateKwargs:
|
||||
"""Generate kwargs for template from minimal VersionInfo.
|
||||
|
||||
The VersionInfo Tuple only has the minimal representation
|
||||
of a parsed version, not the values suitable for formatting.
|
||||
It may for example have month=9, but not the formatted
|
||||
representation '09' for '0M'.
|
||||
"""
|
||||
kwargs: TemplateKwargs = vinfo._asdict()
|
||||
|
||||
tag = vinfo.tag
|
||||
kwargs['TAG'] = tag
|
||||
if tag == 'final':
|
||||
kwargs['PYTAG'] = ""
|
||||
else:
|
||||
kwargs['PYTAG'] = PEP440_TAGS[tag] + "0"
|
||||
|
||||
year_y = vinfo.year_y
|
||||
if year_y:
|
||||
kwargs['0Y' ] = str(year_y)[-2:]
|
||||
kwargs['YY' ] = int(str(year_y)[-2:])
|
||||
kwargs['YYYY'] = year_y
|
||||
|
||||
year_g = vinfo.year_g
|
||||
if year_g:
|
||||
kwargs['0G' ] = str(year_g)[-2:]
|
||||
kwargs['GG' ] = int(str(year_g)[-2:])
|
||||
kwargs['GGGG'] = year_g
|
||||
|
||||
kwargs['BUILD'] = int(vinfo.bid, 10)
|
||||
|
||||
for part_name, field in ID_FIELDS_BY_PART.items():
|
||||
val = kwargs[field]
|
||||
if part_name.lower() == field.lower():
|
||||
if isinstance(val, str):
|
||||
kwargs[part_name] = int(val, base=10)
|
||||
else:
|
||||
kwargs[part_name] = val
|
||||
else:
|
||||
assert len(set(part_name)) == 1
|
||||
padded_len = len(part_name)
|
||||
kwargs[part_name] = str(val).zfill(padded_len)
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def _compile_format_template(pattern: str, kwargs: TemplateKwargs) -> str:
|
||||
# NOTE (mb 2020-09-04): Some parts are optional, we need the kwargs to
|
||||
# determine if part is set to its zero value
|
||||
format_tmpl = pattern
|
||||
for part_name, full_part_format in patterns.FULL_PART_FORMATS.items():
|
||||
format_tmpl = format_tmpl.replace("{" + part_name + "}", full_part_format)
|
||||
return format_tmpl
|
||||
|
||||
|
||||
def format_version(vinfo: VersionInfo, pattern: str) -> str:
|
||||
"""TODO reenable doctest"""
|
||||
pass
|
||||
|
||||
"""Generate version string.
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> vinfo = parse_version_info("v201712.0033-beta", pattern="{pycalver}")
|
||||
>>> vinfo_a = vinfo._replace(**cal_info(date=dt.date(2017, 1, 1))._asdict())
|
||||
>>> vinfo_b = vinfo._replace(**cal_info(date=dt.date(2017, 12, 31))._asdict())
|
||||
|
||||
>>> format_version(vinfo_a, pattern="v{yy}.{BID}{release}")
|
||||
'v17.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYY.BUILD[-TAG]")
|
||||
'v17.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="YYYY0M.BUILD[PYTAG]")
|
||||
'201701.33b0'
|
||||
|
||||
>>> format_version(vinfo_a, pattern="{pycalver}")
|
||||
'v201701.0033-beta'
|
||||
>>> format_version(vinfo_b, pattern="{pycalver}")
|
||||
'v201712.0033-beta'
|
||||
|
||||
>>> format_version(vinfo_a, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
'v2017w00.33-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w00.33-beta'
|
||||
>>> format_version(vinfo_b, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
'v2017w52.33-beta'
|
||||
>>> format_version(vinfo_b, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w52.33-beta'
|
||||
|
||||
>>> format_version(vinfo_a, pattern="v{year}d{doy}.{bid}{release}")
|
||||
'v2017d001.0033-beta'
|
||||
>>> format_version(vinfo_b, pattern="v{year}d{doy}.{bid}{release}")
|
||||
'v2017d365.0033-beta'
|
||||
>>> format_version(vinfo_a, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
'v2017d001.0033-beta'
|
||||
>>> format_version(vinfo_b, pattern="vYYYYdJJJ.BUILD[-TAG]")
|
||||
'v2017d365.0033-beta'
|
||||
|
||||
>>> format_version(vinfo_a, pattern="vGGGGwVV.BUILD[-TAG]")
|
||||
'v2016w52.0033-beta'
|
||||
|
||||
>>> vinfo_c = vinfo_b._replace(major=1, minor=2, patch=34, tag='final')
|
||||
|
||||
>>> format_version(vinfo_c, pattern="v{year}w{iso_week}.{BID}-{tag}")
|
||||
'v2017w52.33-final'
|
||||
>>> format_version(vinfo_c, pattern="v{year}w{iso_week}.{BID}{release}")
|
||||
'v2017w52.33'
|
||||
>>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD-TAG")
|
||||
'v2017w52.33-final'
|
||||
>>> format_version(vinfo_c, pattern="vYYYYwWW.BUILD[-TAG]")
|
||||
'v2017w52.33'
|
||||
|
||||
>>> format_version(vinfo_c, pattern="v{MAJOR}.{MINOR}.{PATCH}")
|
||||
'v1.2.34'
|
||||
>>> format_version(vinfo_c, pattern="vMAJOR.MINOR.PATCH")
|
||||
'v1.2.34'
|
||||
|
||||
>>> vinfo_d = vinfo_b._replace(major=1, minor=0, patch=0, tag='final')
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH-TAG")
|
||||
'v1.0.0-final'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR.PATCH[-TAG]")
|
||||
'v1.0.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.PATCH[-TAG]]")
|
||||
'v1.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR.MINOR[.MICRO[-TAG]]")
|
||||
'v1.0'
|
||||
>>> format_version(vinfo_d, pattern="vMAJOR[.MINOR[.PATCH[-TAG]]]")
|
||||
'v1'
|
||||
"""
|
||||
kwargs = _derive_template_kwargs(vinfo)
|
||||
format_tmpl = _compile_format_template(pattern, kwargs)
|
||||
|
||||
return format_tmpl.format(**kwargs)
|
||||
|
||||
|
||||
def incr(
|
||||
old_version: str,
|
||||
pattern : str = "{pycalver}",
|
||||
*,
|
||||
release: str = None,
|
||||
major : bool = False,
|
||||
minor : bool = False,
|
||||
patch : bool = False,
|
||||
) -> typ.Optional[str]:
|
||||
"""Increment version string.
|
||||
|
||||
'old_version' is assumed to be a string that matches 'pattern'
|
||||
"""
|
||||
try:
|
||||
old_vinfo = parse_version_info(old_version, pattern)
|
||||
except PatternError as ex:
|
||||
logger.error(str(ex))
|
||||
return None
|
||||
|
||||
cur_vinfo = old_vinfo
|
||||
|
||||
cur_cal_nfo = cal_info()
|
||||
|
||||
old_date = (old_vinfo.year_y or 0, old_vinfo.month or 0, old_vinfo.dom or 0)
|
||||
cur_date = (cur_cal_nfo.year_y , cur_cal_nfo.month , cur_cal_nfo.dom)
|
||||
|
||||
if old_date <= cur_date:
|
||||
cur_vinfo = cur_vinfo._replace(**cur_cal_nfo._asdict())
|
||||
else:
|
||||
logger.warning(f"Version appears to be from the future '{old_version}'")
|
||||
|
||||
cur_vinfo = cur_vinfo._replace(bid=lexid.incr(cur_vinfo.bid))
|
||||
|
||||
if major:
|
||||
cur_vinfo = cur_vinfo._replace(major=cur_vinfo.major + 1, minor=0, patch=0)
|
||||
if minor:
|
||||
cur_vinfo = cur_vinfo._replace(minor=cur_vinfo.minor + 1, patch=0)
|
||||
if patch:
|
||||
cur_vinfo = cur_vinfo._replace(patch=cur_vinfo.patch + 1)
|
||||
|
||||
if release:
|
||||
cur_vinfo = cur_vinfo._replace(tag=release)
|
||||
|
||||
new_version = format_version(cur_vinfo, pattern)
|
||||
if new_version == old_version:
|
||||
logger.error("Invalid arguments or pattern, version did not change.")
|
||||
return None
|
||||
else:
|
||||
return new_version
|
||||
|
||||
|
||||
def to_pep440(version: str) -> str:
|
||||
"""Derive pep440 compliant version string from PyCalVer version string.
|
||||
|
||||
>>> to_pep440("v201811.0007-beta")
|
||||
'201811.7b0'
|
||||
"""
|
||||
return str(pkg_resources.parse_version(version))
|
||||
6
test/fixtures/project_d/pyproject.toml
vendored
Normal file
6
test/fixtures/project_d/pyproject.toml
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[pycalver]
|
||||
current_version = "v2017q1.54321"
|
||||
version_pattern = "vYYYYqQ.BUILD"
|
||||
commit = true
|
||||
tag = true
|
||||
push = true
|
||||
|
|
@ -2,11 +2,10 @@
|
|||
# pylint:disable=protected-access ; allowed for test code
|
||||
|
||||
import io
|
||||
from test import util
|
||||
|
||||
from pycalver import config
|
||||
|
||||
from . import util
|
||||
|
||||
PYCALVER_TOML_FIXTURE_1 = """
|
||||
[pycalver]
|
||||
current_version = "v201808.0123-alpha"
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
# pylint:disable=protected-access ; allowed for test code
|
||||
|
||||
import random
|
||||
|
||||
from pycalver import lex_id
|
||||
|
||||
|
||||
def test_next_id_basic():
|
||||
assert lex_id.next_id("01") == "02"
|
||||
assert lex_id.next_id("09") == "110"
|
||||
|
||||
|
||||
def test_next_id_overflow():
|
||||
try:
|
||||
prev_id = "9999"
|
||||
next_id = lex_id.next_id(prev_id)
|
||||
assert False, (prev_id, "->", next_id)
|
||||
except OverflowError:
|
||||
pass
|
||||
|
||||
|
||||
def test_next_id_random():
|
||||
for _ in range(1000):
|
||||
prev_id = str(random.randint(1, 100 * 1000))
|
||||
try:
|
||||
next_id = lex_id.next_id(prev_id)
|
||||
assert prev_id < next_id
|
||||
except OverflowError:
|
||||
assert len(prev_id) == prev_id.count("9")
|
||||
|
||||
|
||||
def test_ord_val():
|
||||
assert lex_id.ord_val("1" ) == 1
|
||||
assert lex_id.ord_val("01" ) == 1
|
||||
assert lex_id.ord_val("02" ) == 2
|
||||
assert lex_id.ord_val("09" ) == 9
|
||||
assert lex_id.ord_val("110") == 10
|
||||
|
||||
|
||||
def test_main(capsys):
|
||||
lex_id._main()
|
||||
captured = capsys.readouterr()
|
||||
assert len(captured.err) == 0
|
||||
|
||||
lines = iter(captured.out.splitlines())
|
||||
header = next(lines)
|
||||
|
||||
assert "lexical" in header
|
||||
assert "numerical" in header
|
||||
|
||||
ids = []
|
||||
ord_vals = []
|
||||
|
||||
for line in lines:
|
||||
if "..." in line:
|
||||
continue
|
||||
_id, _ord_val = line.split()
|
||||
|
||||
assert _id.endswith(_ord_val)
|
||||
assert int(_ord_val) == int(_ord_val, 10)
|
||||
|
||||
ids.append(_id.strip())
|
||||
ord_vals.append(int(_ord_val.strip()))
|
||||
|
||||
assert len(ids) > 0
|
||||
assert sorted(ids) == ids
|
||||
assert sorted(ord_vals) == ord_vals
|
||||
|
|
@ -2,14 +2,17 @@ import re
|
|||
|
||||
import pytest
|
||||
|
||||
from pycalver import patterns
|
||||
import pycalver.patterns as v1patterns
|
||||
import pycalver2.patterns as v2patterns
|
||||
|
||||
# TODO (mb 2020-09-06): test for v2patterns
|
||||
|
||||
|
||||
def _part_re_by_name(name):
|
||||
return re.compile(patterns.PART_PATTERNS[name])
|
||||
return re.compile(v1patterns.PART_PATTERNS[name])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("part_name", patterns.PART_PATTERNS.keys())
|
||||
@pytest.mark.parametrize("part_name", v1patterns.PART_PATTERNS.keys())
|
||||
def test_part_compilation(part_name):
|
||||
assert _part_re_by_name(part_name)
|
||||
|
||||
|
|
@ -64,7 +67,7 @@ PATTERN_CASES = [
|
|||
|
||||
@pytest.mark.parametrize("pattern_str, line, expected", PATTERN_CASES)
|
||||
def test_patterns(pattern_str, line, expected):
|
||||
pattern_re = patterns.compile_pattern(pattern_str)
|
||||
pattern_re = v1patterns.compile_pattern(pattern_str)
|
||||
result = pattern_re.search(line)
|
||||
if result is None:
|
||||
assert expected is None, (pattern_str, line)
|
||||
|
|
@ -82,7 +85,7 @@ CLI_MAIN_FIXTURE = """
|
|||
|
||||
def test_pattern_escapes():
|
||||
pattern = 'click.version_option(version="{pycalver}")'
|
||||
pattern_re = patterns.compile_pattern(pattern)
|
||||
pattern_re = v1patterns.compile_pattern(pattern)
|
||||
match = pattern_re.search(CLI_MAIN_FIXTURE)
|
||||
expected = 'click.version_option(version="v201812.0123-beta")'
|
||||
assert match.group(0) == expected
|
||||
|
|
@ -95,7 +98,7 @@ package_metadata = {"name": "mypackage", "version": "v201812.0123-beta"}
|
|||
|
||||
def test_curly_escapes():
|
||||
pattern = 'package_metadata = {"name": "mypackage", "version": "{pycalver}"}'
|
||||
pattern_re = patterns.compile_pattern(pattern)
|
||||
pattern_re = v1patterns.compile_pattern(pattern)
|
||||
match = pattern_re.search(CURLY_BRACE_FIXTURE)
|
||||
expected = 'package_metadata = {"name": "mypackage", "version": "v201812.0123-beta"}'
|
||||
assert match.group(0) == expected
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
# pylint:disable=protected-access ; allowed for test code
|
||||
|
||||
import copy
|
||||
from test import util
|
||||
|
||||
from pycalver import config
|
||||
from pycalver import rewrite
|
||||
from pycalver import version
|
||||
|
||||
from . import util
|
||||
from pycalver import rewrite as v1rewrite
|
||||
from pycalver import version as v1version
|
||||
from pycalver2 import rewrite as v2rewrite
|
||||
from pycalver2 import version as v2version
|
||||
|
||||
REWRITE_FIXTURE = """
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
|
@ -17,8 +18,8 @@ __version__ = "v201809.0002-beta"
|
|||
def test_rewrite_lines():
|
||||
old_lines = REWRITE_FIXTURE.splitlines()
|
||||
patterns = ['__version__ = "{pycalver}"']
|
||||
new_vinfo = version.parse_version_info("v201911.0003")
|
||||
new_lines = rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
new_vinfo = v1version.parse_version_info("v201911.0003")
|
||||
new_lines = v1rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
|
||||
assert len(new_lines) == len(old_lines)
|
||||
assert "v201911.0003" not in "\n".join(old_lines)
|
||||
|
|
@ -31,8 +32,8 @@ def test_rewrite_final():
|
|||
|
||||
old_lines = REWRITE_FIXTURE.splitlines()
|
||||
patterns = ['__version__ = "v{year}{month}.{build_no}-{release_tag}"']
|
||||
new_vinfo = version.parse_version_info("v201911.0003")
|
||||
new_lines = rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
new_vinfo = v1version.parse_version_info("v201911.0003")
|
||||
new_lines = v1rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
|
||||
assert len(new_lines) == len(old_lines)
|
||||
assert "v201911.0003" not in "\n".join(old_lines)
|
||||
|
|
@ -46,9 +47,8 @@ def test_iter_file_paths():
|
|||
cfg = config.parse(ctx)
|
||||
assert cfg
|
||||
|
||||
file_paths = {
|
||||
str(file_path) for file_path, patterns in rewrite._iter_file_paths(cfg.file_patterns)
|
||||
}
|
||||
_paths_and_patterns = v1rewrite.iter_file_paths(cfg.file_patterns)
|
||||
file_paths = {str(file_path) for file_path, patterns in _paths_and_patterns}
|
||||
|
||||
assert file_paths == {"pycalver.toml", "README.md"}
|
||||
|
||||
|
|
@ -59,9 +59,8 @@ def test_iter_file_globs():
|
|||
cfg = config.parse(ctx)
|
||||
assert cfg
|
||||
|
||||
file_paths = {
|
||||
str(file_path) for file_path, patterns in rewrite._iter_file_paths(cfg.file_patterns)
|
||||
}
|
||||
_paths_and_patterns = v1rewrite.iter_file_paths(cfg.file_patterns)
|
||||
file_paths = {str(file_path) for file_path, patterns in _paths_and_patterns}
|
||||
|
||||
assert file_paths == {
|
||||
"setup.cfg",
|
||||
|
|
@ -80,7 +79,7 @@ def test_error_bad_path():
|
|||
|
||||
(project.dir / "setup.py").unlink()
|
||||
try:
|
||||
list(rewrite._iter_file_paths(cfg.file_patterns))
|
||||
list(v1rewrite.iter_file_paths(cfg.file_patterns))
|
||||
assert False, "expected IOError"
|
||||
except IOError as ex:
|
||||
assert "setup.py" in str(ex)
|
||||
|
|
@ -96,10 +95,10 @@ def test_error_bad_pattern():
|
|||
patterns["setup.py"] = patterns["setup.py"][0] + "invalid"
|
||||
|
||||
try:
|
||||
new_vinfo = version.parse_version_info("v201809.1234")
|
||||
list(rewrite.diff(new_vinfo, patterns))
|
||||
assert False, "expected rewrite.NoPatternMatch"
|
||||
except rewrite.NoPatternMatch as ex:
|
||||
new_vinfo = v1version.parse_version_info("v201809.1234")
|
||||
list(v1rewrite.diff(new_vinfo, patterns))
|
||||
assert False, "expected v1rewrite.NoPatternMatch"
|
||||
except v1rewrite.NoPatternMatch as ex:
|
||||
assert "setup.py" in str(ex)
|
||||
|
||||
|
||||
|
|
@ -109,21 +108,21 @@ __version__ = "2018.0002-beta"
|
|||
"""
|
||||
|
||||
|
||||
def test_optional_release():
|
||||
def test_v1_optional_release():
|
||||
old_lines = OPTIONAL_RELEASE_FIXTURE.splitlines()
|
||||
pattern = "{year}.{build_no}{release}"
|
||||
patterns = ['__version__ = "{year}.{build_no}{release}"']
|
||||
|
||||
new_vinfo = version.parse_version_info("2019.0003", pattern)
|
||||
new_lines = rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
new_vinfo = v1version.parse_version_info("2019.0003", pattern)
|
||||
new_lines = v1rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
|
||||
assert len(new_lines) == len(old_lines)
|
||||
assert "2019.0003" not in "\n".join(old_lines)
|
||||
new_text = "\n".join(new_lines)
|
||||
assert "2019.0003" in new_text
|
||||
|
||||
new_vinfo = version.parse_version_info("2019.0004-beta", pattern)
|
||||
new_lines = rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
new_vinfo = v1version.parse_version_info("2019.0004-beta", pattern)
|
||||
new_lines = v1rewrite.rewrite_lines(patterns, new_vinfo, old_lines)
|
||||
|
||||
# make sure optional release tag is added back on
|
||||
assert len(new_lines) == len(old_lines)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue