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 (05f4ac2d6dd6)

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
# 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/.

from __future__ import absolute_import, print_function, unicode_literals

from collections import defaultdict
import os
import re
from mozbuild.configure.options import Option


class HelpFormatter(object):
    def __init__(self, argv0):
        self.intro = ['Usage: %s [options]' % os.path.basename(argv0)]
        self.options = []

    def add(self, option):
        assert isinstance(option, Option)
        if option.possible_origins == ('implied',):
            # Don't display help if our option can only be implied.
            return
        self.options.append(option)

    def format_options_by_category(self, options_by_category):
        ret = []
        for category, options in sorted(options_by_category.items(),
                                        key=lambda x: x[0]):
            ret.append('  ' + category + ':')
            for option in sorted(options, key=lambda opt: opt.option):
                opt = option.option
                if option.choices:
                    opt += '={%s}' % ','.join(option.choices)
                help = self.format_help(option)
                if len(option.default):
                    if help:
                        help += ' '
                    help += '[%s]' % ','.join(option.default)

                if len(opt) > 24 or not help:
                    ret.append('    %s' % opt)
                    if help:
                        ret.append('%s%s' % (' ' * 30, help))
                else:
                    ret.append('    %-24s  %s' % (opt, help))
            ret.append('')
        return ret

    RE_FORMAT = re.compile(r'{([^|}]*)\|([^|}]*)}')

    # Return formatted help text for --{enable,disable,with,without}-* options.
    #
    # Format is the following syntax:
    #   {String for --enable or --with|String for --disable or --without}
    #
    # For example, '{Enable|Disable} optimizations' will be formatted to
    # 'Enable optimizations' if the options's prefix is 'enable' or 'with',
    # and formatted to 'Disable optimizations' if the options's prefix is
    # 'disable' or 'without'.
    def format_help(self, option):
        if not option.help:
            return ''

        if option.prefix in ('enable', 'with'):
            replacement = r'\1'
        elif option.prefix in ('disable', 'without'):
            replacement = r'\2'
        else:
            return option.help

        return self.RE_FORMAT.sub(replacement, option.help)

    def usage(self, out):
        options_by_category = defaultdict(list)
        env_by_category = defaultdict(list)
        for option in self.options:
            target = options_by_category if option.name else env_by_category
            target[option.category].append(option)
        options_formatted = [
            'Options: [defaults in brackets after descriptions]'
        ] + self.format_options_by_category(options_by_category)
        env_formatted = (['Environment variables:'] +
                         self.format_options_by_category(env_by_category))
        print('\n\n'.join('\n'.join(t)
                          for t in (self.intro, options_formatted,
                                    env_formatted)),
              file=out)