default_arg_parser()   F
last analyzed

Complexity

Conditions 10

Size

Total Lines 194

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
c 2
b 0
f 0
dl 0
loc 194
rs 3.1304

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like default_arg_parser() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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