Completed
Pull Request — master (#2440)
by Tushar
01:55
created

default_arg_parser()   D

Complexity

Conditions 8

Size

Total Lines 188

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 0 Features 0
Metric Value
cc 8
c 9
b 0
f 0
dl 0
loc 188
rs 4

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