Mercurial > hg
annotate mercurial/ui.py @ 1740:f95654385065
add --daemon option to serve command. for issue 45.
code looks odd because it is portable to windows. windows does not have
os.fork, so have to spawn and use pipe to tell parent ready instead.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Fri, 17 Feb 2006 16:29:30 -0800 |
parents | 3b1b44b917f4 |
children | 6f67a4c93493 876e4e6ad82b e4abeafd6eb1 |
rev | line source |
---|---|
207 | 1 # ui.py - user interface bits for mercurial |
2 # | |
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
613
5374955ec5b1
Demand-load most modules in the commands and ui modules.
Bryan O'Sullivan <bos@serpentine.com>
parents:
608
diff
changeset
|
8 import os, ConfigParser |
1400
cf9a1233738a
i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents:
1292
diff
changeset
|
9 from i18n import gettext as _ |
613
5374955ec5b1
Demand-load most modules in the commands and ui modules.
Bryan O'Sullivan <bos@serpentine.com>
parents:
608
diff
changeset
|
10 from demandload import * |
5374955ec5b1
Demand-load most modules in the commands and ui modules.
Bryan O'Sullivan <bos@serpentine.com>
parents:
608
diff
changeset
|
11 demandload(globals(), "re socket sys util") |
207 | 12 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1483
diff
changeset
|
13 class ui(object): |
207 | 14 def __init__(self, verbose=False, debug=False, quiet=False, |
15 interactive=True): | |
960 | 16 self.overlay = {} |
285 | 17 self.cdata = ConfigParser.SafeConfigParser() |
1473
7d66ce9895fa
make readconfig take a filename instead of a file pointer as argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1440
diff
changeset
|
18 self.readconfig(util.rcpath) |
285 | 19 |
20 self.quiet = self.configbool("ui", "quiet") | |
21 self.verbose = self.configbool("ui", "verbose") | |
22 self.debugflag = self.configbool("ui", "debug") | |
23 self.interactive = self.configbool("ui", "interactive", True) | |
24 | |
1071 | 25 self.updateopts(verbose, debug, quiet, interactive) |
1637 | 26 self.diffcache = None |
1071 | 27 |
28 def updateopts(self, verbose=False, debug=False, quiet=False, | |
29 interactive=True): | |
285 | 30 self.quiet = (self.quiet or quiet) and not verbose and not debug |
31 self.verbose = (self.verbose or verbose) or debug | |
32 self.debugflag = (self.debugflag or debug) | |
33 self.interactive = (self.interactive and interactive) | |
34 | |
1473
7d66ce9895fa
make readconfig take a filename instead of a file pointer as argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1440
diff
changeset
|
35 def readconfig(self, fn): |
1483
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
36 if isinstance(fn, basestring): |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
37 fn = [fn] |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
38 for f in fn: |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
39 try: |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
40 self.cdata.read(f) |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
41 except ConfigParser.ParsingError, inst: |
a4ba63e04134
Fix traceback on bad system hgrc files
Soh Tk-r28629 <tksoh@freescale.com>
parents:
1473
diff
changeset
|
42 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst)) |
337 | 43 |
960 | 44 def setconfig(self, section, name, val): |
45 self.overlay[(section, name)] = val | |
46 | |
47 def config(self, section, name, default=None): | |
48 if self.overlay.has_key((section, name)): | |
49 return self.overlay[(section, name)] | |
50 if self.cdata.has_option(section, name): | |
51 return self.cdata.get(section, name) | |
285 | 52 return default |
53 | |
960 | 54 def configbool(self, section, name, default=False): |
55 if self.overlay.has_key((section, name)): | |
56 return self.overlay[(section, name)] | |
57 if self.cdata.has_option(section, name): | |
58 return self.cdata.getboolean(section, name) | |
285 | 59 return default |
60 | |
61 def configitems(self, section): | |
62 if self.cdata.has_section(section): | |
63 return self.cdata.items(section) | |
64 return [] | |
65 | |
1028
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
66 def walkconfig(self): |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
67 seen = {} |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
68 for (section, name), value in self.overlay.iteritems(): |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
69 yield section, name, value |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
70 seen[section, name] = 1 |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
71 for section in self.cdata.sections(): |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
72 for name, value in self.cdata.items(section): |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
73 if (section, name) in seen: continue |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
74 yield section, name, value.replace('\n', '\\n') |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
75 seen[section, name] = 1 |
25e7ea0f2cff
Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents:
981
diff
changeset
|
76 |
1071 | 77 def extensions(self): |
78 return self.configitems("extensions") | |
79 | |
1637 | 80 def diffopts(self): |
81 if self.diffcache: | |
82 return self.diffcache | |
83 ret = { 'showfunc' : True, 'ignorews' : False} | |
84 for x in self.configitems("diff"): | |
85 k = x[0].lower() | |
86 v = x[1] | |
87 if v: | |
88 v = v.lower() | |
89 if v == 'true': | |
90 value = True | |
91 else: | |
92 value = False | |
93 ret[k] = value | |
94 self.diffcache = ret | |
95 return ret | |
96 | |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
97 def username(self): |
691
61c6b4178b9e
HG environment variables take precedence over hgrc
mpm@selenic.com
parents:
662
diff
changeset
|
98 return (os.environ.get("HGUSER") or |
61c6b4178b9e
HG environment variables take precedence over hgrc
mpm@selenic.com
parents:
662
diff
changeset
|
99 self.config("ui", "username") or |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
100 os.environ.get("EMAIL") or |
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
101 (os.environ.get("LOGNAME", |
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
102 os.environ.get("USERNAME", "unknown")) |
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
103 + '@' + socket.getfqdn())) |
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
104 |
1129
ee4f60abad93
Move generating short username to display in hg/hgweb annotate to ui module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1071
diff
changeset
|
105 def shortuser(self, user): |
ee4f60abad93
Move generating short username to display in hg/hgweb annotate to ui module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1071
diff
changeset
|
106 """Return a short representation of a user name or email address.""" |
1147 | 107 if not self.verbose: |
108 f = user.find('@') | |
109 if f >= 0: | |
110 user = user[:f] | |
111 f = user.find('<') | |
112 if f >= 0: | |
113 user = user[f+1:] | |
1129
ee4f60abad93
Move generating short username to display in hg/hgweb annotate to ui module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1071
diff
changeset
|
114 return user |
ee4f60abad93
Move generating short username to display in hg/hgweb annotate to ui module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1071
diff
changeset
|
115 |
1440 | 116 def expandpath(self, loc, root=""): |
506 | 117 paths = {} |
118 for name, path in self.configitems("paths"): | |
1440 | 119 m = path.find("://") |
120 if m == -1: | |
121 path = os.path.join(root, path) | |
506 | 122 paths[name] = path |
123 | |
124 return paths.get(loc, loc) | |
125 | |
207 | 126 def write(self, *args): |
127 for a in args: | |
128 sys.stdout.write(str(a)) | |
565 | 129 |
130 def write_err(self, *args): | |
1609
c50bddfbc812
eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1569
diff
changeset
|
131 if not sys.stdout.closed: sys.stdout.flush() |
565 | 132 for a in args: |
133 sys.stderr.write(str(a)) | |
134 | |
207 | 135 def readline(self): |
136 return sys.stdin.readline()[:-1] | |
1062 | 137 def prompt(self, msg, pat, default="y"): |
207 | 138 if not self.interactive: return default |
139 while 1: | |
140 self.write(msg, " ") | |
141 r = self.readline() | |
142 if re.match(pat, r): | |
143 return r | |
144 else: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
145 self.write(_("unrecognized response\n")) |
207 | 146 def status(self, *msg): |
147 if not self.quiet: self.write(*msg) | |
234
3427806d5ab9
ui.warn can use more than one argument like the other ui methods.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
207
diff
changeset
|
148 def warn(self, *msg): |
565 | 149 self.write_err(*msg) |
207 | 150 def note(self, *msg): |
151 if self.verbose: self.write(*msg) | |
152 def debug(self, *msg): | |
153 if self.debugflag: self.write(*msg) | |
154 def edit(self, text): | |
249 | 155 import tempfile |
207 | 156 (fd, name) = tempfile.mkstemp("hg") |
157 f = os.fdopen(fd, "w") | |
158 f.write(text) | |
159 f.close() | |
160 | |
691
61c6b4178b9e
HG environment variables take precedence over hgrc
mpm@selenic.com
parents:
662
diff
changeset
|
161 editor = (os.environ.get("HGEDITOR") or |
61c6b4178b9e
HG environment variables take precedence over hgrc
mpm@selenic.com
parents:
662
diff
changeset
|
162 self.config("ui", "editor") or |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
163 os.environ.get("EDITOR", "vi")) |
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
565
diff
changeset
|
164 |
662
b55a78595ef6
Pass username to hgeditor, remove temporary file
Radoslaw "AstralStorm" Szkodzinski <astralstorm@gorzow.mm.pl>
parents:
613
diff
changeset
|
165 os.environ["HGUSER"] = self.username() |
1569
dd186cb70a64
quote the filename when calling HGEDITOR
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
166 util.system("%s \"%s\"" % (editor, name), errprefix=_("edit failed")) |
207 | 167 |
168 t = open(name).read() | |
169 t = re.sub("(?m)^HG:.*\n", "", t) | |
170 | |
662
b55a78595ef6
Pass username to hgeditor, remove temporary file
Radoslaw "AstralStorm" Szkodzinski <astralstorm@gorzow.mm.pl>
parents:
613
diff
changeset
|
171 os.unlink(name) |
b55a78595ef6
Pass username to hgeditor, remove temporary file
Radoslaw "AstralStorm" Szkodzinski <astralstorm@gorzow.mm.pl>
parents:
613
diff
changeset
|
172 |
207 | 173 return t |