source: tailor/vcpx/target.py @ 85

Revision 85, 4.9 KB checked in by lele@…, 9 years ago (diff)

Some re-wording, tag the CVS changesets using only the timestamp

Line 
1#! /usr/bin/python
2# -*- mode: python; coding: utf-8 -*-
3# :Progetto: vcpx -- Syncable targets
4# :Creato:   ven 04 giu 2004 00:27:07 CEST
5# :Autore:   Lele Gaifax <lele@nautilus.homeip.net>
6#
7
8"""
9Syncronizable targets are the simplest abstract wrappers around a
10working directory under two different version control systems.
11"""
12
13__docformat__ = 'reStructuredText'
14
15import socket
16
17HOST = socket.getfqdn()
18AUTHOR = "tailor"
19BOOTSTRAP_PATCHNAME = 'Tailorization of %s'
20BOOTSTRAP_CHANGELOG = """\
21Import of the upstream sources from the repository
22
23 %(repository)s
24
25as of revision %(revision)s
26"""
27
28class TargetInitializationFailure(Exception):
29    pass
30
31class SyncronizableTargetWorkingDir(object):
32    """
33    This is an abstract working dir usable as a *shadow* of another
34    kind of VC, sharing the same working directory.
35
36    Most interesting entry points are:
37
38    replayChangeset
39        to replay an already applied changeset, to mimic the actions
40        performed by the upstream VC system on the tree such as
41        renames, deletions and adds.  This is an useful argument to
42        feed as `replay` to `applyUpstreamChangesets`
43
44    initializeNewWorkingDir
45        to initialize a pristine working directory tree under this VC
46        system, possibly extracted under a different kind of VC
47   
48    Subclasses MUST override at least the _underscoredMethods.
49    """
50
51    def replayChangeset(self, root, changeset):
52        """
53        Do whatever is needed to replay the changes under the target
54        VC, to register the already applied (under the other VC)
55        changeset.
56        """
57
58        self._replayChangeset(root, changeset)
59
60        from os.path import split
61
62        module = split(root)[1]
63       
64        remark = '%s: changeset %s' % (module, changeset.revision)
65        changelog = changeset.log
66        entries = [e.name for e in changeset.entries]
67        self._commit(root, changeset.date, changeset.author,
68                     remark, changelog, entries)
69
70    def _replayChangeset(self, root, changeset):
71        """
72        Replicate the actions performed by the changeset on the tree of
73        files.
74        """
75       
76        for e in changeset.entries:
77            if e.action_kind == e.RENAMED:
78                self._renameEntry(root, e.old_name, e.name)
79            elif e.action_kind == e.ADDED:
80                self._addEntry(root, e.name)
81            elif e.action_kind == e.DELETED:
82                self._removeEntry(root, e.name)
83       
84    def _addEntry(self, root, entry):
85        """
86        Add a new entry, maybe registering the directory as well.
87        """
88
89        raise "%s should override this method" % self.__class__
90
91    def _commit(self,root, date, author, remark, changelog=None, entries=None):
92        """
93        Commit the changeset.
94        """
95       
96        raise "%s should override this method" % self.__class__
97       
98    def _removeEntry(self, root, entry):
99        """
100        Remove an entry.
101        """
102
103        raise "%s should override this method" % self.__class__
104
105    def _renameEntry(self, root, oldentry, newentry):
106        """
107        Rename an entry.
108        """
109
110        raise "%s should override this method" % self.__class__
111
112    def initializeNewWorkingDir(self, root, repository, module, revision):
113        """
114        Initialize a new working directory, just extracted from
115        some other VC system, importing everything's there.
116        """
117
118        from datetime import datetime
119
120        now = datetime.now()
121        self._initializeWorkingDir(root, module)
122        self._commit(root, now, '%s@%s' % (AUTHOR, HOST),
123                     BOOTSTRAP_PATCHNAME % module,
124                     BOOTSTRAP_CHANGELOG % locals(),
125                     entries=[module])
126
127    def _initializeWorkingDir(self, root, module, addentry=None):
128        """
129        Assuming the `root` directory contains a working copy `module`
130        extracted from some VC repository, add it and all its content
131        to the target repository.
132
133        This implementation first runs the given `addentry`
134        *SystemCommand* on the `root` directory, then it walks down
135        the `root` tree executing the same command on each entry
136        excepted the usual VC-specific control directories such as
137        ``.svn``, ``_darcs`` or ``CVS``.
138
139        If this does make sense, subclasses should just call this
140        method with the right `addentry` command.
141        """
142
143        assert addentry, "Subclass should have specified something as addentry"
144       
145        from os.path import split, join
146        from os import walk
147
148        c = addentry(working_dir=root)
149        c(entry=repr(module))
150
151        for dir, subdirs, files in walk(join(root, module)):
152            for excd in ['.svn', '_darcs', 'CVS']:
153                if excd in subdirs:
154                    subdirs.remove(excd)
155
156            c = addentry(working_dir=dir)
157            for d in subdirs+files:
158                c(entry=repr(d))
159
Note: See TracBrowser for help on using the repository browser.