mercurial/ui.py
author Yuya Nishihara <yuya@tcha.org>
Sat, 25 Feb 2017 14:09:55 +0900
changeset 31128 0bb3089fe735
parent 31124 791ea883fc44
child 31156 e5aab82edf7f
permissions -rw-r--r--
ui: remove superfluous indent in _write()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
     1
# ui.py - user interface bits for mercurial
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8222
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10243
diff changeset
     6
# GNU General Public License version 2 or any later version.
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
     7
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
from __future__ import absolute_import
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
    10
import atexit
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
    11
import collections
30480
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
    12
import contextlib
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
import errno
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
import getpass
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
    15
import inspect
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    16
import os
27392
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
    17
import re
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
    18
import signal
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
import socket
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
    20
import subprocess
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    21
import sys
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    22
import tempfile
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    23
import traceback
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    24
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    25
from .i18n import _
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    26
from .node import hex
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    27
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    28
from . import (
31087
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
    29
    color,
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    30
    config,
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
    31
    encoding,
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    32
    error,
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    33
    formatter,
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    34
    progress,
30519
20a42325fdef py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30480
diff changeset
    35
    pycompat,
25989
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    36
    scmutil,
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    37
    util,
2cc4e8385661 ui: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    38
)
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
    39
29378
fea71f66ebff url: remember http password database in ui object
liscju <piotr.listkiewicz@gmail.com>
parents: 29366
diff changeset
    40
urlreq = util.urlreq
fea71f66ebff url: remember http password database in ui object
liscju <piotr.listkiewicz@gmail.com>
parents: 29366
diff changeset
    41
30979
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
    42
# for use with str.translate(None, _keepalnum), to keep just alphanumerics
31014
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    43
if pycompat.ispy3:
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    44
    _bytes = [bytes([c]) for c in range(256)]
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    45
    _notalnum = [s for s in _bytes if not s.isalnum()]
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    46
else:
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    47
    _notalnum = [c for c in map(chr, range(256)) if not c.isalnum()]
219629d42786 ui: construct _keepalnum list in a python3-friendly way
Augie Fackler <augie@google.com>
parents: 30998
diff changeset
    48
_keepalnum = ''.join(_notalnum)
30979
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
    49
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    50
samplehgrcs = {
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    51
    'user':
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    52
"""# example user config (see 'hg help config' for more info)
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    53
[ui]
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    54
# name and email, e.g.
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    55
# username = Jane Doe <jdoe@example.com>
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    56
username =
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    57
31124
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
    58
# uncomment to colorize command output
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
    59
# color = auto
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
    60
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    61
[extensions]
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    62
# uncomment these lines to enable some popular extensions
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    63
# (see 'hg help extensions' for more info)
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    64
#
31124
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
    65
# pager =""",
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    66
22837
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    67
    'cloned':
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    68
"""# example repository config (see 'hg help config' for more info)
22837
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    69
[paths]
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    70
default = %s
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    71
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    72
# path aliases to other clones of this repo in URLs or filesystem paths
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    73
# (see 'hg help config.paths' for more info)
22837
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    74
#
31064
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    75
# default:pushurl = ssh://jdoe@example.net/hg/jdoes-fork
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    76
# my-fork         = ssh://jdoe@example.net/hg/jdoes-fork
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    77
# my-clone        = /home/jdoe/jdoes-clone
22837
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    78
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    79
[ui]
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    80
# name and email (local to this repository, optional), e.g.
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    81
# username = Jane Doe <jdoe@example.com>
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    82
""",
2be7d5ebd4d0 config: use the same hgrc for a cloned repo as for an uninitted repo
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22836
diff changeset
    83
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    84
    'local':
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    85
"""# example repository config (see 'hg help config' for more info)
22836
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    86
[paths]
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    87
# path aliases to other clones of this repo in URLs or filesystem paths
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
    88
# (see 'hg help config.paths' for more info)
22836
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    89
#
31064
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    90
# default         = http://example.com/hg/example-repo
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    91
# default:pushurl = ssh://jdoe@example.net/hg/jdoes-fork
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    92
# my-fork         = ssh://jdoe@example.net/hg/jdoes-fork
4431add9aef9 ui: replace obsolete default-push with default:pushurl (issue5485)
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 30848
diff changeset
    93
# my-clone        = /home/jdoe/jdoes-clone
22836
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    94
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    95
[ui]
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    96
# name and email (local to this repository, optional), e.g.
5a831e4e6d7a config: give a more detailed sample repo config
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22783
diff changeset
    97
# username = Jane Doe <jdoe@example.com>
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    98
""",
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
    99
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   100
    'global':
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
   101
"""# example system-wide hg config (see 'hg help config' for more info)
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   102
31124
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
   103
[ui]
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
   104
# uncomment to colorize command output
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
   105
# color = auto
791ea883fc44 config: suggest the 'ui.color' instead of the 'color' extension
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31119
diff changeset
   106
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   107
[extensions]
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   108
# uncomment these lines to enable some popular extensions
29978
3d2ea1403c62 samplehgrcs: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29762
diff changeset
   109
# (see 'hg help extensions' for more info)
22419
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   110
#
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   111
# blackbox =
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   112
# pager =""",
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   113
}
fdfc9faca273 ui: move samplehgrcs from config
Matt Mackall <mpm@selenic.com>
parents: 22291
diff changeset
   114
30945
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   115
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   116
class httppasswordmgrdbproxy(object):
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   117
    """Delays loading urllib2 until it's needed."""
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   118
    def __init__(self):
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   119
        self._mgr = None
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   120
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   121
    def _get_mgr(self):
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   122
        if self._mgr is None:
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   123
            self._mgr = urlreq.httppasswordmgrwithdefaultrealm()
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   124
        return self._mgr
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   125
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   126
    def add_password(self, *args, **kwargs):
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   127
        return self._get_mgr().add_password(*args, **kwargs)
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   128
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   129
    def find_user_password(self, *args, **kwargs):
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   130
        return self._get_mgr().find_user_password(*args, **kwargs)
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   131
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   132
def _catchterm(*args):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   133
    raise error.SignalInterrupt
30945
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   134
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1483
diff changeset
   135
class ui(object):
8190
9b8ac5fb7760 ui: kill most users of parentui name and arg, replace with .copy()
Matt Mackall <mpm@selenic.com>
parents: 8189
diff changeset
   136
    def __init__(self, src=None):
30559
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   137
        """Create a fresh new ui object if no src given
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   138
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   139
        Use uimod.ui.load() to create a ui which knows global and user configs.
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   140
        In most cases, you should use ui.copy() to create a copy of an existing
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   141
        ui object.
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   142
        """
21132
350dc24a553d ui: pushbuffer can now also capture stderr
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20788
diff changeset
   143
        # _buffers: used for temporary capture of output
8202
4746113269c7 ui: buffers -> _buffers
Matt Mackall <mpm@selenic.com>
parents: 8201
diff changeset
   144
        self._buffers = []
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   145
        # 3-tuple describing how each buffer in the stack behaves.
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   146
        # Values are (capture stderr, capture subprocesses, apply labels).
21132
350dc24a553d ui: pushbuffer can now also capture stderr
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20788
diff changeset
   147
        self._bufferstates = []
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   148
        # When a buffer is active, defines whether we are expanding labels.
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   149
        # This exists to prevent an extra list lookup.
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   150
        self._bufferapplylabels = None
9851
9e7b2c49d25d Make it possible to debug failed hook imports via use of --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents: 9786
diff changeset
   151
        self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
8208
32a2a1e244f1 ui: make interactive a method
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
   152
        self._reportuntrusted = True
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   153
        self._ocfg = config.config() # overlay
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   154
        self._tcfg = config.config() # trusted
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   155
        self._ucfg = config.config() # untrusted
8478
d728f126c1b7 ui: use set instead of dict
Martin Geisler <mg@lazybytes.net>
parents: 8409
diff changeset
   156
        self._trustusers = set()
d728f126c1b7 ui: use set instead of dict
Martin Geisler <mg@lazybytes.net>
parents: 8409
diff changeset
   157
        self._trustgroups = set()
17048
15d4d475de9e ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents: 16383
diff changeset
   158
        self.callhooks = True
29109
e9ce33c642e8 ui: add an instance flag to hold --insecure bit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29096
diff changeset
   159
        # Insecure server connections requested.
e9ce33c642e8 ui: add an instance flag to hold --insecure bit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29096
diff changeset
   160
        self.insecureconnections = False
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   161
        # Blocked time
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   162
        self.logblockedtimes = False
31106
a185b903bda3 color: have the 'ui' object carry the '_colormode' directly
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31094
diff changeset
   163
        # color mode: see mercurial/color.py for possible value
a185b903bda3 color: have the 'ui' object carry the '_colormode' directly
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31094
diff changeset
   164
        self._colormode = None
31113
268caf97c38f color: move the dict with terminfo parameters on the ui object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31108
diff changeset
   165
        self._terminfoparams = {}
31115
f5131d4f512a color: move 'styles' definition on the 'ui' object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31114
diff changeset
   166
        self._styles = {}
8136
6b5522cb2ad2 ui: refactor option setting
Matt Mackall <mpm@selenic.com>
parents: 8135
diff changeset
   167
8190
9b8ac5fb7760 ui: kill most users of parentui name and arg, replace with .copy()
Matt Mackall <mpm@selenic.com>
parents: 8189
diff changeset
   168
        if src:
14612
4e1ccd4c2b6d ui: add I/O descriptors
Idan Kamara <idankk86@gmail.com>
parents: 14515
diff changeset
   169
            self.fout = src.fout
4e1ccd4c2b6d ui: add I/O descriptors
Idan Kamara <idankk86@gmail.com>
parents: 14515
diff changeset
   170
            self.ferr = src.ferr
4e1ccd4c2b6d ui: add I/O descriptors
Idan Kamara <idankk86@gmail.com>
parents: 14515
diff changeset
   171
            self.fin = src.fin
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   172
            self.pageractive = src.pageractive
31026
9c827087df38 ui: rename neverpager to disablepager
Augie Fackler <augie@google.com>
parents: 31014
diff changeset
   173
            self._disablepager = src._disablepager
14612
4e1ccd4c2b6d ui: add I/O descriptors
Idan Kamara <idankk86@gmail.com>
parents: 14515
diff changeset
   174
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   175
            self._tcfg = src._tcfg.copy()
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   176
            self._ucfg = src._ucfg.copy()
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   177
            self._ocfg = src._ocfg.copy()
8201
7cf2b987acd3 ui: trusted_users -> _trustusers, trusted_groups -> _trustgroups
Matt Mackall <mpm@selenic.com>
parents: 8200
diff changeset
   178
            self._trustusers = src._trustusers.copy()
7cf2b987acd3 ui: trusted_users -> _trustusers, trusted_groups -> _trustgroups
Matt Mackall <mpm@selenic.com>
parents: 8200
diff changeset
   179
            self._trustgroups = src._trustgroups.copy()
9887
38170eeed18c ui: add environ property to access os.environ or wsgirequest.environ
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
   180
            self.environ = src.environ
17048
15d4d475de9e ui: add a variable to control whether hooks should be called
Idan Kamara <idankk86@gmail.com>
parents: 16383
diff changeset
   181
            self.callhooks = src.callhooks
29109
e9ce33c642e8 ui: add an instance flag to hold --insecure bit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29096
diff changeset
   182
            self.insecureconnections = src.insecureconnections
31106
a185b903bda3 color: have the 'ui' object carry the '_colormode' directly
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31094
diff changeset
   183
            self._colormode = src._colormode
31113
268caf97c38f color: move the dict with terminfo parameters on the ui object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31108
diff changeset
   184
            self._terminfoparams = src._terminfoparams.copy()
31115
f5131d4f512a color: move 'styles' definition on the 'ui' object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31114
diff changeset
   185
            self._styles = src._styles.copy()
31106
a185b903bda3 color: have the 'ui' object carry the '_colormode' directly
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31094
diff changeset
   186
8143
507c49e297e1 ui: simplify init, kill dupconfig
Matt Mackall <mpm@selenic.com>
parents: 8142
diff changeset
   187
            self.fixconfig()
29378
fea71f66ebff url: remember http password database in ui object
liscju <piotr.listkiewicz@gmail.com>
parents: 29366
diff changeset
   188
fea71f66ebff url: remember http password database in ui object
liscju <piotr.listkiewicz@gmail.com>
parents: 29366
diff changeset
   189
            self.httppasswordmgrdb = src.httppasswordmgrdb
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   190
            self._blockedtimes = src._blockedtimes
8143
507c49e297e1 ui: simplify init, kill dupconfig
Matt Mackall <mpm@selenic.com>
parents: 8142
diff changeset
   191
        else:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30348
diff changeset
   192
            self.fout = util.stdout
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30348
diff changeset
   193
            self.ferr = util.stderr
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30348
diff changeset
   194
            self.fin = util.stdin
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   195
            self.pageractive = False
31026
9c827087df38 ui: rename neverpager to disablepager
Augie Fackler <augie@google.com>
parents: 31014
diff changeset
   196
            self._disablepager = False
14612
4e1ccd4c2b6d ui: add I/O descriptors
Idan Kamara <idankk86@gmail.com>
parents: 14515
diff changeset
   197
9887
38170eeed18c ui: add environ property to access os.environ or wsgirequest.environ
Sune Foldager <cryo@cyanite.org>
parents: 9851
diff changeset
   198
            # shared read-only environment
30637
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30618
diff changeset
   199
            self.environ = encoding.environ
8222
d30a21594812 more whitespace cleanup and some other style nits
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8220
diff changeset
   200
30945
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   201
            self.httppasswordmgrdb = httppasswordmgrdbproxy()
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   202
            self._blockedtimes = collections.defaultdict(int)
29378
fea71f66ebff url: remember http password database in ui object
liscju <piotr.listkiewicz@gmail.com>
parents: 29366
diff changeset
   203
30832
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   204
        allowed = self.configlist('experimental', 'exportableenviron')
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   205
        if '*' in allowed:
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   206
            self._exportableenviron = self.environ
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   207
        else:
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   208
            self._exportableenviron = {}
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   209
            for k in allowed:
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   210
                if k in self.environ:
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   211
                    self._exportableenviron[k] = self.environ[k]
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
   212
30559
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   213
    @classmethod
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   214
    def load(cls):
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   215
        """Create a ui and load global and user configs"""
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   216
        u = cls()
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   217
        # we always trust global config files
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   218
        for f in scmutil.rcpath():
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   219
            u.readconfig(f, trust=True)
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   220
        return u
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30537
diff changeset
   221
8189
d2899a856f9f ui: replace parentui mechanism with repo.baseui
Matt Mackall <mpm@selenic.com>
parents: 8187
diff changeset
   222
    def copy(self):
8220
6e6ebeb52899 ui: ui.copy() now takes the ui class into account
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8208
diff changeset
   223
        return self.__class__(self)
1839
876e4e6ad82b Create local ui object per repository, so .hg/hgrc don't get mixed.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1637
diff changeset
   224
29366
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   225
    def resetstate(self):
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   226
        """Clear internal state that shouldn't persist across commands"""
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   227
        if self._progbar:
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   228
            self._progbar.resetstate()  # reset last-print time of progress bar
30945
8b83b626fb1e ui: remove urllib2 from being imported early
Kyle Lippincott <spectral@google.com>
parents: 30932
diff changeset
   229
        self.httppasswordmgrdb = httppasswordmgrdbproxy()
29366
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   230
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   231
    @contextlib.contextmanager
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   232
    def timeblockedsection(self, key):
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   233
        # this is open-coded below - search for timeblockedsection to find them
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   234
        starttime = util.timer()
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   235
        try:
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   236
            yield
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   237
        finally:
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   238
            self._blockedtimes[key + '_blocked'] += \
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   239
                (util.timer() - starttime) * 1000
29366
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 29109
diff changeset
   240
16135
ae5f92e154d3 ui: add formatter method
Matt Mackall <mpm@selenic.com>
parents: 15919
diff changeset
   241
    def formatter(self, topic, opts):
ae5f92e154d3 ui: add formatter method
Matt Mackall <mpm@selenic.com>
parents: 15919
diff changeset
   242
        return formatter.formatter(self, topic, opts)
ae5f92e154d3 ui: add formatter method
Matt Mackall <mpm@selenic.com>
parents: 15919
diff changeset
   243
14859
dccecfaebdd2 ui: rename _is_trusted to _trusted
Matt Mackall <mpm@selenic.com>
parents: 14738
diff changeset
   244
    def _trusted(self, fp, f):
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3676
diff changeset
   245
        st = util.fstat(fp)
8657
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8656
diff changeset
   246
        if util.isowner(st):
3677
1a0fa3914c46 Avoid looking up usernames if the current user owns the .hgrc file
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3676
diff changeset
   247
            return True
8141
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   248
8201
7cf2b987acd3 ui: trusted_users -> _trustusers, trusted_groups -> _trustgroups
Matt Mackall <mpm@selenic.com>
parents: 8200
diff changeset
   249
        tusers, tgroups = self._trustusers, self._trustgroups
8141
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   250
        if '*' in tusers or '*' in tgroups:
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   251
            return True
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   252
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   253
        user = util.username(st.st_uid)
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   254
        group = util.groupname(st.st_gid)
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   255
        if user in tusers or group in tgroups or user == util.username():
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   256
            return True
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   257
8204
797586be575d ui: report_untrusted fixes
Matt Mackall <mpm@selenic.com>
parents: 8203
diff changeset
   258
        if self._reportuntrusted:
16939
fa91ddfc3f36 ui: lowercase "not trusting file" warning message
Martin Geisler <mg@aragost.com>
parents: 16938
diff changeset
   259
            self.warn(_('not trusting file %s from untrusted '
8141
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   260
                        'user %s, group %s\n') % (f, user, group))
e40b629bedd1 ui: cleanup _is_trusted a bit
Matt Mackall <mpm@selenic.com>
parents: 8140
diff changeset
   261
        return False
3551
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3489
diff changeset
   262
8200
865d2c646f29 ui: assumetrusted -> trust
Matt Mackall <mpm@selenic.com>
parents: 8199
diff changeset
   263
    def readconfig(self, filename, root=None, trust=False,
8345
dcebff8a25dd hgwebdir: read --webdir-conf as actual configuration to ui (issue1586)
Alexander Solovyov <piranha@piranha.org.ua>
parents: 8312
diff changeset
   264
                   sections=None, remap=None):
8142
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   265
        try:
30348
9df29b7c62cf ui: explicitly open config files in binary mode
Augie Fackler <augie@google.com>
parents: 30332
diff changeset
   266
            fp = open(filename, u'rb')
8142
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   267
        except IOError:
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   268
            if not sections: # ignore unless we were looking for something
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   269
                return
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   270
            raise
8139
9302404b60f3 ui: always have ucdata
Matt Mackall <mpm@selenic.com>
parents: 8138
diff changeset
   271
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   272
        cfg = config.config()
14859
dccecfaebdd2 ui: rename _is_trusted to _trusted
Matt Mackall <mpm@selenic.com>
parents: 14738
diff changeset
   273
        trusted = sections or trust or self._trusted(fp, filename)
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   274
8142
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   275
        try:
8345
dcebff8a25dd hgwebdir: read --webdir-conf as actual configuration to ui (issue1586)
Alexander Solovyov <piranha@piranha.org.ua>
parents: 8312
diff changeset
   276
            cfg.read(filename, fp, sections=sections, remap=remap)
15407
ee112eb69d2a misc: adding missing file close() calls
Matt Mackall <mpm@selenic.com>
parents: 15089
diff changeset
   277
            fp.close()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25629
diff changeset
   278
        except error.ConfigError as inst:
8142
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   279
            if trusted:
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   280
                raise
16938
ba9bfdc6bfb2 ui: lowercase ConfigError warning message
Martin Geisler <mg@aragost.com>
parents: 16751
diff changeset
   281
            self.warn(_("ignored: %s\n") % str(inst))
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   282
10455
40dfd46d098f ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents: 10426
diff changeset
   283
        if self.plain():
10507
79dd96774187 ui: unset ui.slash when HGPLAIN is set
Brodie Rao <me+hg@dackz.net>
parents: 10506
diff changeset
   284
            for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
24663
7d01371e6358 commands: add ui.statuscopies config knob
Mathias De Maré <mathias.demare@gmail.com>
parents: 24250
diff changeset
   285
                      'logtemplate', 'statuscopies', 'style',
10507
79dd96774187 ui: unset ui.slash when HGPLAIN is set
Brodie Rao <me+hg@dackz.net>
parents: 10506
diff changeset
   286
                      'traceback', 'verbose'):
10455
40dfd46d098f ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents: 10426
diff changeset
   287
                if k in cfg['ui']:
40dfd46d098f ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents: 10426
diff changeset
   288
                    del cfg['ui'][k]
14373
a599431b0ab6 ui: enable alias exception when reading config in plain mode
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14372
diff changeset
   289
            for k, v in cfg.items('defaults'):
a599431b0ab6 ui: enable alias exception when reading config in plain mode
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14372
diff changeset
   290
                del cfg['defaults'][k]
a599431b0ab6 ui: enable alias exception when reading config in plain mode
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14372
diff changeset
   291
        # Don't remove aliases from the configuration if in the exceptionlist
a599431b0ab6 ui: enable alias exception when reading config in plain mode
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14372
diff changeset
   292
        if self.plain('alias'):
10506
42afde35e9f7 ui: suppress aliases when HGPLAIN is set
Brodie Rao <me+hg@dackz.net>
parents: 10455
diff changeset
   293
            for k, v in cfg.items('alias'):
42afde35e9f7 ui: suppress aliases when HGPLAIN is set
Brodie Rao <me+hg@dackz.net>
parents: 10455
diff changeset
   294
                del cfg['alias'][k]
24883
09049042ab99 ui: disable revsetaliases in plain mode (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 24848
diff changeset
   295
        if self.plain('revsetalias'):
09049042ab99 ui: disable revsetaliases in plain mode (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 24848
diff changeset
   296
            for k, v in cfg.items('revsetalias'):
09049042ab99 ui: disable revsetaliases in plain mode (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 24848
diff changeset
   297
                del cfg['revsetalias'][k]
28958
77e566fe31ec ui: drop template aliases by HGPLAIN
Yuya Nishihara <yuya@tcha.org>
parents: 28635
diff changeset
   298
        if self.plain('templatealias'):
77e566fe31ec ui: drop template aliases by HGPLAIN
Yuya Nishihara <yuya@tcha.org>
parents: 28635
diff changeset
   299
            for k, v in cfg.items('templatealias'):
77e566fe31ec ui: drop template aliases by HGPLAIN
Yuya Nishihara <yuya@tcha.org>
parents: 28635
diff changeset
   300
                del cfg['templatealias'][k]
10455
40dfd46d098f ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents: 10426
diff changeset
   301
8142
912bfef12ba6 ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents: 8141
diff changeset
   302
        if trusted:
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   303
            self._tcfg.update(cfg)
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   304
            self._tcfg.update(self._ocfg)
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   305
        self._ucfg.update(cfg)
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   306
        self._ucfg.update(self._ocfg)
8139
9302404b60f3 ui: always have ucdata
Matt Mackall <mpm@selenic.com>
parents: 8138
diff changeset
   307
3347
bce7c1b4c1c8 ui.py: normalize settings every time the configuration changes
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3346
diff changeset
   308
        if root is None:
bce7c1b4c1c8 ui.py: normalize settings every time the configuration changes
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3346
diff changeset
   309
            root = os.path.expanduser('~')
bce7c1b4c1c8 ui.py: normalize settings every time the configuration changes
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3346
diff changeset
   310
        self.fixconfig(root=root)
3014
01454af644b8 load extensions only after the ui object has been completely initialized
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3013
diff changeset
   311
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   312
    def fixconfig(self, root=None, section=None):
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   313
        if section in (None, 'paths'):
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   314
            # expand vars and ~
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   315
            # translate paths relative to root (or home) into absolute paths
30519
20a42325fdef py3: use pycompat.getcwd() instead of os.getcwd()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30480
diff changeset
   316
            root = root or pycompat.getcwd()
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   317
            for c in self._tcfg, self._ucfg, self._ocfg:
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   318
                for n, p in c.items('paths'):
29412
b62bce819d0c ui: don't fixup [paths] sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29378
diff changeset
   319
                    # Ignore sub-options.
b62bce819d0c ui: don't fixup [paths] sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29378
diff changeset
   320
                    if ':' in n:
b62bce819d0c ui: don't fixup [paths] sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29378
diff changeset
   321
                        continue
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   322
                    if not p:
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   323
                        continue
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   324
                    if '%%' in p:
30618
201b44c8875c ui: do not translate empty configsource() to 'none' (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30569
diff changeset
   325
                        s = self.configsource('paths', n) or 'none'
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   326
                        self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
30618
201b44c8875c ui: do not translate empty configsource() to 'none' (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30569
diff changeset
   327
                                  % (n, p, s))
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   328
                        p = p.replace('%%', '%')
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   329
                    p = util.expandpath(p)
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 13984
diff changeset
   330
                    if not util.hasscheme(p) and not os.path.isabs(p):
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   331
                        p = os.path.normpath(os.path.join(root, p))
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   332
                    c.set("paths", n, p)
3347
bce7c1b4c1c8 ui.py: normalize settings every time the configuration changes
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3346
diff changeset
   333
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   334
        if section in (None, 'ui'):
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   335
            # update ui options
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   336
            self.debugflag = self.configbool('ui', 'debug')
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   337
            self.verbose = self.debugflag or self.configbool('ui', 'verbose')
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   338
            self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   339
            if self.verbose and self.quiet:
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   340
                self.quiet = self.verbose = False
13493
95b0d4c1c9e1 ui: always report untrusted hgrc files when debug enabled
Ry4an Brase <ry4an-hg@ry4an.org>
parents: 13238
diff changeset
   341
            self._reportuntrusted = self.debugflag or self.configbool("ui",
95b0d4c1c9e1 ui: always report untrusted hgrc files when debug enabled
Ry4an Brase <ry4an-hg@ry4an.org>
parents: 13238
diff changeset
   342
                "report_untrusted", True)
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   343
            self.tracebackflag = self.configbool('ui', 'traceback', False)
30976
e92daf156d5c ui: provide a mechanism to track and log blocked time
Simon Farnsworth <simonfar@fb.com>
parents: 30945
diff changeset
   344
            self.logblockedtimes = self.configbool('ui', 'logblockedtimes')
3350
ab900698b832 update ui.quiet/verbose/debug/interactive every time the config changes
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3349
diff changeset
   345
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   346
        if section in (None, 'trusted'):
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   347
            # update trust information
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   348
            self._trustusers.update(self.configlist('trusted', 'users'))
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   349
            self._trustgroups.update(self.configlist('trusted', 'groups'))
3551
3b07e223534b Only read .hg/hgrc files from trusted users/groups
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3489
diff changeset
   350
15919
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   351
    def backupconfig(self, section, item):
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   352
        return (self._ocfg.backup(section, item),
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   353
                self._tcfg.backup(section, item),
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   354
                self._ucfg.backup(section, item),)
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   355
    def restoreconfig(self, data):
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   356
        self._ocfg.restore(data[0])
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   357
        self._tcfg.restore(data[1])
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   358
        self._ucfg.restore(data[2])
69e792cf7851 config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15407
diff changeset
   359
20788
f144928dd058 config: give a useful hint of source for the most common command line settings
Mads Kiilerich <madski@unity3d.com>
parents: 20787
diff changeset
   360
    def setconfig(self, section, name, value, source=''):
20787
be179da10d5f config: backout 77f1f206e135 - 743daa601445 removed the only use of overlay
Mads Kiilerich <madski@unity3d.com>
parents: 20606
diff changeset
   361
        for cfg in (self._ocfg, self._tcfg, self._ucfg):
20788
f144928dd058 config: give a useful hint of source for the most common command line settings
Mads Kiilerich <madski@unity3d.com>
parents: 20787
diff changeset
   362
            cfg.set(section, name, value, source)
12764
ad2506f097d3 ui: only fix config if the relevant section has changed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12689
diff changeset
   363
        self.fixconfig(section=section)
960
abfb5cc97fcd Add ui.setconfig overlay
mpm@selenic.com
parents: 953
diff changeset
   364
8199
e9f90e5989d9 ui: _get_cdata -> _data
Matt Mackall <mpm@selenic.com>
parents: 8198
diff changeset
   365
    def _data(self, untrusted):
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   366
        return untrusted and self._ucfg or self._tcfg
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   367
8182
b97abc7c1135 showconfig: show source file and line with --debug
Matt Mackall <mpm@selenic.com>
parents: 8175
diff changeset
   368
    def configsource(self, section, name, untrusted=False):
30618
201b44c8875c ui: do not translate empty configsource() to 'none' (API)
Yuya Nishihara <yuya@tcha.org>
parents: 30569
diff changeset
   369
        return self._data(untrusted).source(section, name)
8182
b97abc7c1135 showconfig: show source file and line with --debug
Matt Mackall <mpm@selenic.com>
parents: 8175
diff changeset
   370
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   371
    def config(self, section, name, default=None, untrusted=False):
15035
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   372
        if isinstance(name, list):
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   373
            alternates = name
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   374
        else:
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   375
            alternates = [name]
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   376
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   377
        for n in alternates:
19536
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   378
            value = self._data(untrusted).get(section, n, None)
15035
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   379
            if value is not None:
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   380
                name = n
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   381
                break
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   382
        else:
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   383
            value = default
cc669e4fec95 ui: allow alternatives for config options
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   384
8204
797586be575d ui: report_untrusted fixes
Matt Mackall <mpm@selenic.com>
parents: 8203
diff changeset
   385
        if self.debugflag and not untrusted and self._reportuntrusted:
19536
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   386
            for n in alternates:
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   387
                uvalue = self._ucfg.get(section, n)
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   388
                if uvalue is not None and uvalue != value:
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   389
                    self.debug("ignoring untrusted configuration option "
ab3cf67740d6 ui.config: fix bug in config alternatives from cc669e4fec95
Augie Fackler <durin42@gmail.com>
parents: 19226
diff changeset
   390
                               "%s.%s = %s\n" % (section, n, uvalue))
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   391
        return value
3341
a7cec14c9b40 ui.py: move common code out of config and configbool
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3340
diff changeset
   392
27252
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   393
    def configsuboptions(self, section, name, default=None, untrusted=False):
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   394
        """Get a config option and all sub-options.
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   395
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   396
        Some config options have sub-options that are declared with the
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   397
        format "key:opt = value". This method is used to return the main
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   398
        option and all its declared sub-options.
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   399
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   400
        Returns a 2-tuple of ``(option, sub-options)``, where `sub-options``
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   401
        is a dict of defined sub-options where keys and values are strings.
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   402
        """
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   403
        data = self._data(untrusted)
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   404
        main = data.get(section, name, default)
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   405
        if self.debugflag and not untrusted and self._reportuntrusted:
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   406
            uvalue = self._ucfg.get(section, name)
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   407
            if uvalue is not None and uvalue != main:
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   408
                self.debug('ignoring untrusted configuration option '
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   409
                           '%s.%s = %s\n' % (section, name, uvalue))
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   410
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   411
        sub = {}
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   412
        prefix = '%s:' % name
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   413
        for k, v in data.items(section):
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   414
            if k.startswith(prefix):
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   415
                sub[k[len(prefix):]] = v
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   416
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   417
        if self.debugflag and not untrusted and self._reportuntrusted:
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   418
            for k, v in sub.items():
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   419
                uvalue = self._ucfg.get(section, '%s:%s' % (name, k))
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   420
                if uvalue is not None and uvalue != v:
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   421
                    self.debug('ignoring untrusted configuration option '
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   422
                               '%s:%s.%s = %s\n' % (section, name, k, uvalue))
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   423
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   424
        return main, sub
dccbebcff075 ui: add method to return option and all sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27153
diff changeset
   425
13238
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   426
    def configpath(self, section, name, default=None, untrusted=False):
14924
545e00279670 ui: config path relative to repo root
Simon Heimberg <simohe@besonet.ch>
parents: 14923
diff changeset
   427
        'get a path config item, expanded relative to repo root or config file'
13238
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   428
        v = self.config(section, name, default, untrusted)
14923
351624f8f523 ui: providing no default value to configpath should not raise an Error
Simon Heimberg <simohe@besonet.ch>
parents: 14922
diff changeset
   429
        if v is None:
351624f8f523 ui: providing no default value to configpath should not raise an Error
Simon Heimberg <simohe@besonet.ch>
parents: 14922
diff changeset
   430
            return None
13238
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   431
        if not os.path.isabs(v) or "://" not in v:
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   432
            src = self.configsource(section, name, untrusted)
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   433
            if ':' in src:
14922
1bc970a77977 ui: fix error, base can not be a list
Simon Heimberg <simohe@besonet.ch>
parents: 14859
diff changeset
   434
                base = os.path.dirname(src.rsplit(':')[0])
13238
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   435
                v = os.path.join(base, os.path.expanduser(v))
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   436
        return v
1b591f9b7fd2 ui: add configpath helper
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   437
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   438
    def configbool(self, section, name, default=False, untrusted=False):
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   439
        """parse a configuration element as a boolean
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   440
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   441
        >>> u = ui(); s = 'foo'
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   442
        >>> u.setconfig(s, 'true', 'yes')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   443
        >>> u.configbool(s, 'true')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   444
        True
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   445
        >>> u.setconfig(s, 'false', 'no')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   446
        >>> u.configbool(s, 'false')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   447
        False
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   448
        >>> u.configbool(s, 'unknown')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   449
        False
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   450
        >>> u.configbool(s, 'unknown', True)
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   451
        True
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   452
        >>> u.setconfig(s, 'invalid', 'somevalue')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   453
        >>> u.configbool(s, 'invalid')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   454
        Traceback (most recent call last):
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   455
            ...
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   456
        ConfigError: foo.invalid is not a boolean ('somevalue')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   457
        """
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   458
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   459
        v = self.config(section, name, None, untrusted)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8478
diff changeset
   460
        if v is None:
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   461
            return default
10243
cd3e5c47d663 ui: just return it if it's already a bool
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10220
diff changeset
   462
        if isinstance(v, bool):
cd3e5c47d663 ui: just return it if it's already a bool
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10220
diff changeset
   463
            return v
12087
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 11984
diff changeset
   464
        b = util.parsebool(v)
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 11984
diff changeset
   465
        if b is None:
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   466
            raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   467
                                    % (section, name, v))
12087
a88a4720c2f0 parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents: 11984
diff changeset
   468
        return b
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   469
30926
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   470
    def configwith(self, convert, section, name, default=None,
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   471
                   desc=None, untrusted=False):
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   472
        """parse a configuration element with a conversion function
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   473
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   474
        >>> u = ui(); s = 'foo'
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   475
        >>> u.setconfig(s, 'float1', '42')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   476
        >>> u.configwith(float, s, 'float1')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   477
        42.0
30932
f61c5680a862 ui: fix configwith doctest
Jun Wu <quark@fb.com>
parents: 30927
diff changeset
   478
        >>> u.setconfig(s, 'float2', '-4.25')
30926
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   479
        >>> u.configwith(float, s, 'float2')
30932
f61c5680a862 ui: fix configwith doctest
Jun Wu <quark@fb.com>
parents: 30927
diff changeset
   480
        -4.25
30926
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   481
        >>> u.configwith(float, s, 'unknown', 7)
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   482
        7
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   483
        >>> u.setconfig(s, 'invalid', 'somevalue')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   484
        >>> u.configwith(float, s, 'invalid')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   485
        Traceback (most recent call last):
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   486
            ...
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   487
        ConfigError: foo.invalid is not a valid float ('somevalue')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   488
        >>> u.configwith(float, s, 'invalid', desc='womble')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   489
        Traceback (most recent call last):
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   490
            ...
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   491
        ConfigError: foo.invalid is not a valid womble ('somevalue')
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   492
        """
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   493
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   494
        v = self.config(section, name, None, untrusted)
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   495
        if v is None:
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   496
            return default
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   497
        try:
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   498
            return convert(v)
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   499
        except ValueError:
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   500
            if desc is None:
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   501
                desc = convert.__name__
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   502
            raise error.ConfigError(_("%s.%s is not a valid %s ('%s')")
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   503
                                    % (section, name, desc, v))
120682fce099 ui: add a configwith method
Bryan O'Sullivan <bryano@fb.com>
parents: 30925
diff changeset
   504
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   505
    def configint(self, section, name, default=None, untrusted=False):
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   506
        """parse a configuration element as an integer
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   507
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   508
        >>> u = ui(); s = 'foo'
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   509
        >>> u.setconfig(s, 'int1', '42')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   510
        >>> u.configint(s, 'int1')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   511
        42
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   512
        >>> u.setconfig(s, 'int2', '-42')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   513
        >>> u.configint(s, 'int2')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   514
        -42
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   515
        >>> u.configint(s, 'unknown', 7)
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   516
        7
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   517
        >>> u.setconfig(s, 'invalid', 'somevalue')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   518
        >>> u.configint(s, 'invalid')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   519
        Traceback (most recent call last):
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   520
            ...
30927
8fa3ab6221b9 ui: rewrite configint in terms of configwith
Bryan O'Sullivan <bryano@fb.com>
parents: 30926
diff changeset
   521
        ConfigError: foo.invalid is not a valid integer ('somevalue')
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   522
        """
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   523
30927
8fa3ab6221b9 ui: rewrite configint in terms of configwith
Bryan O'Sullivan <bryano@fb.com>
parents: 30926
diff changeset
   524
        return self.configwith(int, section, name, default, 'integer',
8fa3ab6221b9 ui: rewrite configint in terms of configwith
Bryan O'Sullivan <bryano@fb.com>
parents: 30926
diff changeset
   525
                               untrusted)
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   526
19065
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   527
    def configbytes(self, section, name, default=0, untrusted=False):
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   528
        """parse a configuration element as a quantity in bytes
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   529
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   530
        Units can be specified as b (bytes), k or kb (kilobytes), m or
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   531
        mb (megabytes), g or gb (gigabytes).
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   532
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   533
        >>> u = ui(); s = 'foo'
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   534
        >>> u.setconfig(s, 'val1', '42')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   535
        >>> u.configbytes(s, 'val1')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   536
        42
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   537
        >>> u.setconfig(s, 'val2', '42.5 kb')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   538
        >>> u.configbytes(s, 'val2')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   539
        43520
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   540
        >>> u.configbytes(s, 'unknown', '7 MB')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   541
        7340032
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   542
        >>> u.setconfig(s, 'invalid', 'somevalue')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   543
        >>> u.configbytes(s, 'invalid')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   544
        Traceback (most recent call last):
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   545
            ...
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   546
        ConfigError: foo.invalid is not a byte quantity ('somevalue')
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   547
        """
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   548
19195
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   549
        value = self.config(section, name)
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   550
        if value is None:
19065
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   551
            if not isinstance(default, str):
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   552
                return default
19195
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   553
            value = default
19065
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   554
        try:
19195
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   555
            return util.sizetoint(value)
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   556
        except error.ParseError:
19065
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   557
            raise error.ConfigError(_("%s.%s is not a byte quantity ('%s')")
19195
9311cd5c09ed ui: use util.sizetoint in configbytes
Bryan O'Sullivan <bryano@fb.com>
parents: 19085
diff changeset
   558
                                    % (section, name, value))
19065
2c4cd1c42365 ui: add a configbytes method, for space configuration
Bryan O'Sullivan <bryano@fb.com>
parents: 18966
diff changeset
   559
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   560
    def configlist(self, section, name, default=None, untrusted=False):
14171
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   561
        """parse a configuration element as a list of comma/space separated
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   562
        strings
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   563
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   564
        >>> u = ui(); s = 'foo'
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   565
        >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   566
        >>> u.configlist(s, 'list1')
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   567
        ['this', 'is', 'a small', 'test']
fa2b596db182 ui: add configint function and tests
Sune Foldager <cryo@cyanite.org>
parents: 14076
diff changeset
   568
        """
10982
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   569
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   570
        def _parse_plain(parts, s, offset):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   571
            whitespace = False
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   572
            while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   573
                whitespace = True
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   574
                offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   575
            if offset >= len(s):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   576
                return None, parts, offset
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   577
            if whitespace:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   578
                parts.append('')
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   579
            if s[offset] == '"' and not parts[-1]:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   580
                return _parse_quote, parts, offset + 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   581
            elif s[offset] == '"' and parts[-1][-1] == '\\':
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   582
                parts[-1] = parts[-1][:-1] + s[offset]
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   583
                return _parse_plain, parts, offset + 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   584
            parts[-1] += s[offset]
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   585
            return _parse_plain, parts, offset + 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   586
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   587
        def _parse_quote(parts, s, offset):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   588
            if offset < len(s) and s[offset] == '"': # ""
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   589
                parts.append('')
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   590
                offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   591
                while offset < len(s) and (s[offset].isspace() or
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   592
                        s[offset] == ','):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   593
                    offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   594
                return _parse_plain, parts, offset
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   595
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   596
            while offset < len(s) and s[offset] != '"':
11036
4efdccaca21d ui: fix check-code error
Henrik Stuart <hg@hstuart.dk>
parents: 10982
diff changeset
   597
                if (s[offset] == '\\' and offset + 1 < len(s)
4efdccaca21d ui: fix check-code error
Henrik Stuart <hg@hstuart.dk>
parents: 10982
diff changeset
   598
                        and s[offset + 1] == '"'):
10982
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   599
                    offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   600
                    parts[-1] += '"'
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   601
                else:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   602
                    parts[-1] += s[offset]
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   603
                offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   604
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   605
            if offset >= len(s):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   606
                real_parts = _configlist(parts[-1])
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   607
                if not real_parts:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   608
                    parts[-1] = '"'
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   609
                else:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   610
                    real_parts[0] = '"' + real_parts[0]
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   611
                    parts = parts[:-1]
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   612
                    parts.extend(real_parts)
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   613
                return None, parts, offset
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   614
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   615
            offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   616
            while offset < len(s) and s[offset] in [' ', ',']:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   617
                offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   618
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   619
            if offset < len(s):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   620
                if offset + 1 == len(s) and s[offset] == '"':
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   621
                    parts[-1] += '"'
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   622
                    offset += 1
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   623
                else:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   624
                    parts.append('')
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   625
            else:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   626
                return None, parts, offset
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   627
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   628
            return _parse_plain, parts, offset
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   629
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   630
        def _configlist(s):
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   631
            s = s.rstrip(' ,')
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   632
            if not s:
11945
5094e6b2f640 ui: differentiate empty configlist from None
Alecs King <alecsk@gmail.com>
parents: 11600
diff changeset
   633
                return []
10982
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   634
            parser, parts, offset = _parse_plain, [''], 0
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   635
            while parser:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   636
                parser, parts, offset = parser(parts, s, offset)
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   637
            return parts
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   638
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   639
        result = self.config(section, name, untrusted=untrusted)
2499
894435215344 Added ui.configlist method to get comma/space separated lists of strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2498
diff changeset
   640
        if result is None:
2502
18cf95ad3666 Allow using default values with ui.configlist, too, and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2499
diff changeset
   641
            result = default or []
30569
bcb858396233 py3: avoid use of basestring
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   642
        if isinstance(result, bytes):
11309
ef7636efeb01 ui: handle leading newlines/spaces/commas in configlist
Thomas Arendsen Hein <thomas@intevation.de>
parents: 11302
diff changeset
   643
            result = _configlist(result.lstrip(' ,\n'))
10982
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   644
            if result is None:
0a548640e012 ui: support quotes in configlist (issue2147)
Henrik Stuart <hg@hstuart.dk>
parents: 10815
diff changeset
   645
                result = default or []
2502
18cf95ad3666 Allow using default values with ui.configlist, too, and add a test for this.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2499
diff changeset
   646
        return result
2499
894435215344 Added ui.configlist method to get comma/space separated lists of strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2498
diff changeset
   647
27696
e70c97cc9243 config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents: 27563
diff changeset
   648
    def hasconfig(self, section, name, untrusted=False):
e70c97cc9243 config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents: 27563
diff changeset
   649
        return self._data(untrusted).hasitem(section, name)
e70c97cc9243 config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents: 27563
diff changeset
   650
4487
1b5b98837bb5 ui: Rename has_config to has_section.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4258
diff changeset
   651
    def has_section(self, section, untrusted=False):
2343
af81d8770620 add ui.has_config method.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2335
diff changeset
   652
        '''tell whether section exists in config.'''
8199
e9f90e5989d9 ui: _get_cdata -> _data
Matt Mackall <mpm@selenic.com>
parents: 8198
diff changeset
   653
        return section in self._data(untrusted)
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   654
27253
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   655
    def configitems(self, section, untrusted=False, ignoresub=False):
8199
e9f90e5989d9 ui: _get_cdata -> _data
Matt Mackall <mpm@selenic.com>
parents: 8198
diff changeset
   656
        items = self._data(untrusted).items(section)
27253
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   657
        if ignoresub:
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   658
            newitems = {}
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   659
            for k, v in items:
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   660
                if ':' not in k:
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   661
                    newitems[k] = v
f43988e5954c ui: optionally ignore sub-options from configitems()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27252
diff changeset
   662
            items = newitems.items()
8204
797586be575d ui: report_untrusted fixes
Matt Mackall <mpm@selenic.com>
parents: 8203
diff changeset
   663
        if self.debugflag and not untrusted and self._reportuntrusted:
8222
d30a21594812 more whitespace cleanup and some other style nits
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8220
diff changeset
   664
            for k, v in self._ucfg.items(section):
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   665
                if self._tcfg.get(section, k) != v:
14708
8083f4d00bd1 i18n: remove translation of debug messages
David Soria Parra <dsp@php.net>
parents: 14614
diff changeset
   666
                    self.debug("ignoring untrusted configuration option "
8083f4d00bd1 i18n: remove translation of debug messages
David Soria Parra <dsp@php.net>
parents: 14614
diff changeset
   667
                               "%s.%s = %s\n" % (section, k, v))
8144
fca54469480e ui: introduce new config parser
Matt Mackall <mpm@selenic.com>
parents: 8143
diff changeset
   668
        return items
285
5a1e6d27f399 ui: add configuration file support
mpm@selenic.com
parents: 249
diff changeset
   669
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   670
    def walkconfig(self, untrusted=False):
8203
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   671
        cfg = self._data(untrusted)
3377fa11af67 ui: privatize cdata vars
Matt Mackall <mpm@selenic.com>
parents: 8202
diff changeset
   672
        for section in cfg.sections():
3552
9b52239dc740 save settings from untrusted config files in a separate configparser
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3551
diff changeset
   673
            for name, value in self.configitems(section, untrusted):
13576
edd06611a7c6 ui: yield unchanged values in walkconfig
Martin Geisler <mg@aragost.com>
parents: 13493
diff changeset
   674
                yield section, name, value
1028
25e7ea0f2cff Add commands.debugconfig.
Bryan O'Sullivan <bos@serpentine.com>
parents: 981
diff changeset
   675
14372
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   676
    def plain(self, feature=None):
11325
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
   677
        '''is plain mode active?
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
   678
13849
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   679
        Plain mode means that all configuration variables which affect
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   680
        the behavior and output of Mercurial should be
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   681
        ignored. Additionally, the output should be stable,
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   682
        reproducible and suitable for use in scripts or applications.
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   683
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   684
        The only way to trigger plain mode is by setting either the
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   685
        `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
11325
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
   686
14372
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   687
        The return value can either be
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   688
        - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   689
        - True otherwise
11325
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
   690
        '''
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   691
        if ('HGPLAIN' not in encoding.environ and
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   692
                'HGPLAINEXCEPT' not in encoding.environ):
13849
9f97de157aad HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   693
            return False
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   694
        exceptions = encoding.environ.get('HGPLAINEXCEPT',
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   695
                '').strip().split(',')
14372
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   696
        if feature and exceptions:
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   697
            return feature not in exceptions
be0daa0eeb3e ui: test plain mode against exceptions
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14171
diff changeset
   698
        return True
10455
40dfd46d098f ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents: 10426
diff changeset
   699
608
d2994b5298fb Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents: 565
diff changeset
   700
    def username(self):
1985
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   701
        """Return default username to be used in commits.
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   702
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   703
        Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   704
        and stop searching if one of these is set.
6862
7192876ac329 ui: add an option to prompt for the username when it isn't provided
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6762
diff changeset
   705
        If not found and ui.askusername is True, ask the user, else use
7192876ac329 ui: add an option to prompt for the username when it isn't provided
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6762
diff changeset
   706
        ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
1985
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   707
        """
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   708
        user = encoding.environ.get("HGUSER")
1985
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   709
        if user is None:
21955
6dfb78f18bdb config: allow 'user' in .hgrc ui section (issue3169)
anatoly techtonik <techtonik@gmail.com>
parents: 21195
diff changeset
   710
            user = self.config("ui", ["username", "user"])
11225
d6dbd5e4ee72 ui.username(): expand environment variables in username configuration value.
Chad Dombrova <chadrik@gmail.com>
parents: 11036
diff changeset
   711
            if user is not None:
d6dbd5e4ee72 ui.username(): expand environment variables in username configuration value.
Chad Dombrova <chadrik@gmail.com>
parents: 11036
diff changeset
   712
                user = os.path.expandvars(user)
1985
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   713
        if user is None:
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
   714
            user = encoding.environ.get("EMAIL")
6862
7192876ac329 ui: add an option to prompt for the username when it isn't provided
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6762
diff changeset
   715
        if user is None and self.configbool("ui", "askusername"):
7600
f7739cf3833c lowercase prompts
Martin Geisler <mg@daimi.au.dk>
parents: 7497
diff changeset
   716
            user = self.prompt(_("enter a commit username:"), default=None)
9613
c63c336ee2f7 ui: only use "user@host" as username in noninteractive mode
Martin Geisler <mg@lazybytes.net>
parents: 9610
diff changeset
   717
        if user is None and not self.interactive():
3721
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3678
diff changeset
   718
            try:
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3678
diff changeset
   719
                user = '%s@%s' % (util.getuser(), socket.getfqdn())
16940
6409a5c75125 ui: lowercase "no username" warning
Martin Geisler <mg@aragost.com>
parents: 16939
diff changeset
   720
                self.warn(_("no username found, using '%s' instead\n") % user)
3721
98f2507c5551 only print a warning when no username is specified
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3678
diff changeset
   721
            except KeyError:
4044
78a0dd93db0b Abort on empty username so specifying a username can be forced.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3984
diff changeset
   722
                pass
78a0dd93db0b Abort on empty username so specifying a username can be forced.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3984
diff changeset
   723
        if not user:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26451
diff changeset
   724
            raise error.Abort(_('no username supplied'),
28962
ad2cd2ef25d9 config: use single quotes around command hint
timeless <timeless@mozdev.org>
parents: 28958
diff changeset
   725
                             hint=_("use 'hg config --edit' "
20580
b75a23eec9c9 ui: fix extra space in username abort
Matt Mackall <mpm@selenic.com>
parents: 20574
diff changeset
   726
                                    'to set your username'))
6351
eed0a6a05096 ui: disallow newlines in usernames (issue1034)
Matt Mackall <mpm@selenic.com>
parents: 6333
diff changeset
   727
        if "\n" in user:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26451
diff changeset
   728
            raise error.Abort(_("username %s contains a newline\n")
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26451
diff changeset
   729
                              % repr(user))
1985
c577689006fa Adapted behaviour of ui.username() to documentation and mention it explicitly:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1984
diff changeset
   730
        return user
608
d2994b5298fb Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents: 565
diff changeset
   731
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
   732
    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
   733
        """Return a short representation of a user name or email address."""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   734
        if not self.verbose:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   735
            user = util.shortuser(user)
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
   736
        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
   737
2494
73ac95671788 push, outgoing, bundle: fall back to "default" if "default-push" not defined
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2470
diff changeset
   738
    def expandpath(self, loc, default=None):
1892
622ee75cb4c9 Directory names take precedence over symbolic names consistently.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1882
diff changeset
   739
        """Return repository location relative to cwd or from [paths]"""
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   740
        try:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   741
            p = self.paths.getpath(loc)
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   742
            if p:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   743
                return p.rawloc
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   744
        except error.RepoError:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   745
            pass
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   746
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   747
        if default:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   748
            try:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   749
                p = self.paths.getpath(default)
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   750
                if p:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   751
                    return p.rawloc
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   752
            except error.RepoError:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   753
                pass
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
   754
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
   755
        return loc
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
   756
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
   757
    @util.propertycache
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
   758
    def paths(self):
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
   759
        return paths(self)
506
1f81ebff98c9 [PATCH] Add ui.expandpath command
mpm@selenic.com
parents: 350
diff changeset
   760
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   761
    def pushbuffer(self, error=False, subproc=False, labeled=False):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23053
diff changeset
   762
        """install a buffer to capture standard output of the ui object
21132
350dc24a553d ui: pushbuffer can now also capture stderr
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20788
diff changeset
   763
24848
2f88821856eb ui: allow capture of subprocess output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24687
diff changeset
   764
        If error is True, the error output will be captured too.
2f88821856eb ui: allow capture of subprocess output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24687
diff changeset
   765
2f88821856eb ui: allow capture of subprocess output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24687
diff changeset
   766
        If subproc is True, output from subprocesses (typically hooks) will be
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   767
        captured too.
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   768
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   769
        If labeled is True, any labels associated with buffered
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   770
        output will be handled. By default, this has no effect
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   771
        on the output returned, but extensions and GUI tools may
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   772
        handle this argument and returned styled output. If output
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   773
        is being buffered so it can be captured and parsed or
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   774
        processed, labeled should not be set to True.
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   775
        """
8202
4746113269c7 ui: buffers -> _buffers
Matt Mackall <mpm@selenic.com>
parents: 8201
diff changeset
   776
        self._buffers.append([])
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   777
        self._bufferstates.append((error, subproc, labeled))
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   778
        self._bufferapplylabels = labeled
3737
9f5c46c50118 add a simple nested buffering scheme to ui
Matt Mackall <mpm@selenic.com>
parents: 3721
diff changeset
   779
27109
a93d53f79e6e ui: remove labeled argument from popbuffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27106
diff changeset
   780
    def popbuffer(self):
a93d53f79e6e ui: remove labeled argument from popbuffer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27106
diff changeset
   781
        '''pop the last buffer and return the buffered output'''
21132
350dc24a553d ui: pushbuffer can now also capture stderr
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20788
diff changeset
   782
        self._bufferstates.pop()
27106
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   783
        if self._bufferstates:
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   784
            self._bufferapplylabels = self._bufferstates[-1][2]
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   785
        else:
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   786
            self._bufferapplylabels = None
6ef17697b03d ui: track label expansion when creating buffers
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27068
diff changeset
   787
8202
4746113269c7 ui: buffers -> _buffers
Matt Mackall <mpm@selenic.com>
parents: 8201
diff changeset
   788
        return "".join(self._buffers.pop())
3737
9f5c46c50118 add a simple nested buffering scheme to ui
Matt Mackall <mpm@selenic.com>
parents: 3721
diff changeset
   789
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   790
    def write(self, *args, **opts):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   791
        '''write args to output
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   792
31091
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   793
        By default, this method simply writes to the buffer or stdout.
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   794
        Color mode can be set on the UI class to have the output decorated
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   795
        with color modifier before being written to stdout.
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   796
31091
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   797
        The color used is controlled by an optional keyword argument, "label".
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   798
        This should be a string containing label names separated by space.
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   799
        Label names take the form of "topic.type". For example, ui.debug()
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   800
        issues a label of "ui.debug".
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   801
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   802
        When labeling output for a specific command, a label of
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   803
        "cmdname.type" is recommended. For example, status issues
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   804
        a label of "status.modified" for modified files.
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   805
        '''
28633
e35d7f131483 ui: add prompt argument to write (issue5154) (API)
timeless <timeless@mozdev.org>
parents: 28598
diff changeset
   806
        if self._buffers and not opts.get('prompt', False):
31091
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   807
            if self._bufferapplylabels:
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   808
                label = opts.get('label', '')
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   809
                self._buffers[-1].extend(self.label(a, label) for a in args)
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   810
            else:
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   811
                self._buffers[-1].extend(args)
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   812
        elif self._colormode == 'win32':
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   813
            # windows color printing is its own can of crab, defer to
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   814
            # the color module and that is it.
31114
1613c55ad3d6 color: pass 'ui' to 'win32print'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31113
diff changeset
   815
            color.win32print(self, self._write, *args, **opts)
3737
9f5c46c50118 add a simple nested buffering scheme to ui
Matt Mackall <mpm@selenic.com>
parents: 3721
diff changeset
   816
        else:
31091
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   817
            msgs = args
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   818
            if self._colormode is not None:
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   819
                label = opts.get('label', '')
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   820
                msgs = [self.label(a, label) for a in args]
ad074f900907 color: move 'write' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31090
diff changeset
   821
            self._write(*msgs, **opts)
31090
e9f96ccf36a6 ui: extract the low level part of 'write' in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31087
diff changeset
   822
e9f96ccf36a6 ui: extract the low level part of 'write' in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31087
diff changeset
   823
    def _write(self, *msgs, **opts):
31128
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   824
        self._progclear()
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   825
        # opencode timeblockedsection because this is a critical path
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   826
        starttime = util.timer()
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   827
        try:
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   828
            for a in msgs:
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   829
                self.fout.write(a)
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   830
        finally:
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   831
            self._blockedtimes['stdio_blocked'] += \
0bb3089fe735 ui: remove superfluous indent in _write()
Yuya Nishihara <yuya@tcha.org>
parents: 31124
diff changeset
   832
                (util.timer() - starttime) * 1000
565
9a80418646dd [PATCH] Make ui.warn write to stderr
mpm@selenic.com
parents: 515
diff changeset
   833
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
   834
    def write_err(self, *args, **opts):
25499
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
   835
        self._progclear()
31092
cb759f7f940d ui: extract buffer write from protect and timed 'write_err' output
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31091
diff changeset
   836
        if self._bufferstates and self._bufferstates[-1][0]:
31094
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   837
            self.write(*args, **opts)
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   838
        elif self._colormode == 'win32':
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   839
            # windows color printing is its own can of crab, defer to
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   840
            # the color module and that is it.
31114
1613c55ad3d6 color: pass 'ui' to 'win32print'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31113
diff changeset
   841
            color.win32print(self, self._write_err, *args, **opts)
31094
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   842
        else:
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   843
            msgs = args
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   844
            if self._colormode is not None:
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   845
                label = opts.get('label', '')
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   846
                msgs = [self.label(a, label) for a in args]
0c003943134f color: move 'write-err' logic to the core ui class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31093
diff changeset
   847
            self._write_err(*msgs, **opts)
31093
15d6488554b9 ui: extract low level part of 'write_err' in its own method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31092
diff changeset
   848
15d6488554b9 ui: extract low level part of 'write_err' in its own method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31092
diff changeset
   849
    def _write_err(self, *msgs, **opts):
1989
0541768fa558 ignore EPIPE in ui.err_write
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1985
diff changeset
   850
        try:
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   851
            with self.timeblockedsection('stdio'):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   852
                if not getattr(self.fout, 'closed', False):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   853
                    self.fout.flush()
31093
15d6488554b9 ui: extract low level part of 'write_err' in its own method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31092
diff changeset
   854
                for a in msgs:
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   855
                    self.ferr.write(a)
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   856
                # stderr may be buffered under win32 when redirected to files,
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   857
                # including stdout.
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   858
                if not getattr(self.ferr, 'closed', False):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   859
                    self.ferr.flush()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25629
diff changeset
   860
        except IOError as inst:
16367
c14898df3b92 ui: swallow EBADF on stderr
Kevin Bullock <kbullock@ringworld.org>
parents: 15919
diff changeset
   861
            if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
1989
0541768fa558 ignore EPIPE in ui.err_write
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1985
diff changeset
   862
                raise
565
9a80418646dd [PATCH] Make ui.warn write to stderr
mpm@selenic.com
parents: 515
diff changeset
   863
1837
6f67a4c93493 make ui flush output. this makes error happen if printing to /dev/full.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1637
diff changeset
   864
    def flush(self):
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   865
        # opencode timeblockedsection because this is a critical path
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   866
        starttime = util.timer()
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   867
        try:
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   868
            try: self.fout.flush()
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   869
            except (IOError, ValueError): pass
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   870
            try: self.ferr.flush()
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   871
            except (IOError, ValueError): pass
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   872
        finally:
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   873
            self._blockedtimes['stdio_blocked'] += \
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
   874
                (util.timer() - starttime) * 1000
1837
6f67a4c93493 make ui flush output. this makes error happen if printing to /dev/full.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1637
diff changeset
   875
16751
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
   876
    def _isatty(self, fh):
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
   877
        if self.configbool('ui', 'nontty', False):
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
   878
            return False
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
   879
        return util.isatty(fh)
1837
6f67a4c93493 make ui flush output. this makes error happen if printing to /dev/full.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1637
diff changeset
   880
31026
9c827087df38 ui: rename neverpager to disablepager
Augie Fackler <augie@google.com>
parents: 31014
diff changeset
   881
    def disablepager(self):
9c827087df38 ui: rename neverpager to disablepager
Augie Fackler <augie@google.com>
parents: 31014
diff changeset
   882
        self._disablepager = True
30994
3ed6e43998df ui: introduce neverpager() call
Augie Fackler <augie@google.com>
parents: 30992
diff changeset
   883
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   884
    def pager(self, command):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   885
        """Start a pager for subsequent command output.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   886
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   887
        Commands which produce a long stream of output should call
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   888
        this function to activate the user's preferred pagination
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   889
        mechanism (which may be no pager). Calling this function
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   890
        precludes any future use of interactive functionality, such as
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   891
        prompting the user or activating curses.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   892
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   893
        Args:
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   894
          command: The full, non-aliased name of the command. That is, "log"
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   895
                   not "history, "summary" not "summ", etc.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   896
        """
31026
9c827087df38 ui: rename neverpager to disablepager
Augie Fackler <augie@google.com>
parents: 31014
diff changeset
   897
        if (self._disablepager
30994
3ed6e43998df ui: introduce neverpager() call
Augie Fackler <augie@google.com>
parents: 30992
diff changeset
   898
            or self.pageractive
30995
5e85bab867a7 ui: add ignore-single-command functionality
Augie Fackler <augie@google.com>
parents: 30994
diff changeset
   899
            or command in self.configlist('pager', 'ignore')
31062
88203f26ea57 pager: add a config knob to just globally turn off the pager
Augie Fackler <augie@google.com>
parents: 31026
diff changeset
   900
            or not self.configbool('pager', 'enable', True)
30997
29a4a8d01bc9 ui: respect historic pager.attend-$COMMAND=no
Augie Fackler <augie@google.com>
parents: 30995
diff changeset
   901
            or not self.configbool('pager', 'attend-' + command, True)
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   902
            # TODO: if we want to allow HGPLAINEXCEPT=pager,
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   903
            # formatted() will need some adjustment.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   904
            or not self.formatted()
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   905
            or self.plain()
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   906
            # TODO: expose debugger-enabled on the UI object
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   907
            or '--debugger' in sys.argv):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   908
            # We only want to paginate if the ui appears to be
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   909
            # interactive, the user didn't say HGPLAIN or
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   910
            # HGPLAINEXCEPT=pager, and the user didn't specify --debug.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   911
            return
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   912
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   913
        # TODO: add a "system defaults" config section so this default
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   914
        # of more(1) can be easily replaced with a global
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   915
        # configuration file. For example, on OS X the sane default is
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   916
        # less(1), not more(1), and on debian it's
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   917
        # sensible-pager(1). We should probably also give the system
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   918
        # default editor command similar treatment.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   919
        envpager = encoding.environ.get('PAGER', 'more')
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   920
        pagercmd = self.config('pager', 'pager', envpager)
31079
873ebdd6e84d pager: do not try to run an empty pager command
Yuya Nishihara <yuya@tcha.org>
parents: 31062
diff changeset
   921
        if not pagercmd:
873ebdd6e84d pager: do not try to run an empty pager command
Yuya Nishihara <yuya@tcha.org>
parents: 31062
diff changeset
   922
            return
873ebdd6e84d pager: do not try to run an empty pager command
Yuya Nishihara <yuya@tcha.org>
parents: 31062
diff changeset
   923
873ebdd6e84d pager: do not try to run an empty pager command
Yuya Nishihara <yuya@tcha.org>
parents: 31062
diff changeset
   924
        self.debug('starting pager for command %r\n' % command)
30992
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   925
        self.pageractive = True
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   926
        # Preserve the formatted-ness of the UI. This is important
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   927
        # because we mess with stdout, which might confuse
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   928
        # auto-detection of things being formatted.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   929
        self.setconfig('ui', 'formatted', self.formatted(), 'pager')
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   930
        self.setconfig('ui', 'interactive', False, 'pager')
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   931
        if util.safehasattr(signal, "SIGPIPE"):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   932
            signal.signal(signal.SIGPIPE, _catchterm)
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   933
        self._runpager(pagercmd)
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   934
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   935
    def _runpager(self, command):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   936
        """Actually start the pager and set up file descriptors.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   937
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   938
        This is separate in part so that extensions (like chg) can
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   939
        override how a pager is invoked.
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   940
        """
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   941
        pager = subprocess.Popen(command, shell=True, bufsize=-1,
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   942
                                 close_fds=util.closefds, stdin=subprocess.PIPE,
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   943
                                 stdout=util.stdout, stderr=util.stderr)
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   944
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   945
        # back up original file descriptors
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   946
        stdoutfd = os.dup(util.stdout.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   947
        stderrfd = os.dup(util.stderr.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   948
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   949
        os.dup2(pager.stdin.fileno(), util.stdout.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   950
        if self._isatty(util.stderr):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   951
            os.dup2(pager.stdin.fileno(), util.stderr.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   952
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   953
        @atexit.register
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   954
        def killpager():
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   955
            if util.safehasattr(signal, "SIGINT"):
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   956
                signal.signal(signal.SIGINT, signal.SIG_IGN)
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   957
            # restore original fds, closing pager.stdin copies in the process
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   958
            os.dup2(stdoutfd, util.stdout.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   959
            os.dup2(stderrfd, util.stderr.fileno())
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   960
            pager.stdin.close()
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   961
            pager.wait()
61b4122019d3 pager: move pager-initiating code into core
Augie Fackler <augie@google.com>
parents: 30980
diff changeset
   962
28542
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   963
    def interface(self, feature):
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   964
        """what interface to use for interactive console features?
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   965
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   966
        The interface is controlled by the value of `ui.interface` but also by
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   967
        the value of feature-specific configuration. For example:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   968
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   969
        ui.interface.histedit = text
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   970
        ui.interface.chunkselector = curses
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   971
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   972
        Here the features are "histedit" and "chunkselector".
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   973
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   974
        The configuration above means that the default interfaces for commands
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   975
        is curses, the interface for histedit is text and the interface for
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   976
        selecting chunk is crecord (the best curses interface available).
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   977
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30314
diff changeset
   978
        Consider the following example:
28542
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   979
        ui.interface = curses
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   980
        ui.interface.histedit = text
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   981
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   982
        Then histedit will use the text interface and chunkselector will use
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   983
        the default curses interface (crecord at the moment).
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   984
        """
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   985
        alldefaults = frozenset(["text", "curses"])
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   986
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   987
        featureinterfaces = {
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   988
            "chunkselector": [
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   989
                "text",
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   990
                "curses",
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   991
            ]
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   992
        }
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   993
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   994
        # Feature-specific interface
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   995
        if feature not in featureinterfaces.keys():
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   996
            # Programming error, not user error
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   997
            raise ValueError("Unknown feature requested %s" % feature)
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   998
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
   999
        availableinterfaces = frozenset(featureinterfaces[feature])
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1000
        if alldefaults > availableinterfaces:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1001
            # Programming error, not user error. We need a use case to
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1002
            # define the right thing to do here.
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1003
            raise ValueError(
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1004
                "Feature %s does not handle all default interfaces" %
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1005
                feature)
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1006
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1007
        if self.plain():
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1008
            return "text"
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1009
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1010
        # Default interface for all the features
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1011
        defaultinterface = "text"
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1012
        i = self.config("ui", "interface", None)
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1013
        if i in alldefaults:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1014
            defaultinterface = i
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1015
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1016
        choseninterface = defaultinterface
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1017
        f = self.config("ui", "interface.%s" % feature, None)
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1018
        if f in availableinterfaces:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1019
            choseninterface = f
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1020
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1021
        if i is not None and defaultinterface != i:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1022
            if f is not None:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1023
                self.warn(_("invalid value for ui.interface: %s\n") %
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1024
                          (i,))
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1025
            else:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1026
                self.warn(_("invalid value for ui.interface: %s (using %s)\n") %
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1027
                         (i, choseninterface))
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1028
        if f is not None and choseninterface != f:
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1029
            self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") %
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1030
                      (feature, f, choseninterface))
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1031
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1032
        return choseninterface
71e12fc53b80 ui: add new config flag for interface selection
Simon Farnsworth <simonfar@fb.com>
parents: 28498
diff changeset
  1033
8208
32a2a1e244f1 ui: make interactive a method
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
  1034
    def interactive(self):
11325
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1035
        '''is interactive input allowed?
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1036
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1037
        An interactive session is a session where input can be reasonably read
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1038
        from `sys.stdin'. If this function returns false, any attempt to read
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1039
        from stdin should fail with an error, unless a sensible default has been
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1040
        specified.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1041
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1042
        Interactiveness is triggered by the value of the `ui.interactive'
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1043
        configuration variable or - if it is unset - when `sys.stdin' points
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1044
        to a terminal device.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1045
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1046
        This function refers to input only; for output, see `ui.formatted()'.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1047
        '''
8538
6419bc7b3d9c ui: honor interactive=off even if isatty()
Patrick Mezard <pmezard@gmail.com>
parents: 8527
diff changeset
  1048
        i = self.configbool("ui", "interactive", None)
6419bc7b3d9c ui: honor interactive=off even if isatty()
Patrick Mezard <pmezard@gmail.com>
parents: 8527
diff changeset
  1049
        if i is None:
14515
76f295eaed86 util: add helper function isatty(fd) to check for tty-ness
Idan Kamara <idankk86@gmail.com>
parents: 14373
diff changeset
  1050
            # some environments replace stdin without implementing isatty
76f295eaed86 util: add helper function isatty(fd) to check for tty-ness
Idan Kamara <idankk86@gmail.com>
parents: 14373
diff changeset
  1051
            # usually those are non-interactive
16751
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
  1052
            return self._isatty(self.fin)
10077
89617aacb495 make ui.interactive() return false in case stdin lacks isatty
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 9887
diff changeset
  1053
8538
6419bc7b3d9c ui: honor interactive=off even if isatty()
Patrick Mezard <pmezard@gmail.com>
parents: 8527
diff changeset
  1054
        return i
8208
32a2a1e244f1 ui: make interactive a method
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
  1055
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1056
    def termwidth(self):
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1057
        '''how wide is the terminal in columns?
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1058
        '''
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
  1059
        if 'COLUMNS' in encoding.environ:
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1060
            try:
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
  1061
                return int(encoding.environ['COLUMNS'])
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1062
            except ValueError:
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1063
                pass
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30310
diff changeset
  1064
        return scmutil.termsize(self)[0]
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12665
diff changeset
  1065
11324
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1066
    def formatted(self):
11325
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1067
        '''should formatted output be used?
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1068
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1069
        It is often desirable to format the output to suite the output medium.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1070
        Examples of this are truncating long lines or colorizing messages.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1071
        However, this is not often not desirable when piping output into other
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1072
        utilities, e.g. `grep'.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1073
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1074
        Formatted output is triggered by the value of the `ui.formatted'
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1075
        configuration variable or - if it is unset - when `sys.stdout' points
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1076
        to a terminal device. Please note that `ui.formatted' should be
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1077
        considered an implementation detail; it is not intended for use outside
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1078
        Mercurial or its extensions.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1079
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1080
        This function refers to output only; for input, see `ui.interactive()'.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1081
        This function always returns false when in plain mode, see `ui.plain()'.
22a737306ba5 ui: document the formatted(), interactive() & plain() functions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11324
diff changeset
  1082
        '''
11324
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1083
        if self.plain():
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1084
            return False
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1085
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1086
        i = self.configbool("ui", "formatted", None)
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1087
        if i is None:
14515
76f295eaed86 util: add helper function isatty(fd) to check for tty-ness
Idan Kamara <idankk86@gmail.com>
parents: 14373
diff changeset
  1088
            # some environments replace stdout without implementing isatty
76f295eaed86 util: add helper function isatty(fd) to check for tty-ness
Idan Kamara <idankk86@gmail.com>
parents: 14373
diff changeset
  1089
            # usually those are non-interactive
16751
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
  1090
            return self._isatty(self.fout)
11324
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1091
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1092
        return i
cdf6d861b207 ui: add ui.formatted configuration variable and accessor function.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11311
diff changeset
  1093
5337
8c5ef3b87cb1 Don't try to determine interactivity if ui() called with interactive=False.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5154
diff changeset
  1094
    def _readline(self, prompt=''):
16751
2d432a1fc0db ui: add _isatty method to easily disable cooked I/O
Matt Mackall <mpm@selenic.com>
parents: 16703
diff changeset
  1095
        if self._isatty(self.fin):
5036
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1096
            try:
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1097
                # magically add command line editing support, where
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1098
                # available
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1099
                import readline
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1100
                # force demandimport to really load the module
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1101
                readline.read_history_file
7496
0a27d0db256d issue1419: catch strange readline import error on windows
Brendan Cully <brendan@kublai.com>
parents: 7320
diff changeset
  1102
                # windows sometimes raises something other than ImportError
0a27d0db256d issue1419: catch strange readline import error on windows
Brendan Cully <brendan@kublai.com>
parents: 7320
diff changeset
  1103
            except Exception:
5036
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1104
                pass
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14612
diff changeset
  1105
15000
68b5d7005cca ui: call write() so the prompt string goes through subclassed implementation
Idan Kamara <idankk86@gmail.com>
parents: 14738
diff changeset
  1106
        # call write() so output goes through subclassed implementation
68b5d7005cca ui: call write() so the prompt string goes through subclassed implementation
Idan Kamara <idankk86@gmail.com>
parents: 14738
diff changeset
  1107
        # e.g. color extension on Windows
28633
e35d7f131483 ui: add prompt argument to write (issue5154) (API)
timeless <timeless@mozdev.org>
parents: 28598
diff changeset
  1108
        self.write(prompt, prompt=True)
15000
68b5d7005cca ui: call write() so the prompt string goes through subclassed implementation
Idan Kamara <idankk86@gmail.com>
parents: 14738
diff changeset
  1109
15062
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1110
        # instead of trying to emulate raw_input, swap (self.fin,
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1111
        # self.fout) with (sys.stdin, sys.stdout)
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1112
        oldin = sys.stdin
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1113
        oldout = sys.stdout
15000
68b5d7005cca ui: call write() so the prompt string goes through subclassed implementation
Idan Kamara <idankk86@gmail.com>
parents: 14738
diff changeset
  1114
        sys.stdin = self.fin
15062
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1115
        sys.stdout = self.fout
22291
3b39e1522d8f ui: add brief comment why raw_input() needs dummy ' ' prompt string
Yuya Nishihara <yuya@tcha.org>
parents: 22205
diff changeset
  1116
        # prompt ' ' must exist; otherwise readline may delete entire line
3b39e1522d8f ui: add brief comment why raw_input() needs dummy ' ' prompt string
Yuya Nishihara <yuya@tcha.org>
parents: 22205
diff changeset
  1117
        # - http://bugs.python.org/issue12833
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1118
        with self.timeblockedsection('stdio'):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1119
            line = raw_input(' ')
15062
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1120
        sys.stdin = oldin
0fc95f5cea57 ui: also swap sys.stdout with self.fout in _readline
Martin Geisler <mg@aragost.com>
parents: 15053
diff changeset
  1121
        sys.stdout = oldout
14614
afccc64eea73 ui: use I/O descriptors internally
Idan Kamara <idankk86@gmail.com>
parents: 14612
diff changeset
  1122
5613
2e76e5a23c2b workaround for raw_input() on Windows
Steve Borho <steve@borho.org>
parents: 5337
diff changeset
  1123
        # When stdin is in binary mode on Windows, it can cause
2e76e5a23c2b workaround for raw_input() on Windows
Steve Borho <steve@borho.org>
parents: 5337
diff changeset
  1124
        # raw_input() to emit an extra trailing carriage return
2e76e5a23c2b workaround for raw_input() on Windows
Steve Borho <steve@borho.org>
parents: 5337
diff changeset
  1125
        if os.linesep == '\r\n' and line and line[-1] == '\r':
2e76e5a23c2b workaround for raw_input() on Windows
Steve Borho <steve@borho.org>
parents: 5337
diff changeset
  1126
            line = line[:-1]
2e76e5a23c2b workaround for raw_input() on Windows
Steve Borho <steve@borho.org>
parents: 5337
diff changeset
  1127
        return line
5036
ca0d02222d6a ui: get readline and prompt to behave better depending on interactivity
Bryan O'Sullivan <bos@serpentine.com>
parents: 4729
diff changeset
  1128
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1129
    def prompt(self, msg, default="y"):
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1130
        """Prompt user with msg, read response.
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1131
        If ui is not interactive, the default is returned.
5751
bc475d1f74ca prompt: kill matchflags
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5709
diff changeset
  1132
        """
8208
32a2a1e244f1 ui: make interactive a method
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
  1133
        if not self.interactive():
28039
89003c49315c ui: fix crash by non-interactive prompt echo for user name
Yuya Nishihara <yuya@tcha.org>
parents: 27696
diff changeset
  1134
            self.write(msg, ' ', default or '', "\n")
7320
8dca507e56ce ui: log non-interactive default response to stdout when verbose
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 6862
diff changeset
  1135
            return default
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1136
        try:
15053
17ffb30d9174 ui: pass ' ' to raw_input when prompting
Idan Kamara <idankk86@gmail.com>
parents: 15000
diff changeset
  1137
            r = self._readline(self.label(msg, 'ui.prompt'))
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1138
            if not r:
22589
9ab18a912c44 ui: show prompt choice if input is not a tty but is forced to be interactive
Mads Kiilerich <madski@unity3d.com>
parents: 22419
diff changeset
  1139
                r = default
23053
5ba11ab48fcf ui: separate option to show prompt echo, enabled only in tests (issue4417)
Yuya Nishihara <yuya@tcha.org>
parents: 22837
diff changeset
  1140
            if self.configbool('ui', 'promptecho'):
22589
9ab18a912c44 ui: show prompt choice if input is not a tty but is forced to be interactive
Mads Kiilerich <madski@unity3d.com>
parents: 22419
diff changeset
  1141
                self.write(r, "\n")
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1142
            return r
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1143
        except EOFError:
26896
5e46123e6c35 error: add structured exception for EOF at prompt
Siddharth Agarwal <sid0@fb.com>
parents: 26820
diff changeset
  1144
            raise error.ResponseExpected()
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1145
20265
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1146
    @staticmethod
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1147
    def extractchoices(prompt):
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1148
        """Extract prompt message and list of choices from specified prompt.
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1149
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1150
        This returns tuple "(message, choices)", and "choices" is the
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1151
        list of tuple "(response character, text without &)".
27392
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1152
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1153
        >>> ui.extractchoices("awake? $$ &Yes $$ &No")
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1154
        ('awake? ', [('y', 'Yes'), ('n', 'No')])
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1155
        >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1156
        ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1157
        >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1158
        ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
20265
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1159
        """
27392
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1160
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1161
        # Sadly, the prompt string may have been built with a filename
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1162
        # containing "$$" so let's try to find the first valid-looking
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1163
        # prompt to start parsing. Sadly, we also can't rely on
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1164
        # choices containing spaces, ASCII, or basically anything
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1165
        # except an ampersand followed by a character.
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1166
        m = re.match(r'(?s)(.+?)\$\$([^\$]*&[^ \$].*)', prompt)
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1167
        msg = m.group(1)
00aa37c65e0a ui: try to handle $$ more robustly in prompts (issue4970)
Matt Mackall <mpm@selenic.com>
parents: 26820
diff changeset
  1168
        choices = [p.strip(' ') for p in m.group(2).split('$$')]
20265
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1169
        return (msg,
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1170
                [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1171
                 for s in choices])
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1172
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1173
    def promptchoice(self, prompt, default=0):
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1174
        """Prompt user with a message, read response, and ensure it matches
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1175
        one of the provided choices. The prompt is formatted as follows:
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1176
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1177
           "would you like fries with that (Yn)? $$ &Yes $$ &No"
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1178
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1179
        The index of the choice is returned. Responses are case
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1180
        insensitive. If ui is not interactive, the default is
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1181
        returned.
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1182
        """
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19195
diff changeset
  1183
20265
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1184
        msg, choices = self.extractchoices(prompt)
e5803150ea1d ui: add "extractchoices()" to share the logic to extract choices from prompt
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19886
diff changeset
  1185
        resps = [r for r, t in choices]
5671
b5605d88dc27 Make ui.prompt repeat on "unrecognized response" again (issue897)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5337
diff changeset
  1186
        while True:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1187
            r = self.prompt(msg, resps[default])
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1188
            if r.lower() in resps:
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1189
                return resps.index(r.lower())
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1190
            self.write(_("unrecognized response\n"))
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8940
diff changeset
  1191
2281
7761597b5da3 prompt user for http authentication info
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2206
diff changeset
  1192
    def getpass(self, prompt=None, default=None):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1193
        if not self.interactive():
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1194
            return default
7798
57fee79e5588 catch CTRL-D at password prompt
Steve Borho <steve@borho.org>
parents: 7600
diff changeset
  1195
        try:
19880
ba2be32d14f2 ui: send password prompts to stderr again (issue4056)
Matt Mackall <mpm@selenic.com>
parents: 19226
diff changeset
  1196
            self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
21195
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 21132
diff changeset
  1197
            # disable getpass() only if explicitly specified. it's still valid
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 21132
diff changeset
  1198
            # to interact with tty even if fin is not a tty.
30978
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1199
            with self.timeblockedsection('stdio'):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1200
                if self.configbool('ui', 'nontty'):
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1201
                    l = self.fin.readline()
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1202
                    if not l:
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1203
                        raise EOFError
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1204
                    return l.rstrip('\n')
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1205
                else:
fdecd24ca4dc ui: log time spent blocked on stdio
Simon Farnsworth <simonfar@fb.com>
parents: 30976
diff changeset
  1206
                    return getpass.getpass('')
7798
57fee79e5588 catch CTRL-D at password prompt
Steve Borho <steve@borho.org>
parents: 7600
diff changeset
  1207
        except EOFError:
26896
5e46123e6c35 error: add structured exception for EOF at prompt
Siddharth Agarwal <sid0@fb.com>
parents: 26820
diff changeset
  1208
            raise error.ResponseExpected()
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1209
    def status(self, *msg, **opts):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1210
        '''write status message to output (if ui.quiet is False)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1211
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1212
        This adds an output label of "ui.status".
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1213
        '''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1214
        if not self.quiet:
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1215
            opts['label'] = opts.get('label', '') + ' ui.status'
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1216
            self.write(*msg, **opts)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1217
    def warn(self, *msg, **opts):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1218
        '''write warning message to output (stderr)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1219
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1220
        This adds an output label of "ui.warning".
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1221
        '''
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1222
        opts['label'] = opts.get('label', '') + ' ui.warning'
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1223
        self.write_err(*msg, **opts)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1224
    def note(self, *msg, **opts):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1225
        '''write note to output (if ui.verbose is True)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1226
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1227
        This adds an output label of "ui.note".
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1228
        '''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1229
        if self.verbose:
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1230
            opts['label'] = opts.get('label', '') + ' ui.note'
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1231
            self.write(*msg, **opts)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1232
    def debug(self, *msg, **opts):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1233
        '''write debug message to output (if ui.debugflag is True)
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1234
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1235
        This adds an output label of "ui.debug".
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1236
        '''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1237
        if self.debugflag:
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1238
            opts['label'] = opts.get('label', '') + ' ui.debug'
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1239
            self.write(*msg, **opts)
26750
9f9ec4abe700 cmdutil: make in-memory changes visible to external editor (issue4378)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26587
diff changeset
  1240
30835
bcad61a1f9a7 ui: add a parameter to set the temporary directory for edit
Sean Farley <sean@farley.io>
parents: 30832
diff changeset
  1241
    def edit(self, text, user, extra=None, editform=None, pending=None,
30848
7080652af6e6 ui: rename tmpdir parameter to more specific repopath
Sean Farley <sean@farley.io>
parents: 30835
diff changeset
  1242
             repopath=None):
28635
87f92d6f0bc3 edit: allow to configure the suffix of the temporary filename
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 28633
diff changeset
  1243
        extra_defaults = {
87f92d6f0bc3 edit: allow to configure the suffix of the temporary filename
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 28633
diff changeset
  1244
            'prefix': 'editor',
87f92d6f0bc3 edit: allow to configure the suffix of the temporary filename
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 28633
diff changeset
  1245
            'suffix': '.txt',
87f92d6f0bc3 edit: allow to configure the suffix of the temporary filename
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 28633
diff changeset
  1246
        }
27153
3553e40d0770 ui: allow open editor with custom filename
Mykola Nikishov <mn@mn.com.ua>
parents: 27110
diff changeset
  1247
        if extra is not None:
3553e40d0770 ui: allow open editor with custom filename
Mykola Nikishov <mn@mn.com.ua>
parents: 27110
diff changeset
  1248
            extra_defaults.update(extra)
3553e40d0770 ui: allow open editor with custom filename
Mykola Nikishov <mn@mn.com.ua>
parents: 27110
diff changeset
  1249
        extra = extra_defaults
30835
bcad61a1f9a7 ui: add a parameter to set the temporary directory for edit
Sean Farley <sean@farley.io>
parents: 30832
diff changeset
  1250
30848
7080652af6e6 ui: rename tmpdir parameter to more specific repopath
Sean Farley <sean@farley.io>
parents: 30835
diff changeset
  1251
        rdir = None
30835
bcad61a1f9a7 ui: add a parameter to set the temporary directory for edit
Sean Farley <sean@farley.io>
parents: 30832
diff changeset
  1252
        if self.configbool('experimental', 'editortmpinhg'):
30848
7080652af6e6 ui: rename tmpdir parameter to more specific repopath
Sean Farley <sean@farley.io>
parents: 30835
diff changeset
  1253
            rdir = repopath
27153
3553e40d0770 ui: allow open editor with custom filename
Mykola Nikishov <mn@mn.com.ua>
parents: 27110
diff changeset
  1254
        (fd, name) = tempfile.mkstemp(prefix='hg-' + extra['prefix'] + '-',
30835
bcad61a1f9a7 ui: add a parameter to set the temporary directory for edit
Sean Farley <sean@farley.io>
parents: 30832
diff changeset
  1255
                                      suffix=extra['suffix'], text=True,
30848
7080652af6e6 ui: rename tmpdir parameter to more specific repopath
Sean Farley <sean@farley.io>
parents: 30835
diff changeset
  1256
                                      dir=rdir)
1984
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1257
        try:
30925
82f1ef8b4477 py3: convert the mode argument of os.fdopen to unicodes (2 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30848
diff changeset
  1258
            f = os.fdopen(fd, pycompat.sysstr("w"))
1984
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1259
            f.write(text)
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1260
            f.close()
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1261
20605
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1262
            environ = {'HGUSER': user}
20606
be140ebd506b ui: edit(): transplant: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20605
diff changeset
  1263
            if 'transplant_source' in extra:
be140ebd506b ui: edit(): transplant: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20605
diff changeset
  1264
                environ.update({'HGREVISION': hex(extra['transplant_source'])})
24687
28d76bc069db editor: prefer 'intermediate-source' extra to use for HGREVISION environment variable
Alexander Drozdov <al.drozdov@gmail.com>
parents: 24663
diff changeset
  1265
            for label in ('intermediate-source', 'source', 'rebase_source'):
20605
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1266
                if label in extra:
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1267
                    environ.update({'HGREVISION': extra[label]})
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1268
                    break
22205
9fa429723f26 ui: invoke editor for committing with HGEDITFORM environment variable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21955
diff changeset
  1269
            if editform:
9fa429723f26 ui: invoke editor for committing with HGEDITFORM environment variable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21955
diff changeset
  1270
                environ.update({'HGEDITFORM': editform})
26750
9f9ec4abe700 cmdutil: make in-memory changes visible to external editor (issue4378)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26587
diff changeset
  1271
            if pending:
9f9ec4abe700 cmdutil: make in-memory changes visible to external editor (issue4378)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26587
diff changeset
  1272
                environ.update({'HG_PENDING': pending})
20605
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1273
5660
3c80ecdc1bcd Use VISUAL in addition to EDITOR when choosing the editor to use.
Osku Salerma <osku@iki.fi>
parents: 5613
diff changeset
  1274
            editor = self.geteditor()
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
  1275
23269
d9d8d2e0f701 ui: introduce util.system() wrapper to make sure ui.fout is used
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
  1276
            self.system("%s \"%s\"" % (editor, name),
20605
a8aa699a812a ui: edit(): rebase, graft: set HGREVISION environment variable for an editor
Alexander Drozdov <al.drozdov@gmail.com>
parents: 20603
diff changeset
  1277
                        environ=environ,
30980
60b5db2ab586 ui: give editor() a tag of its own
Simon Farnsworth <simonfar@fb.com>
parents: 30979
diff changeset
  1278
                        onerr=error.Abort, errprefix=_("edit failed"),
60b5db2ab586 ui: give editor() a tag of its own
Simon Farnsworth <simonfar@fb.com>
parents: 30979
diff changeset
  1279
                        blockedtag='editor')
608
d2994b5298fb Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents: 565
diff changeset
  1280
1984
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1281
            f = open(name)
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1282
            t = f.read()
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1283
            f.close()
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1284
        finally:
df7436f439a0 Improved ui.edit():
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1983
diff changeset
  1285
            os.unlink(name)
662
b55a78595ef6 Pass username to hgeditor, remove temporary file
Radoslaw "AstralStorm" Szkodzinski <astralstorm@gorzow.mm.pl>
parents: 613
diff changeset
  1286
207
ec327cf0d3a9 Move ui class to its own module
mpm@selenic.com
parents:
diff changeset
  1287
        return t
2200
9f43b6e24232 move mail sending code into core, so extensions can share it.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2166
diff changeset
  1288
30979
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
  1289
    def system(self, cmd, environ=None, cwd=None, onerr=None, errprefix=None,
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
  1290
               blockedtag=None):
23269
d9d8d2e0f701 ui: introduce util.system() wrapper to make sure ui.fout is used
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
  1291
        '''execute shell command with appropriate output stream. command
d9d8d2e0f701 ui: introduce util.system() wrapper to make sure ui.fout is used
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
  1292
        output will be redirected if fout is not stdout.
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1293
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1294
        if command fails and onerr is None, return status, else raise onerr
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1295
        object as exception.
23269
d9d8d2e0f701 ui: introduce util.system() wrapper to make sure ui.fout is used
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
  1296
        '''
30979
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
  1297
        if blockedtag is None:
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
  1298
            blockedtag = 'unknown_system_' + cmd.translate(None, _keepalnum)
24848
2f88821856eb ui: allow capture of subprocess output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24687
diff changeset
  1299
        out = self.fout
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25125
diff changeset
  1300
        if any(s[1] for s in self._bufferstates):
24848
2f88821856eb ui: allow capture of subprocess output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24687
diff changeset
  1301
            out = self
30979
fd598149112b ui: time calls to ui.system
Simon Farnsworth <simonfar@fb.com>
parents: 30978
diff changeset
  1302
        with self.timeblockedsection(blockedtag):
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1303
            rc = self._runsystem(cmd, environ=environ, cwd=cwd, out=out)
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1304
        if rc and onerr:
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1305
            errmsg = '%s %s' % (os.path.basename(cmd.split(None, 1)[0]),
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1306
                                util.explainexit(rc)[0])
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1307
            if errprefix:
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1308
                errmsg = '%s: %s' % (errprefix, errmsg)
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1309
            raise onerr(errmsg)
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1310
        return rc
31107
fbce78c58f1e chg: refactor ui.system() to be partly overridden
Yuya Nishihara <yuya@tcha.org>
parents: 31106
diff changeset
  1311
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1312
    def _runsystem(self, cmd, environ, cwd, out):
31107
fbce78c58f1e chg: refactor ui.system() to be partly overridden
Yuya Nishihara <yuya@tcha.org>
parents: 31106
diff changeset
  1313
        """actually execute the given shell command (can be overridden by
fbce78c58f1e chg: refactor ui.system() to be partly overridden
Yuya Nishihara <yuya@tcha.org>
parents: 31106
diff changeset
  1314
        extensions like chg)"""
31108
3f8f53190d6a chg: deduplicate error handling of ui.system()
Yuya Nishihara <yuya@tcha.org>
parents: 31107
diff changeset
  1315
        return util.system(cmd, environ=environ, cwd=cwd, out=out)
23269
d9d8d2e0f701 ui: introduce util.system() wrapper to make sure ui.fout is used
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
  1316
18966
5572f688e0a9 ui: add 'force' parameter to traceback() to override the current print setting
Matt Harbison <matt_harbison@yahoo.com>
parents: 18965
diff changeset
  1317
    def traceback(self, exc=None, force=False):
5572f688e0a9 ui: add 'force' parameter to traceback() to override the current print setting
Matt Harbison <matt_harbison@yahoo.com>
parents: 18965
diff changeset
  1318
        '''print exception traceback if traceback printing enabled or forced.
2335
f0680b2d1d64 add ui.print_exc(), make all traceback printing central.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2293
diff changeset
  1319
        only to call in exception handler. returns true if traceback
f0680b2d1d64 add ui.print_exc(), make all traceback printing central.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2293
diff changeset
  1320
        printed.'''
18966
5572f688e0a9 ui: add 'force' parameter to traceback() to override the current print setting
Matt Harbison <matt_harbison@yahoo.com>
parents: 18965
diff changeset
  1321
        if self.tracebackflag or force:
18965
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1322
            if exc is None:
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1323
                exc = sys.exc_info()
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1324
            cause = getattr(exc[1], 'cause', None)
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1325
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1326
            if cause is not None:
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1327
                causetb = traceback.format_tb(cause[2])
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1328
                exctb = traceback.format_tb(exc[2])
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1329
                exconly = traceback.format_exception_only(cause[0], cause[1])
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1330
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1331
                # exclude frame where 'exc' was chained and rethrown from exctb
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1332
                self.write_err('Traceback (most recent call last):\n',
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1333
                               ''.join(exctb[:-1]),
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1334
                               ''.join(causetb),
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1335
                               ''.join(exconly))
0062508b1900 ui: add support for fully printing chained exception stacks in ui.traceback()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18669
diff changeset
  1336
            else:
25568
c1ff82daed62 ui: flush stderr after printing a non-chained exception for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 25519
diff changeset
  1337
                output = traceback.format_exception(exc[0], exc[1], exc[2])
c1ff82daed62 ui: flush stderr after printing a non-chained exception for Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 25519
diff changeset
  1338
                self.write_err(''.join(output))
18966
5572f688e0a9 ui: add 'force' parameter to traceback() to override the current print setting
Matt Harbison <matt_harbison@yahoo.com>
parents: 18965
diff changeset
  1339
        return self.tracebackflag or force
5660
3c80ecdc1bcd Use VISUAL in addition to EDITOR when choosing the editor to use.
Osku Salerma <osku@iki.fi>
parents: 5613
diff changeset
  1340
3c80ecdc1bcd Use VISUAL in addition to EDITOR when choosing the editor to use.
Osku Salerma <osku@iki.fi>
parents: 5613
diff changeset
  1341
    def geteditor(self):
3c80ecdc1bcd Use VISUAL in addition to EDITOR when choosing the editor to use.
Osku Salerma <osku@iki.fi>
parents: 5613
diff changeset
  1342
        '''return editor to use'''
30641
16b5df5792a8 py3: replace sys.platform with pycompat.sysplatform (part 1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30637
diff changeset
  1343
        if pycompat.sysplatform == 'plan9':
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1344
            # vi is the MIPS instruction simulator on Plan 9. We
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1345
            # instead default to E to plumb commit messages to
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1346
            # avoid confusion.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1347
            editor = 'E'
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1348
        else:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16373
diff changeset
  1349
            editor = 'vi'
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
  1350
        return (encoding.environ.get("HGEDITOR") or
5660
3c80ecdc1bcd Use VISUAL in addition to EDITOR when choosing the editor to use.
Osku Salerma <osku@iki.fi>
parents: 5613
diff changeset
  1351
                self.config("ui", "editor") or
30277
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
  1352
                encoding.environ.get("VISUAL") or
e9fca89c6d58 py3: use encoding.environ in ui.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29978
diff changeset
  1353
                encoding.environ.get("EDITOR", editor))
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1354
25499
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1355
    @util.propertycache
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1356
    def _progbar(self):
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1357
        """setup the progbar singleton to the ui object"""
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1358
        if (self.quiet or self.debugflag
25519
09e2cb2a00d7 progress: display progress bars by default with core Mercurial
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25499
diff changeset
  1359
                or self.configbool('progress', 'disable', False)
25499
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1360
                or not progress.shouldprint(self)):
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1361
            return None
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1362
        return getprogbar(self)
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1363
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1364
    def _progclear(self):
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1365
        """clear progress bar output if any. use it before any output"""
26781
1aee2ab0f902 spelling: trivial spell checking
Mads Kiilerich <madski@unity3d.com>
parents: 26750
diff changeset
  1366
        if '_progbar' not in vars(self): # nothing loaded yet
25499
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1367
            return
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1368
        if self._progbar is not None and self._progbar.printed:
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1369
            self._progbar.clear()
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1370
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1371
    def progress(self, topic, pos, item="", unit="", total=None):
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1372
        '''show a progress message
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1373
28598
c30d5ca4945b progress: update comment to reflect implementation
timeless <timeless@mozdev.org>
parents: 28542
diff changeset
  1374
        By default a textual progress bar will be displayed if an operation
c30d5ca4945b progress: update comment to reflect implementation
timeless <timeless@mozdev.org>
parents: 28542
diff changeset
  1375
        takes too long. 'topic' is the current operation, 'item' is a
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17059
diff changeset
  1376
        non-numeric marker of the current position (i.e. the currently
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17059
diff changeset
  1377
        in-process file), 'pos' is the current numeric position (i.e.
9398
3fb8c6dbeeec ui: fix NameError in ui.progress due to unit/units typo
Brodie Rao <me+hg@dackz.net>
parents: 9312
diff changeset
  1378
        revision, bytes, etc.), unit is a corresponding unit label,
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1379
        and total is the highest expected pos.
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1380
10425
f8a9de664a1c ui.progress: clarify termination requirement
Augie Fackler <durin42@gmail.com>
parents: 10383
diff changeset
  1381
        Multiple nested topics may be active at a time.
f8a9de664a1c ui.progress: clarify termination requirement
Augie Fackler <durin42@gmail.com>
parents: 10383
diff changeset
  1382
f8a9de664a1c ui.progress: clarify termination requirement
Augie Fackler <durin42@gmail.com>
parents: 10383
diff changeset
  1383
        All topics should be marked closed by setting pos to None at
f8a9de664a1c ui.progress: clarify termination requirement
Augie Fackler <durin42@gmail.com>
parents: 10383
diff changeset
  1384
        termination.
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1385
        '''
25499
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1386
        if self._progbar is not None:
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1387
            self._progbar.progress(topic, pos, item=item, unit=unit,
0fa964d6fd48 progress: move all logic altering the ui object logic in mercurial.ui
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25498
diff changeset
  1388
                                   total=total)
25125
bd625cd4e5e7 progress: get the extremely verbose output out of default debug
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24883
diff changeset
  1389
        if pos is None or not self.configbool('progress', 'debug'):
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1390
            return
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1391
9398
3fb8c6dbeeec ui: fix NameError in ui.progress due to unit/units typo
Brodie Rao <me+hg@dackz.net>
parents: 9312
diff changeset
  1392
        if unit:
3fb8c6dbeeec ui: fix NameError in ui.progress due to unit/units typo
Brodie Rao <me+hg@dackz.net>
parents: 9312
diff changeset
  1393
            unit = ' ' + unit
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1394
        if item:
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1395
            item = ' ' + item
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1396
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1397
        if total:
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1398
            pct = 100.0 * pos / total
10220
500d09be7ace ui: display progress with decimal notation
Patrick Mezard <pmezard@gmail.com>
parents: 9851
diff changeset
  1399
            self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
9398
3fb8c6dbeeec ui: fix NameError in ui.progress due to unit/units typo
Brodie Rao <me+hg@dackz.net>
parents: 9312
diff changeset
  1400
                     % (topic, item, pos, total, unit, pct))
9153
6adc899c98d0 Add ui.progress API
Matt Mackall <mpm@selenic.com>
parents: 9048
diff changeset
  1401
        else:
9749
1b1b33ae5a24 Related to Issue919: ui.progress, apparently unused before now, is busted.
Jesse Glick <jesse.glick@sun.com>
parents: 9613
diff changeset
  1402
            self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1403
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents: 18054
diff changeset
  1404
    def log(self, service, *msg, **opts):
11984
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1405
        '''hook for logging facility extensions
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1406
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1407
        service should be a readily-identifiable subsystem, which will
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1408
        allow filtering.
26235
6c962145f523 ui: improve docs on ui.log
Augie Fackler <augie@google.com>
parents: 26189
diff changeset
  1409
6c962145f523 ui: improve docs on ui.log
Augie Fackler <augie@google.com>
parents: 26189
diff changeset
  1410
        *msg should be a newline-terminated format string to log, and
6c962145f523 ui: improve docs on ui.log
Augie Fackler <augie@google.com>
parents: 26189
diff changeset
  1411
        then any values to %-format into that format string.
6c962145f523 ui: improve docs on ui.log
Augie Fackler <augie@google.com>
parents: 26189
diff changeset
  1412
6c962145f523 ui: improve docs on ui.log
Augie Fackler <augie@google.com>
parents: 26189
diff changeset
  1413
        **opts currently has no defined meanings.
11984
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1414
        '''
2db0fccc8143 ui: add logging hook
Matt Mackall <mpm@selenic.com>
parents: 11970
diff changeset
  1415
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1416
    def label(self, msg, label):
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1417
        '''style msg based on supplied label
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1418
31087
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
  1419
        If some color mode is enabled, this will add the necessary control
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
  1420
        characters to apply such color. In addition, 'debug' color mode adds
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
  1421
        markup showing which label affects a piece of text.
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1422
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1423
        ui.write(s, 'label') is equivalent to
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1424
        ui.write(ui.label(s, 'label')).
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1425
        '''
31087
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
  1426
        if self._colormode is not None:
894bdcdc75df color: move the 'colorlabel' call to the core 'ui' class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31083
diff changeset
  1427
            return color.colorlabel(self, msg, label)
10815
32b213b9b22c ui: add ui.write() output labeling API
Brodie Rao <brodie@bitheap.org>
parents: 10567
diff changeset
  1428
        return msg
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1429
29095
3f33831a9202 develwarn: move config gating inside the develwarn function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29082
diff changeset
  1430
    def develwarn(self, msg, stacklevel=1, config=None):
27274
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1431
        """issue a developer warning message
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1432
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1433
        Use 'stacklevel' to report the offender some layers further up in the
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1434
        stack.
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1435
        """
29095
3f33831a9202 develwarn: move config gating inside the develwarn function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29082
diff changeset
  1436
        if not self.configbool('devel', 'all-warnings'):
3f33831a9202 develwarn: move config gating inside the develwarn function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29082
diff changeset
  1437
            if config is not None and not self.configbool('devel', config):
3f33831a9202 develwarn: move config gating inside the develwarn function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29082
diff changeset
  1438
                return
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1439
        msg = 'devel-warn: ' + msg
27274
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1440
        stacklevel += 1 # get in develwarn
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1441
        if self.tracebackflag:
27274
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1442
            util.debugstacktrace(msg, stacklevel, self.ferr, self.fout)
28498
d09be0b8a3c6 ui: log devel warnings
timeless <timeless@mozdev.org>
parents: 28218
diff changeset
  1443
            self.log('develwarn', '%s at:\n%s' %
d09be0b8a3c6 ui: log devel warnings
timeless <timeless@mozdev.org>
parents: 28218
diff changeset
  1444
                     (msg, ''.join(util.getstackframes(stacklevel))))
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1445
        else:
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1446
            curframe = inspect.currentframe()
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1447
            calframe = inspect.getouterframes(curframe, 2)
27274
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1448
            self.write_err('%s at: %s:%s (%s)\n'
82910fdc216f ui: add a 'stacklevel' argument to 'develwarn'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27266
diff changeset
  1449
                           % ((msg,) + calframe[stacklevel][1:4]))
28498
d09be0b8a3c6 ui: log devel warnings
timeless <timeless@mozdev.org>
parents: 28218
diff changeset
  1450
            self.log('develwarn', '%s at: %s:%s (%s)\n',
d09be0b8a3c6 ui: log devel warnings
timeless <timeless@mozdev.org>
parents: 28218
diff changeset
  1451
                     msg, *calframe[stacklevel][1:4])
29762
96bd27eb23f0 ui: drop values returned by inspect.*frame*() to avoid cycles
Jun Wu <quark@fb.com>
parents: 29413
diff changeset
  1452
            curframe = calframe = None  # avoid cycles
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1453
27275
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1454
    def deprecwarn(self, msg, version):
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1455
        """issue a deprecation warning
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1456
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1457
        - msg: message explaining what is deprecated and how to upgrade,
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1458
        - version: last version where the API will be supported,
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1459
        """
29082
77de985d7c91 deprecation: gate deprecation warning behind devel configuration
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28962
diff changeset
  1460
        if not (self.configbool('devel', 'all-warnings')
77de985d7c91 deprecation: gate deprecation warning behind devel configuration
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28962
diff changeset
  1461
                or self.configbool('devel', 'deprec-warn')):
77de985d7c91 deprecation: gate deprecation warning behind devel configuration
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 28962
diff changeset
  1462
            return
27275
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1463
        msg += ("\n(compatibility will be dropped after Mercurial-%s,"
f2cd240f2f7c ui: add a 'deprecwarn' helper to issue deprecation warnings
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 27274
diff changeset
  1464
                " update your code.)") % version
29096
33a10e212b80 devel: use the new 'config' argument of the develwarn in deprecwarn
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29095
diff changeset
  1465
        self.develwarn(msg, stacklevel=2, config='deprec-warn')
25629
52e5f68d8363 devel-warn: move the develwarn function as a method of the ui object
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25568
diff changeset
  1466
30832
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1467
    def exportableenviron(self):
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1468
        """The environment variables that are safe to export, e.g. through
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1469
        hgweb.
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1470
        """
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1471
        return self._exportableenviron
da5fa0f13a41 ui: introduce an experimental dict of exportable environment variables
Matt Harbison <matt_harbison@yahoo.com>
parents: 30814
diff changeset
  1472
30480
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1473
    @contextlib.contextmanager
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1474
    def configoverride(self, overrides, source=""):
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1475
        """Context manager for temporary config overrides
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1476
        `overrides` must be a dict of the following structure:
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1477
        {(section, name) : value}"""
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1478
        backups = {}
30537
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1479
        try:
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1480
            for (section, name), value in overrides.items():
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1481
                backups[(section, name)] = self.backupconfig(section, name)
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1482
                self.setconfig(section, name, value, source)
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1483
            yield
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1484
        finally:
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1485
            for __, backup in backups.items():
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1486
                self.restoreconfig(backup)
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1487
            # just restoring ui.quiet config to the previous value is not enough
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1488
            # as it does not update ui.quiet class member
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1489
            if ('ui', 'quiet') in overrides:
4b0e6677eed1 ui: use try..finally in configoverride
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30519
diff changeset
  1490
                self.fixconfig(section='ui')
30480
b0a8337ba9af ui: add configoverride context manager
Kostia Balytskyi <ikostia@fb.com>
parents: 30473
diff changeset
  1491
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1492
class paths(dict):
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1493
    """Represents a collection of paths and their configs.
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1494
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1495
    Data is initially derived from ui instances and the config files they have
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1496
    loaded.
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1497
    """
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1498
    def __init__(self, ui):
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1499
        dict.__init__(self)
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1500
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1501
        for name, loc in ui.configitems('paths', ignoresub=True):
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1502
            # No location is the same as not existing.
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1503
            if not loc:
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1504
                continue
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1505
            loc, sub = ui.configsuboptions('paths', name)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1506
            self[name] = path(ui, name, rawloc=loc, suboptions=sub)
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1507
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1508
    def getpath(self, name, default=None):
27561
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1509
        """Return a ``path`` from a string, falling back to default.
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1510
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1511
        ``name`` can be a named path or locations. Locations are filesystem
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1512
        paths or URIs.
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1513
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1514
        Returns None if ``name`` is not a registered path, a URI, or a local
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1515
        path to a repo.
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1516
        """
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1517
        # Only fall back to default if no path was requested.
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1518
        if name is None:
27561
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1519
            if not default:
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1520
                default = ()
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1521
            elif not isinstance(default, (tuple, list)):
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1522
                default = (default,)
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1523
            for k in default:
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1524
                try:
27561
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1525
                    return self[k]
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1526
                except KeyError:
27561
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1527
                    continue
723413ee000e paths: make getpath() accept multiple defaults
Yuya Nishihara <yuya@tcha.org>
parents: 27500
diff changeset
  1528
            return None
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1529
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1530
        # Most likely empty string.
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1531
        # This may need to raise in the future.
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1532
        if not name:
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1533
            return None
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1534
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1535
        try:
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1536
            return self[name]
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1537
        except KeyError:
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1538
            # Try to resolve as a local path or URI.
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1539
            try:
27265
47539ea08bdb ui: pass ui instance to path.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27264
diff changeset
  1540
                # We don't pass sub-options in, so no need to pass ui instance.
47539ea08bdb ui: pass ui instance to path.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27264
diff changeset
  1541
                return path(None, None, rawloc=name)
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1542
            except ValueError:
26189
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1543
                raise error.RepoError(_('repository %s does not exist') %
663fbc336e22 ui: change default path fallback mechanism (issue4796)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26076
diff changeset
  1544
                                        name)
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1545
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1546
_pathsuboptions = {}
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1547
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1548
def pathsuboption(option, attr):
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1549
    """Decorator used to declare a path sub-option.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1550
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1551
    Arguments are the sub-option name and the attribute it should set on
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1552
    ``path`` instances.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1553
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1554
    The decorated function will receive as arguments a ``ui`` instance,
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1555
    ``path`` instance, and the string value of this option from the config.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1556
    The function should return the value that will be set on the ``path``
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1557
    instance.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1558
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1559
    This decorator can be used to perform additional verification of
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1560
    sub-options and to change the type of sub-options.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1561
    """
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1562
    def register(func):
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1563
        _pathsuboptions[option] = (attr, func)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1564
        return func
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1565
    return register
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1566
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1567
@pathsuboption('pushurl', 'pushloc')
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1568
def pushurlpathoption(ui, path, value):
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1569
    u = util.url(value)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1570
    # Actually require a URL.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1571
    if not u.scheme:
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1572
        ui.warn(_('(paths.%s:pushurl not a URL; ignoring)\n') % path.name)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1573
        return None
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1574
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1575
    # Don't support the #foo syntax in the push URL to declare branch to
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1576
    # push.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1577
    if u.fragment:
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1578
        ui.warn(_('("#fragment" in paths.%s:pushurl not supported; '
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1579
                  'ignoring)\n') % path.name)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1580
        u.fragment = None
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1581
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1582
    return str(u)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1583
29413
31d3ab7985b8 ui: path option to declare which revisions to push by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29412
diff changeset
  1584
@pathsuboption('pushrev', 'pushrev')
31d3ab7985b8 ui: path option to declare which revisions to push by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29412
diff changeset
  1585
def pushrevpathoption(ui, path, value):
31d3ab7985b8 ui: path option to declare which revisions to push by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29412
diff changeset
  1586
    return value
31d3ab7985b8 ui: path option to declare which revisions to push by default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29412
diff changeset
  1587
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1588
class path(object):
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1589
    """Represents an individual path and its configuration."""
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1590
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1591
    def __init__(self, ui, name, rawloc=None, suboptions=None):
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1592
        """Construct a path from its config options.
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1593
27265
47539ea08bdb ui: pass ui instance to path.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27264
diff changeset
  1594
        ``ui`` is the ``ui`` instance the path is coming from.
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1595
        ``name`` is the symbolic name of the path.
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1596
        ``rawloc`` is the raw location, as defined in the config.
26064
1b1ab6ff58c4 ui: capture push location on path instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26056
diff changeset
  1597
        ``pushloc`` is the raw locations pushes should be made to.
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1598
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1599
        If ``name`` is not defined, we require that the location be a) a local
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1600
        filesystem path with a .hg directory or b) a URL. If not,
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1601
        ``ValueError`` is raised.
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1602
        """
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1603
        if not rawloc:
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1604
            raise ValueError('rawloc must be defined')
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1605
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1606
        # Locations may define branches via syntax <base>#<branch>.
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1607
        u = util.url(rawloc)
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1608
        branch = None
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1609
        if u.fragment:
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1610
            branch = u.fragment
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1611
            u.fragment = None
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1612
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1613
        self.url = u
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1614
        self.branch = branch
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1615
24250
9c32eea2ca04 ui: represent paths as classes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23269
diff changeset
  1616
        self.name = name
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1617
        self.rawloc = rawloc
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1618
        self.loc = str(u)
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1619
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1620
        # When given a raw location but not a symbolic name, validate the
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1621
        # location is valid.
26076
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1622
        if not name and not u.scheme and not self._isvalidlocalpath(self.loc):
26056
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1623
            raise ValueError('location is not a URL or path to a local '
5f2a4fc3c4fa ui: move URL and path detection into path API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25989
diff changeset
  1624
                             'repo: %s' % rawloc)
25498
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1625
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1626
        suboptions = suboptions or {}
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1627
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1628
        # Now process the sub-options. If a sub-option is registered, its
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1629
        # attribute will always be present. The value will be None if there
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1630
        # was no valid sub-option.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1631
        for suboption, (attr, func) in _pathsuboptions.iteritems():
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1632
            if suboption not in suboptions:
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1633
                setattr(self, attr, None)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1634
                continue
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1635
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1636
            value = func(ui, self, suboptions[suboption])
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1637
            setattr(self, attr, value)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1638
26076
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1639
    def _isvalidlocalpath(self, path):
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1640
        """Returns True if the given path is a potentially valid repository.
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1641
        This is its own function so that extensions can change the definition of
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1642
        'valid' in this case (like when pulling from a git repo into a hg
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1643
        one)."""
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1644
        return os.path.isdir(os.path.join(path, '.hg'))
cebf7e48365e paths: move path validation logic to its own function
Durham Goode <durham@fb.com>
parents: 26064
diff changeset
  1645
26064
1b1ab6ff58c4 ui: capture push location on path instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26056
diff changeset
  1646
    @property
27266
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1647
    def suboptions(self):
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1648
        """Return sub-options and their values for this path.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1649
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1650
        This is intended to be used for presentation purposes.
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1651
        """
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1652
        d = {}
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1653
        for subopt, (attr, _func) in _pathsuboptions.iteritems():
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1654
            value = getattr(self, attr)
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1655
            if value is not None:
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1656
                d[subopt] = value
4dccc37b87bd ui: support declaring path push urls as sub-options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27265
diff changeset
  1657
        return d
26064
1b1ab6ff58c4 ui: capture push location on path instances
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26056
diff changeset
  1658
25498
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1659
# we instantiate one globally shared progress bar to avoid
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1660
# competing progress bars when multiple UI objects get created
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1661
_progresssingleton = None
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1662
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1663
def getprogbar(ui):
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1664
    global _progresssingleton
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1665
    if _progresssingleton is None:
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1666
        # passing 'ui' object to the singleton is fishy,
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1667
        # this is how the extension used to work but feel free to rework it.
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1668
        _progresssingleton = progress.progbar(ui)
7a5335ed7e1a progress: move the singleton logic to the ui module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25363
diff changeset
  1669
    return _progresssingleton