Skip to content

Commit

Permalink
Merge pull request #143 from p12tic/accept-multiple-dots-filenames
Browse files Browse the repository at this point in the history
Accept multiple dots in filenames
  • Loading branch information
hawkowl authored Aug 11, 2019
2 parents e134811 + c4eb4ea commit 018a6d8
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 24 deletions.
53 changes: 35 additions & 18 deletions src/towncrier/_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,38 @@
from jinja2 import Template


# Returns ticket, category and counter or (None, None, None) if the basename
# could not be parsed
def parse_newfragment_basename(basename, definitions):
parts = basename.split(u".")

if len(parts) == 1:
return (None, None, None)
if len(parts) == 2:
ticket, category = parts
return ticket, category, 0

# fix-1.2.3.feature and fix.1.feature.2 are valid formats. The former is
# used in projects which don't put ticket numbers to newfragment names.
if parts[-1] in definitions:
category = parts[-1]
ticket = parts[-2]
return ticket, category, 0

# If there is a number after the category then use it as a counter,
# otherwise ignore it.
# This means 1.feature.1 and 1.feature do not conflict but
# 1.feature.rst and 1.feature do.
counter = 0
try:
counter = int(parts[-1])
except ValueError:
pass
category = parts[-2]
ticket = parts[-3]
return ticket, category, counter


# Returns a structure like:
#
# OrderedDict([
Expand Down Expand Up @@ -45,25 +77,10 @@ def find_fragments(base_directory, sections, fragment_directory, definitions):
file_content = {}

for basename in files:
parts = basename.split(u".")

counter = 0
if len(parts) == 1:
continue
else:
ticket, category = parts[:2]

# If there is a number after the category then use it as a counter,
# otherwise ignore it.
# This means 1.feature.1 and 1.feature do not conflict but
# 1.feature.rst and 1.feature do.
if len(parts) > 2:
try:
counter = int(parts[2])
except ValueError:
pass

if category not in definitions:
ticket, category, counter = parse_newfragment_basename(basename,
definitions)
if category is None or category not in definitions:
continue

full_filename = os.path.join(section_dir, basename)
Expand Down
1 change: 1 addition & 0 deletions src/towncrier/newsfragments/142.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Accept newsfragment filenames with multiple dots, like `fix-1.2.3.bugfix`.
43 changes: 43 additions & 0 deletions src/towncrier/test/test_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) Povilas Kanapickas, 2019
# See LICENSE for details.

from twisted.trial.unittest import TestCase

from .._builder import parse_newfragment_basename


class TestParseNewsfragmentBasename(TestCase):

def test_simple(self):
self.assertEqual(parse_newfragment_basename('123.feature', ['feature']),
('123', 'feature', 0))

def test_counter(self):
self.assertEqual(parse_newfragment_basename('123.feature.1',
['feature']),
('123', 'feature', 1))

def test_ignores_extension(self):
self.assertEqual(parse_newfragment_basename('123.feature.ext',
['feature']),
('123', 'feature', 0))

def test_non_numeric_ticket(self):
self.assertEqual(parse_newfragment_basename('baz.feature',
['feature']),
('baz', 'feature', 0))

def test_dots_in_ticket_name(self):
self.assertEqual(parse_newfragment_basename('baz.1.2.feature',
['feature']),
('2', 'feature', 0))

def test_dots_in_ticket_name_unknown_category(self):
self.assertEqual(parse_newfragment_basename('baz.1.2.notfeature',
['feature']),
('1', '2', 0))

def test_dots_in_ticket_name_and_counter(self):
self.assertEqual(parse_newfragment_basename('baz.1.2.feature.3',
['feature']),
('2', 'feature', 3))
33 changes: 27 additions & 6 deletions src/towncrier/test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def test_happy_path(self):
# Towncrier treats this as 124.feature, ignoring .rst extension
with open("foo/newsfragments/124.feature.rst", "w") as f:
f.write("Extends levitation")
# Towncrier supports non-numeric newsfragment names.
with open("foo/newsfragments/baz.feature.rst", "w") as f:
f.write("Baz levitation")
# Towncrier supports files that have a dot in the name of the
# newsfragment
with open("foo/newsfragments/fix-1.2.feature", "w") as f:
f.write("Baz fix levitation")
# Towncrier ignores files that don't have a dot
with open("foo/newsfragments/README", "w") as f:
f.write("Blah blah")
Expand All @@ -44,12 +51,26 @@ def test_happy_path(self):
self.assertEqual(0, result.exit_code)
self.assertEqual(
result.output,
u"Loading template...\nFinding news fragments...\nRendering news "
u"fragments...\nDraft only -- nothing has been written.\nWhat is "
u"seen below is what would be written.\n\nFoo 1.2.3 (01-01-2001)"
u"\n======================\n"
u"\n\nFeatures\n--------\n\n- Adds levitation (#123)\n"
u"- Extends levitation (#124)\n\n",
dedent("""\
Loading template...
Finding news fragments...
Rendering news fragments...
Draft only -- nothing has been written.
What is seen below is what would be written.
Foo 1.2.3 (01-01-2001)
======================
Features
--------
- Baz levitation (baz)
- Baz fix levitation (#2)
- Adds levitation (#123)
- Extends levitation (#124)
""")
)

def test_collision(self):
Expand Down

0 comments on commit 018a6d8

Please sign in to comment.