Last active
August 12, 2017 07:26
-
-
Save cmcginty/dc862da9d01837dca3d81d5ff1d33022 to your computer and use it in GitHub Desktop.
Command-line tool for automated software version numbering.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import click | |
MIN_DIGITS = 2 | |
MAX_DIGITS = 3 | |
@click.command() | |
@click.argument('version') | |
@click.option('--major', 'bump_idx', flag_value=0, help='Increment major number.') | |
@click.option('--minor', 'bump_idx', flag_value=1, help='Increment minor number.') | |
@click.option('--patch', 'bump_idx', flag_value=2, default=True, help='Increment patch number.') | |
def cli(version, bump_idx): | |
"""Bumps a MAJOR.MINOR.PATCH version string at the specified index location or 'patch' digit. An | |
optional 'v' prefix is allow and will be included in the output if found.""" | |
prefix = version[0] if version[0].isalpha() else '' | |
digits = version.lower().lstrip('v').split('.') | |
if len(digits) > MAX_DIGITS: | |
click.secho('ERROR: Too many digits', fg='red', err=True) | |
sys.exit(1) | |
digits = (digits + ['0'] * MAX_DIGITS)[:MAX_DIGITS] # Extend total digits to max. | |
digits[bump_idx] = str(int(digits[bump_idx]) + 1) # Increment the desired digit. | |
# Zero rightmost digits after bump position. | |
for i in range(bump_idx + 1, MAX_DIGITS): | |
digits[i] = '0' | |
digits = digits[:max(MIN_DIGITS, bump_idx + 1)] # Trim rightmost digits. | |
click.echo(prefix + '.'.join(digits), nl=False) | |
if __name__ == '__main__': | |
cli() | |
import unittest | |
from click.testing import CliRunner | |
class VersionBumpTestCase(unittest.TestCase): | |
def setUp(self): | |
self.runner = CliRunner() | |
def test_greater_than_max_digits_is_error(self): | |
result = self.runner.invoke(cli, ['0.0.0.0']) | |
self.assertIn('ERROR', result.output) | |
self.assertEqual(result.exit_code, 1) | |
def test_v_prefix_is_kept_in_result(self): | |
result = self.runner.invoke(cli, ['v0.0.0']) | |
self.assertEqual('v0.0.1', result.output) | |
def test_patch_arg(self): | |
result = self.runner.invoke(cli, ['0.0.0', '--patch']) | |
self.assertEqual('0.0.1', result.output) | |
def test_minor_arg(self): | |
result = self.runner.invoke(cli, ['0.0.0', '--minor']) | |
self.assertEqual('0.1', result.output) | |
def test_major_arg(self): | |
result = self.runner.invoke(cli, ['0.0.0', '--major']) | |
self.assertEqual('1.0', result.output) | |
def test_short_ver_with_patch_arg(self): | |
result = self.runner.invoke(cli, ['1', '--patch']) | |
self.assertEqual('1.0.1', result.output) | |
def test_short_ver_with_minor_arg(self): | |
result = self.runner.invoke(cli, ['1', '--minor']) | |
self.assertEqual('1.1', result.output) | |
def test_short_ver_with_major_arg(self): | |
result = self.runner.invoke(cli, ['1', '--major']) | |
self.assertEqual('2.0', result.output) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment