PR#578: cli: fix changelog encode for PY3

Merges #578
https://pagure.io/koji/pull-request/578

Fixes #577
https://pagure.io/koji/issue/577
buildinfo --changelog prints bytestring
This commit is contained in:
Mike McLean 2017-12-07 14:26:52 -05:00
commit 62d4d1d1d1
4 changed files with 74 additions and 11 deletions

View file

@ -2966,6 +2966,21 @@ def removeNonprintable(value):
# expects raw-encoded string, not unicode
return value.translate(None, NONPRINTABLE_CHARS)
def _fix_print(value):
"""Fix a string so it is suitable to print
In python2, this means we return a utf8 encoded str
In python3, this means we return unicode
"""
if six.PY2 and isinstance(value, six.text_type):
return value.encode('utf8')
elif six.PY3 and isinstance(value, six.binary_type):
return value.decode('utf8')
else:
return value
def fixEncoding(value, fallback='iso8859-15', remove_nonprintable=False):
"""
Convert value to a 'str' object encoded as UTF-8.
@ -2976,8 +2991,8 @@ def fixEncoding(value, fallback='iso8859-15', remove_nonprintable=False):
return six.b('')
if isinstance(value, six.text_type):
# value is already unicode, so just convert it
# to a utf8-encoded str
# value is already unicode(py3: str), so just convert it
# to a utf8-encoded str(py3: bytes)
s = value.encode('utf8')
else:
# value is a str, but may be encoded in utf8 or some

View file

@ -48,9 +48,11 @@ try:
except ImportError: # pragma: no cover
from sha import new as sha1_constructor
def _changelogDate(cldate):
return time.strftime('%a %b %d %Y', time.strptime(koji.formatTime(cldate), '%Y-%m-%d %H:%M:%S'))
def formatChangelog(entries):
"""Format a list of changelog entries (dicts)
into a string representation."""
@ -59,9 +61,9 @@ def formatChangelog(entries):
result += """* %s %s
%s
""" % (_changelogDate(entry['date']), entry['author'].encode("utf-8"),
entry['text'].encode("utf-8"))
""" % (_changelogDate(entry['date']),
koji._fix_print(entry['author']),
koji._fix_print(entry['text']))
return result
DATE_RE = re.compile(r'(\d+)-(\d+)-(\d+)')

View file

@ -7,6 +7,7 @@ from __future__ import absolute_import
import koji
import six
import unittest
import mock
class FixEncodingTestCase(unittest.TestCase):
"""Main test case container"""
@ -44,6 +45,23 @@ class FixEncodingTestCase(unittest.TestCase):
d = a[:-3] + u'\x00\x01' + a[-3:]
self.assertEqual(koji.fixEncoding(d, remove_nonprintable=True), b)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_fix_print(self, stdout):
"""Test the _fix_print function"""
expected = ''
for a, b in self.simple_values:
if six.PY3:
self.assertEqual(koji._fix_print(b), a)
else:
self.assertEqual(koji._fix_print(b), b)
print(koji._fix_print(b))
if six.PY3:
expected = expected + a + '\n'
else:
expected = expected + b + '\n'
actual = stdout.getvalue()
self.assertEqual(actual, expected)
complex_values = [
# [ value, fixed ]
[{}, {}],

View file

@ -1,3 +1,4 @@
# coding=utf-8
from __future__ import absolute_import
import mock
import unittest
@ -494,12 +495,39 @@ class MavenUtilTestCase(unittest.TestCase):
def test_formatChangelog(self):
"""Test formatChangelog function"""
entries = {'date': datetime(2017, 10, 10, 12, 34, 56),
'author': 'koji <kojiadmin@localhost.local>',
'text': 'This is a test release'}
sample = "* Tue Oct 10 2017 {0}\n{1}\n\n".format(
entries['author'].encode('utf-8'), entries['text'].encode('utf-8'))
self.assertEqual(sample, koji.util.formatChangelog((entries,)))
data = [
{
'author': 'Happy Koji User <user1@example.com> - 1.1-1',
'date': '2017-10-25 08:00:00',
'date_ts': 1508932800,
'text': '- Line 1\n- Line 2',
},
{
'author': u'Happy \u0138\u014dji \u016cs\u0259\u0155 <user2@example.com>',
'date': '2017-08-28 08:00:00',
'date_ts': 1503921600,
'text': '- some changelog entry',
},
{
'author': 'Koji Admin <admin@example.com> - 1.49-6',
'date': datetime(2017, 10, 10, 12, 34, 56),
'text': '- mass rebuild',
}
]
expect = (
'''* Wed Oct 25 2017 Happy Koji User <user1@example.com> - 1.1-1
- Line 1
- Line 2
* Mon Aug 28 2017 Happy ĸōji Ŭsəŕ <user2@example.com>
- some changelog entry
* Tue Oct 10 2017 Koji Admin <admin@example.com> - 1.49-6
- mass rebuild
''')
result = koji.util.formatChangelog(data)
self.assertMultiLineEqual(expect, result)
def test_parseTime(self):
"""Test parseTime function"""