3464175ba34534639eb1974f70b17dc5e37168d5
[stgit] / stgit / out.py
1 # -*- coding: utf-8 -*-
2
3 __copyright__ = """
4 Copyright (C) 2007, Karl Hasselström <kha@treskal.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 """
19
20 import sys
21
22 class MessagePrinter(object):
23 def __init__(self):
24 class Output(object):
25 def __init__(self, write, flush):
26 self.write = write
27 self.flush = flush
28 self.at_start_of_line = True
29 self.level = 0
30 def new_line(self):
31 """Ensure that we're at the beginning of a line."""
32 if not self.at_start_of_line:
33 self.write('\n')
34 self.at_start_of_line = True
35 def single_line(self, msg, print_newline = True,
36 need_newline = True):
37 """Write a single line. Newline before and after are
38 separately configurable."""
39 if need_newline:
40 self.new_line()
41 if self.at_start_of_line:
42 self.write(' '*self.level)
43 self.write(msg)
44 if print_newline:
45 self.write('\n')
46 self.at_start_of_line = True
47 else:
48 self.flush()
49 self.at_start_of_line = False
50 def tagged_lines(self, tag, lines):
51 tag += ': '
52 for line in lines:
53 self.single_line(tag + line)
54 tag = ' '*len(tag)
55 def write_line(self, line):
56 """Write one line of text on a lines of its own, not
57 indented."""
58 self.new_line()
59 self.write('%s\n' % line)
60 self.at_start_of_line = True
61 def write_raw(self, string):
62 """Write an arbitrary string, possibly containing
63 newlines."""
64 self.new_line()
65 self.write(string)
66 self.at_start_of_line = string.endswith('\n')
67 self.__stderr = Output(sys.stderr.write, sys.stderr.flush)
68 self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
69 if sys.stdout.isatty():
70 self.__out = self.__stdout
71 self.__err = self.__stdout
72 else:
73 self.__out = Output(lambda msg: None, lambda: None)
74 self.__err = self.__stderr
75 def stdout(self, line):
76 """Write a line to stdout."""
77 self.__stdout.write_line(line)
78 def stdout_raw(self, string):
79 """Write a string possibly containing newlines to stdout."""
80 self.__stdout.write_raw(string)
81 def err_raw(self, string):
82 """Write a string possibly containing newlines to the error
83 output."""
84 self.__err.write_raw(string)
85 def info(self, *msgs):
86 for msg in msgs:
87 self.__out.single_line(msg)
88 def note(self, *msgs):
89 self.__out.tagged_lines('Notice', msgs)
90 def warn(self, *msgs):
91 self.__err.tagged_lines('Warning', msgs)
92 def error(self, *msgs):
93 self.__err.tagged_lines('Error', msgs)
94 def start(self, msg):
95 """Start a long-running operation."""
96 self.__out.single_line('%s ... ' % msg, print_newline = False)
97 self.__out.level += 1
98 def done(self, extramsg = None):
99 """Finish long-running operation."""
100 self.__out.level -= 1
101 if extramsg:
102 msg = 'done (%s)' % extramsg
103 else:
104 msg = 'done'
105 self.__out.single_line(msg, need_newline = False)
106
107 out = MessagePrinter()