Passed
Pull Request — main (#107)
by
unknown
01:14
created

pyclean.debris   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 15
eloc 96
dl 0
loc 130
rs 10
c 0
b 0
f 0

4 Functions

Rating   Name   Duplication   Size   Complexity  
A suggest_debris_option() 0 17 4
A detect_debris_in_directory() 0 13 5
A remove_debris_for() 0 5 1
A recursive_delete_debris() 0 17 5
1
# SPDX-FileCopyrightText: 2020 Peter Bittner <[email protected]>
2
#
3
# SPDX-License-Identifier: GPL-3.0-or-later
4
5
import logging
6
import os
7
from pathlib import Path
8
9
from .runner import Runner
10
from .traversal import should_ignore
11
from .usability import delete_filesystem_objects
12
13
log = logging.getLogger(__name__)
14
15
DEBRIS_TOPICS = {
16
    'cache': [
17
        '.cache/**/*',
18
        '.cache/',
19
    ],
20
    'coverage': [
21
        '.coverage',
22
        'coverage.json',
23
        'coverage.lcov',
24
        'coverage.xml',
25
        'htmlcov/**/*',
26
        'htmlcov/',
27
    ],
28
    'jupyter': [
29
        '.ipynb_checkpoints/**/*',
30
        '.ipynb_checkpoints/',
31
    ],
32
    'mypy': [
33
        '.mypy_cache/**/*',
34
        '.mypy_cache/',
35
    ],
36
    'package': [
37
        'build/bdist.*/**/*',
38
        'build/bdist.*/',
39
        'build/lib/**/*',
40
        'build/lib/',
41
        'build/',
42
        'dist/**/*',
43
        'dist/',
44
        'sdist/**/*',
45
        'sdist/',
46
        '*.egg-info/**/*',
47
        '*.egg-info/',
48
    ],
49
    'pyright': [
50
        '.pyright-app-cache-*/**/*',
51
        '.pyright-app-cache-*/',
52
        '.pyright-stubs-*/**/*',
53
        '.pyright-stubs-*/',
54
        '.pyright/',
55
    ],
56
    'pytest': [
57
        '.pytest_cache/**/*',
58
        '.pytest_cache/',
59
        'pytestdebug.log',
60
    ],
61
    'ruff': [
62
        '.ruff_cache/**/*',
63
        '.ruff_cache/',
64
    ],
65
    'tox': [
66
        '.tox/**/*',
67
        '.tox/',
68
    ],
69
}
70
71
72
def remove_debris_for(topic, directory):
73
    log.debug('Scanning for debris of %s ...', topic.title())
74
75
    patterns = DEBRIS_TOPICS[topic]
76
    recursive_delete_debris(directory, patterns)
77
78
79
def recursive_delete_debris(directory, patterns):
80
    for pattern in patterns:
81
        delete_filesystem_objects(directory, pattern)
82
83
    try:
84
        subdirs = (
85
            Path(entry.path) for entry in os.scandir(directory) if entry.is_dir()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable entry does not seem to be defined.
Loading history...
86
        )
87
    except (OSError, PermissionError) as err:
88
        log.warning('Cannot access directory %s: %s', directory, err)
89
        return
90
91
    for subdir in subdirs:
92
        if should_ignore(subdir, Runner.ignore):
93
            log.debug('Skipping %s', subdir)
94
        else:
95
            recursive_delete_debris(subdir, patterns)
96
97
98
def detect_debris_in_directory(directory):
99
    detected_topics = []
100
101
    for topic, patterns in DEBRIS_TOPICS.items():
102
        for pattern in patterns:
103
            if '**' in pattern:
104
                continue
105
            matches = list(directory.glob(pattern))
106
            if matches:
107
                detected_topics.append(topic)
108
                break
109
110
    return detected_topics
111
112
113
def suggest_debris_option(args):
114
    all_detected = set()
115
    for dir_name in args.directory:
116
        dir_path = Path(dir_name)
117
        if dir_path.exists():
118
            detected = detect_debris_in_directory(dir_path)
119
            all_detected.update(detected)
120
121
    if all_detected:
122
        topics_str = ' '.join(sorted(all_detected))
123
        log.info(
124
            'Hint: Use --debris to also clean up build artifacts. Detected: %s',
125
            topics_str,
126
        )
127
    else:
128
        log.info(
129
            'Hint: Use --debris to also clean up build artifacts '
130
            'from common Python development tools.',
131
        )
132