/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
7490.109.1 by Jelmer Vernooij
Add a workspace module.
1
#!/usr/bin/python3
2
# Copyright (C) 2019 Jelmer Vernooij
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
18
"""Track whether a directory structure was touched since last revision.
19
"""
20
7490.109.5 by Jelmer Vernooij
Enable absolute import.
21
from __future__ import absolute_import
22
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
23
# TODO(jelmer): Add support for ignore files
7490.109.1 by Jelmer Vernooij
Add a workspace module.
24
25
import os
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
26
try:
27
    from pyinotify import (
28
        WatchManager,
29
        IN_CREATE,
30
        IN_CLOSE_WRITE,
31
        IN_Q_OVERFLOW,
32
        IN_DELETE,
33
        IN_MOVED_TO,
34
        IN_MOVED_FROM,
35
        IN_ATTRIB,
36
        ProcessEvent,
37
        Notifier,
38
        Event,
39
        )
40
except ImportError as e:
41
    from .errors import DependencyNotPresent
42
    raise DependencyNotPresent(library='pyinotify', error=e)
7490.109.1 by Jelmer Vernooij
Add a workspace module.
43
44
45
MASK = (
46
    IN_CLOSE_WRITE | IN_DELETE | IN_Q_OVERFLOW | IN_MOVED_TO | IN_MOVED_FROM |
47
    IN_ATTRIB)
48
49
50
class _Process(ProcessEvent):
51
52
    def my_init(self):
53
        self.paths = set()
54
        self.created = set()
55
56
    def process_default(self, event):
57
        path = os.path.join(event.path, event.name)
58
        if event.mask & IN_CREATE:
59
            self.created.add(path)
60
        self.paths.add(path)
61
        if event.mask & IN_DELETE and path in self.created:
62
            self.paths.remove(path)
63
            self.created.remove(path)
64
65
66
class DirtyTracker(object):
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
67
    """Track the changes to (part of) a working tree."""
7490.109.1 by Jelmer Vernooij
Add a workspace module.
68
69
    def __init__(self, tree, subpath='.'):
70
        self._tree = tree
71
        self._wm = WatchManager()
72
        self._process = _Process()
73
        self._notifier = Notifier(self._wm, self._process)
74
        self._notifier.coalesce_events(True)
75
76
        def check_excluded(p):
77
            return tree.is_control_filename(tree.relpath(p))
78
        self._wdd = self._wm.add_watch(
79
            tree.abspath(subpath), MASK, rec=True, auto_add=True,
80
            exclude_filter=check_excluded)
81
82
    def _process_pending(self):
83
        if self._notifier.check_events(timeout=0):
84
            self._notifier.read_events()
85
        self._notifier.process_events()
86
87
    def __del__(self):
88
        self._notifier.stop()
89
90
    def mark_clean(self):
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
91
        """Mark the subtree as not having any changes."""
7490.109.1 by Jelmer Vernooij
Add a workspace module.
92
        self._process_pending()
93
        self._process.paths.clear()
94
        self._process.created.clear()
95
96
    def is_dirty(self):
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
97
        """Check whether there are any changes."""
7490.109.1 by Jelmer Vernooij
Add a workspace module.
98
        self._process_pending()
99
        return bool(self._process.paths)
100
101
    def paths(self):
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
102
        """Return the paths that have changed."""
7490.109.1 by Jelmer Vernooij
Add a workspace module.
103
        self._process_pending()
104
        return self._process.paths
105
106
    def relpaths(self):
7490.109.2 by Jelmer Vernooij
Update NEWS, add tests.
107
        """Return the paths relative to the tree root that changed."""
7490.109.1 by Jelmer Vernooij
Add a workspace module.
108
        return set(self._tree.relpath(p) for p in self.paths())