##// END OF EJS Templates
adding local_hostname option to smtp configuration
Valentino Volonghi aka dialtone -
r2583:6e542744 default
parent child Browse files
Show More
@@ -1,449 +1,452 b''
1 1 HGRC(5)
2 2 =======
3 3 Bryan O'Sullivan <bos@serpentine.com>
4 4
5 5 NAME
6 6 ----
7 7 hgrc - configuration files for Mercurial
8 8
9 9 SYNOPSIS
10 10 --------
11 11
12 12 The Mercurial system uses a set of configuration files to control
13 13 aspects of its behaviour.
14 14
15 15 FILES
16 16 -----
17 17
18 18 Mercurial reads configuration data from several files, if they exist.
19 19 The names of these files depend on the system on which Mercurial is
20 20 installed.
21 21
22 22 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
23 23 (Unix) <install-root>/etc/mercurial/hgrc::
24 24 Per-installation configuration files, searched for in the
25 25 directory where Mercurial is installed. For example, if installed
26 26 in /shared/tools, Mercurial will look in
27 27 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
28 28 all Mercurial commands executed by any user in any directory.
29 29
30 30 (Unix) /etc/mercurial/hgrc.d/*.rc::
31 31 (Unix) /etc/mercurial/hgrc::
32 32 (Windows) C:\Mercurial\Mercurial.ini::
33 33 Per-system configuration files, for the system on which Mercurial
34 34 is running. Options in these files apply to all Mercurial
35 35 commands executed by any user in any directory. Options in these
36 36 files override per-installation options.
37 37
38 38 (Unix) $HOME/.hgrc::
39 39 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
40 40 (Windows) $HOME\Mercurial.ini::
41 41 Per-user configuration file, for the user running Mercurial.
42 42 Options in this file apply to all Mercurial commands executed by
43 43 any user in any directory. Options in this file override
44 44 per-installation and per-system options.
45 45 On Windows system, one of these is chosen exclusively according
46 46 to definition of HOME environment variable.
47 47
48 48 (Unix, Windows) <repo>/.hg/hgrc::
49 49 Per-repository configuration options that only apply in a
50 50 particular repository. This file is not version-controlled, and
51 51 will not get transferred during a "clone" operation. Options in
52 52 this file override options in all other configuration files.
53 53
54 54 SYNTAX
55 55 ------
56 56
57 57 A configuration file consists of sections, led by a "[section]" header
58 58 and followed by "name: value" entries; "name=value" is also accepted.
59 59
60 60 [spam]
61 61 eggs=ham
62 62 green=
63 63 eggs
64 64
65 65 Each line contains one entry. If the lines that follow are indented,
66 66 they are treated as continuations of that entry.
67 67
68 68 Leading whitespace is removed from values. Empty lines are skipped.
69 69
70 70 The optional values can contain format strings which refer to other
71 71 values in the same section, or values in a special DEFAULT section.
72 72
73 73 Lines beginning with "#" or ";" are ignored and may be used to provide
74 74 comments.
75 75
76 76 SECTIONS
77 77 --------
78 78
79 79 This section describes the different sections that may appear in a
80 80 Mercurial "hgrc" file, the purpose of each section, its possible
81 81 keys, and their possible values.
82 82
83 83 decode/encode::
84 84 Filters for transforming files on checkout/checkin. This would
85 85 typically be used for newline processing or other
86 86 localization/canonicalization of files.
87 87
88 88 Filters consist of a filter pattern followed by a filter command.
89 89 Filter patterns are globs by default, rooted at the repository
90 90 root. For example, to match any file ending in ".txt" in the root
91 91 directory only, use the pattern "*.txt". To match any file ending
92 92 in ".c" anywhere in the repository, use the pattern "**.c".
93 93
94 94 The filter command can start with a specifier, either "pipe:" or
95 95 "tempfile:". If no specifier is given, "pipe:" is used by default.
96 96
97 97 A "pipe:" command must accept data on stdin and return the
98 98 transformed data on stdout.
99 99
100 100 Pipe example:
101 101
102 102 [encode]
103 103 # uncompress gzip files on checkin to improve delta compression
104 104 # note: not necessarily a good idea, just an example
105 105 *.gz = pipe: gunzip
106 106
107 107 [decode]
108 108 # recompress gzip files when writing them to the working dir (we
109 109 # can safely omit "pipe:", because it's the default)
110 110 *.gz = gzip
111 111
112 112 A "tempfile:" command is a template. The string INFILE is replaced
113 113 with the name of a temporary file that contains the data to be
114 114 filtered by the command. The string OUTFILE is replaced with the
115 115 name of an empty temporary file, where the filtered data must be
116 116 written by the command.
117 117
118 118 NOTE: the tempfile mechanism is recommended for Windows systems,
119 119 where the standard shell I/O redirection operators often have
120 120 strange effects. In particular, if you are doing line ending
121 121 conversion on Windows using the popular dos2unix and unix2dos
122 122 programs, you *must* use the tempfile mechanism, as using pipes will
123 123 corrupt the contents of your files.
124 124
125 125 Tempfile example:
126 126
127 127 [encode]
128 128 # convert files to unix line ending conventions on checkin
129 129 **.txt = tempfile: dos2unix -n INFILE OUTFILE
130 130
131 131 [decode]
132 132 # convert files to windows line ending conventions when writing
133 133 # them to the working dir
134 134 **.txt = tempfile: unix2dos -n INFILE OUTFILE
135 135
136 136 email::
137 137 Settings for extensions that send email messages.
138 138 from;;
139 139 Optional. Email address to use in "From" header and SMTP envelope
140 140 of outgoing messages.
141 141 method;;
142 142 Optional. Method to use to send email messages. If value is
143 143 "smtp" (default), use SMTP (see section "[mail]" for
144 144 configuration). Otherwise, use as name of program to run that
145 145 acts like sendmail (takes "-f" option for sender, list of
146 146 recipients on command line, message on stdin). Normally, setting
147 147 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
148 148 sendmail to send messages.
149 149
150 150 Email example:
151 151
152 152 [email]
153 153 from = Joseph User <joe.user@example.com>
154 154 method = /usr/sbin/sendmail
155 155
156 156 extensions::
157 157 Mercurial has an extension mechanism for adding new features. To
158 158 enable an extension, create an entry for it in this section.
159 159
160 160 If you know that the extension is already in Python's search path,
161 161 you can give the name of the module, followed by "=", with nothing
162 162 after the "=".
163 163
164 164 Otherwise, give a name that you choose, followed by "=", followed by
165 165 the path to the ".py" file (including the file name extension) that
166 166 defines the extension.
167 167
168 168 Example for ~/.hgrc:
169 169
170 170 [extensions]
171 171 # (the mq extension will get loaded from mercurial's path)
172 172 hgext.mq =
173 173 # (this extension will get loaded from the file specified)
174 174 myfeature = ~/.hgext/myfeature.py
175 175
176 176 hooks::
177 177 Commands or Python functions that get automatically executed by
178 178 various actions such as starting or finishing a commit. Multiple
179 179 hooks can be run for the same action by appending a suffix to the
180 180 action. Overriding a site-wide hook can be done by changing its
181 181 value or setting it to an empty string.
182 182
183 183 Example .hg/hgrc:
184 184
185 185 [hooks]
186 186 # do not use the site-wide hook
187 187 incoming =
188 188 incoming.email = /my/email/hook
189 189 incoming.autobuild = /my/build/hook
190 190
191 191 Most hooks are run with environment variables set that give added
192 192 useful information. For each hook below, the environment variables
193 193 it is passed are listed with names of the form "$HG_foo".
194 194
195 195 changegroup;;
196 196 Run after a changegroup has been added via push, pull or
197 197 unbundle. ID of the first new changeset is in $HG_NODE.
198 198 commit;;
199 199 Run after a changeset has been created in the local repository.
200 200 ID of the newly created changeset is in $HG_NODE. Parent
201 201 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
202 202 incoming;;
203 203 Run after a changeset has been pulled, pushed, or unbundled into
204 204 the local repository. The ID of the newly arrived changeset is in
205 205 $HG_NODE.
206 206 outgoing;;
207 207 Run after sending changes from local repository to another. ID of
208 208 first changeset sent is in $HG_NODE. Source of operation is in
209 209 $HG_SOURCE; see "preoutgoing" hook for description.
210 210 prechangegroup;;
211 211 Run before a changegroup is added via push, pull or unbundle.
212 212 Exit status 0 allows the changegroup to proceed. Non-zero status
213 213 will cause the push, pull or unbundle to fail.
214 214 precommit;;
215 215 Run before starting a local commit. Exit status 0 allows the
216 216 commit to proceed. Non-zero status will cause the commit to fail.
217 217 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
218 218 preoutgoing;;
219 219 Run before computing changes to send from the local repository to
220 220 another. Non-zero status will cause failure. This lets you
221 221 prevent pull over http or ssh. Also prevents against local pull,
222 222 push (outbound) or bundle commands, but not effective, since you
223 223 can just copy files instead then. Source of operation is in
224 224 $HG_SOURCE. If "serve", operation is happening on behalf of
225 225 remote ssh or http repository. If "push", "pull" or "bundle",
226 226 operation is happening on behalf of repository on same system.
227 227 pretag;;
228 228 Run before creating a tag. Exit status 0 allows the tag to be
229 229 created. Non-zero status will cause the tag to fail. ID of
230 230 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
231 231 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
232 232 pretxnchangegroup;;
233 233 Run after a changegroup has been added via push, pull or unbundle,
234 234 but before the transaction has been committed. Changegroup is
235 235 visible to hook program. This lets you validate incoming changes
236 236 before accepting them. Passed the ID of the first new changeset
237 237 in $HG_NODE. Exit status 0 allows the transaction to commit.
238 238 Non-zero status will cause the transaction to be rolled back and
239 239 the push, pull or unbundle will fail.
240 240 pretxncommit;;
241 241 Run after a changeset has been created but the transaction not yet
242 242 committed. Changeset is visible to hook program. This lets you
243 243 validate commit message and changes. Exit status 0 allows the
244 244 commit to proceed. Non-zero status will cause the transaction to
245 245 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
246 246 IDs are in $HG_PARENT1 and $HG_PARENT2.
247 247 preupdate;;
248 248 Run before updating the working directory. Exit status 0 allows
249 249 the update to proceed. Non-zero status will prevent the update.
250 250 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
251 251 of second new parent is in $HG_PARENT2.
252 252 tag;;
253 253 Run after a tag is created. ID of tagged changeset is in
254 254 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
255 255 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
256 256 update;;
257 257 Run after updating the working directory. Changeset ID of first
258 258 new parent is in $HG_PARENT1. If merge, ID of second new parent
259 259 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
260 260 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
261 261
262 262 Note: In earlier releases, the names of hook environment variables
263 263 did not have a "HG_" prefix. The old unprefixed names are no longer
264 264 provided in the environment.
265 265
266 266 The syntax for Python hooks is as follows:
267 267
268 268 hookname = python:modulename.submodule.callable
269 269
270 270 Python hooks are run within the Mercurial process. Each hook is
271 271 called with at least three keyword arguments: a ui object (keyword
272 272 "ui"), a repository object (keyword "repo"), and a "hooktype"
273 273 keyword that tells what kind of hook is used. Arguments listed as
274 274 environment variables above are passed as keyword arguments, with no
275 275 "HG_" prefix, and names in lower case.
276 276
277 277 A Python hook must return a "true" value to succeed. Returning a
278 278 "false" value or raising an exception is treated as failure of the
279 279 hook.
280 280
281 281 http_proxy::
282 282 Used to access web-based Mercurial repositories through a HTTP
283 283 proxy.
284 284 host;;
285 285 Host name and (optional) port of the proxy server, for example
286 286 "myproxy:8000".
287 287 no;;
288 288 Optional. Comma-separated list of host names that should bypass
289 289 the proxy.
290 290 passwd;;
291 291 Optional. Password to authenticate with at the proxy server.
292 292 user;;
293 293 Optional. User name to authenticate with at the proxy server.
294 294
295 295 smtp::
296 296 Configuration for extensions that need to send email messages.
297 297 host;;
298 298 Optional. Host name of mail server. Default: "mail".
299 299 port;;
300 300 Optional. Port to connect to on mail server. Default: 25.
301 301 tls;;
302 302 Optional. Whether to connect to mail server using TLS. True or
303 303 False. Default: False.
304 304 username;;
305 305 Optional. User name to authenticate to SMTP server with.
306 306 If username is specified, password must also be specified.
307 307 Default: none.
308 308 password;;
309 309 Optional. Password to authenticate to SMTP server with.
310 310 If username is specified, password must also be specified.
311 311 Default: none.
312 local_hostname;;
313 Optional. It's the hostname that the sender can use to identify itself
314 to the MTA.
312 315
313 316 paths::
314 317 Assigns symbolic names to repositories. The left side is the
315 318 symbolic name, and the right gives the directory or URL that is the
316 319 location of the repository. Default paths can be declared by
317 320 setting the following entries.
318 321 default;;
319 322 Directory or URL to use when pulling if no source is specified.
320 323 Default is set to repository from which the current repository
321 324 was cloned.
322 325 default-push;;
323 326 Optional. Directory or URL to use when pushing if no destination
324 327 is specified.
325 328
326 329 ui::
327 330 User interface controls.
328 331 debug;;
329 332 Print debugging information. True or False. Default is False.
330 333 editor;;
331 334 The editor to use during a commit. Default is $EDITOR or "vi".
332 335 ignore;;
333 336 A file to read per-user ignore patterns from. This file should be in
334 337 the same format as a repository-wide .hgignore file. This option
335 338 supports hook syntax, so if you want to specify multiple ignore
336 339 files, you can do so by setting something like
337 340 "ignore.other = ~/.hgignore2". For details of the ignore file
338 341 format, see the hgignore(5) man page.
339 342 interactive;;
340 343 Allow to prompt the user. True or False. Default is True.
341 344 logtemplate;;
342 345 Template string for commands that print changesets.
343 346 style;;
344 347 Name of style to use for command output.
345 348 merge;;
346 349 The conflict resolution program to use during a manual merge.
347 350 Default is "hgmerge".
348 351 quiet;;
349 352 Reduce the amount of output printed. True or False. Default is False.
350 353 remotecmd;;
351 354 remote command to use for clone/push/pull operations. Default is 'hg'.
352 355 ssh;;
353 356 command to use for SSH connections. Default is 'ssh'.
354 357 timeout;;
355 358 The timeout used when a lock is held (in seconds), a negative value
356 359 means no timeout. Default is 600.
357 360 username;;
358 361 The committer of a changeset created when running "commit".
359 362 Typically a person's name and email address, e.g. "Fred Widget
360 363 <fred@example.com>". Default is $EMAIL or username@hostname, unless
361 364 username is set to an empty string, which enforces specifying the
362 365 username manually.
363 366 verbose;;
364 367 Increase the amount of output printed. True or False. Default is False.
365 368
366 369
367 370 web::
368 371 Web interface configuration.
369 372 accesslog;;
370 373 Where to output the access log. Default is stdout.
371 374 address;;
372 375 Interface address to bind to. Default is all.
373 376 allow_archive;;
374 377 List of archive format (bz2, gz, zip) allowed for downloading.
375 378 Default is empty.
376 379 allowbz2;;
377 380 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
378 381 Default is false.
379 382 allowgz;;
380 383 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
381 384 Default is false.
382 385 allowpull;;
383 386 Whether to allow pulling from the repository. Default is true.
384 387 allow_push;;
385 388 Whether to allow pushing to the repository. If empty or not set,
386 389 push is not allowed. If the special value "*", any remote user
387 390 can push, including unauthenticated users. Otherwise, the remote
388 391 user must have been authenticated, and the authenticated user name
389 392 must be present in this list (separated by whitespace or ",").
390 393 The contents of the allow_push list are examined after the
391 394 deny_push list.
392 395 allowzip;;
393 396 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
394 397 Default is false. This feature creates temporary files.
395 398 baseurl;;
396 399 Base URL to use when publishing URLs in other locations, so
397 400 third-party tools like email notification hooks can construct URLs.
398 401 Example: "http://hgserver/repos/"
399 402 contact;;
400 403 Name or email address of the person in charge of the repository.
401 404 Default is "unknown".
402 405 deny_push;;
403 406 Whether to deny pushing to the repository. If empty or not set,
404 407 push is not denied. If the special value "*", all remote users
405 408 are denied push. Otherwise, unauthenticated users are all denied,
406 409 and any authenticated user name present in this list (separated by
407 410 whitespace or ",") is also denied. The contents of the deny_push
408 411 list are examined before the allow_push list.
409 412 description;;
410 413 Textual description of the repository's purpose or contents.
411 414 Default is "unknown".
412 415 errorlog;;
413 416 Where to output the error log. Default is stderr.
414 417 ipv6;;
415 418 Whether to use IPv6. Default is false.
416 419 name;;
417 420 Repository name to use in the web interface. Default is current
418 421 working directory.
419 422 maxchanges;;
420 423 Maximum number of changes to list on the changelog. Default is 10.
421 424 maxfiles;;
422 425 Maximum number of files to list per changeset. Default is 10.
423 426 port;;
424 427 Port to listen on. Default is 8000.
425 428 push_ssl;;
426 429 Whether to require that inbound pushes be transported over SSL to
427 430 prevent password sniffing. Default is true.
428 431 style;;
429 432 Which template map style to use.
430 433 templates;;
431 434 Where to find the HTML templates. Default is install path.
432 435
433 436
434 437 AUTHOR
435 438 ------
436 439 Bryan O'Sullivan <bos@serpentine.com>.
437 440
438 441 Mercurial was written by Matt Mackall <mpm@selenic.com>.
439 442
440 443 SEE ALSO
441 444 --------
442 445 hg(1), hgignore(5)
443 446
444 447 COPYING
445 448 -------
446 449 This manual page is copyright 2005 Bryan O'Sullivan.
447 450 Mercurial is copyright 2005, 2006 Matt Mackall.
448 451 Free use of this software is granted under the terms of the GNU General
449 452 Public License (GPL).
@@ -1,355 +1,356 b''
1 1 # ui.py - user interface bits for mercurial
2 2 #
3 3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from i18n import gettext as _
9 9 from demandload import *
10 10 demandload(globals(), "errno getpass os re smtplib socket sys tempfile")
11 11 demandload(globals(), "ConfigParser templater traceback util")
12 12
13 13 class ui(object):
14 14 def __init__(self, verbose=False, debug=False, quiet=False,
15 15 interactive=True, traceback=False, parentui=None):
16 16 self.overlay = {}
17 17 if parentui is None:
18 18 # this is the parent of all ui children
19 19 self.parentui = None
20 20 self.cdata = ConfigParser.SafeConfigParser()
21 21 self.readconfig(util.rcpath())
22 22
23 23 self.quiet = self.configbool("ui", "quiet")
24 24 self.verbose = self.configbool("ui", "verbose")
25 25 self.debugflag = self.configbool("ui", "debug")
26 26 self.interactive = self.configbool("ui", "interactive", True)
27 27 self.traceback = traceback
28 28
29 29 self.updateopts(verbose, debug, quiet, interactive)
30 30 self.diffcache = None
31 31 self.header = []
32 32 self.prev_header = []
33 33 self.revlogopts = self.configrevlog()
34 34 else:
35 35 # parentui may point to an ui object which is already a child
36 36 self.parentui = parentui.parentui or parentui
37 37 parent_cdata = self.parentui.cdata
38 38 self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
39 39 # make interpolation work
40 40 for section in parent_cdata.sections():
41 41 self.cdata.add_section(section)
42 42 for name, value in parent_cdata.items(section, raw=True):
43 43 self.cdata.set(section, name, value)
44 44
45 45 def __getattr__(self, key):
46 46 return getattr(self.parentui, key)
47 47
48 48 def updateopts(self, verbose=False, debug=False, quiet=False,
49 49 interactive=True, traceback=False, config=[]):
50 50 self.quiet = (self.quiet or quiet) and not verbose and not debug
51 51 self.verbose = (self.verbose or verbose) or debug
52 52 self.debugflag = (self.debugflag or debug)
53 53 self.interactive = (self.interactive and interactive)
54 54 self.traceback = self.traceback or traceback
55 55 for cfg in config:
56 56 try:
57 57 name, value = cfg.split('=', 1)
58 58 section, name = name.split('.', 1)
59 59 if not self.cdata.has_section(section):
60 60 self.cdata.add_section(section)
61 61 if not section or not name:
62 62 raise IndexError
63 63 self.cdata.set(section, name, value)
64 64 except (IndexError, ValueError):
65 65 raise util.Abort(_('malformed --config option: %s') % cfg)
66 66
67 67 def readconfig(self, fn, root=None):
68 68 if isinstance(fn, basestring):
69 69 fn = [fn]
70 70 for f in fn:
71 71 try:
72 72 self.cdata.read(f)
73 73 except ConfigParser.ParsingError, inst:
74 74 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
75 75 # translate paths relative to root (or home) into absolute paths
76 76 if root is None:
77 77 root = os.path.expanduser('~')
78 78 for name, path in self.configitems("paths"):
79 79 if path and path.find("://") == -1 and not os.path.isabs(path):
80 80 self.cdata.set("paths", name, os.path.join(root, path))
81 81
82 82 def setconfig(self, section, name, val):
83 83 self.overlay[(section, name)] = val
84 84
85 85 def config(self, section, name, default=None):
86 86 if self.overlay.has_key((section, name)):
87 87 return self.overlay[(section, name)]
88 88 if self.cdata.has_option(section, name):
89 89 try:
90 90 return self.cdata.get(section, name)
91 91 except ConfigParser.InterpolationError, inst:
92 92 raise util.Abort(_("Error in configuration:\n%s") % inst)
93 93 if self.parentui is None:
94 94 return default
95 95 else:
96 96 return self.parentui.config(section, name, default)
97 97
98 98 def configlist(self, section, name, default=None):
99 99 """Return a list of comma/space separated strings"""
100 100 result = self.config(section, name)
101 101 if result is None:
102 102 result = default or []
103 103 if isinstance(result, basestring):
104 104 result = result.replace(",", " ").split()
105 105 return result
106 106
107 107 def configbool(self, section, name, default=False):
108 108 if self.overlay.has_key((section, name)):
109 109 return self.overlay[(section, name)]
110 110 if self.cdata.has_option(section, name):
111 111 try:
112 112 return self.cdata.getboolean(section, name)
113 113 except ConfigParser.InterpolationError, inst:
114 114 raise util.Abort(_("Error in configuration:\n%s") % inst)
115 115 if self.parentui is None:
116 116 return default
117 117 else:
118 118 return self.parentui.configbool(section, name, default)
119 119
120 120 def has_config(self, section):
121 121 '''tell whether section exists in config.'''
122 122 return self.cdata.has_section(section)
123 123
124 124 def configitems(self, section):
125 125 items = {}
126 126 if self.parentui is not None:
127 127 items = dict(self.parentui.configitems(section))
128 128 if self.cdata.has_section(section):
129 129 try:
130 130 items.update(dict(self.cdata.items(section)))
131 131 except ConfigParser.InterpolationError, inst:
132 132 raise util.Abort(_("Error in configuration:\n%s") % inst)
133 133 x = items.items()
134 134 x.sort()
135 135 return x
136 136
137 137 def walkconfig(self, seen=None):
138 138 if seen is None:
139 139 seen = {}
140 140 for (section, name), value in self.overlay.iteritems():
141 141 yield section, name, value
142 142 seen[section, name] = 1
143 143 for section in self.cdata.sections():
144 144 for name, value in self.cdata.items(section):
145 145 if (section, name) in seen: continue
146 146 yield section, name, value.replace('\n', '\\n')
147 147 seen[section, name] = 1
148 148 if self.parentui is not None:
149 149 for parent in self.parentui.walkconfig(seen):
150 150 yield parent
151 151
152 152 def extensions(self):
153 153 result = self.configitems("extensions")
154 154 for i, (key, value) in enumerate(result):
155 155 if value:
156 156 result[i] = (key, os.path.expanduser(value))
157 157 return result
158 158
159 159 def hgignorefiles(self):
160 160 result = []
161 161 for key, value in self.configitems("ui"):
162 162 if key == 'ignore' or key.startswith('ignore.'):
163 163 result.append(os.path.expanduser(value))
164 164 return result
165 165
166 166 def configrevlog(self):
167 167 result = {}
168 168 for key, value in self.configitems("revlog"):
169 169 result[key.lower()] = value
170 170 return result
171 171
172 172 def diffopts(self):
173 173 if self.diffcache:
174 174 return self.diffcache
175 175 result = {'showfunc': True, 'ignorews': False}
176 176 for key, value in self.configitems("diff"):
177 177 if value:
178 178 result[key.lower()] = (value.lower() == 'true')
179 179 self.diffcache = result
180 180 return result
181 181
182 182 def username(self):
183 183 """Return default username to be used in commits.
184 184
185 185 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
186 186 and stop searching if one of these is set.
187 187 Abort if found username is an empty string to force specifying
188 188 the commit user elsewhere, e.g. with line option or repo hgrc.
189 189 If not found, use ($LOGNAME or $USER or $LNAME or
190 190 $USERNAME) +"@full.hostname".
191 191 """
192 192 user = os.environ.get("HGUSER")
193 193 if user is None:
194 194 user = self.config("ui", "username")
195 195 if user is None:
196 196 user = os.environ.get("EMAIL")
197 197 if user is None:
198 198 try:
199 199 user = '%s@%s' % (getpass.getuser(), socket.getfqdn())
200 200 except KeyError:
201 201 raise util.Abort(_("Please specify a username."))
202 202 return user
203 203
204 204 def shortuser(self, user):
205 205 """Return a short representation of a user name or email address."""
206 206 if not self.verbose: user = util.shortuser(user)
207 207 return user
208 208
209 209 def expandpath(self, loc, default=None):
210 210 """Return repository location relative to cwd or from [paths]"""
211 211 if loc.find("://") != -1 or os.path.exists(loc):
212 212 return loc
213 213
214 214 path = self.config("paths", loc)
215 215 if not path and default is not None:
216 216 path = self.config("paths", default)
217 217 return path or loc
218 218
219 219 def write(self, *args):
220 220 if self.header:
221 221 if self.header != self.prev_header:
222 222 self.prev_header = self.header
223 223 self.write(*self.header)
224 224 self.header = []
225 225 for a in args:
226 226 sys.stdout.write(str(a))
227 227
228 228 def write_header(self, *args):
229 229 for a in args:
230 230 self.header.append(str(a))
231 231
232 232 def write_err(self, *args):
233 233 try:
234 234 if not sys.stdout.closed: sys.stdout.flush()
235 235 for a in args:
236 236 sys.stderr.write(str(a))
237 237 except IOError, inst:
238 238 if inst.errno != errno.EPIPE:
239 239 raise
240 240
241 241 def flush(self):
242 242 try: sys.stdout.flush()
243 243 except: pass
244 244 try: sys.stderr.flush()
245 245 except: pass
246 246
247 247 def readline(self):
248 248 return sys.stdin.readline()[:-1]
249 249 def prompt(self, msg, pat=None, default="y"):
250 250 if not self.interactive: return default
251 251 while 1:
252 252 self.write(msg, " ")
253 253 r = self.readline()
254 254 if not pat or re.match(pat, r):
255 255 return r
256 256 else:
257 257 self.write(_("unrecognized response\n"))
258 258 def getpass(self, prompt=None, default=None):
259 259 if not self.interactive: return default
260 260 return getpass.getpass(prompt or _('password: '))
261 261 def status(self, *msg):
262 262 if not self.quiet: self.write(*msg)
263 263 def warn(self, *msg):
264 264 self.write_err(*msg)
265 265 def note(self, *msg):
266 266 if self.verbose: self.write(*msg)
267 267 def debug(self, *msg):
268 268 if self.debugflag: self.write(*msg)
269 269 def edit(self, text, user):
270 270 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
271 271 text=True)
272 272 try:
273 273 f = os.fdopen(fd, "w")
274 274 f.write(text)
275 275 f.close()
276 276
277 277 editor = (os.environ.get("HGEDITOR") or
278 278 self.config("ui", "editor") or
279 279 os.environ.get("EDITOR", "vi"))
280 280
281 281 util.system("%s \"%s\"" % (editor, name),
282 282 environ={'HGUSER': user},
283 283 onerr=util.Abort, errprefix=_("edit failed"))
284 284
285 285 f = open(name)
286 286 t = f.read()
287 287 f.close()
288 288 t = re.sub("(?m)^HG:.*\n", "", t)
289 289 finally:
290 290 os.unlink(name)
291 291
292 292 return t
293 293
294 294 def sendmail(self):
295 295 '''send mail message. object returned has one method, sendmail.
296 296 call as sendmail(sender, list-of-recipients, msg).'''
297 297
298 298 def smtp():
299 299 '''send mail using smtp.'''
300 300
301 s = smtplib.SMTP()
301 local_hostname = self.config('smtp', 'local_hostname')
302 s = smtplib.SMTP(local_hostname=local_hostname)
302 303 mailhost = self.config('smtp', 'host')
303 304 if not mailhost:
304 305 raise util.Abort(_('no [smtp]host in hgrc - cannot send mail'))
305 306 mailport = int(self.config('smtp', 'port', 25))
306 307 self.note(_('sending mail: smtp host %s, port %s\n') %
307 308 (mailhost, mailport))
308 309 s.connect(host=mailhost, port=mailport)
309 310 if self.configbool('smtp', 'tls'):
310 311 self.note(_('(using tls)\n'))
311 312 s.ehlo()
312 313 s.starttls()
313 314 s.ehlo()
314 315 username = self.config('smtp', 'username')
315 316 password = self.config('smtp', 'password')
316 317 if username and password:
317 318 self.note(_('(authenticating to mail server as %s)\n') %
318 319 (username))
319 320 s.login(username, password)
320 321 return s
321 322
322 323 class sendmail(object):
323 324 '''send mail using sendmail.'''
324 325
325 326 def __init__(self, ui, program):
326 327 self.ui = ui
327 328 self.program = program
328 329
329 330 def sendmail(self, sender, recipients, msg):
330 331 cmdline = '%s -f %s %s' % (
331 332 self.program, templater.email(sender),
332 333 ' '.join(map(templater.email, recipients)))
333 334 self.ui.note(_('sending mail: %s\n') % cmdline)
334 335 fp = os.popen(cmdline, 'w')
335 336 fp.write(msg)
336 337 ret = fp.close()
337 338 if ret:
338 339 raise util.Abort('%s %s' % (
339 340 os.path.basename(self.program.split(None, 1)[0]),
340 341 util.explain_exit(ret)[0]))
341 342
342 343 method = self.config('email', 'method', 'smtp')
343 344 if method == 'smtp':
344 345 mail = smtp()
345 346 else:
346 347 mail = sendmail(self, method)
347 348 return mail
348 349
349 350 def print_exc(self):
350 351 '''print exception traceback if traceback printing enabled.
351 352 only to call in exception handler. returns true if traceback
352 353 printed.'''
353 354 if self.traceback:
354 355 traceback.print_exc()
355 356 return self.traceback
General Comments 0
You need to be logged in to leave comments. Login now