Passed
Push — master ( 61e6a6...28b40d )
by Emmanuel
07:42
created

stakkr.services.install()   B

Complexity

Conditions 6

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 21
nop 3
dl 0
loc 27
ccs 0
cts 21
cp 0
crap 42
rs 8.4426
c 0
b 0
f 0
1
# coding: utf-8
2
"""
3
Manage Stakkr Packages (extra packages)
4
"""
5
6
from git import Repo, exc
7
from requests import head, HTTPError
8
9
__github_url__ = 'https://github.com/stakkr-org'
10
11
12
def install(services_dir: str, package: str, name: str):
13
    """Install a specific service by cloning a repo"""
14
    from os.path import isdir
15
    from urllib.parse import urlparse
16
17
    url = '{}/services-{}.git'.format(__github_url__, package)
18
    if urlparse(package).scheme != '':
19
        url = package
20
21
    path = '{}/{}'.format(services_dir, name)
22
    try:
23
        _check_repo_exists(url)
24
25
        if isdir(path):
26
            msg = 'Package "{}" is already installed, updating'.format(package)
27
            update_package(path)
28
            return True, msg
29
30
        Repo.clone_from(url, path)
31
32
        return True, None
33
    except HTTPError as error:
34
        return False, "Can't add package: {}".format(str(error))
35
    except ImportError:
36
        return False, 'Make sure git is installed'
37
    except exc.GitCommandError as error:
38
        return False, "Couldn't clone {} ({})".format(url, error)
39
40
41
def update_all(services_dir: str):
42
    """Update all services by pulling"""
43
    from os import listdir
44
45
    for folder in listdir(services_dir):
46
        path = services_dir + '/' + folder
47
        update_package(path)
48
49
50
def update_package(path: str):
51
    """Update a single service withgit pull"""
52
    try:
53
        repo = Repo(path)
54
        if repo.remotes.origin.url.endswith('.git'):
55
            repo.remotes.origin.pull()
56
    except exc.InvalidGitRepositoryError:
57
        pass
58
59
60
def _check_repo_exists(repo: str):
61
    status_code = head(repo, allow_redirects=True).status_code
62
    if status_code != 200:
63
        raise HTTPError("{} is not a valid repo (status = {})".format(repo, status_code))
64