Completed
Pull Request — master (#2554)
by Lasse
02:44
created

default_arg_parser()   F

Complexity

Conditions 9

Size

Total Lines 193

Duplication

Lines 0
Ratio 0 %

Importance

Changes 10
Bugs 0 Features 0
Metric Value
cc 9
c 10
b 0
f 0
dl 0
loc 193
rs 3.1304

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import argparse
2
import sys
3
4
from coalib.misc import Constants
5
from coalib.collecting.Collectors import get_all_bears_names
6
7
8
class CustomFormatter(argparse.RawDescriptionHelpFormatter):
9
    """
10
    A Custom Formatter that will keep the metavars in the usage but remove them
11
    in the more detailed arguments section.
12
    """
13
14
    def _format_action_invocation(self, action):
15
        if not action.option_strings:
16
            # For arguments that don't have options strings
17
            metavar, = self._metavar_formatter(action, action.dest)(1)
18
            return metavar
19
        else:
20
            # Option string arguments (like "-f, --files")
21
            parts = action.option_strings
22
            return ', '.join(parts)
23
24
25
def default_arg_parser(formatter_class=None):
26
    """
27
    This function creates an ArgParser to parse command line arguments.
28
29
    :param formatter_class: Formatting the arg_parser output into a specific
30
                            form. For example: In the manpage format.
31
    """
32
    formatter_class = formatter_class or CustomFormatter
33
34
    entry_point = sys.argv[0]
35
    for entry in ['coala-ci', 'coala-dbus', 'coala-format', 'coala-json',
36
                  'coala-delete-orig']:
37
        if entry_point.endswith(entry):
38
            parser_type = entry
39
            break
40
    else:
41
        parser_type = 'coala'
42
43
    description = """
44
coala provides a common command-line interface for linting and fixing all your
45
code, regardless of the programming languages you use.
46
47
To find out what kind of analysis coala offers for the languages you use, visit
48
<https://github.com/coala-analyzer/bear-docs/blob/master/README.rst#supported-languages>
49
or run:
50
51
    $ coala --show-bears --filter-by-language C Python
52
53
To perform code analysis, simply specify the analysis routines (bears) and the
54
files you want it to run on, for example:
55
56
    $ coala --bears SpaceConsistencyBear --files **.py
57
58
coala can also automatically fix your code:
59
60
    $ coala --bears SpaceConsistencyBear --files **.py --apply-patches
61
"""
62
63
    arg_parser = argparse.ArgumentParser(
64
        formatter_class=formatter_class,
65
        prog="coala",
66
        description=description,
67
        # Use our own help so that we can put it in the group we want
68
        add_help=False)
69
70
    arg_parser.add_argument('TARGETS',
71
                            nargs='*',
72
                            help="sections to be executed exclusively")
73
74
    info_group = arg_parser.add_argument_group('Info')
75
76
    info_group.add_argument('-h',
77
                            '--help',
78
                            action='help',
79
                            help='show this help message and exit')
80
81
    info_group.add_argument('-v',
82
                            '--version',
83
                            action='version',
84
                            version=Constants.VERSION)
85
86
    config_group = arg_parser.add_argument_group('Configuration')
87
88
    config_group.add_argument(
89
        '-c', '--config', nargs=1, metavar='FILE',
90
        help="configuration file to be used, defaults to {}".format(
91
            Constants.default_coafile))
92
93
    config_group.add_argument(
94
        '-F', '--find-config', action='store_const', const=True,
95
        help="find {} in ancestors of the working directory".format(
96
            Constants.default_coafile))
97
98
    config_group.add_argument(
99
        '-I', '--no-config', const=True, action='store_const',
100
        help="run without using any config file")
101
102
    config_group.add_argument(
103
        '-s', '--save', nargs='?', const=True, metavar='FILE',
104
        help="save used arguments to a config file to a {}, the given path, "
105
             "or at the value of -c".format(Constants.default_coafile))
106
107
    config_group.add_argument(
108
        '--disable-caching', const=True, action='store_const',
109
        help='run on all files even if unchanged')
110
    config_group.add_argument(
111
        '--flush-cache', const=True, action='store_const',
112
        help='rebuild the file cache')
113
114
    inputs_group = arg_parser.add_argument_group('Inputs')
115
116
    inputs_group.add_argument(
117
        '-b', '--bears', nargs='+', metavar='NAME',
118
        help='names of bears to use').completer = (
119
            lambda *args, **kwargs: get_all_bears_names())  # pragma: no cover
120
121
    inputs_group.add_argument(
122
        '-f', '--files', nargs='+', metavar='FILE',
123
        help='files that should be checked')
124
125
    inputs_group.add_argument(
126
        '-i', '--ignore', nargs='+', metavar='FILE',
127
        help='files that should be ignored')
128
129
    inputs_group.add_argument(
130
        '--limit-files', nargs='+', metavar='FILE',
131
        help="filter the `--files` argument's matches further")
132
133
    inputs_group.add_argument(
134
        '-d', '--bear-dirs', nargs='+', metavar='DIR',
135
        help='additional directories which may contain bears')
136
137
    outputs_group = arg_parser.add_argument_group('Outputs')
138
139
    outputs_group.add_argument(
140
        '-V', '--verbose', action='store_const',
141
        dest='log_level', const='DEBUG',
142
        help="alias for `-L DEBUG`")
143
144
    outputs_group.add_argument(
145
        '-L', '--log-level', nargs=1,
146
        choices=['ERROR', 'INFO', 'WARNING', 'DEBUG'], metavar='ENUM',
147
        help="set log output level to ERROR/INFO/WARNING/DEBUG")
148
149
    outputs_group.add_argument(
150
        '-m', '--min-severity', nargs=1,
151
        choices=('INFO', 'NORMAL', 'MAJOR'), metavar='ENUM',
152
        help="set minimal result severity to INFO/NORMAL/MAJOR")
153
154
    # Specific arguments
155
    if parser_type in ('coala', 'coala-json'):
156
        outputs_group.add_argument(
157
            '-B', '--show-bears', const=True, action='store_const',
158
            help='list all bears')
159
160
        outputs_group.add_argument(
161
            '-l', '--filter-by-language', nargs='+', metavar='LANG',
162
            help="filters `--show-bears` by the given languages")
163
164
        outputs_group.add_argument(
165
            '-p', '--show-capabilities', nargs='+', metavar='LANG',
166
            help="show what coala can fix and detect for the given languages")
167
168
    if parser_type == 'coala':
169
        outputs_group.add_argument(
170
            '-D', '--show-description', const=True, action='store_const',
171
            help="show bear descriptions for `--show-bears`")
172
173
        outputs_group.add_argument(
174
            '--show-details', const=True, action='store_const',
175
            help='show bear details for `--show-bears`')
176
177
    # The following are "coala-json" specific arguments
178
    if parser_type == 'coala-json':
179
        outputs_group.add_argument(
180
            '-o', '--output', nargs=1, metavar='FILE',
181
            help='write JSON logs to the given file')
182
183
        outputs_group.add_argument(
184
            '--text-logs', nargs='?', const=True, metavar='BOOL',
185
            help="use regular log messages instead of JSON")
186
187
        outputs_group.add_argument(
188
            '-r', '--relpath', nargs='?', const=True,
189
            help="return relative paths for files")
190
191
    misc_group = arg_parser.add_argument_group('Miscellaneous')
192
193
    misc_group.add_argument(
194
        '-S', '--settings', nargs='+', metavar='SETTING',
195
        help="arbitrary settings in the form of section.key=value")
196
197
    misc_group.add_argument(
198
        '-a', '--apply-patches', action='store_const',
199
        dest='default_actions', const='*: ApplyPatchAction',
200
        help='apply all patches automatically if possible')
201
202
    misc_group.add_argument(
203
        "-j", "--jobs", type=int,
204
        help="number of jobs to use in parallel")
205
206
    misc_group.add_argument(
207
        '-n', '--no-orig', const=True, action='store_const',
208
        help="don't create .orig backup files before patching")
209
210
    try:  # pragma: no cover
211
        # Auto completion should be optional, because of somewhat complicated
212
        # setup.
213
        import argcomplete
214
        argcomplete.autocomplete(arg_parser)
215
    except ImportError:
216
        pass
217
    return arg_parser
218