Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/devbot/state.py
blob: 1a6e5b0a08328a293c4619cf21407f63cecade57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import hashlib
import os
import json

from devbot import config

_BUILT_MODULES = "builtmodules"
_FULL_BUILD = "fullbuild"
_SYSTEM_CHECK = "syscheck"


def built_module_touch(module):
    built_modules = _load_state(_BUILT_MODULES, {})

    source_hash = _compute_mtime_hash(module.get_source_dir())
    built_modules[module.name] = {"source_hash": source_hash}

    _save_state(_BUILT_MODULES, built_modules)


def built_module_is_unchanged(module):
    built_modules = _load_state(_BUILT_MODULES, {})
    if module.name not in built_modules:
        return False

    built_module = built_modules[module.name]
    if "source_hash" not in built_module:
        return False

    old_source_hash = built_module["source_hash"]
    new_source_hash = _compute_mtime_hash(module.get_source_dir())

    return old_source_hash == new_source_hash


def system_check_is_unchanged():
    system_check = _load_state(_SYSTEM_CHECK)
    if not system_check or not "config_hash" in system_check:
        return False

    config_hash = _compute_mtime_hash(config.config_dir)

    return system_check["config_hash"] == config_hash


def system_check_touch():
    system_check = _load_state(_SYSTEM_CHECK, {})

    config_hash = _compute_mtime_hash(config.config_dir)
    system_check["config_hash"] = config_hash

    _save_state(_SYSTEM_CHECK, system_check)


def full_build_is_required():
    full_build = _load_state(_FULL_BUILD)
    if not full_build:
        return True

    return not (full_build["last"] == config.get_full_build())


def full_build_touch():
    full_build = _load_state(_FULL_BUILD, {})
    full_build["last"] = config.get_full_build()
    _save_state(_FULL_BUILD, full_build)


def clean(build_only=False):
    print "* Deleting state"

    names = [_BUILT_MODULES, _FULL_BUILD]
    if not build_only:
        names.append(_SYSTEM_CHECK)

    for name in names:
        try:
            os.unlink(_get_state_path(name))
        except OSError:
            pass


def _get_state_path(name):
    return os.path.join(config.build_state_dir, "%s.json" % name)


def _load_state(name, default=None):
    state = default

    try:
        with open(_get_state_path(name)) as f:
            state = json.load(f)
    except IOError:
        pass

    return state


def _save_state(name, state):
    with open(_get_state_path(name), "w+") as f:
        json.dump(state, f, indent=4)
        f.write('\n')


def _compute_mtime_hash(path):
    # For some reason if path is unicode we
    # get a 10x slow down for some directories
    path = str(path)

    data = ""
    for root, dirs, files in os.walk(path):
        for name in files:
            path = os.path.join(root, name)
            mtime = os.lstat(path).st_mtime
            data = "%s%s %s\n" % (data, mtime, path)

    return hashlib.sha256(data).hexdigest()