Passed
Branch v4.0-dev (e005f1)
by Emmanuel
05:49
created

docker_clean   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 127
Duplicated Lines 22.05 %

Test Coverage

Coverage 81.25%

Importance

Changes 0
Metric Value
wmc 20
eloc 82
dl 28
loc 127
ccs 65
cts 80
cp 0.8125
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A stakkr.docker_clean.remove_containers() 0 15 3
A stakkr.docker_clean.remove_networks() 0 13 3
A stakkr.docker_clean.main() 0 19 2
A stakkr.docker_clean.remove_volumes() 14 14 4
A stakkr.docker_clean.remove_images() 14 14 3
B stakkr.docker_clean.clean() 0 21 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
#!/usr/bin/env python
2
# coding: utf-8
3 1
"""
4
Docker Clean command.
5
6
Clean unused containers, images, volumes and networks.
7
That saves a lot of space ...
8
"""
9
10 1
import sys
11 1
from subprocess import check_output, CalledProcessError, STDOUT
12 1
import click
13 1
import humanfriendly
14 1
from stakkr.docker_actions import get_client as get_docker_client
15
16
17 1
@click.command(help="""Clean Docker containers, images, volumes and networks
18
that are not in use""", name="docker-clean")
19 1
@click.option('--force', '-f', help="Do it", is_flag=True)
20 1
@click.option('--containers/--no-containers', '-c/', help="Remove containers", is_flag=True, default=True)
21 1
@click.option('--images/--no-images', '-i/', help="Remove images", is_flag=True, default=True)
22 1
@click.option('--volumes/--no-volumes', '-V/', help="Remove volumes", is_flag=True, default=True)
23 1
@click.option('--networks/--no-networks', '-n/', help="Remove networks", is_flag=True, default=True)
24 1
def clean(force: bool, containers: bool, images: bool, volumes: bool, networks: bool):
25
    """See command help."""
26 1
    if containers is True:
27 1
        click.secho('Cleaning Docker stopped containers:', fg='green')
28 1
        remove_containers(force)
29 1
    if images is True:
30 1
        click.secho('Cleaning Docker unused images:', fg='green')
31 1
        remove_images(force)
32 1
    if volumes is True:
33 1
        click.secho('Cleaning Docker unused volumes:', fg='green')
34 1
        remove_volumes(force)
35 1
    if networks is True:
36 1
        click.secho('Cleaning Docker unused networks:', fg='green')
37 1
        remove_networks(force)
38
39
40 1
def remove_containers(force: bool):
41
    """Remove exited containers."""
42 1
    stopped_containers = get_docker_client().containers.list(filters={'status': 'exited'})
43 1
    if len(stopped_containers) is 0:
44 1
        print('  No exited container to remove')
45 1
        return
46
47 1
    if force is False:
48
        click.secho("  --force is not set so I won't do anything", fg='red')
49
        return
50
51 1
    res = get_docker_client().containers.prune()
52 1
    cts = len(res['ContainersDeleted'])
53 1
    space = humanfriendly.format_size(res['SpaceReclaimed'])
54 1
    click.echo('  Removed {} exited container(s), saved {}'.format(cts, space))
55
56
57 1 View Code Duplication
def remove_images(force: bool):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
58
    """Remove unused images."""
59 1
    if force is False:
60 1
        click.secho("  --force is not set so I won't do anything", fg='red')
61 1
        return
62
63 1
    res = get_docker_client().images.prune(filters={'dangling': False})
64 1
    if res['ImagesDeleted'] is None:
65
        print('  No image to remove')
66
        return
67
68 1
    images = len(res['ImagesDeleted'])
69 1
    space = humanfriendly.format_size(res['SpaceReclaimed'])
70 1
    click.echo('  Removed {} images(s), saved {}'.format(images, space))
71
72
73 1
def remove_networks(force: bool):
74
    """Remove unused networks."""
75 1
    if force is False:
76 1
        click.secho("  --force is not set so I won't do anything", fg='red')
77 1
        return
78
79 1
    res = get_docker_client().networks.prune()
80 1
    if res['NetworksDeleted'] is None:
81
        print('  No network to remove')
82
        return
83
84 1
    networks = len(res['NetworksDeleted'])
85 1
    click.echo('  Removed {} network(s)'.format(networks))
86
87
88 1 View Code Duplication
def remove_volumes(force: bool):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
89
    """Remove unused volumes."""
90 1
    if force is False:
91 1
        click.secho("  --force is not set so I won't do anything", fg='red')
92 1
        return
93
94 1
    res = get_docker_client().volumes.prune()
95 1
    if res['VolumesDeleted'] is None or len(res['VolumesDeleted']) is 0:
96 1
        print('  No volume to remove')
97 1
        return
98
99 1
    volumes = len(res['VolumesDeleted'])
100 1
    space = humanfriendly.format_size(res['SpaceReclaimed'])
101 1
    click.echo('  Removed {} volume(s), saved {}'.format(volumes, space))
102
103
104 1
def main():
105
    """Generate the CLI."""
106
    try:
107
        clean()
108
    except Exception as error:
109
        msg = click.style(r""" ______ _____  _____   ____  _____
110
|  ____|  __ \|  __ \ / __ \|  __ \
111
| |__  | |__) | |__) | |  | | |__) |
112
|  __| |  _  /|  _  /| |  | |  _  /
113
| |____| | \ \| | \ \| |__| | | \ \
114
|______|_|  \_\_|  \_\\____/|_|  \_\
115
116
""", fg='yellow')
117
        msg += click.style('{}'.format(error), fg='red')
118
119
        click.echo(msg)
120
        click.echo()
121
        # raise error
122
        sys.exit(1)
123
124
125 1
if __name__ == '__main__':
126
    main()
127