DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (3be27275aa4d)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#!/usr/bin/env python3
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# This script is used to upgrade pip requirements files using pip-compile.

import argparse
import os
import pathlib
import subprocess
import sys


def process_input_file(source: pathlib.Path, dest: pathlib.Path):
    print('processing %s' % dest)

    env = dict(os.environ)
    env['CUSTOM_COMPILE_COMMAND'] = sys.argv[0]

    subprocess.run([
        'pip-compile',
        '--generate-hashes',
        '--emit-trusted-host',
        '--annotate',
        '--header',
        '--index',
        '--output-file', '%s' % dest,
        '-U',
        '%s' % source
    ],
    check=True, capture_output=True, env=env)

    # pip-compile doesn't preserve --find-links from input file. So do
    # that manually.
    with source.open('rb') as fh:
        find_links = []
        for line in fh:
            if line.startswith(b'--find-links'):
                find_links.append(line)

    if find_links:
        with dest.open('rb') as fh:
            dest_lines = []
            in_header = True

            for line in fh:
                if in_header and not line.startswith(b'#'):
                    in_header = False
                    dest_lines.extend(find_links)

                dest_lines.append(line)

        with dest.open('wb') as fh:
            fh.write(b''.join(dest_lines))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('path', nargs='*', default=[],
                        help='Explicit requirements file to operate on')

    args = parser.parse_args()

    if not args.path:
        files = subprocess.check_output(['hg', 'files'])
        files = {f.strip() for f in files.splitlines() if f.strip()}

        requirements = set()

        for f in files:
            if b'requirements' not in f or not f.endswith(b'.txt'):
                continue

            base = f[:-4]
            if b'%s.in' % base in files:
                requirements.add(os.fsdecode(f))

    else:
        for p in args.path:
            if 'requirements' not in p or not p.endswith('.txt'):
                print('%s does not appear to be a requirements file' % p)
                sys.exit(1)

        requirements = set(args.path)

    for p in sorted(requirements):
        assert p.endswith('.txt')
        base = p[:-4]

        source = pathlib.Path('%s.in' % base)
        dest = pathlib.Path(p)

        process_input_file(source, dest)


if __name__ == '__main__':
    main()