6 Copyright (C) 2007, Karl Hasselström <kha@treskal.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see http://www.gnu.org/licenses/.
23 def __init__(self
, file):
25 self
.write
= file.write
26 self
.write_bytes
= file.buffer.write
27 self
.flush
= file.flush
29 self
.write
= self
.write_bytes
= lambda s
: None
30 self
.flush
= lambda: None
31 self
.at_start_of_line
= True
35 """Ensure that we're at the beginning of a line."""
36 if not self
.at_start_of_line
:
38 self
.at_start_of_line
= True
40 def single_line(self
, msg
, print_newline
=True, need_newline
=True):
41 """Write a single line. Newline before and after are
42 separately configurable."""
45 if self
.at_start_of_line
:
46 self
.write(' ' * self
.level
)
50 self
.at_start_of_line
= True
53 self
.at_start_of_line
= False
55 def tagged_lines(self
, tag
, lines
):
57 width
= 79 - (2 * self
.level
) - len(tag
)
61 for wl
in textwrap
.wrap(line
, width
, break_long_words
=False)
64 self
.single_line(tag
+ line
)
67 def write_line(self
, line
):
68 """Write one line of text on a lines of its own, not
71 self
.write('%s\n' % line
)
72 self
.at_start_of_line
= True
76 def __init__(self
, file=None):
78 self
._stdout
= self
._stderr
= Output(file)
81 self
._stdout
= Output(
82 io
.open(sys
.stdout
.fileno(), 'w', buffering
=1, encoding
='utf-8')
84 self
._stderr
= Output(
85 io
.open(sys
.stderr
.fileno(), 'w', buffering
=1, encoding
='utf-8')
87 self
.isatty
= sys
.stdout
.isatty()
89 def stdout(self
, line
):
90 """Write a line to stdout."""
91 self
._stdout
.write_line(line
)
93 def stdout_bytes(self
, byte_data
):
94 self
._stdout
.write_bytes(byte_data
)
98 """Write a line to stderr."""
99 self
._stderr
.write_line(line
)
101 def err_bytes(self
, byte_data
):
102 """Write encoded byte data to the error output."""
103 self
._stderr
.write_bytes(byte_data
)
106 def info(self
, *msgs
):
108 self
._stderr
.single_line(msg
)
110 def warn(self
, *msgs
, **kw
):
111 self
._stderr
.tagged_lines(kw
.get('title', 'Warning'), msgs
)
113 def error(self
, *msgs
, **kw
):
114 self
._stderr
.tagged_lines(kw
.get('title', 'Error'), msgs
)
116 def start(self
, msg
):
117 """Start a long-running operation."""
118 self
._stderr
.single_line('%s ... ' % msg
, print_newline
=False)
119 self
._stderr
.level
+= 1
121 def done(self
, extramsg
=None):
122 """Finish long-running operation."""
123 self
._stderr
.level
-= 1
125 msg
= 'done (%s)' % extramsg
128 self
._stderr
.single_line(msg
, need_newline
=False)
131 out
= MessagePrinter()