Skip to content

Commit

Permalink
Merge db77edb into 97a0449
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljoseph committed Aug 23, 2014
2 parents 97a0449 + db77edb commit 336f329
Show file tree
Hide file tree
Showing 24 changed files with 298 additions and 351 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ project="${PWD##*/}"
use_env $project

watch() {
tdaemon -t py --custom-args="--durations=3 --cov $project--cov-report term-missing -x"
tdaemon -d -t py --custom-args="--durations=3 --cov $project--cov-report term-missing -x tests" changes tests
}

alias test="py.test --durations=10 --cov $project --cov-report term-missing -x tests"
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ install:
before_success:
- coverage erase
script:
- py.test --durations=10 --cov changes --cov-report term-missing -x tests
- py.test --durations=10 --cov changes --cov-report term-missing tests
after_success:
- coverage combine
- coveralls
Expand Down
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include README.md CHANGELOG.md LICENSE
include README.md CHANGELOG.md LICENSE
recursive-include requirements *.txt
2 changes: 2 additions & 0 deletions changes/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def extract_attribute(module_name, attribute_name):


def replace_attribute(module_name, attribute_name, new_value, dry_run=True):
"""Update a metadata attribute"""
init_file = '%s/__init__.py' % module_name
_, tmp_file = tempfile.mkstemp()

Expand All @@ -36,6 +37,7 @@ def replace_attribute(module_name, attribute_name, new_value, dry_run=True):


def has_attribute(module_name, attribute_name):
"""Is this attribute present?"""
init_file = '%s/__init__.py' % module_name
return any(
[attribute_name in init_line for
Expand Down
51 changes: 21 additions & 30 deletions changes/changelog.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import logging
import re

import click
from plumbum.cmd import git

from changes import attributes, config, version
from changes import config, version
from changes.attributes import extract_attribute

log = logging.getLogger(__name__)


def write_new_changelog(module_name, filename, content_lines, dry_run=True):
heading_and_newline = (
'# [Changelog](%s/releases)\n' %
attributes.extract_attribute(module_name, '__url__')
)
def write_new_changelog(repo_url, filename, content_lines, dry_run=True):
heading_and_newline = '# [Changelog](%s/releases)\n' % repo_url

with open(filename, 'r+') as f:
existing = f.readlines()
Expand All @@ -34,13 +33,9 @@ def write_new_changelog(module_name, filename, content_lines, dry_run=True):
log.info('New changelog:\n%s', ''.join(content_lines))


def replace_sha_with_commit_link(git_log_content):
repo_url = attributes.extract_attribute(
config.common_arguments()[0],
'__url__'
)

for index, line in enumerate(git_log_content.split('\n')):
def replace_sha_with_commit_link(repo_url, git_log_content):
git_log_content = git_log_content.split('\n')
for index, line in enumerate(git_log_content):
# http://stackoverflow.com/a/468378/5549
sha1_re = re.match(r'^[0-9a-f]{5,40}\b', line)
if sha1_re:
Expand All @@ -56,32 +51,28 @@ def replace_sha_with_commit_link(git_log_content):
return git_log_content


def changelog():
module_name, dry_run, new_version = config.common_arguments()
def generate_changelog(context):
"""Generates an automatic changelog from your commit messages."""

changelog_content = [
'\n## [%s](%s/compare/%s...%s)\n\n' % (
new_version, attributes.extract_attribute(module_name, '__url__'),
version.current_version(module_name), new_version,
context.new_version, context.repo_url,
context.current_version, context.new_version,
)
]

git_log_content = None
git_log = 'log --oneline --no-merges --no-color'.split(' ')
try:

git_log = 'log --oneline --no-merges --no-color'.split(' ')
git_log.append('%s..master' % version.current_version(module_name))
git_log_content = git(git_log)
git_log_tag = git_log + '%s..master' % context.current_version
git_log_content = git(git_log_tag)
log.debug('content: %s' % git_log_content)
except:
log.warn('Error diffing previous version, initial release')
git_log_content = git(git_log.split(' '))

git_log_content = replace_sha_with_commit_link(git_log_content)

log.debug('content: %s' % git_log_content)
git_log_content = git(git_log)

# makes change log entries into bullet points
git_log_content = replace_sha_with_commit_link(context.repo_url, git_log_content)
# turn change log entries into markdown bullet points
if git_log_content:
[
changelog_content.append('* %s\n' % line)
Expand All @@ -90,9 +81,9 @@ def changelog():
]

write_new_changelog(
module_name,
config.CHANGELOG,
context.repo_url,
'CHANGELOG.md',
changelog_content,
dry_run=dry_run
dry_run=context.dry_run
)
log.info('Added content to CHANGELOG.md')
203 changes: 113 additions & 90 deletions changes/cli.py
Original file line number Diff line number Diff line change
@@ -1,99 +1,122 @@
"""
changes.
Usage:
changes [options] <module_name> changelog
changes [options] <module_name> release
changes [options] <module_name> bump_version
changes [options] <module_name> run_tests
changes [options] <module_name> install
changes [options] <module_name> upload
changes [options] <module_name> pypi
changes [options] <module_name> tag
changes -h | --help
Options:
--new-version=<ver> Specify version.
-p --patch Patch-level version increment.
-m --minor Minor-level version increment.
-M --major Minor-level version increment.
-h --help Show this screen.
--pypi=<pypi> Use alternative package index
--dry-run Prints the commands that would have been executed.
--skip-changelog For the release task: should the changelog be
generated and committed?
--tox Use `tox` instead of the default: `nosetests`
--test-command=<cmd> Command to use to test the newly installed package
--version-prefix=<prefix> Specify a prefix for version number tags
--noinput To be used in conjuction with one of the version
increment options above, this option stops
`changes` from confirming the new version number.
--package-name=<package> If your module and package aren't the same
--requirements=<req> Requirements file name (default: requirements.txt)
--debug Debug output.
The commands do the following:
changelog Generates an automatic changelog from your commit messages
bump_version Increments the __version__ attribute of your module's __init__
run_tests Runs your tests with nosetests
install Attempts to install the sdist and wheel
tag Tags your git repo with the new version number
upload Uploads your project with setup.py clean sdist bdist_wheel upload
pypi Attempts to install your package from pypi
release Runs all the previous commands
"""
import logging

from docopt import docopt

import changes
from changes import config, probe, util, version
from changes.changelog import changelog
from changes.flow import release
from changes.packaging import install, upload, pypi
from changes.vcs import tag, commit_version_change
from changes.verification import run_tests
from changes.version import bump_version
import click

from changes import attributes, config, probe, version
from changes.changelog import generate_changelog
from changes.flow import perform_release
from changes.packaging import install_package, upload_package, install_from_pypi
from changes.vcs import tag_and_push
from changes.version import increment_version

log = logging.getLogger(__name__)


def initialise():
arguments = docopt(__doc__, version=changes.__version__)
debug = arguments['--debug']
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
log.debug('arguments: %s', arguments)
config.arguments = arguments
return arguments


def main():
arguments = initialise()
class Changes(object):
test_command = None
pypi = None
skip_changelog = None

def __init__(self, module_name, dry_run, debug, no_input, requirements, new_version, current_version, repo_url, version_prefix):
self.module_name = module_name
self.dry_run = dry_run
self.debug = debug
self.no_input = no_input
self.requirements = requirements
self.new_version = version_prefix + new_version if version_prefix else new_version
self.current_version = current_version
self.repo_url = repo_url


@click.group()
@click.argument('module_name')
@click.option('--dry-run', is_flag=True, default=False, help='Prints (instead of executing) the operations to be performed.')
@click.option('--debug', is_flag=True, default=False, help='Enables debug output.')
@click.option('--no-input', is_flag=True, default=False, help='Suppresses version number confirmation prompt.')
@click.option('--requirements', default='requirements.txt', help='Requirements file name')
@click.option('-p', '--patch', is_flag=True, help='Patch-level version increment.')
@click.option('-m', '--minor', is_flag=True, help='Minor-level version increment.')
@click.option('-M', '--major', is_flag=True, help='Minor-level version increment.')
@click.option('--version-prefix', help='Specify a prefix for version number tags.')
@click.pass_context
def main(context, module_name, dry_run, debug, no_input, requirements, patch, minor, major, version_prefix):
"""Ch-ch-changes"""

version_arguments = ['--major', '--minor', '--patch']
commands = ['release', 'changelog', 'run_tests', 'bump_version', 'tag',
'upload', 'install', 'pypi']
suppress_version_prompt_for = ['run_tests', 'upload']

if arguments['--new-version']:
arguments['new_version'] = arguments['--new-version']

module_name = config.arguments['<module_name>']

if not probe.probe_project(module_name):
raise Exception('Project does not meet `changes` requirements')
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)

for command in commands:
if arguments[command]:
if command not in suppress_version_prompt_for:
arguments['new_version'] = version.get_new_version(
module_name,
version.current_version(module_name),
arguments.get('--noinput', False),
**util.extract_arguments(arguments, version_arguments)
)
globals()[command]()
new_version = version.get_new_version(
module_name,
version.current_version(module_name),
no_input, major, minor, patch,
)

current_version = version.current_version(module_name)
repo_url = attributes.extract_attribute(module_name, '__url__')
context.obj = Changes(module_name, dry_run, debug, no_input, requirements, new_version, current_version, repo_url, version_prefix)

probe.probe_project(context.obj)


@click.command()
@click.pass_context
def changelog(context):
"""Generates an automatic changelog from your commit messages."""
generate_changelog(context.obj)


@click.command()
@click.pass_context
def bump_version(context):
"""Increments the __version__ attribute of your module's __init__."""
increment_version(context.obj)


@click.command()
@click.option('--test-command', help='Command to use to test the newly installed package.')
@click.pass_context
def install(context, test_command):
"""Attempts to install the sdist and wheel."""
context.obj.test_command = test_command
install_package(context.obj)


@click.command()
@click.option('--pypi', help='Use an alternative package index.')
@click.pass_context
def upload(context, pypi):
"""Uploads your project with setup.py clean sdist bdist_wheel upload."""
context.obj.pypi = pypi
upload_package(context.obj)


@click.command()
@click.option('--pypi', help='Use an alternative package index.')
@click.pass_context
def pypi(context, pypi):
"""Attempts to install your package from pypi."""
context.obj.pypi = pypi
install_from_pypi(context.obj)


@click.command()
@click.pass_context
def tag(context):
"""Tags your git repo with the new version number"""
tag_and_push(context.obj)

@click.command()
@click.option('--skip-changelog', is_flag=True, help='For the release task: should the changelog be generated and committed?')
@click.pass_context
def release(context, skip_changelog):
"""Executes the release process."""
context.obj.skip_changelog = skip_changelog
perform_release(context.obj)


main.add_command(changelog)
main.add_command(bump_version)
main.add_command(install)
main.add_command(upload)
main.add_command(pypi)
main.add_command(tag)
main.add_command(release)
23 changes: 0 additions & 23 deletions changes/config.py

This file was deleted.

Loading

0 comments on commit 336f329

Please sign in to comment.