Skip to content

Commit

Permalink
Merge branch 'release/0.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
prawn-cake committed Jul 8, 2016
2 parents 9f581ad + b2a6502 commit fe267cd
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.1.1
current_version = 0.1.2
tag = False
tag_name = {new_version}
commit = True
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.vagrant
.coverage
.tox
release.txt
7 changes: 6 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
Changelog
=========

0.1.1 (2016-07-07)
0.1.2 (2016-07-08)
--------------------
* [Improvement] py2/3 compatibility
* [Improvement] implemented changelog.undo()

0.1.1 (2016-07-07)
------------------
* [Improvement] Rename cli command current -> last
* [Improvement] updated append command, added --no-edit key
* [Improvement] improve add_message feature, new --split-by key to add multiple entries at once
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ Changelog may look like

### New release

Release currently unreleased version

# Open in editor to update version manually
md-changelog release

# Set the version explicitly
md-changelog release -v 1.0.0


Expand Down
23 changes: 21 additions & 2 deletions md_changelog/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ def __repr__(self):
(self.__class__.__name__, str(self.version), str(self._date),
self.declared, len(self._messages))

def __eq__(self, other):
return all([self.version == other.version,
self._date == other._date,
self._messages == other._messages])


class Changelog(object):
"""Changelog representation"""
Expand All @@ -119,6 +124,7 @@ def __init__(self, path, entries=None):
self.header = 'Changelog'
self.path = path
self.entries = entries or []
self._backup = None

@property
def last_entry(self):
Expand Down Expand Up @@ -146,11 +152,11 @@ def parse(cls, path):
return instance

@classmethod
def parse_entries(cls, text: str):
def parse_entries(cls, text):
"""Parse text into log entries
:param text: str: raw changelog text
:param only_last: bool: parse only last entry
:rtype: list
"""
entries = []
stack = []
Expand Down Expand Up @@ -189,6 +195,7 @@ def new_entry(self):
:return: LogEntry instance
"""
self._make_backup()
log_entry = LogEntry()
if len(self.entries) == 0:
last_version = self.INIT_VERSION
Expand All @@ -205,6 +212,7 @@ def add_entry(self, entry):
if not isinstance(entry, LogEntry):
raise ValueError('Wrong entry type %r, must be %s'
% (entry, LogEntry))
self._make_backup()
self.entries.append(entry)

def save(self):
Expand All @@ -224,5 +232,16 @@ def reload(self):
reloaded = self.parse(self.path)
self.__dict__ = copy.deepcopy(reloaded.__dict__)

def undo(self):
if self._backup:
self.__dict__ = copy.deepcopy(self._backup.__dict__)
return True
return False

def _make_backup(self):
"""Make deep copy of itself
"""
self._backup = copy.deepcopy(self)

def __repr__(self):
return "%s(entries=%d)" % (self.__class__.__name__, len(self.entries))
5 changes: 1 addition & 4 deletions md_changelog/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import argparse
import configparser
import copy
import functools
import logging
import os
Expand Down Expand Up @@ -136,8 +135,6 @@ def release(args):
logger.info("No UNRELEASED entries. Run 'md-changelog append'")
sys.exit(99)

# backup = copy.deepcopy(changelog)

if args.version:
# Set up specific version
v = tokens.Version(args.version)
Expand All @@ -155,7 +152,7 @@ def release(args):
# confirm = input('Confirm changes? [Y/n]')

# if confirm == 'n':
# backup.save()
# changelog.undo()
# logger.info('Undo changes')
# sys.exit(0)

Expand Down
24 changes: 24 additions & 0 deletions md_changelog/tests/test_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,27 @@ def test_new_changelog_save():
assert len(changelog.entries) == len(changelog_2.entries)
for e1, e2 in zip(changelog.entries, changelog_2.entries):
assert e1.eval() == e2.eval()


def test_changelog_backup():
with tempfile.NamedTemporaryFile() as tmp_file:
changelog = Changelog(path=tmp_file.name)
assert len(changelog.entries) == 0

# Test undo new entry
changelog.new_entry()
assert len(changelog.entries) == 1

assert changelog.undo() is True
assert len(changelog.entries) == 0

# Add new entry + one entry manually, then undo the last one
new_entry = changelog.new_entry()
entry = LogEntry(version=tokens.Version('0.1.0'), date=tokens.Date())
entry.add_message(Message(text='Test message'))
changelog.add_entry(entry)
assert len(changelog.entries) == 2

assert changelog.undo() is True
assert len(changelog.entries) == 1
assert changelog.entries[0] == new_entry
24 changes: 20 additions & 4 deletions md_changelog/tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# -*- coding: utf-8 -*-
import os.path as op
import tempfile

import mock
import pytest
import os.path as op
from unittest import mock

# from six.moves import tempfile
from contextlib import contextmanager

import shutil

from md_changelog import main
from md_changelog.entry import Changelog
from md_changelog.exceptions import ConfigNotFoundError
Expand All @@ -14,10 +20,20 @@ def parser():
return main.create_parser()


@contextmanager
def TemporaryDirectory():
"""Py2/3 tempfile.TemporaryDirectory replacement without external backports
"""
tmp_dir = tempfile.mkdtemp()
yield tmp_dir
shutil.rmtree(tmp_dir)


@contextmanager
def get_test_config():
parser = main.create_parser()
with tempfile.TemporaryDirectory() as tmp_dir:
with TemporaryDirectory() as tmp_dir:
args = parser.parse_args(['init', '--path', tmp_dir])
args.func(args)
cfg_path = op.join(tmp_dir, main.CONFIG_NAME)
Expand All @@ -31,7 +47,7 @@ def test_get_config():


def test_init(parser):
with tempfile.TemporaryDirectory() as tmp_dir:
with TemporaryDirectory() as tmp_dir:
args = parser.parse_args(['init', '--path', tmp_dir])
args.func(args)

Expand Down
26 changes: 21 additions & 5 deletions md_changelog/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@


class Evaluable(object):
@abc.abstractmethod
def eval(self):
"""This method should generally evaluate the value of it's holder.
In most cases it should return some markdown string
"""
pass
raise NotImplementedError()


class Token(Evaluable):
"""Token interface"""

@abc.abstractclassmethod
def parse(self, raw_text):
pass
raise NotImplementedError()

def __str__(self):
return str(self.eval())
Expand Down Expand Up @@ -74,6 +72,9 @@ def __ge__(self, other):
def __le__(self, other):
return self._version_tuple <= other._version_tuple

def __eq__(self, other):
return self._version_tuple == other._version_tuple


class Date(Token):
"""Date token"""
Expand Down Expand Up @@ -110,7 +111,22 @@ def eval(self):
return self.UNRELEASED

def __repr__(self):
return ''
return '%s(%s)' % (self.__class__.__name__, self.dt)

def __eq__(self, other):
return self.dt == other.dt

def __gt__(self, other):
return self.dt > other.dt

def __lt__(self, other):
return self.dt < other.dt

def __ge__(self, other):
return self.dt >= other.dt

def __le__(self, other):
return self.dt <= other.dt


# Declare message type namedtuple
Expand Down
3 changes: 3 additions & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mock
six
configparser; python_version < '3.2'
pytest
coverage
11 changes: 10 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import sys
from setuptools import setup


req = ['six']
if sys.version_info >= (3, 2):
pass
else:
req.extend(["configparser"])

setup(
name='md-changelog',
version='0.1.1',
version='0.1.2',
packages=['md_changelog'],
url='',
license='MIT',
author='Maksim Ekimovskii',
author_email='ekimovsky.maksim@gmail.com',
description='Changelog command-line tool manager',
install_requires=req,
entry_points={
'console_scripts': [
'md-changelog = md_changelog.main:main'
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py34
envlist = py27, py34

[testenv]
passenv = *
Expand Down

0 comments on commit fe267cd

Please sign in to comment.