tests/printenv.py
author Augie Fackler <augie@google.com>
Mon, 08 Jul 2019 13:12:20 -0400
branchstable
changeset 42562 97ada9b8d51b
parent 41036 73da729ccfef
child 43076 2372284d9457
permissions -rwxr-xr-x
posix: always seek to EOF when opening a file in append mode Python 3 already does this, so skip it there. Consider the program: #include <stdio.h> int main() { FILE *f = fopen("narf", "w"); fprintf(f, "narf\n"); fclose(f); f = fopen("narf", "a"); printf("%ld\n", ftell(f)); fprintf(f, "troz\n"); printf("%ld\n", ftell(f)); return 0; } on macOS, FreeBSD, and Linux with glibc, this program prints 5 10 but on musl libc (Alpine Linux and probably others) this prints 0 10 By my reading of https://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html this is technically correct, specifically: > Opening a file with append mode (a as the first character in the > mode argument) shall cause all subsequent writes to the file to be > forced to the then current end-of-file, regardless of intervening > calls to fseek(). in other words, the file position doesn't really matter in append-mode files, and we can't depend on it being at all meaningful unless we perform a seek() before tell() after open(..., 'a'). Experimentally after a .write() we can do a .tell() and it'll always be reasonable, but I'm unclear from reading the specification if that's a smart thing to rely on. This matches what we do on Windows and what Python 3 does for free, so let's just be consistent. Thanks to Yuya for the idea.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25477
a372f7b4463b tests: make printenv executable
Matt Mackall <mpm@selenic.com>
parents: 17018
diff changeset
     1
#!/usr/bin/env python
a372f7b4463b tests: make printenv executable
Matt Mackall <mpm@selenic.com>
parents: 17018
diff changeset
     2
#
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     3
# simple script to be used in hooks
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     4
#
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     5
# put something like this in the repo .hg/hgrc:
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     6
#
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     7
#     [hooks]
17018
e7fdfc702d9f tests: consistently use printenv.py the same MSYS/Windows-compatible way
Mads Kiilerich <mads@kiilerich.com>
parents: 16982
diff changeset
     8
#     changegroup = python "$TESTDIR/printenv.py" <hookname> [exit] [output]
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
     9
#
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    10
#   - <hookname> is a mandatory argument (e.g. "changegroup")
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    11
#   - [exit] is the exit code of the hook (default: 0)
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    12
#   - [output] is the name of the output file (default: use sys.stdout)
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    13
#              the file will be opened in append mode.
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    14
#
28944
036787c10b16 py3: use absolute_import in printenv.py
Robert Stanca <robert.stanca7@gmail.com>
parents: 25477
diff changeset
    15
from __future__ import absolute_import
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    16
import argparse
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    17
import os
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    18
import sys
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    19
7080
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    20
try:
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    21
    import msvcrt
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    22
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    23
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7080
diff changeset
    24
    msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
7080
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    25
except ImportError:
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    26
    pass
a6477aa893b8 tests: Windows compatibility fixes
Patrick Mezard <pmezard@gmail.com>
parents: 4659
diff changeset
    27
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    28
parser = argparse.ArgumentParser()
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    29
parser.add_argument("name", help="the hook name, used for display")
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    30
parser.add_argument(
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    31
    "exitcode",
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    32
    nargs="?",
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    33
    default=0,
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    34
    type=int,
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    35
    help="the exit code for the hook",
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    36
)
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    37
parser.add_argument(
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    38
    "out", nargs="?", default=None, help="where to write the output"
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    39
)
41036
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    40
parser.add_argument(
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    41
    "--line",
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    42
    action="store_true",
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    43
    help="print environment variables one per line instead of on a single line",
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    44
)
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    45
args = parser.parse_args()
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    46
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    47
if args.out is None:
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    48
    out = sys.stdout
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    49
    out = getattr(out, "buffer", out)
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    50
else:
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    51
    out = open(args.out, "ab")
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    52
4643
a39cec1d5cb8 printenv: filter empty environment variables for portability.
Patrick Mezard <pmezard@gmail.com>
parents: 4285
diff changeset
    53
# variables with empty values may not exist on all platforms, filter
a39cec1d5cb8 printenv: filter empty environment variables for portability.
Patrick Mezard <pmezard@gmail.com>
parents: 4285
diff changeset
    54
# them now for portability sake.
36254
84a6e39bc723 printenv: port to python3
Augie Fackler <augie@google.com>
parents: 28944
diff changeset
    55
env = [(k, v) for k, v in os.environ.items()
4643
a39cec1d5cb8 printenv: filter empty environment variables for portability.
Patrick Mezard <pmezard@gmail.com>
parents: 4285
diff changeset
    56
       if k.startswith("HG_") and v]
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    57
env.sort()
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    58
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    59
out.write(b"%s hook: " % args.name.encode('ascii'))
16982
9c892c830a72 tests/printenv.py: eliminate trailing spaces on output
Adrian Buehlmann <adrian@cadifra.com>
parents: 16963
diff changeset
    60
if os.name == 'nt':
9c892c830a72 tests/printenv.py: eliminate trailing spaces on output
Adrian Buehlmann <adrian@cadifra.com>
parents: 16963
diff changeset
    61
    filter = lambda x: x.replace('\\', '/')
9c892c830a72 tests/printenv.py: eliminate trailing spaces on output
Adrian Buehlmann <adrian@cadifra.com>
parents: 16963
diff changeset
    62
else:
9c892c830a72 tests/printenv.py: eliminate trailing spaces on output
Adrian Buehlmann <adrian@cadifra.com>
parents: 16963
diff changeset
    63
    filter = lambda x: x
41036
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    64
38111
bacbe829c2bf py3: use bytes in tests/printenv.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36254
diff changeset
    65
vars = [b"%s=%s" % (k.encode('ascii'), filter(v).encode('ascii'))
bacbe829c2bf py3: use bytes in tests/printenv.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36254
diff changeset
    66
        for k, v in env]
41036
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    67
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    68
# Print variables on out
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    69
if not args.line:
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    70
    out.write(b" ".join(vars))
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    71
else:
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    72
    for var in vars:
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    73
        out.write(var)
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    74
        out.write(b"\n")
73da729ccfef test: introduce a new flag to display env variable line per line
Boris Feld <boris.feld@octobus.net>
parents: 41025
diff changeset
    75
38111
bacbe829c2bf py3: use bytes in tests/printenv.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36254
diff changeset
    76
out.write(b"\n")
4285
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    77
out.close()
4fd6f7e60894 Add tests/printenv.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
diff changeset
    78
41025
3c5aaea9638f tests: update printenv.py argument parsing
Boris Feld <boris.feld@octobus.net>
parents: 38296
diff changeset
    79
sys.exit(args.exitcode)