File: generation.py

package info (click to toggle)
crazy-complete 0.3.6-2
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 2,404 kB
  • sloc: python: 7,949; sh: 4,636; makefile: 74
file content (149 lines) | stat: -rw-r--r-- 4,715 bytes parent folder | download | duplicates (3)
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
146
147
148
149
'''Functions that are used in the generation process.'''

from .errors import CrazyError
from . import completion_validator
from . import cli
from . import config as _config
from . import when


class GenerationContext:
    '''Holds global configuration and helpers used during code generation.'''

    # pylint: disable=too-few-public-methods

    def __init__(self, config, helpers):
        self.config = config
        self.helpers = helpers

    def get_option_context(self, commandline, option):
        '''Return OptionGenerationContext based on current context.'''

        return OptionGenerationContext(
            self.config,
            self.helpers,
            commandline,
            option
        )


class OptionGenerationContext(GenerationContext):
    '''Extends GenerationContext; holds commandline and option objects.'''

    # pylint: disable=too-few-public-methods

    def __init__(self, config, helpers, commandline, option):
        super().__init__(config, helpers)
        self.commandline = commandline
        self.option = option


def _apply_config(commandline, config):
    '''Applies configuration settings to a command line object.

    If a setting in the CommandLine or Option object is set to ExtendedBool.INHERIT,
    it will be overridden by the corresponding setting from the config object.

    Args:
        commandline (CommandLine): The command line object to apply the configuration to.
        config (Config): The configuration object containing the settings to apply.

    Returns:
        None
    '''
    assert isinstance(commandline, cli.CommandLine), \
        "commandline_apply_config: commandline: expected CommandLine, got %r" % commandline

    assert isinstance(config, _config.Config), \
        "commandline_apply_config: config: expected Config, got %r" % config

    if commandline.abbreviate_commands == cli.ExtendedBool.INHERIT:
        commandline.abbreviate_commands = config.abbreviate_commands

    if commandline.abbreviate_options == cli.ExtendedBool.INHERIT:
        commandline.abbreviate_options = config.abbreviate_options

    if commandline.inherit_options == cli.ExtendedBool.INHERIT:
        commandline.inherit_options = config.inherit_options

    for option in commandline.options:
        if option.repeatable == cli.ExtendedBool.INHERIT:
            option.repeatable = config.repeatable_options

    if config.disabled_hidden:
        for option in commandline.options:
            option.hidden = False

    if config.disabled_final:
        for option in commandline.options:
            option.final = False

    if config.disabled_groups:
        for option in commandline.options:
            option.groups = []

    if config.disabled_repeatable:
        for option in commandline.options:
            option.repeatable = True

    if config.disabled_when:
        for option in commandline.options:
            option.when = None

        for positional in commandline.positionals:
            positional.when = None


def _add_parsed_when(commandline):
    for option in commandline.options:
        if option.when:
            try:
                option.when_parsed = when.parse_when(option.when)
            except CrazyError as e:
                raise CrazyError('%s: %s: when: %s: %s' % (
                    commandline.get_command_path(),
                    option.get_option_strings_key('|'),
                    option.when,
                    e)) from e
        else:
            option.when_parsed = None

    for positional in commandline.positionals:
        if positional.when:
            try:
                positional.when_parsed = when.parse_when(positional.when)
            except CrazyError as e:
                raise CrazyError('%s: %s: %s: when: %s: %s' % (
                    commandline.get_command_path(),
                    positional.number,
                    positional.metavar,
                    positional.when,
                    e)) from e


def enhance_commandline(commandline, config):
    '''Enhance commandline.

    - Make a copy of commandline
    - Apply configuration to it
    - Add `when_parsed` attribute
    '''

    commandline = commandline.copy()
    commandline.visit_commandlines(lambda c: _apply_config(c, config))
    commandline.visit_commandlines(_add_parsed_when)
    completion_validator.validate_commandlines(commandline)
    return commandline


def visit_commandlines(completion_class, ctxt, commandline):
    '''Visit commandlines with a completer class.'''

    result = []

    def _call_generator(commandline):
        result.append(completion_class(ctxt, commandline))

    commandline.visit_commandlines(_call_generator)

    return result