mirror of https://github.com/docker/compose.git
Merge pull request #1924 from dnephin/python3_fix_for_logs
Fix `docker-compose logs` on python3
This commit is contained in:
commit
e777d08854
|
@ -57,7 +57,7 @@ class LogPrinter(object):
|
||||||
def _make_log_generator(self, container, color_fn):
|
def _make_log_generator(self, container, color_fn):
|
||||||
prefix = color_fn(self._generate_prefix(container))
|
prefix = color_fn(self._generate_prefix(container))
|
||||||
# Attach to container before log printer starts running
|
# Attach to container before log printer starts running
|
||||||
line_generator = split_buffer(self._attach(container), '\n')
|
line_generator = split_buffer(self._attach(container), u'\n')
|
||||||
|
|
||||||
for line in line_generator:
|
for line in line_generator:
|
||||||
yield prefix + line
|
yield prefix + line
|
||||||
|
|
|
@ -2,12 +2,12 @@ from __future__ import absolute_import
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import ssl
|
import ssl
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
import six
|
||||||
from docker import version as docker_py_version
|
from docker import version as docker_py_version
|
||||||
from six.moves import input
|
from six.moves import input
|
||||||
|
|
||||||
|
@ -36,39 +36,6 @@ def yesno(prompt, default=None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# http://stackoverflow.com/a/5164027
|
|
||||||
def prettydate(d):
|
|
||||||
diff = datetime.datetime.utcnow() - d
|
|
||||||
s = diff.seconds
|
|
||||||
if diff.days > 7 or diff.days < 0:
|
|
||||||
return d.strftime('%d %b %y')
|
|
||||||
elif diff.days == 1:
|
|
||||||
return '1 day ago'
|
|
||||||
elif diff.days > 1:
|
|
||||||
return '{0} days ago'.format(diff.days)
|
|
||||||
elif s <= 1:
|
|
||||||
return 'just now'
|
|
||||||
elif s < 60:
|
|
||||||
return '{0} seconds ago'.format(s)
|
|
||||||
elif s < 120:
|
|
||||||
return '1 minute ago'
|
|
||||||
elif s < 3600:
|
|
||||||
return '{0} minutes ago'.format(s / 60)
|
|
||||||
elif s < 7200:
|
|
||||||
return '1 hour ago'
|
|
||||||
else:
|
|
||||||
return '{0} hours ago'.format(s / 3600)
|
|
||||||
|
|
||||||
|
|
||||||
def mkdir(path, permissions=0o700):
|
|
||||||
if not os.path.exists(path):
|
|
||||||
os.mkdir(path)
|
|
||||||
|
|
||||||
os.chmod(path, permissions)
|
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def find_candidates_in_parent_dirs(filenames, path):
|
def find_candidates_in_parent_dirs(filenames, path):
|
||||||
"""
|
"""
|
||||||
Given a directory path to start, looks for filenames in the
|
Given a directory path to start, looks for filenames in the
|
||||||
|
@ -97,11 +64,11 @@ def split_buffer(reader, separator):
|
||||||
separator, except for the last one if none was found on the end
|
separator, except for the last one if none was found on the end
|
||||||
of the input.
|
of the input.
|
||||||
"""
|
"""
|
||||||
buffered = str('')
|
buffered = six.text_type('')
|
||||||
separator = str(separator)
|
separator = six.text_type(separator)
|
||||||
|
|
||||||
for data in reader:
|
for data in reader:
|
||||||
buffered += data
|
buffered += data.decode('utf-8')
|
||||||
while True:
|
while True:
|
||||||
index = buffered.find(separator)
|
index = buffered.find(separator)
|
||||||
if index == -1:
|
if index == -1:
|
||||||
|
|
|
@ -5,14 +5,14 @@ import os
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from .. import unittest
|
|
||||||
from compose.cli.log_printer import LogPrinter
|
from compose.cli.log_printer import LogPrinter
|
||||||
|
from tests import unittest
|
||||||
|
|
||||||
|
|
||||||
class LogPrinterTest(unittest.TestCase):
|
class LogPrinterTest(unittest.TestCase):
|
||||||
def get_default_output(self, monochrome=False):
|
def get_default_output(self, monochrome=False):
|
||||||
def reader(*args, **kwargs):
|
def reader(*args, **kwargs):
|
||||||
yield "hello\nworld"
|
yield b"hello\nworld"
|
||||||
|
|
||||||
container = MockContainer(reader)
|
container = MockContainer(reader)
|
||||||
output = run_log_printer([container], monochrome=monochrome)
|
output = run_log_printer([container], monochrome=monochrome)
|
||||||
|
@ -36,11 +36,10 @@ class LogPrinterTest(unittest.TestCase):
|
||||||
glyph = u'\u2022'
|
glyph = u'\u2022'
|
||||||
|
|
||||||
def reader(*args, **kwargs):
|
def reader(*args, **kwargs):
|
||||||
yield glyph + '\n'
|
yield glyph.encode('utf-8') + b'\n'
|
||||||
|
|
||||||
container = MockContainer(reader)
|
container = MockContainer(reader)
|
||||||
output = run_log_printer([container])
|
output = run_log_printer([container])
|
||||||
|
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
output = output.decode('utf-8')
|
output = output.decode('utf-8')
|
||||||
|
|
|
@ -8,33 +8,33 @@ from compose.cli.utils import split_buffer
|
||||||
class SplitBufferTest(unittest.TestCase):
|
class SplitBufferTest(unittest.TestCase):
|
||||||
def test_single_line_chunks(self):
|
def test_single_line_chunks(self):
|
||||||
def reader():
|
def reader():
|
||||||
yield 'abc\n'
|
yield b'abc\n'
|
||||||
yield 'def\n'
|
yield b'def\n'
|
||||||
yield 'ghi\n'
|
yield b'ghi\n'
|
||||||
|
|
||||||
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi\n'])
|
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi\n'])
|
||||||
|
|
||||||
def test_no_end_separator(self):
|
def test_no_end_separator(self):
|
||||||
def reader():
|
def reader():
|
||||||
yield 'abc\n'
|
yield b'abc\n'
|
||||||
yield 'def\n'
|
yield b'def\n'
|
||||||
yield 'ghi'
|
yield b'ghi'
|
||||||
|
|
||||||
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi'])
|
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi'])
|
||||||
|
|
||||||
def test_multiple_line_chunk(self):
|
def test_multiple_line_chunk(self):
|
||||||
def reader():
|
def reader():
|
||||||
yield 'abc\ndef\nghi'
|
yield b'abc\ndef\nghi'
|
||||||
|
|
||||||
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi'])
|
self.assert_produces(reader, ['abc\n', 'def\n', 'ghi'])
|
||||||
|
|
||||||
def test_chunked_line(self):
|
def test_chunked_line(self):
|
||||||
def reader():
|
def reader():
|
||||||
yield 'a'
|
yield b'a'
|
||||||
yield 'b'
|
yield b'b'
|
||||||
yield 'c'
|
yield b'c'
|
||||||
yield '\n'
|
yield b'\n'
|
||||||
yield 'd'
|
yield b'd'
|
||||||
|
|
||||||
self.assert_produces(reader, ['abc\n', 'd'])
|
self.assert_produces(reader, ['abc\n', 'd'])
|
||||||
|
|
||||||
|
@ -42,12 +42,12 @@ class SplitBufferTest(unittest.TestCase):
|
||||||
string = u"a\u2022c\n"
|
string = u"a\u2022c\n"
|
||||||
|
|
||||||
def reader():
|
def reader():
|
||||||
yield string
|
yield string.encode('utf-8')
|
||||||
|
|
||||||
self.assert_produces(reader, [string])
|
self.assert_produces(reader, [string])
|
||||||
|
|
||||||
def assert_produces(self, reader, expectations):
|
def assert_produces(self, reader, expectations):
|
||||||
split = split_buffer(reader(), '\n')
|
split = split_buffer(reader(), u'\n')
|
||||||
|
|
||||||
for (actual, expected) in zip(split, expectations):
|
for (actual, expected) in zip(split, expectations):
|
||||||
self.assertEqual(type(actual), type(expected))
|
self.assertEqual(type(actual), type(expected))
|
||||||
|
|
Loading…
Reference in New Issue