[bzr] Updated bzr tree_id to a more bzr-backwards implementation
[jhbuild.git] / jhbuild / versioncontrol / bzr.py
blobb5f7d2132cc2907260ef4e26f848ae8e802a9d9e
1 # jhbuild - a build script for GNOME 1.x and 2.x
2 # Copyright (C) 2001-2006 James Henstridge
4 # bzr.py: some code to handle various bazaar-ng operations
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 __all__ = []
21 __metaclass__ = type
23 import os
24 import errno
25 import urlparse
26 import logging
28 from jhbuild.errors import FatalError, CommandError
29 from jhbuild.utils.cmds import get_output
30 from jhbuild.versioncontrol import Repository, Branch, register_repo_type
31 from jhbuild.commands.sanitycheck import inpath
32 from jhbuild.utils.sxml import sxml
34 # Make sure that the urlparse module considers bzr://, bzr+ssh://, sftp:// and lp:
35 # scheme to be netloc aware and set to allow relative URIs.
36 if 'bzr' not in urlparse.uses_netloc:
37 urlparse.uses_netloc.append('bzr')
38 if 'bzr' not in urlparse.uses_relative:
39 urlparse.uses_relative.append('bzr')
40 if 'bzr+ssh' not in urlparse.uses_netloc:
41 urlparse.uses_netloc.append('bzr+ssh')
42 if 'bzr+ssh' not in urlparse.uses_relative:
43 urlparse.uses_relative.append('bzr+ssh')
44 if 'sftp' not in urlparse.uses_netloc:
45 urlparse.uses_netloc.append('sftp')
46 if 'sftp' not in urlparse.uses_relative:
47 urlparse.uses_relative.append('sftp')
48 if 'lp' not in urlparse.uses_relative:
49 urlparse.uses_relative.append('lp')
52 class BzrRepository(Repository):
53 """A class representing a Bzr repository.
55 It can be a parent of a number of Bzr repositories or branches.
56 """
58 init_xml_attrs = ['href', 'trunk-template', 'branches-template']
60 def __init__(self, config, name, href, trunk_template='%(module)s', branches_template='%(module)s/%(branch)s'):
61 Repository.__init__(self, config, name)
62 # allow user to adjust location of branch.
63 self.href = config.repos.get(name, href)
64 self.trunk_template = trunk_template
65 self.branches_template = branches_template
67 branch_xml_attrs = ['module', 'checkoutdir', 'revision', 'tag', 'user', 'revspec', 'branch']
69 def branch(self, name, module=None, checkoutdir=None, revision=None,
70 tag=None, user=None, revspec=None, branch=None, module_href=None):
71 if name in self.config.branches:
72 module_href = self.config.branches[name]
73 if not module_href:
74 raise FatalError(_('branch for %s has wrong override, check your .jhbuildrc') % name)
76 if module is None:
77 module = name
79 if revision or branch:
80 template = urlparse.urljoin(self.href, self.branches_template)
81 else:
82 template = urlparse.urljoin(self.href, self.trunk_template)
84 if not module_href:
85 module_href = template % {
86 'module': module,
87 'revision': revision,
88 'branch': branch,
89 'tag' : tag,
90 'user': user,
93 if checkoutdir is None:
94 checkoutdir = name
96 return BzrBranch(self, module_href, checkoutdir, tag, revspec)
98 def to_sxml(self):
99 return [sxml.repository(type='bzr', name=self.name, href=self.href,
100 trunk=self.trunk_template, branches=self.branches_template)]
102 class BzrBranch(Branch):
103 """A class representing a Bazaar branch."""
105 def __init__(self, repository, module_href, checkoutdir, tag, revspec):
106 Branch.__init__(self, repository, module_href, checkoutdir)
107 self._revspec = None
108 self.revspec = (tag, revspec)
110 def get_revspec(self):
111 return self._revspec
113 def set_revspec(self, (tag, revspec)):
114 if revspec:
115 self._revspec = ['-r%s' % revspec]
116 elif tag:
117 logging.info('tag ' + _('attribute is deprecated. Use revspec instead.'))
118 self._revspec = ['-rtag:%s' % tag]
119 elif self.config.sticky_date:
120 self._revspec = ['-rdate:%s' % self.config.sticky_date]
121 else:
122 self._revspec = []
123 revspec = property(get_revspec, set_revspec)
125 def srcdir(self):
126 return Branch.get_checkoutdir(self)
128 srcdir = property(srcdir)
130 def get_module_basename(self):
131 return self.checkoutdir
133 def branchname(self):
134 try:
135 return get_output(['bzr', 'nick', self.srcdir])
136 except:
137 return None
138 branchname = property(branchname)
140 def exists(self):
141 try:
142 get_output(['bzr', 'ls', self.module])
143 return True
144 except:
145 return False
147 def create_mirror(self, buildscript):
148 if not self.config.dvcs_mirror_dir:
149 return
150 if self.config.nonetwork:
151 return
153 if not os.path.exists(os.path.join(self.config.dvcs_mirror_dir, '.bzr')):
154 cmd = ['bzr', 'init-repo', '--no-trees', self.config.dvcs_mirror_dir]
155 buildscript.execute(cmd)
157 local_mirror = os.path.join(self.config.dvcs_mirror_dir, self.checkoutdir)
159 if not os.path.exists(local_mirror):
160 cmd = ['bzr', 'init', '--create-prefix', local_mirror]
161 buildscript.execute(cmd)
163 if os.path.exists(self.srcdir):
164 cmd = ['bzr', 'info', self.srcdir]
165 cwd = self.config.dvcs_mirror_dir
166 try:
167 info = get_output(cmd, cwd=cwd)
168 if info.find('checkout of branch: %s' % self.checkoutdir) == -1:
169 raise NameError
170 except:
171 raise FatalError(_("""
172 Path %s does not seem to be a checkout from dvcs_mirror_dir.
173 Remove it or change your dvcs_mirror_dir settings.""") % self.srcdir)
175 else:
176 cmd = ['bzr', 'co', '--light', mirror_href, self.srcdir]
177 buildscript.execute(cmd)
179 def _checkout(self, buildscript, copydir=None):
180 if self.config.dvcs_mirror_dir:
181 self.create_mirror(buildscript)
182 self.real_update(buildscript)
183 else:
184 cmd = ['bzr', 'branch'] + self.revspec + [self.module, self.srcdir]
185 buildscript.execute(cmd)
187 def _export(self, buildscript):
188 cmd = ['bzr', 'export'] + self.revspec + [self.srcdir, self.module]
189 buildscript.execute(cmd)
191 def real_update(self, buildscript):
192 cmd = ['bzr', 'pull'] + self.revspec + [self.module, '-d', self.srcdir]
193 buildscript.execute(cmd)
194 cmd = ['bzr', 'update'] + self.revspec + [self.srcdir]
196 def _update(self, buildscript, copydir=None):
197 self.create_mirror(buildscript)
198 self.real_update(buildscript)
200 def checkout(self, buildscript):
201 if not inpath('bzr', os.environ['PATH'].split(os.pathsep)):
202 raise CommandError(_('%s not found') % 'bzr')
203 Branch.checkout(self, buildscript)
205 def tree_id(self):
206 if not os.path.exists(self.srcdir):
207 return None
208 else:
209 try:
210 # --tree is relatively new (bzr 1.17)
211 cmd = ['bzr', 'revision-info', '--tree']
212 tree_id = get_output(cmd, cwd=self.srcdir).strip()
213 except:
214 cmd = ['bzr', 'revision-info']
215 tree_id = get_output(cmd, cwd=self.srcdir).strip()
216 return tree_id
218 def to_sxml(self):
219 attrs = {}
220 if self.revspec:
221 attrs = self.revspec()[0]
222 return [sxml.branch(repo=self.repository.name,
223 module=self.module,
224 revid=self.tree_id(),
225 **attrs)]
227 register_repo_type('bzr', BzrRepository)