source: tailor/vcpx/repository.py @ 552

Revision 552, 6.4 KB checked in by Robin Farine <robin.farine@…>, 8 years ago (diff)

Initial backend implementation for 'tla' aka Arch 1.x
The backend maps the tailor repository, module and start-revision
options to 'tla' archive, category--branch--version and revision.

Current limitations and pitfalls.

  • Target backend not implemented.
  • In-version continuations not supported (raises an exception); this would probably require to compute a changeset with 'tla delta' instead of using replay.
  • Pika escaped file names. This implementations requires a version of tla that supports pika escapes. For changesets created with a version of tla that did not support pika escapes, if one of these changeset contains a file name with a valid embedded pika escape sequence, things will break.
Line 
1# -*- mode: python; coding: utf-8 -*-
2# :Progetto: vcpx -- Configuration details about known repository kinds
3# :Creato:   gio 04 ago 2005 13:32:55 CEST
4# :Autore:   Lele Gaifax <lele@nautilus.homeip.net>
5# :Licenza:  GNU General Public License
6#
7
8"""
9This module holds a simple abstraction of what a repository is for
10Tailor purposes.
11"""
12
13__docformat__ = 'reStructuredText'
14
15class Repository(object):
16    """
17    Collector for the configuration of a single repository.
18    """
19
20    def __init__(self, name, kind, project, which):
21        self.name = name
22        self.kind = kind
23        self.project = project
24        self._load(project.config, which)
25
26    def __str__(self):
27        return "%s repository at %s%s" % (self.kind, self.repository,
28                                          self.module or '')
29
30    def _load(self, config, which):
31        """
32        Load the configuration for this repository.
33
34        The two main and mandatory attributes, ``repository`` and ``module``
35        can be specified either on the specific slot in the config file, or
36        as ``source-repository`` (or ``target-repository``) in its [DEFAULT]
37        section.
38
39        If the configuration does not specify a specific ``root-directory``
40        take the one from the project.
41        """
42
43        from os.path import split, expanduser
44
45        self.repository = config.get(self.name, 'repository') or \
46                          config.get(self.name, '%s-repository' % which)
47        if self.repository:
48            self.repository = expanduser(self.repository)
49        self.module = config.get(self.name, 'module') or \
50                      config.get(self.name, '%s-module' % which)
51        self.rootdir = config.get(self.name, 'root-directory',
52                                  self.project.rootdir)
53        self.subdir = config.get(self.name, 'subdir', self.project.subdir)
54
55    def _validateConfiguration(self):
56        """
57        Validate the configuration, possibly altering/completing it.
58        """
59
60    def log_info(self, what):
61        """
62        Print some info on the log and, in verbose mode, to stdout as well.
63        """
64
65        self.project.log_info(what)
66
67    def log_error(self, what, exc=False):
68        """
69        Print an error message, possibly with an exception traceback,
70        to the log and to stdout as well.
71        """
72
73        self.project.log_error(what, exc)
74
75    def workingDir(self):
76        """
77        Return an instance of the specific WorkingDir for this kind of
78        repository.
79        """
80
81        from source import InvocationError
82
83        self._validateConfiguration()
84
85        wdname = self.kind.capitalize() + 'WorkingDir'
86        modname = 'vcpx.' + self.kind
87        try:
88            wdmod = __import__(modname, globals(), locals(), [wdname])
89            workingdir = getattr(wdmod, wdname)
90        except (AttributeError, ImportError):
91            raise InvocationError("Unhandled source VCS kind: " + self.kind)
92
93        return workingdir(self)
94
95
96class ArxRepository(Repository):
97    METADIR = '_arx'
98    ARX_CMD = "arx"
99
100    def _load(self, config, which):
101        Repository._load(self, config, which)
102        self.ARX_CMD = config.get(self.name, 'arx-command', self.ARX_CMD)
103
104
105
106class BzrRepository(Repository):
107    METADIR = '.bzr'
108    BZR_CMD = 'bzr'
109
110    def _load(self, config, which):
111        Repository._load(self, config, which)
112        self.BZR_CMD = config.get(self.name, 'bzr-command', self.BZR_CMD)
113
114
115class CdvRepository(Repository):
116    METADIR = '.cdv'
117    CDV_CMD = 'cdv'
118
119    def _load(self, config, which):
120        Repository._load(self, config, which)
121        self.CDV_CMD = config.get(self.name, 'cdv-command', self.CDV_CMD)
122
123
124class CvsRepository(Repository):
125    METADIR = 'CVS'
126    CVS_CMD = 'cvs'
127
128    def _load(self, config, which):
129        Repository._load(self, config, which)
130        self.CVS_CMD = config.get(self.name, 'cvs-command', self.CVS_CMD)
131
132    def _validateConfiguration(self):
133        from os.path import split
134        from config import ConfigurationError
135
136
137        if not self.module and self.repository:
138            self.module = split(self.repository)[1]
139
140        if not self.module:
141            raise ConfigurationError("Must specify a repository and maybe a module also")
142
143class CvspsRepository(CvsRepository):
144    CVSPS_CMD = 'cvsps'
145
146    def _load(self, config, which):
147        CvsRepository._load(self, config, which)
148        self.CVSPS_CMD = config.get(self.name, 'cvsps-command', self.CVSPS_CMD)
149
150
151class DarcsRepository(Repository):
152    METADIR = '_darcs'
153    DARCS_CMD = 'darcs'
154
155    def _load(self, config, which):
156        Repository._load(self, config, which)
157        self.DARCS_CMD = config.get(self.name, 'darcs-command', self.DARCS_CMD)
158
159
160class HgRepository(Repository):
161    METADIR = '.hg'
162    HG_CMD = "hg"
163
164    def _load(self, config, which):
165        Repository._load(self, config, which)
166        self.HG_CMD = config.get(self.name, 'hg-command', self.HG_CMD)
167
168
169class MonotoneRepository(Repository):
170    METADIR = 'MT'
171    MONOTONE_CMD = "monotone"
172
173    def _load(self, config, which):
174        Repository._load(self, config, which)
175        self.MONOTONE_CMD = config.get(self.name,
176                                       'monotone-command', self.MONOTONE_CMD)
177        self.passphrase = config.get(self.name, 'passphrase')
178
179
180class SvnRepository(Repository):
181    METADIR = '.svn'
182    SVN_CMD = "svn"
183    SVNADMIN_CMD = "svnadmin"
184
185    def _load(self, config, which):
186        Repository._load(self, config, which)
187        self.SVN_CMD = config.get(self.name, 'svn-command', self.SVN_CMD)
188        self.SVNADMIN_CMD = config.get(self.name,
189                                       'svnadmin-command', self.SVNADMIN_CMD)
190        self.use_propset = config.get(self.name, 'use-propset', False)
191
192    def _validateConfiguration(self):
193        if not self.module:
194            raise ConfigurationError("Must the path within the "
195                                     "Subversion repository")
196
197        if not self.module.startswith('/'):
198            self.project.log_info("Prepending '/' to module")
199            self.module = '/' + self.module
200
201    def workingDir(self):
202        wd = Repository.workingDir(self)
203        wd.USE_PROPSET = self.use_propset
204        return wd
205
206
207class TlaRepository(Repository):
208    METADIR = '{arch}'
209    TLA_CMD = "tla"
210
211    def _load(self, config, which):
212        Repository._load(self, config, which)
213        self.TLA_CMD = config.get(self.name, 'tla-command', self.TLA_CMD)
Note: See TracBrowser for help on using the repository browser.