Completed
Push — master ( 5f68ae...c3dae1 )
by Bjorn
01:12
created

which()   F

Complexity

Conditions 19

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 19
c 1
b 0
f 0
dl 0
loc 52
rs 3.073

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 which() 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
# -*- coding: utf-8 -*-
2
"""Print where on the path an executable is located.
3
"""
4
from __future__ import print_function
5
import sys
6
import os
7
from stat import ST_MODE, S_IXUSR, S_IXGRP, S_IXOTH
8
9
10
def get_executable(name):
11
    """Return the first executable on the path that matches `name`.
12
    """
13
    for result in which(name):
14
        return result
15
    return None
16
17
18
def get_path_directories():
19
    """Return a list of all the directories on the path.
20
    """
21
    pth = os.environ['PATH']
22
    if sys.platform == 'win32' and os.environ.get("BASH"):
23
        # winbash has a bug..
24
        if pth[1] == ';':  # pragma: nocover
25
            pth = pth.replace(';', ':', 1)
26
    return pth.split(os.pathsep)
27
28
29
def is_executable(fname):
30
    """Check if a file is executable.
31
    """
32
    return os.stat(fname)[ST_MODE] & (S_IXUSR | S_IXGRP | S_IXOTH)
33
34
35
def which(filename, interactive=False, verbose=False):
36
    """Yield all executable files on path that matches `filename`.
37
    """
38
    exe = os.environ.get('PATHEXT', ['.cmd', '.bat', '.exe', '.com'])
39
40
    name, ext = os.path.splitext(filename)
41
    if ext and (ext in exe):  # pragma: nocover
42
        exe = []
43
44
    def match(filenames):
45
        res = set()
46
        for fname in filenames:
47
            if fname == filename:  # pragma: nocover
48
                res.add(fname)
49
                continue
50
51
            fn_name, fn_ext = os.path.splitext(fname)
52
            if name == fn_name:
53
                for suffix in exe:
54
                    if name + fn_ext == fname:
55
                        res.add(fname)
56
57
        return sorted(res)
58
59
    returnset = set()
60
    found = False
61
    for pth in get_path_directories():
62
        if not pth.strip():  # pragma: nocover
63
            continue
64
65
        if verbose:  # pragma: nocover
66
            print('checking pth..')
67
68
        try:
69
            fnames = os.listdir(pth)
70
        except:  # pragma: nocover
71
            continue
72
73
        matched = match(fnames)
74
75
        if matched:
76
            for m in matched:
77
                found_file = os.path.normcase(os.path.normpath(os.path.join(pth, m)))
78
                if found_file not in returnset:
79
                    if is_executable(found_file):
80
                        yield found_file
81
                    returnset.add(found_file)
82
            found = True
83
84
    if not found and interactive:  # pragma: nocover
85
        print("Couldn't find %r anywhere on the path.." % filename)
86
        sys.exit(1)
87
88
89
if __name__ == "__main__":  # pragma: nocover
90
    for _fname in which(sys.argv[1], interactive=True, verbose='-v' in sys.argv):
91
        print(_fname)
92
    sys.exit(0)
93