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 (6863f516ba38)

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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
# 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

import ConfigParser
import os
import subprocess
from collections import defaultdict

import yaml
from mozboot.util import get_state_dir


class PresetHandler(object):

    def __init__(self, path):
        self.path = path
        self._presets = {}

    @property
    def presets(self):
        if not self._presets and os.path.isfile(self.path):
            with open(self.path, 'r') as fh:
                self._presets = yaml.safe_load(fh) or {}

        return self._presets

    def __contains__(self, name):
        return name in self.presets

    def __getitem__(self, name):
        return self.presets[name]

    def __len__(self):
        return len(self.presets)

    def __str__(self):
        if not self.presets:
            return ''
        return yaml.safe_dump(self.presets, default_flow_style=False)

    def list(self):
        if not self.presets:
            print("no presets found")
        else:
            print(self)

    def edit(self):
        if 'EDITOR' not in os.environ:
            print("error: must set the $EDITOR environment variable to use --edit-presets")
            return

        subprocess.call([os.environ['EDITOR'], self.path])

    def save(self, name, **data):
        self.presets[name] = data

        with open(self.path, "w") as fh:
            fh.write(str(self))


class MergedHandler(object):
    def __init__(self, *paths):
        """Helper class for dealing with multiple preset files."""
        self.handlers = [PresetHandler(p) for p in paths]

    def __contains__(self, name):
        return any(name in handler for handler in self.handlers)

    def __getitem__(self, name):
        for handler in self.handlers:
            if name in handler:
                return handler[name]
        raise KeyError(name)

    def __len__(self):
        return sum(len(h) for h in self.handlers)

    def __str__(self):
        all_presets = {
            k: v
            for handler in self.handlers
            for k, v in handler.presets.items()
        }
        return yaml.safe_dump(all_presets, default_flow_style=False)

    def list(self):
        if len(self) == 0:
            print("no presets found")
            return

        for handler in self.handlers:
            val = str(handler)
            if val:
                val = '\n  '.join([''] + val.splitlines() + [''])  # indent all lines by 2 spaces
                print("Presets from {}:".format(handler.path))
                print(val)


def migrate_old_presets(presets):
    """Move presets from the old `autotry.ini` format to the new
    `try_presets.yml` one.

    Args:
        presets (PresetHandler): Handler to migrate old presets into.
    """
    from .selectors.syntax import AutoTry, SyntaxParser
    old_preset_path = os.path.join(get_state_dir(), 'autotry.ini')
    if os.path.isfile(presets.path) or not os.path.isfile(old_preset_path):
        return

    print("migrating saved presets from '{}' to '{}'".format(old_preset_path, presets.path))
    config = ConfigParser.ConfigParser()
    config.read(old_preset_path)

    unknown = defaultdict(list)
    for section in config.sections():
        for name, value in config.items(section):
            kwargs = {}
            if section == 'fuzzy':  # try fuzzy
                kwargs['query'] = [value]
                kwargs['selector'] = 'fuzzy'

            elif section == 'try':  # try syntax
                parser = SyntaxParser()
                kwargs = vars(parser.parse_args(AutoTry.split_try_string(value)))
                kwargs = {k: v for k, v in kwargs.items() if v != parser.get_default(k)}
                kwargs['selector'] = 'syntax'

            else:
                unknown[section].append("{} = {}".format(name, value))
                continue

            presets.save(name, **kwargs)

    os.remove(old_preset_path)

    if unknown:
        for section, values in unknown.items():
            print("""
warning: unknown section '{}', the following presets were not migrated:
  {}
""".format(section, '\n  '.join(values)).lstrip())