tests/test-pager.t
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
Tue, 02 May 2017 20:01:54 +0200
branchstable
changeset 32102 9a85ea1daf49
parent 32098 149440d7e1a7
child 32103 9a98023ac8db
permissions -rw-r--r--
color: turn 'ui.color' into a boolean (auto or off) Previously, 'ui.color=yes' meant "always show color", While "ui.color=auto" meant "use color automatically when it appears sensible". This feels problematic to some people because if an administrator has disabled color with "ui.color=off", and a user turn it back on using "color=on", it will get surprised (because it breaks their output when redirected to a file.) This patch changes ui.color=true to only move the default value of --color from "never" to "auto". I'm not really in favor of this changes as I suspect the above case will be pretty rare and I would rather keep the logic simpler. However, I'm providing this patch to help the 4.2 release in the case were others decide to make this changes. Users that want to force colors without specifying --color on the command line can use the 'ui.formatted' config knob, which had to be enabled in a handful of tests for this patch. Nice summary table (credit: Augie Fackler) That is, before this patch: +--------------------+--------------------+--------------------+ | | not a tty | a tty | | | --color not set | --color not set | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color (not set) | no color | no color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = auto | no color | color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = yes | *color* | color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = no | no color | no color | | | | | +--------------------+--------------------+--------------------+ (if --color is specified, it always clobbers the setting in [ui]) and after this patch: +--------------------+--------------------+--------------------+ | | not a tty | a tty | | | --color not set | --color not set | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color (not set) | no color | no color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = auto | no color | color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = yes | *no color* | color | | | | | +--------------------+--------------------+--------------------+ | [ui] | | | | color = no | no color | no color | | | | | +--------------------+--------------------+--------------------+ (if --color is specified, it always clobbers the setting in [ui])

  $ cat >> fakepager.py <<EOF
  > import sys
  > for line in sys.stdin:
  >     sys.stdout.write('paged! %r\n' % line)
  > EOF

Enable ui.formatted because pager won't fire without it, and set up
pager and tell it to use our fake pager that lets us see when the
pager was running.
  $ cat >> $HGRCPATH <<EOF
  > [ui]
  > formatted = yes
  > color = no
  > [pager]
  > pager = python $TESTTMP/fakepager.py
  > EOF

  $ hg init repo
  $ cd repo
  $ echo a >> a
  $ hg add a
  $ hg ci -m 'add a'
  $ for x in `python $TESTDIR/seq.py 1 10`; do
  >   echo a $x >> a
  >   hg ci -m "modify a $x"
  > done

By default diff and log are paged, but id is not:

  $ hg diff -c 2 --pager=yes
  paged! 'diff -r f4be7687d414 -r bce265549556 a\n'
  paged! '--- a/a\tThu Jan 01 00:00:00 1970 +0000\n'
  paged! '+++ b/a\tThu Jan 01 00:00:00 1970 +0000\n'
  paged! '@@ -1,2 +1,3 @@\n'
  paged! ' a\n'
  paged! ' a 1\n'
  paged! '+a 2\n'

  $ hg log --limit 2
  paged! 'changeset:   10:46106edeeb38\n'
  paged! 'tag:         tip\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 10\n'
  paged! '\n'
  paged! 'changeset:   9:6dd8ea7dd621\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 9\n'
  paged! '\n'

  $ hg id
  46106edeeb38 tip

We can control the pager from the config

  $ hg log --limit 1 --config 'pager.enable=False'
  changeset:   10:46106edeeb38
  tag:         tip
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     modify a 10
  
  $ hg log --limit 1 --config 'pager.enable=0'
  changeset:   10:46106edeeb38
  tag:         tip
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     modify a 10
  
  $ hg log --limit 1 --config 'pager.enable=1'
  paged! 'changeset:   10:46106edeeb38\n'
  paged! 'tag:         tip\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 10\n'
  paged! '\n'

We can enable the pager on id:

BROKEN: should be paged
  $ hg --config pager.attend-id=yes id
  46106edeeb38 tip

Setting attend-$COMMAND to a false value works, even with pager in
core:
  $ hg --config pager.attend-diff=no diff -c 2
  diff -r f4be7687d414 -r bce265549556 a
  --- a/a	Thu Jan 01 00:00:00 1970 +0000
  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
  @@ -1,2 +1,3 @@
   a
   a 1
  +a 2

Command aliases should have same behavior as main command

  $ hg history --limit 2
  paged! 'changeset:   10:46106edeeb38\n'
  paged! 'tag:         tip\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 10\n'
  paged! '\n'
  paged! 'changeset:   9:6dd8ea7dd621\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 9\n'
  paged! '\n'

Abbreviated command alias should also be paged

  $ hg hist -l 1
  paged! 'changeset:   10:46106edeeb38\n'
  paged! 'tag:         tip\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 10\n'
  paged! '\n'

Attend for an abbreviated command does not work

  $ hg --config pager.attend-ident=true ident
  46106edeeb38 tip

  $ hg --config extensions.pager= --config pager.attend-ident=true ident
  46106edeeb38 tip

Pager should not start if stdout is not a tty.

  $ hg log -l1 -q --config ui.formatted=False
  10:46106edeeb38

Pager should be disabled if pager.pager is empty (otherwise the output would
be silently lost.)

  $ hg log -l1 -q --config pager.pager=
  10:46106edeeb38

Pager with color enabled allows colors to come through by default,
even though stdout is no longer a tty.
  $ cat >> $HGRCPATH <<EOF
  > [ui]
  > color = yes
  > formatted = yes
  > [color]
  > mode = ansi
  > EOF
  $ hg log --limit 3
  paged! '\x1b[0;33mchangeset:   10:46106edeeb38\x1b[0m\n'
  paged! 'tag:         tip\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 10\n'
  paged! '\n'
  paged! '\x1b[0;33mchangeset:   9:6dd8ea7dd621\x1b[0m\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 9\n'
  paged! '\n'
  paged! '\x1b[0;33mchangeset:   8:cff05a6312fe\x1b[0m\n'
  paged! 'user:        test\n'
  paged! 'date:        Thu Jan 01 00:00:00 1970 +0000\n'
  paged! 'summary:     modify a 8\n'
  paged! '\n'

An invalid pager command name is reported sensibly if we don't have to
use shell=True in the subprocess call:
  $ hg log --limit 3 --config pager.pager=this-command-better-never-exist
  missing pager command 'this-command-better-never-exist', skipping pager
  \x1b[0;33mchangeset:   10:46106edeeb38\x1b[0m (esc)
  tag:         tip
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     modify a 10
  
  \x1b[0;33mchangeset:   9:6dd8ea7dd621\x1b[0m (esc)
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     modify a 9
  
  \x1b[0;33mchangeset:   8:cff05a6312fe\x1b[0m (esc)
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  summary:     modify a 8
  

A complicated pager command gets worse behavior. Bonus points if you can
improve this.
  $ hg log --limit 3 \
  >   --config pager.pager='this-command-better-never-exist --seriously' \
  >  2>/dev/null || true

Pager works with shell aliases.

  $ cat >> $HGRCPATH <<EOF
  > [alias]
  > echoa = !echo a
  > EOF

  $ hg echoa
  a
BROKEN: should be paged
  $ hg --config pager.attend-echoa=yes echoa
  a

Pager works with hg aliases including environment variables.

  $ cat >> $HGRCPATH <<'EOF'
  > [alias]
  > printa = log -T "$A\n" -r 0
  > EOF

  $ A=1 hg --config pager.attend-printa=yes printa
  paged! '1\n'
  $ A=2 hg --config pager.attend-printa=yes printa
  paged! '2\n'

Something that's explicitly attended is still not paginated if the
pager is globally set to off using a flag:
  $ A=2 hg --config pager.attend-printa=yes printa --pager=no
  2

Pager should not override the exit code of other commands

  $ cat >> $TESTTMP/fortytwo.py <<'EOF'
  > from mercurial import cmdutil, commands
  > cmdtable = {}
  > command = cmdutil.command(cmdtable)
  > @command('fortytwo', [], 'fortytwo', norepo=True)
  > def fortytwo(ui, *opts):
  >     ui.write('42\n')
  >     return 42
  > EOF

  $ cat >> $HGRCPATH <<'EOF'
  > [extensions]
  > fortytwo = $TESTTMP/fortytwo.py
  > EOF

  $ hg fortytwo --pager=on
  paged! '42\n'
  [42]

A command that asks for paging using ui.pager() directly works:
  $ hg blame a
  paged! ' 0: a\n'
  paged! ' 1: a 1\n'
  paged! ' 2: a 2\n'
  paged! ' 3: a 3\n'
  paged! ' 4: a 4\n'
  paged! ' 5: a 5\n'
  paged! ' 6: a 6\n'
  paged! ' 7: a 7\n'
  paged! ' 8: a 8\n'
  paged! ' 9: a 9\n'
  paged! '10: a 10\n'
but not with HGPLAIN
  $ HGPLAIN=1 hg blame a
   0: a
   1: a 1
   2: a 2
   3: a 3
   4: a 4
   5: a 5
   6: a 6
   7: a 7
   8: a 8
   9: a 9
  10: a 10
explicit flags work too:
  $ hg blame --pager=no a
   0: a
   1: a 1
   2: a 2
   3: a 3
   4: a 4
   5: a 5
   6: a 6
   7: a 7
   8: a 8
   9: a 9
  10: a 10

Put annotate in the ignore list for pager:
  $ cat >> $HGRCPATH <<EOF
  > [pager]
  > ignore = annotate
  > EOF
  $ hg blame a
   0: a
   1: a 1
   2: a 2
   3: a 3
   4: a 4
   5: a 5
   6: a 6
   7: a 7
   8: a 8
   9: a 9
  10: a 10

Environment variables like LESS and LV are set automatically:
  $ cat > $TESTTMP/printlesslv.py <<EOF
  > import os, sys
  > sys.stdin.read()
  > for name in ['LESS', 'LV']:
  >     sys.stdout.write(('%s=%s\n') % (name, os.environ.get(name, '-')))
  > sys.stdout.flush()
  > EOF

  $ cat >> $HGRCPATH <<EOF
  > [alias]
  > noop = log -r 0 -T ''
  > [ui]
  > formatted=1
  > [pager]
  > pager = $PYTHON $TESTTMP/printlesslv.py
  > EOF
  $ unset LESS
  $ unset LV
  $ hg noop --pager=on
  LESS=FRX
  LV=-c
  $ LESS=EFGH hg noop --pager=on
  LESS=EFGH
  LV=-c