| 1 | # -*- mode: python; coding: utf-8 -*- |
|---|
| 2 | # :Progetto: vcpx -- Darcs details |
|---|
| 3 | # :Creato: ven 18 giu 2004 14:45:28 CEST |
|---|
| 4 | # :Autore: Lele Gaifax <lele@nautilus.homeip.net> |
|---|
| 5 | # :Licenza: GNU General Public License |
|---|
| 6 | # |
|---|
| 7 | |
|---|
| 8 | """ |
|---|
| 9 | This module contains supporting classes for the ``darcs`` versioning system. |
|---|
| 10 | """ |
|---|
| 11 | |
|---|
| 12 | __docformat__ = 'reStructuredText' |
|---|
| 13 | |
|---|
| 14 | import re |
|---|
| 15 | |
|---|
| 16 | from vcpx.repository import Repository |
|---|
| 17 | from vcpx.shwrap import ExternalCommand, PIPE |
|---|
| 18 | from vcpx.target import TargetInitializationFailure |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | class DarcsRepository(Repository): |
|---|
| 22 | METADIR = '_darcs' |
|---|
| 23 | |
|---|
| 24 | # Darcs needs the deletion, because of the new way the backend assemble |
|---|
| 25 | # the new patches by writing directly to the pending file. |
|---|
| 26 | EXTRA_RSYNC_FLAGS = ['--delete'] |
|---|
| 27 | |
|---|
| 28 | def _load(self, project): |
|---|
| 29 | from os.path import join |
|---|
| 30 | |
|---|
| 31 | Repository._load(self, project) |
|---|
| 32 | cget = project.config.get |
|---|
| 33 | self.EXECUTABLE = cget(self.name, 'darcs-command', 'darcs') |
|---|
| 34 | self._darcs_version = None |
|---|
| 35 | init_options = cget(self.name, 'init-options', '') |
|---|
| 36 | if init_options: |
|---|
| 37 | self.init_options = tuple(init_options.split(' ')) |
|---|
| 38 | else: |
|---|
| 39 | self.init_options = None |
|---|
| 40 | self.use_look_for_adds = cget(self.name, 'look-for-adds', 'False') |
|---|
| 41 | self.metadir = join(self.basedir, cget( |
|---|
| 42 | self.name, 'metadir', self.METADIR)) |
|---|
| 43 | self.split_initial_import_level = int( |
|---|
| 44 | cget(self.name, 'split-initial-changeset-level', '0')) |
|---|
| 45 | self.replace_badchars = eval(cget(self.name, 'replace-badchars', |
|---|
| 46 | "{" |
|---|
| 47 | "'\xb4': '´'," |
|---|
| 48 | "'\xc1': 'Á'," |
|---|
| 49 | "'\xc4': 'Ä'," |
|---|
| 50 | "'\xc5': 'Å'," |
|---|
| 51 | "'\xc9': 'É'," |
|---|
| 52 | "'\xcd': 'Í'," |
|---|
| 53 | "'\xd3': 'Ó'," |
|---|
| 54 | "'\xd5': 'Ő'," |
|---|
| 55 | "'\xd6': 'Ö'," |
|---|
| 56 | "'\xda': 'Ú'," |
|---|
| 57 | "'\xdb': 'Ű'," |
|---|
| 58 | "'\xdc': 'Ü'," |
|---|
| 59 | "'\xdf': 'ß'," |
|---|
| 60 | "'\xe1': 'á'," |
|---|
| 61 | "'\xe5': 'å'," |
|---|
| 62 | "'\xe9': 'é'," |
|---|
| 63 | "'\xed': 'í'," |
|---|
| 64 | "'\xf1': 'ñ'," |
|---|
| 65 | "'\xf3': 'ó'," |
|---|
| 66 | "'\xf5': 'ő'," |
|---|
| 67 | "'\xf6': 'ö'," |
|---|
| 68 | "'\xfa': 'ú'," |
|---|
| 69 | "'\xfb': 'ű'," |
|---|
| 70 | "'\xfc': 'ü'," |
|---|
| 71 | "}")) |
|---|
| 72 | |
|---|
| 73 | @property |
|---|
| 74 | def darcs_version(self): |
|---|
| 75 | if self._darcs_version is None: |
|---|
| 76 | cmd = self.command('--version') |
|---|
| 77 | version = ExternalCommand(command=cmd) |
|---|
| 78 | self._darcs_version = version.execute(stdout=PIPE)[0].read().strip() |
|---|
| 79 | self.log.debug('Using %s, version %s', self.EXECUTABLE, self._darcs_version) |
|---|
| 80 | return self._darcs_version |
|---|
| 81 | |
|---|
| 82 | def command(self, *args, **kwargs): |
|---|
| 83 | if args[0] == 'record' and self.use_look_for_adds: |
|---|
| 84 | args = args + ('--look-for-adds',) |
|---|
| 85 | elif args[0] == 'initialize' and self.init_options: |
|---|
| 86 | args = args + self.init_options |
|---|
| 87 | return Repository.command(self, *args, **kwargs) |
|---|
| 88 | |
|---|
| 89 | def create(self): |
|---|
| 90 | from vcpx.dualwd import IGNORED_METADIRS |
|---|
| 91 | from os.path import join |
|---|
| 92 | |
|---|
| 93 | cmd = self.command("initialize") |
|---|
| 94 | init = ExternalCommand(cwd=self.basedir, command=cmd) |
|---|
| 95 | init.execute() |
|---|
| 96 | |
|---|
| 97 | if init.exit_status: |
|---|
| 98 | raise TargetInitializationFailure( |
|---|
| 99 | "%s returned status %s" % (str(init), init.exit_status)) |
|---|
| 100 | |
|---|
| 101 | prefsdir = join(self.metadir, 'prefs') |
|---|
| 102 | prefsname = join(prefsdir, 'prefs') |
|---|
| 103 | boringname = join(prefsdir, 'boring') |
|---|
| 104 | |
|---|
| 105 | boring = open(boringname, 'rU') |
|---|
| 106 | ignored = boring.read().rstrip().split('\n') |
|---|
| 107 | boring.close() |
|---|
| 108 | |
|---|
| 109 | # Augment the boring file, that contains a regexp per line |
|---|
| 110 | # with all known VCs metadirs to be skipped. |
|---|
| 111 | ignored.extend(['(^|/)%s($|/)' % re.escape(md) |
|---|
| 112 | for md in IGNORED_METADIRS]) |
|---|
| 113 | |
|---|
| 114 | # Eventually omit our own log... |
|---|
| 115 | logfile = self.projectref().logfile |
|---|
| 116 | if logfile.startswith(self.basedir): |
|---|
| 117 | ignored.append('^%s$' % |
|---|
| 118 | re.escape(logfile[len(self.basedir)+1:])) |
|---|
| 119 | |
|---|
| 120 | # ... and state file |
|---|
| 121 | sfname = self.projectref().state_file.filename |
|---|
| 122 | if sfname.startswith(self.basedir): |
|---|
| 123 | sfrelname = sfname[len(self.basedir)+1:] |
|---|
| 124 | ignored.append('^%s$' % re.escape(sfrelname)) |
|---|
| 125 | ignored.append('^%s$' % re.escape(sfrelname+'.old')) |
|---|
| 126 | ignored.append('^%s$' % re.escape(sfrelname+'.journal')) |
|---|
| 127 | |
|---|
| 128 | boring = open(boringname, 'w') |
|---|
| 129 | boring.write('\n'.join(ignored)) |
|---|
| 130 | boring.write('\n') |
|---|
| 131 | boring.close() |
|---|