Commit Graph

362 Commits

Author SHA1 Message Date
Pierre-Yves David
2fdfd87513 profile: drop maybeprofile
It seems sufficiently simple to use "profile(enabled=X)" to not justify having
a dedicated context manager just to read the config.

(I do not have a too strong opinion about this).
2017-06-09 12:29:29 +01:00
Pierre-Yves David
81c8d3b7b6 profile: support --profile in alias and abbreviated version (--prof)
We now process the "--profile" a second time after alias has been processed and
the command argument fully parsed. If appropriate we enable profiling at that
time.

In these situation, the --profile will cover less than if the full --profile
flag was passed on the command line. This is better than the previous behavior
(flag ignored) and still fullfil multiple valid usecases.
2017-06-09 12:36:07 +01:00
Yuya Nishihara
02355fbadc dispatch: do not close stdout and stderr, just flush() instead
Since 348863ccec7e "util: always force line buffered stdout when stdout is
a tty", we have two file objects attached to the same STDOUT_FILENO. If one
is closed, the underlying file descriptor is also closed, and writing to
the other file object would crash the Python interpreter in a hard way, at
least on Windows.

So, it seems safer to not close the standard streams. This also matches
the behavior of the default sys.stdout/stderr.close(), which never close
the FILE* streams in C layer.

https://hg.python.org/cpython/file/v2.7.13/Python/sysmodule.c#l1401
2017-04-23 00:31:29 +09:00
Augie Fackler
9a722d4382 merge with stable 2017-06-03 16:33:28 -04:00
FUJIWARA Katsunori
6e23c59850 dispatch: setup color before pager for correct console information on windows
Before this patch, "hg CMD --pager on" on Windows shows output
unintentionally decorated with ANSI color escape sequences, if color
mode is "auto". This issue occurs in steps below.

  1. dispatch() invokes ui.pager() at detection of "--pager on"
  2. stdout of hg process is redirected into stdin of pager process
  3. "ui.formatted" = True, because isatty(stdout) is so before (2)
  4. color module is loaded for colorization
  5. color.w32effects = None, because GetConsoleScreenBufferInfo()
     fails on stdout redirected at (2)
  6. "ansi" color mode is chosen, because of "not w32effects"
  7. output is colorized in "ansi" mode because of "ui.formatted" = True

Even if "ansi" color mode is chosen, ordinarily redirected stdout
makes ui.formatted() return False, and colorization is avoided. But in
this issue case, "ui.formatted" = True at (3) forces output to be
colorized.

For correct console information on win32, it is needed to ensure that
color module is loaded before redirection of stdout for pagination.

BTW, if any of enabled extensions has "colortable" attribute, this
issue is avoided even before this patch, because color module is
imported as a part of loading such extension, and extension loading
occurs before setting up pager. For example, mq and keyword have
"colortable".
2017-05-23 03:29:23 +09:00
Augie Fackler
3d0bf6c892 freeze: merge default into stable for 4.2 code freeze 2017-04-18 12:24:34 -04:00
Augie Fackler
b2bd435955 dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
Some shared-ssh installations assume that 'hg serve --stdio' is a safe
command to run for minimally trusted users. Unfortunately, the messy
implementation of argument parsing here meant that trying to access a
repo named '--debugger' would give the user a pdb prompt, thereby
sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S)
is unaffected.

We're not currently hardening any subcommands other than 'serve'. If
your service exposes other commands to users with arbitrary repository
names, it is imperative that you defend against repository names of
'--debugger' and anything starting with '--config'.

The read-only mode of hg-ssh stopped working because it provided its hook
configuration to "hg serve --stdio" via --config parameter. This is banned for
security reasons now. This patch switches it to directly call ui.setconfig().
If your custom hosting infrastructure relies on passing --config to
"hg serve --stdio", you'll need to find a different way to get that configuration
into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch,
or by placing an hgrc file someplace where Mercurial will read it.

mitrandir@fb.com provided some extra fixes for the dispatch code and
for hg-ssh in places that I overlooked.
2017-04-12 11:23:55 -07:00
Yuya Nishihara
649f9bf987 dispatch: ignore further SIGPIPE while handling KeyboardInterrupt
I got the following error by running "hg log" and quitting the pager
immediately. Any output here may trigger another SIGPIPE, so only thing
we can do is to swallow the exception and exit with an error status.

  Traceback (most recent call last):
    File "./hg", line 45, in <module>
      mercurial.dispatch.run()
    File "mercurial/dispatch.py", line 83, in run
      status = (dispatch(req) or 0) & 255
    File "mercurial/dispatch.py", line 167, in dispatch
      req.ui.warn(_("interrupted!\n"))
    File "mercurial/ui.py", line 1224, in warn
      self.write_err(*msg, **opts)
    File "mercurial/ui.py", line 790, in write_err
      self._write_err(*msgs, **opts)
    File "mercurial/ui.py", line 798, in _write_err
      self.ferr.write(a)
    File "mercurial/ui.py", line 129, in _catchterm
      raise error.SignalInterrupt
  mercurial.error.SignalInterrupt

Perhaps this wasn't visible before ee4f321cd621 because the original stderr
handle was restored very late.
2017-04-17 23:53:19 +09:00
Yuya Nishihara
aabbe05fb5 dispatch: print traceback in scmutil.callcatch() if --traceback specified
Otherwise, traceback wouldn't be printed for a known exception occurred in
worker processes.
2017-04-15 13:02:34 +09:00
Yuya Nishihara
1ea92e7f19 dispatch: mark callcatch() as a private function 2017-04-15 12:58:06 +09:00
Bryan O'Sullivan
ebffdb4558 stdio: catch StdioError in dispatch.run and clean up appropriately
We attempt to report what went wrong, and more importantly exit the
program with an error code.

(The exception we catch is not yet raised anywhere in the code.)
2017-04-11 14:54:12 -07:00
Bryan O'Sullivan
287bd28acf atexit: switch to home-grown implementation 2017-04-11 14:54:12 -07:00
Bryan O'Sullivan
0c663fe04d ui: add special-purpose atexit functionality
In spite of its longstanding use, Python's built-in atexit code is
not suitable for Mercurial's purposes, for several reasons:

* Handlers run after application code has finished.

* Because of this, the code that runs handlers swallows exceptions
  (since there's no possible stacktrace to associate errors with).
  If we're lucky, we'll get something spat out to stderr (if stderr
  still works), which of course isn't any use in a big deployment
  where it's important that exceptions get logged and aggregated.

* Mercurial's current atexit handlers make unfortunate assumptions
  about process state (specifically stdio) that, coupled with the
  above problems, make it impossible to deal with certain categories
  of error (try "hg status > /dev/full" on a Linux box).

* In Python 3, the atexit implementation is completely hidden, so
  we can't hijack the platform's atexit code to run handlers at a
  time of our choosing.

As a result, here's a perfectly cromulent atexit-like implementation
over which we have control.  This lets us decide exactly when the
handlers run (after each request has completed), and control what
the process state is when that occurs (and afterwards).
2017-04-11 14:54:12 -07:00
Augie Fackler
11355eb015 dispatch: convert exception payload to bytes more carefully
We were previously depending on str() doing something reasonable here,
and we can't depend on the objects in question supporting __bytes__,
so we work around the lack of direct bytes formatting.
2017-05-28 15:47:00 -04:00
Pulkit Goyal
dbc47c9005 dispatch: use pycompat.maplist() instead of map() to get a list 2017-03-26 20:49:18 +05:30
Pulkit Goyal
d310fba3dd py3: have a bytes version of shlex.split()
shlex.split() only accepts unicodes on Python 3. After this patch we will be
using pycompat.shlexsplit(). This patch also replaces existing occurences of
shlex.split with pycompat.shlexsplit.
2016-12-25 03:06:55 +05:30
Pierre-Yves David
9ff835aa99 color: load 'colortable' from extension using an 'extraloader'
Now that we have the '_style' dictionary in core, we can use the clean and
standard 'extraloader' mechanism to load extension's 'colortable'.
color.loadcolortable
2016-11-18 18:18:15 +01:00
Pulkit Goyal
9d833da676 py3: make keys of keyword arguments strings
keys of keyword arguments on Python 3 has to be string. We are dealing with
bytes in our codebase so the keys are also bytes. Done that using
pycompat.strkwargs().

Also after this patch, `hg version` now runs on Python 3.5. Hurray!
2016-12-13 20:53:40 +05:30
Pulkit Goyal
9523fa9b6b fancyopts: switch from fancyopts.getopt.* to getopt.*
In the next patch, we will be creating a bytes version of getopt.getopt() and
doing that will leave getopt as unused import in fancyopts. So before removing
that there are instances in codebase where instead of importing getopt, we
have used fancyopts.getopt. This patch will switch all those cases so that
the next patch can remove the import of getopt from fancyopts without breaking
things.
2016-12-06 06:27:58 +05:30
Yuya Nishihara
1d44bd2bbb ui: factor out ui.load() to create a ui without loading configs (API)
This allows us to write doctests depending on a ui object, but not on global
configs.

ui.load() is a class method so we can do wsgiui.load(). All ui() calls but
for doctests are replaced with ui.load(). Some of them could be changed to
not load configs later.
2016-10-22 14:35:10 +09:00
Jun Wu
115ee04855 dispatch: move part of callcatch to scmutil
Per discussion at 7d927e65eaf2 [1], we need "callcatch" in worker.py. Move
it to scmutil.py to avoid cycles.

Note that dispatch's callcatch handles some additional high-level exceptions
related to config parsing, and commands. Moving them to scmutil will make
scmutil depend on "commands" or require "_formatparse" and "_getsimilar"
(and "difflib") to be moved as well. In the worker use-case, it is forked
when config and commands are fully loaded. So it should not care about those
exceptions.

[1]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-August/087116.html
2016-11-24 00:48:40 +00:00
Pulkit Goyal
97f340e354 py3: use pycompat.getcwd() instead of os.getcwd()
We have pycompat.getcwd() which returns bytes path on Python 3. This patch
changes most of the occurences of the os.getcwd() with pycompat one.
2016-11-23 00:03:11 +05:30
Pulkit Goyal
57f271b08e py3: add os.getcwdb() to have bytes path
Following the behaviour of Python 3, os.getcwd() return unicodes. We need
bytes version as path variables are bytes in UNIX. Python 3 has os.getcwdb()
which returns current working directory in bytes.

Like rest of the things there in pycompat, like osname, ossep, we need to
rewrite every instance of os.getcwd to pycompat.getcwd to make them work
correctly on Python 3.
2016-11-22 18:46:50 +05:30
Augie Fackler
d3b8e6d277 dispatch: stop supporting non-use of @command
We said we'd delete this after 3.8. It's time.
2016-11-21 21:51:23 -05:00
Yuya Nishihara
47f9c8b52e py3: bulk replace sys.stdin/out/err by util's
Almost all sys.stdin/out/err in hgext/ and mercurial/ are replaced by util's.
There are a few exceptions:

 - lsprof.py and statprof.py are untouched since they are a kind of vendor
   code and they never import mercurial modules right now.
 - ui._readline() needs to replace sys.stdin and stdout to pass them to
   raw_input(). We'll need another workaround here.
2016-10-20 23:53:36 +09:00
Pulkit Goyal
bf942f7498 py3: use pycompat.sysargv in dispatch.run()
Another one to have a bytes result from sys.argv in Python 3.
This one is also a part of running `hg version` on Python 3.
2016-11-21 15:35:22 +05:30
Augie Fackler
7a3b5c3c7d dispatch: use pycompat.maplist to allow summing with args 2017-03-19 14:17:07 -04:00
Augie Fackler
f1710548b8 dispatch: replace mayberepr with shellquote
The quoting logic here was actually insufficient, and would have had
bogus b-prefixes on Python 3. shellquote seems more appropriate
anyway. Surprisingly, only two tests have output changes, and both of
them look reasonable to me (both are in blackbox logs).

Spotted by Yuya during review.
2017-03-19 14:23:30 -04:00
Augie Fackler
4eeee9b0e9 dispatch: ensure repr is bytes in _mayberepr
Fixes command line arguments containing spaces on Python 3.
2017-03-19 00:22:04 -04:00
Augie Fackler
ecf3381175 dispatch: extract maybe-use-repr formatting to helper function
I think this makes the code much clearer. I had to think for a bit to
unpack the old-school `condition and if-true or if-false` dance, and
formatting argument lists here shouldn't be performance critical.
2017-03-19 00:21:26 -04:00
Augie Fackler
956c1da8ce dispatch: consolidate formatting of arguments
This was getting done twice, and it's clever enough I'm about to split
it apart and then fix it for Python 3.
2017-03-19 00:18:53 -04:00
Pulkit Goyal
03903626e4 py3: make the regular expression bytes to prevent TypeError 2017-03-17 05:10:58 +05:30
Yuya Nishihara
877b7b1d1a help: pass commands module by argument
This removes import cycle.
2017-05-21 16:57:32 +09:00
Jun Wu
cf441f3e42 dispatch: make request accept additional reposetups
chg needs special logic around repo object creation (like, collecting and
reporting repo path to the master server). Adding "reposetup" to
dispatch.request seems to be an easy and reasonably clean way to allow that.
2017-04-29 21:39:47 -07:00
Yuya Nishihara
c283f56e61 debugcommands: use temporary dict for its command table
Instead, load the table by commands.py so the debug commands should always
be populated. The table in debugcommands.py is unnamed so extension authors
wouldn't be confused to wrap debugcommands.table in place of commands.table.
2017-05-04 17:13:12 +09:00
Yuya Nishihara
1e7ba75af3 error: add hint to ProgrammingError
As the hint isn't shown by the default exception handler, we need to print
it manually. I've copied the "** " style from _exceptionwarning().
2017-05-14 15:41:27 +09:00
Martin von Zweigbergk
c3406ac3db cleanup: use set literals
We no longer support Python 2.6, so we can now use set literals.
2017-02-10 16:56:29 -08:00
Pulkit Goyal
a52d872f30 py3: make adefaults keys str to be compatible with getattr
getattr passes a str value of the attribute to be looked and keys in adefaults
dict are bytes which resulted in AttributeError. This patch abuses r'' to
make the keys str.
2017-05-04 00:44:53 +05:30
Pulkit Goyal
fb9e5b4f21 py3: use %d instead of %s for integers
dispatch._runcatch() always returns an integer value.
2017-04-21 01:13:18 +05:30
Jun Wu
1894115dcb dispatch: take over SignalInterrupt handling from scmutil
dispatch handles KeyboardInterrupt already. This makes the code more
consistent, and makes worker not print "killed!" if it receives SIGTERM in
most cases (in rare cases there is still "killed!" printed, which will be
fixed by the next patch).
2017-04-22 15:00:17 -07:00
Gregory Szorc
f70b24b885 debugcommands: introduce standalone module for debug commands
commands.py is our largest .py file by nearly 2x. Debug commands live
in a world of their own. So let's extract them to their own module.

We start with "debugancestor."

We currently reuse the commands table with commands.py and have a hack
in dispatch.py for loading debugcommands.py. In the future, we could
potentially use a separate commands table and avoid the import of
debugcommands.py.
2016-08-17 21:07:38 -07:00
Augie Fackler
5759889c58 dispatch: enforce bytes when converting boolean flags to config items
This fixes --verbose on Python 3.
2017-03-03 14:43:27 -05:00
Augie Fackler
7405058a22 dispatch: add pagination of two more help cases
I missed these in the last round anf Yuya spotted them in
review. Thanks!
2017-03-08 18:32:42 -05:00
Simon Farnsworth
36d4b32d0f dispatch: set a blockedtag when running an external alias 2017-03-06 03:25:44 -08:00
Augie Fackler
601a6ec266 dispatch: cope with sys.version being unicode on Python 3 2017-03-03 13:29:50 -05:00
Augie Fackler
5bdccc39a5 dispatch: allow testedwith to be bytes or str 2017-03-03 13:29:25 -05:00
Pierre-Yves David
b29eb57306 color: add a 'ui.color' option to control color behavior
This new option control whether or not color will be used. It mirror the behavior
of '--color'. I usually avoid adding new option to '[ui]' as the section is
already filled with many option. However, I feel like 'color' is central enough
to deserves a spot in this '[ui]' section.

For now the option is not documented so it is still marked as experimental. Once
it get documented and official, we should be able to deprecate the color
extensions.

There is more cleanup to do before that documentation is written, but we need
this option early to made them. Having that option will allow for more cleanup
of the initialisation process and proper separation between color
configuration.
2017-02-25 19:44:23 +01:00
Pierre-Yves David
89576090e1 color: move triggering of the initialisation logic in core
We now run the color initialisation as part of the standard dispatch. This is
opening the way for multiple cleanups since we now have access to the multiple 'ui'
object and we'll be able to see difference between global and local config. This
cleanup will arrive in later changesets.

As a side effect, the '--color' flag is now working without the extension.

Since we now properly initialize color for each ui idependently, we get a
warning message twice.
2017-02-21 18:20:12 +01:00
Augie Fackler
b88e5ebe27 dispatch: rearrange 'unknown command' code to better employ pager
dispatch calls help like a ninja if you give it a truly unknown
command, and that might want to be paged. If it gets paged, then the
'hg: unknown command' text gets eaten by a grue, unless we call the
pager first. This change rearranges the codepaths so we can safely
only invoke the pager in the case where we'll have long output from
the help command code, rather than just a short message like "did you
mean stat instead of start" or "fetch is provided by the fetch
extension".
2017-02-21 14:20:05 -05:00
Augie Fackler
4357a98af3 dispatch: consolidate pager flag handling to a single place
This makes a little more sense, thanks to Martin for suggesting it.
2017-02-19 20:16:11 -05:00