Commit 53b62f4e by Sébastien Eustace

Add the version command

parent 64bdcfe2
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
### Added ### Added
- Added compatibility with Python 3.4 and 3.5. - Added compatibility with Python 3.4 and 3.5.
- Added the `version` command to automatically bump the packages' version.
### Changed ### Changed
......
...@@ -281,3 +281,11 @@ This command locks (without installing) the dependencies specified in `pyproject ...@@ -281,3 +281,11 @@ This command locks (without installing) the dependencies specified in `pyproject
```bash ```bash
poetry lock poetry lock
``` ```
## version
This command bumps the version of the project
and writes the new version back to `pyproject.toml`
The new version should ideally be a valid semver string or a valid bump rule:
`patch`, `minor`, `major`, `prepatch`, `preminor`, `premajor`, `prerelease`.
...@@ -21,6 +21,7 @@ from .commands import RemoveCommand ...@@ -21,6 +21,7 @@ from .commands import RemoveCommand
from .commands import RunCommand from .commands import RunCommand
from .commands import ShowCommand from .commands import ShowCommand
from .commands import UpdateCommand from .commands import UpdateCommand
from .commands import VersionCommand
from .commands.debug import DebugInfoCommand from .commands.debug import DebugInfoCommand
from .commands.debug import DebugResolveCommand from .commands.debug import DebugResolveCommand
...@@ -99,6 +100,7 @@ class Application(BaseApplication): ...@@ -99,6 +100,7 @@ class Application(BaseApplication):
RunCommand(), RunCommand(),
ShowCommand(), ShowCommand(),
UpdateCommand(), UpdateCommand(),
VersionCommand(),
] ]
# Debug commands # Debug commands
......
...@@ -11,3 +11,4 @@ from .remove import RemoveCommand ...@@ -11,3 +11,4 @@ from .remove import RemoveCommand
from .run import RunCommand from .run import RunCommand
from .show import ShowCommand from .show import ShowCommand
from .update import UpdateCommand from .update import UpdateCommand
from .version import VersionCommand
import re
from .command import Command
class VersionCommand(Command):
"""
Bumps the version of the project.
version
{ version=patch }
"""
help = """\
The version command bumps the version of the project
and writes the new version back to <comment>pyproject.toml</>.
The new version should ideally be a valid semver string or a valid bump rule:
patch, minor, major, prepatch, preminor, premajor, prerelease.
"""
RESERVED = {
'major', 'minor', 'patch',
'premajor', 'preminor', 'prepatch',
'prerelease'
}
def handle(self):
version = self.argument('version')
if version in self.RESERVED:
version = self.increment_version(
self.poetry.package.pretty_version, version
)
self.line(
'Bumping version from <comment>{}</> to <info>{}</>'.format(
self.poetry.package.pretty_version, version
)
)
content = self.poetry.file.read()
poetry_content = content['tool']['poetry']
poetry_content['version'] = version
#self.poetry.file.write(content)
def increment_version(self, version, rule):
from poetry.semver.version_parser import VersionParser
parser = VersionParser()
version_regex = (
'v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?{}(?:\+[^\s]+)?'
).format(parser._modifier_regex)
m = re.match(version_regex, version)
if not m:
raise ValueError(
'The project\'s version doesn\'t seem to follow semver'
)
if m.group(3):
index = 2
elif m.group(2):
index = 1
else:
index = 0
matches = m.groups()[:index+1]
base = '.'.join(matches)
extra_matches = list(g or '' for g in m.groups()[4:])
extras = version[len('.'.join(matches)):]
increment = 1
is_prerelease = (extra_matches[0] or extra_matches[1]) != ''
bump_prerelease = rule in {
'premajor', 'preminor', 'prepatch', 'prerelease'
}
position = -1
if rule in {'major', 'premajor'}:
if m.group(1) != '0' or m.group(2) != '0' or not is_prerelease:
position = 0
elif rule in {'minor', 'preminor'}:
if m.group(2) != '0' or not is_prerelease:
position = 1
elif rule in {'patch', 'prepatch'}:
if not is_prerelease:
position = 2
elif rule == 'prerelease' and not is_prerelease:
position = 2
if position != -1:
extra_matches[0] = None
base = parser._manipulate_version_string(
matches,
position,
increment=increment
)
if bump_prerelease:
# We bump the prerelease part of the version
sep = ''
if not extra_matches[0]:
extra_matches[0] = 'alpha'
extra_matches[1] = '.0'
sep = '-'
else:
if extras.startswith(('.', '_', '-')):
sep = extras[0]
prerelease = extra_matches[1]
if not prerelease:
prerelease = '.1'
psep = ''
if prerelease.startswith(('.', '-')):
psep = prerelease[0]
prerelease = prerelease[1:]
new_prerelease = str(int(prerelease) + 1)
extra_matches[1] = '{}{}'.format(psep, new_prerelease)
extras = '{}{}{}{}'.format(
sep,
extra_matches[0],
extra_matches[1],
extra_matches[2]
)
else:
extras = ''
return '.'.join(base.split('.')[:max(index, position)+1]) + extras
...@@ -204,14 +204,14 @@ class VersionParser: ...@@ -204,14 +204,14 @@ class VersionParser:
Increment, decrement, or simply pad a version number. Increment, decrement, or simply pad a version number.
""" """
matches = [matches[i] matches = [matches[i]
if i < len(matches) - 1 and matches[i] is not None else '0' if i <= len(matches) - 1 and matches[i] is not None else pad
for i in range(4)] for i in range(4)]
for i in range(3, -1, -1): for i in range(3, -1, -1):
if i > position: if i > position:
matches[i] = pad matches[i] = pad
elif i == position and increment: elif i == position and increment:
matches[i] = int(matches[i]) + increment matches[i] = int(matches[i]) + increment
# If $matches[i] was 0, carry the decrement # If matches[i] was 0, carry the decrement
if matches[i] < 0: if matches[i] < 0:
matches[i] = pad matches[i] = pad
position -= 1 position -= 1
......
import pytest
from poetry.console.commands import VersionCommand
@pytest.fixture()
def command():
return VersionCommand()
@pytest.mark.parametrize(
'version, rule, expected',
[
('0.0.0', 'patch', '0.0.1'),
('0.0.0', 'minor', '0.1.0'),
('0.0.0', 'major', '1.0.0'),
('0.0', 'major', '1.0'),
('0.0', 'minor', '0.1'),
('0.0', 'patch', '0.0.1'),
('1.2.3', 'patch', '1.2.4'),
('1.2.3', 'minor', '1.3.0'),
('1.2.3', 'major', '2.0.0'),
('1.2.3', 'prepatch', '1.2.4-alpha.0'),
('1.2.3', 'preminor', '1.3.0-alpha.0'),
('1.2.3', 'premajor', '2.0.0-alpha.0'),
('1.2.3-beta.1', 'patch', '1.2.3'),
('1.2.3-beta.1', 'minor', '1.3.0'),
('1.2.3-beta.1', 'major', '2.0.0'),
('1.2.3-beta.1', 'prerelease', '1.2.3-beta.2'),
('1.2.3-beta1', 'prerelease', '1.2.3-beta2'),
('1.2.3beta1', 'prerelease', '1.2.3beta2'),
('1.2.3b1', 'prerelease', '1.2.3b2'),
('1.2.3', 'prerelease', '1.2.4-alpha.0')
]
)
def test_increment_version(version, rule, expected, command):
assert expected == command.increment_version(version, rule)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment