##// END OF EJS Templates
global: use python3 in shebangs...
global: use python3 in shebangs Python 3 is the future. We want Python scripts to be using Python 3 by default. This change updates all `#!/usr/bin/env python` shebangs to use `python3`. Does this mean all scripts use or require Python 3: no. In the test environment, the `PATH` environment variable in tests is updated to guarantee that the Python executable used to run run-tests.py is used. Since test scripts all now use `#!/usr/bin/env python3`, we had to update this code to install a `python3` symlink instead of `python`. It is possible there are some random scripts now executed with the incorrect Python interpreter in some contexts. However, I would argue that this was a pre-existing bug: we should almost always be executing new Python processes using the `sys.executable` from the originating Python script, as `python` or `python3` won't guarantee we'll use the same interpreter. Differential Revision: https://phab.mercurial-scm.org/D9273

File last commit:

r46434:c102b704 default
r46434:c102b704 default
Show More
f
216 lines | 6.8 KiB | text/plain | FortranFixedLexer
Gregory Szorc
global: use python3 in shebangs...
r46434 #!/usr/bin/env python3
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860
"""
Utility for inspecting files in various ways.
This tool is like the collection of tools found in a unix environment but are
cross platform and stable and suitable for our needs in the test suite.
This can be used instead of tools like:
[
dd
find
head
hexdump
ls
md5sum
readlink
sha1sum
stat
tail
test
readlink.py
md5sum.py
"""
Pulkit Goyal
py3: make tests/f use absolute_import
r29160 from __future__ import absolute_import
Gregory Szorc
py3: port f to Python 3...
r36275 import binascii
Pulkit Goyal
py3: make tests/f use absolute_import
r29160 import glob
Yuya Nishihara
tests: make 'f' utility import hashlib unconditionally...
r29233 import hashlib
Pulkit Goyal
py3: make tests/f use absolute_import
r29160 import optparse
import os
import re
import sys
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 # Python 3 adapters
Gregory Szorc
black: blacken scripts...
r44089 ispy3 = sys.version_info[0] >= 3
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 if ispy3:
Gregory Szorc
black: blacken scripts...
r44089
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 def iterbytes(s):
for i in range(len(s)):
Gregory Szorc
black: blacken scripts...
r44089 yield s[i : i + 1]
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 else:
iterbytes = iter
Gregory Szorc
black: blacken scripts...
r44089
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 def visit(opts, filenames, outfile):
"""Process filenames in the way specified in opts, writing output to
outfile."""
for f in sorted(filenames):
isstdin = f == '-'
if not isstdin and not os.path.lexists(f):
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b'%s: file not found\n' % f.encode('utf-8'))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 continue
quiet = opts.quiet and not opts.recurse or isstdin
isdir = os.path.isdir(f)
islink = os.path.islink(f)
isfile = os.path.isfile(f) and not islink
dirfiles = None
content = None
facts = []
if isfile:
if opts.type:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'file')
Matt Harbison
tests: teach `f` to handle sha256 checksums
r35488 if any((opts.hexdump, opts.dump, opts.md5, opts.sha1, opts.sha256)):
Augie Fackler
cleanup: fix some latent open(path).read() et al calls we previously missed...
r36966 with open(f, 'rb') as fobj:
content = fobj.read()
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif islink:
if opts.type:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'link')
Augie Fackler
tests: fix last failure in test-tools.t...
r40282 content = os.readlink(f).encode('utf8')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif isstdin:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 content = getattr(sys.stdin, 'buffer', sys.stdin).read()
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.size:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'size=%d' % len(content))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif isdir:
if opts.recurse or opts.type:
dirfiles = glob.glob(f + '/*')
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'directory with %d files' % len(dirfiles))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif opts.type:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'type unknown')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if not isstdin:
stat = os.lstat(f)
Matt Mackall
tests: teach f not to report directory size...
r23911 if opts.size and not isdir:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'size=%d' % stat.st_size)
Matt Mackall
tests: teach f not to report symlink mode bits...
r23912 if opts.mode and not islink:
Gregory Szorc
py3: port f to Python 3...
r36275 facts.append(b'mode=%o' % (stat.st_mode & 0o777))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.links:
Pulkit Goyal
py3: use '%d' for os.stat_result.st_nlink instead of '%s'...
r38383 facts.append(b'links=%d' % stat.st_nlink)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.newer:
# mtime might be in whole seconds so newer file might be same
if stat.st_mtime >= os.stat(opts.newer).st_mtime:
Gregory Szorc
black: blacken scripts...
r44089 facts.append(
b'newer than %s' % opts.newer.encode('utf8', 'replace')
)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 else:
Gregory Szorc
black: blacken scripts...
r44089 facts.append(
b'older than %s' % opts.newer.encode('utf8', 'replace')
)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.md5 and content is not None:
Yuya Nishihara
tests: make 'f' utility import hashlib unconditionally...
r29233 h = hashlib.md5(content)
Gregory Szorc
black: blacken scripts...
r44089 facts.append(b'md5=%s' % binascii.hexlify(h.digest())[: opts.bytes])
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.sha1 and content is not None:
Yuya Nishihara
tests: make 'f' utility import hashlib unconditionally...
r29233 h = hashlib.sha1(content)
Gregory Szorc
black: blacken scripts...
r44089 facts.append(
b'sha1=%s' % binascii.hexlify(h.digest())[: opts.bytes]
)
Matt Harbison
tests: teach `f` to handle sha256 checksums
r35488 if opts.sha256 and content is not None:
h = hashlib.sha256(content)
Gregory Szorc
black: blacken scripts...
r44089 facts.append(
b'sha256=%s' % binascii.hexlify(h.digest())[: opts.bytes]
)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if isstdin:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b', '.join(facts) + b'\n')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif facts:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b'%s: %s\n' % (f.encode('utf-8'), b', '.join(facts)))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 elif not quiet:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b'%s:\n' % f.encode('utf-8'))
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if content is not None:
chunk = content
if not islink:
if opts.lines:
if opts.lines >= 0:
Gregory Szorc
black: blacken scripts...
r44089 chunk = b''.join(chunk.splitlines(True)[: opts.lines])
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 else:
Gregory Szorc
black: blacken scripts...
r44089 chunk = b''.join(chunk.splitlines(True)[opts.lines :])
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.bytes:
if opts.bytes >= 0:
Gregory Szorc
black: blacken scripts...
r44089 chunk = chunk[: opts.bytes]
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 else:
Gregory Szorc
black: blacken scripts...
r44089 chunk = chunk[opts.bytes :]
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.hexdump:
for i in range(0, len(chunk), 16):
Gregory Szorc
black: blacken scripts...
r44089 s = chunk[i : i + 16]
outfile.write(
b'%04x: %-47s |%s|\n'
% (
i,
b' '.join(b'%02x' % ord(c) for c in iterbytes(s)),
re.sub(b'[^ -~]', b'.', s),
)
)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.dump:
if not quiet:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b'>>>\n')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 outfile.write(chunk)
if not quiet:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 if chunk.endswith(b'\n'):
outfile.write(b'<<<\n')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 else:
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 outfile.write(b'\n<<< no trailing newline\n')
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if opts.recurse and dirfiles:
assert not isstdin
visit(opts, dirfiles, outfile)
Gregory Szorc
black: blacken scripts...
r44089
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 if __name__ == "__main__":
parser = optparse.OptionParser("%prog [options] [filenames]")
Gregory Szorc
black: blacken scripts...
r44089 parser.add_option(
"-t",
"--type",
action="store_true",
help="show file type (file or directory)",
)
parser.add_option(
"-m", "--mode", action="store_true", help="show file mode"
)
parser.add_option(
"-l", "--links", action="store_true", help="show number of links"
)
parser.add_option(
"-s", "--size", action="store_true", help="show size of file"
)
parser.add_option(
"-n", "--newer", action="store", help="check if file is newer (or same)"
)
parser.add_option(
"-r", "--recurse", action="store_true", help="recurse into directories"
)
parser.add_option(
"-S",
"--sha1",
action="store_true",
help="show sha1 hash of the content",
)
parser.add_option(
"",
"--sha256",
action="store_true",
help="show sha256 hash of the content",
)
parser.add_option(
"-M", "--md5", action="store_true", help="show md5 hash of the content"
)
parser.add_option(
"-D", "--dump", action="store_true", help="dump file content"
)
parser.add_option(
"-H", "--hexdump", action="store_true", help="hexdump file content"
)
parser.add_option(
"-B", "--bytes", type="int", help="number of characters to dump"
)
parser.add_option(
"-L", "--lines", type="int", help="number of lines to dump"
)
parser.add_option(
"-q", "--quiet", action="store_true", help="no default output"
)
Mads Kiilerich
tests: add 'f' tool for cross platform file operations in the tests...
r23860 (opts, filenames) = parser.parse_args(sys.argv[1:])
if not filenames:
filenames = ['-']
Augie Fackler
tests: update `f` helper script to work on Python 3
r34271 visit(opts, filenames, getattr(sys.stdout, 'buffer', sys.stdout))