Completed
Push — master ( ebbd13...afe8ce )
by Chris
01:11
created

get_dotfile_tree()   A

Complexity

Conditions 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
dl 0
loc 19
rs 9.2
c 1
b 0
f 0
1
#!/usr/bin/env python
2
3
"""
4
A utility for getting digraph friendly data structures
5
from the list of files and directories on a given path.
6
"""
7
8
import os
9
import errno
10
11
import click
12
13
14
def path_hierarchy(path, hierarchy=[], prev=None):
15
    """Create a dotfile representation of a filesystem tree.
16
17
    Format is suitable for graphviz applications.
18
    """
19
    name = os.path.basename(path)
20
    if prev is not None:
21
        prev = str(prev)
22
        # Ensure empty names or current dir '.' are not added.
23
        if all([prev != '', prev != '.']):
24
            # Wrap in quotes to prevent dot parsing errors.
25
            hierarchy.append('"{}" -> "{}"'.format(prev, name))
26
    try:
27
        # Recursively add all subfolders and files.
28
        hierarchy += [
29
            path_hierarchy(os.path.join(path, contents), prev=name)
30
            for contents in os.listdir(path)
31
        ]
32
    except OSError as e:
33
        if e.errno != errno.ENOTDIR:
34
            raise
35
    return hierarchy
36
37
38
def make_dotfile(path):
39
    """Generate the recursive path and then format into dotfile format."""
40
    _res = [w for w in path_hierarchy(path) if not isinstance(w, list)]
41
    res = 'digraph {\n'
42
    for item in _res:
43
        if item.startswith(' ->'):
44
            continue
45
        res += '\t{};\n'.format(item)
46
    res += '}\n'
47
    return res
48
49
50
@click.command()
51
@click.option('--dot', '-d',
52
              default=None,
53
              help='Output specified file as a dotfile.')
54
@click.option('--path', '-p',
55
              default='.',
56
              help='The starting path')
57
def get_dotfile_tree(path, dot):
58
    """CLI wrapper for existing functions."""
59
    res = make_dotfile(path)
60
    if path == '.':
61
        raise ValueError('Running in the same directory when no'
62
                         ' folders are present does not make sense.')
63
    if dot is not None:
64
        with open(dot, 'w') as dotfile:
65
            dotfile.write(res)
66
        return
67
    else:
68
        print(res)
69
70
71
if __name__ == '__main__':
72
    get_dotfile_tree()
73