Passed
Push — main ( c1b2c3...bb321b )
by Peter
02:08
created

pyclean.cli.parse_arguments()   C

Complexity

Conditions 7

Size

Total Lines 106
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 80
dl 0
loc 106
rs 6.2545
c 0
b 0
f 0
cc 7
nop 0

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
"""
2
Command line interface implementation for pyclean.
3
"""
4
5
import argparse
6
import logging
7
import sys
8
9
from . import __version__, compat, modern
10
11
log = logging.getLogger(__name__)
12
13
14
def parse_arguments():
15
    """
16
    Parse and handle CLI arguments.
17
    """
18
    debris_default_topics = ['cache', 'coverage', 'package', 'pytest', 'ruff']
19
    debris_optional_topics = ['jupyter', 'mypy', 'tox']
20
    debris_choices = ['all', *debris_default_topics, *debris_optional_topics]
21
    ignore_default_items = [
22
        '.git',
23
        '.hg',
24
        '.svn',
25
        '.tox',
26
        '.venv',
27
        'node_modules',
28
        'venv',
29
    ]
30
31
    parser = argparse.ArgumentParser(
32
        description='Remove byte-compiled files for a package or project.',
33
    )
34
35
    if sys.version_info < (3, 8):  # pragma: no-cover-gt-py37
36
        parser.register('action', 'extend', compat.ExtendAction)
37
38
    parser.add_argument('--version', action='version', version=__version__)
39
    parser.add_argument(
40
        'directory',
41
        nargs='+',
42
        help='directory tree to traverse for byte-code',
43
    )
44
    parser.add_argument(
45
        '-i',
46
        '--ignore',
47
        metavar='DIRECTORY',
48
        action='extend',
49
        nargs='+',
50
        default=ignore_default_items,
51
        help='directory that should be ignored (may be specified multiple times;'
52
        ' default: %s)' % ' '.join(ignore_default_items),
53
    )
54
    parser.add_argument(
55
        '-d',
56
        '--debris',
57
        metavar='TOPIC',
58
        action='extend',
59
        nargs='*',
60
        default=argparse.SUPPRESS,
61
        choices=debris_choices,
62
        help='remove leftovers from popular Python development tools'
63
        ' (may be specified multiple times; optional: all %s; default: %s)'
64
        % (
65
            ' '.join(debris_optional_topics),
66
            ' '.join(debris_default_topics),
67
        ),
68
    )
69
    parser.add_argument(
70
        '-e',
71
        '--erase',
72
        metavar='PATTERN',
73
        action='extend',
74
        nargs='+',
75
        default=[],
76
        help='delete files or folders matching a globbing pattern (may be specified'
77
        ' multiple times); this will be interactive unless --yes is used.',
78
    )
79
    parser.add_argument(
80
        '-n',
81
        '--dry-run',
82
        action='store_true',
83
        help='show what would be done',
84
    )
85
86
    verbosity = parser.add_mutually_exclusive_group()
87
    verbosity.add_argument('-q', '--quiet', action='store_true', help='be quiet')
88
    verbosity.add_argument(
89
        '-v',
90
        '--verbose',
91
        action='store_true',
92
        help='be more verbose',
93
    )
94
95
    parser.add_argument(
96
        '-y',
97
        '--yes',
98
        action='store_true',
99
        help='assume yes as answer for interactive questions',
100
    )
101
102
    args = parser.parse_args()
103
    init_logging(args)
104
105
    if args.yes and not args.erase:
106
        parser.error('Specifying --yes only makes sense with --erase.')
107
108
    if 'debris' in args:
109
        if 'all' in args.debris:
110
            args.debris = debris_default_topics + debris_optional_topics
111
        elif not args.debris:
112
            args.debris = debris_default_topics
113
        log.debug('Debris topics to scan for: %s', ' '.join(args.debris))
114
    else:
115
        args.debris = []
116
117
    log.debug('Ignored directories: %s', ' '.join(args.ignore))
118
119
    return args
120
121
122
def init_logging(args):
123
    """
124
    Set the log level according to the -v/-q command line options.
125
    """
126
    log_level = (
127
        logging.FATAL if args.quiet else logging.DEBUG if args.verbose else logging.INFO
128
    )
129
    log_format = '%(message)s'
130
    logging.basicConfig(level=log_level, format=log_format)
131
132
133
def main():
134
    """
135
    Entry point for CLI application.
136
    """
137
    args = parse_arguments()
138
139
    try:
140
        modern.pyclean(args)
141
    except Exception as err:
142
        raise SystemExit(err)
143