Package pybaz :: Package backends :: Module baz
[frames] | no frames]

Source Code for Module pybaz.backends.baz

  1  # arch-tag: david@allouche.net - 2003-11-17 15:29:01 469107000 
  2  # Copyright (C) 2003  John Goerzen, David Allouche 
  3  # <jgoerzen@complete.org> <david@allouche.net> 
  4  # 
  5  #    This program is free software; you can redistribute it and/or modify 
  6  #    it under the terms of the GNU General Public License as published by 
  7  #    the Free Software Foundation; either version 2 of the License, or 
  8  #    (at your option) any later version. 
  9  # 
 10  #    This program is distributed in the hope that it will be useful, 
 11  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  #    GNU General Public License for more details. 
 14  # 
 15  #    You should have received a copy of the GNU General Public License 
 16  #    along with this program; if not, write to the Free Software 
 17  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 18   
 19  """Construction of tla commands 
 20  """ 
 21   
 22  import os.path 
 23  from pybaz.pathname import DirName, FileName 
 24  from pybaz import errors 
 25  from pybaz._escaping import * 
 26  from pybaz._nameparser import NameParser 
 27   
 28  tlasyn = None 
 29  tlaobj = None 
 30   
 31   
32 -def gettlasyntax():
33 global tlasyn, tlaobj 34 if tlasyn != None: 35 return tlasyn 36 if text_cmd(['-V']).splitlines()[0].find('tla-1.0.') != -1: 37 tlasyn = '1.0' 38 tlaobj = Tla10() 39 else: 40 tlasyn = '1.1' 41 tlaobj = Tla11() 42 tlaobj.name_escaping = (0 == status_cmd(['escape'], (0,1))) 43 return tlasyn
44 45
46 -class Tla10:
47 tagging_method = 'tagging-method' 48 add = 'add-tag' 49 move = 'move-tag' 50 delete = 'delete-tag' 51 update = 'update --in-place .' 52 replay = 'replay --in-place .' 53 log_versions = 'logs' 54 log_ls = 'log-ls' 55 merges = None 56 get_changeset = 'get-patch'
57 58
59 -class Tla11:
60 tagging_method = 'id-tagging-method' 61 add = 'add' 62 move = 'move' 63 delete = 'delete' 64 update = 'update' 65 replay = 'replay' 66 log_versions = 'log-versions' 67 log_ls = 'logs' 68 merges = 'merges' 69 get_changeset = 'get-changeset'
70 71
72 -def cmd():
73 global tlaobj 74 gettlasyntax() 75 return tlaobj
76 77 78 ### Utility functions ### 79
80 -def _check_expected_param(expected):
81 msg_format = ("'expected' param must be a sequence of positive" 82 " integers but was: %r") 83 try: 84 iterator = iter(expected) 85 except TypeError: 86 raise TypeError, msg_format % expected 87 for status in iterator: 88 if not isinstance(status, int): 89 raise TypeError, msg_format % expected 90 if status < 0: 91 raise ValueError, msg_format % expected
92 93 94 ### Subrocess spawning ### 95
96 -def _backend():
97 import pybaz 98 return pybaz.backend
99
100 -def null_cmd(args, chdir=None):
101 """Deprecated, for internal use only.""" 102 _backend().null_cmd(args, chdir)
103
104 -def one_cmd(args, chdir=None):
105 """Deprecated, for internal use only.""" 106 return _backend().one_cmd(args, chdir)
107
108 -def sequence_cmd(args, chdir=None, expected=(0,)):
109 """Deprecated, for internal use only.""" 110 return _backend().sequence_cmd(args, expected, chdir)
111
112 -def text_cmd(args, chdir=None):
113 """Deprecated, for internal use only.""" 114 return _backend().text_cmd(args, chdir)
115
116 -def status_cmd(args, expected):
117 """Deprecated, for internal use only.""" 118 return _backend().status_cmd(args, expected)
119
120 -def status_one_cmd(args, chdir, expected):
121 """Deprecated, for internal use only.""" 122 return _backend().status_one_cmd(args, expected, chdir)
123
124 -def status_text_cmd(args, expected):
125 """Deprecated, for internal use only.""" 126 return _backend().status_text_cmd(args, expected)
127 128 129 ### tla commands ### 130 131 # User Commands 132
133 -def default_archive():
134 status, output = status_one_cmd(('my-default-archive',), None, (0,1)) 135 if status != 0: return None 136 return output
137 138
139 -def set_default_archive(archive):
140 null_cmd(('my-default-archive', archive))
141 142 143 # Project Tree commands 144
145 -def init_tree(dir, version=None, nested=False):
146 args = ['init-tree', '--dir', dir] 147 if nested: args.append('--nested') 148 if version is not None: args.append(version) 149 null_cmd(args)
150
151 -def tree_root(dir):
152 status, output = status_text_cmd(('tree-root', dir), (0,1)) 153 if status == 1: raise errors.TreeRootError(dir) 154 return output[:-1]
155
156 -def sync_tree(dir, revision):
157 null_cmd(('sync-tree', '--dir', dir, revision))
158
159 -def resolved(dir, all=False):
160 args = ['resolved', '--dir', dir] 161 if all: 162 args.append('--all') 163 null_cmd(args)
164
165 -def undo(dir, revision=None, output=None, quiet=False, throw_away=False):
166 args = ['undo', '--dir', dir] 167 if quiet: args.append('--quiet') 168 if throw_away: 169 args.append('--no-output') 170 elif output: 171 args.extend(('--output', output)) 172 if revision: args.append(revision) 173 null_cmd(args)
174
175 -def log_for_merge(dir):
176 args = ['log-for-merge', '--dir', dir] 177 return text_cmd(args)
178 179
180 -def redo(dir, patch=None, keep=False, quiet=False):
181 args = ['redo', '--dir', dir] 182 if quiet: args.append('--quiet') 183 if keep: args.append('--keep') 184 if patch: args.extend(('--patch', patch)) 185 null_cmd(args)
186
187 -def update(dir):
188 """FIXME: add the other parameters.""" 189 ### Correct implementation 190 # args = ['update', '--dir', dir] 191 # return null_cmd(args) 192 ### Work around bug in tla 1.2.1 193 null_cmd(['update'], chdir=dir)
194
195 -def replay(dir):
196 """FIXME: add the other parameters.""" 197 args = ['replay', '--dir', dir] 198 null_cmd(args)
199 200 201 # Project Tree Inventory commands 202
203 -def tagging_method(dir):
204 return one_cmd((cmd().tagging_method, '--dir', dir))
205
206 -def set_tagging_method(dir, method):
207 null_cmd((cmd().tagging_method, '--dir', dir, method))
208
209 -def add(file):
210 null_cmd((cmd().add, file))
211
212 -def delete(file):
213 null_cmd((cmd().delete, file))
214
215 -def move(src, dest):
216 return null_cmd((cmd().move, src, dest))
217 218 219 # Patch Set Commands 220
221 -def changeset(orig, mod, dest, files=()):
222 return null_cmd(('changeset', orig, mod, dest) + files)
223 224 225 # Archive Transaction Commands 226
227 -def get_patch(revision, dir):
228 P = NameParser(revision) 229 # XXX Work around bug in 1.2.2rc2 and corresponding integration revisions 230 # XXX where get-changeset would fail with "no default archive set". 231 args = [cmd().get_changeset, '-A', P.get_archive(), P.get_nonarch(), dir] 232 null_cmd(args)
233 234 # Archive Commands 235
236 -def cacherev(revision, cache=None):
237 if cache is None: 238 return null_cmd(('cacherev', revision)) 239 else: 240 return null_cmd(('cacherev', '--cache', cache, revision))
241 242
243 -def cachedrevs(version):
244 return sequence_cmd(('cachedrevs', version))
245 246
247 -def uncacherev(revision):
248 null_cmd(('uncacherev', revision))
249 250
251 -def iter_merges(version1, version2=None, reverse=False, metoo=True):
252 subcmd = cmd().merges 253 if subcmd is None: 254 raise NotImplementedError, \ 255 "merges is not implemented in tla 1.0""" 256 args = [ subcmd ] 257 if reverse: args.append('--reverse') 258 args.append('--full') 259 args.append(version1) 260 if version2 is not None: args.append(version2) 261 for line in sequence_cmd(args): 262 target, source = line.split('\t') 263 if metoo or '%s--%s' % (version1, target) != source: 264 yield target, source
265 266 267 # Patch Log Commands 268
269 -def make_log(dir):
270 return text_cmd(('make-log', '--dir', dir))[:-1]
271
272 -def add_log_version(dir, version):
273 null_cmd(('add-log-version', '--dir', dir, version))
274
275 -def remove_log_version(dir, version):
276 null_cmd(('remove-log-version', '--dir', dir, version))
277 278
279 -def iter_log_versions(dir, reverse=False, 280 archive=None, category=None, branch=None, version=None):
281 opts = (cmd().log_versions, '--dir', dir) 282 if reverse: opts += ('--reverse',) 283 if archive: opts += ('--archive', archive) 284 if category: opts += ('--category', category) 285 if branch: opts += ('--branch', branch) 286 if version: opts += ('--vsn', version) 287 return sequence_cmd(opts)
288 289
290 -def iter_log_ls(dir, version, reverse=False):
291 opts = [ cmd().log_ls, '--full', '--dir', dir ] 292 if reverse: opts.append('--reverse') 293 opts.append(version) 294 return sequence_cmd(opts)
295 296 297 # Multi-project Configuration Commands 298 299 # Commands for Branching and Merging 300
301 -def tag(source_revision, tag_version):
302 null_cmd(('branch', source_revision, tag_version))
303 304 305 # Local Cache Commands 306
307 -def file_find(tree, file_name, revision):
308 args = ('file-find', '--new-file', file_name, revision) 309 # XXX Work around missing --silent option, ignore chatter 310 output = text_cmd(args, chdir=tree) 311 path = output.splitlines()[-1] 312 if path == '/dev/null': return None 313 if cmd().name_escaping: 314 return name_unescape(path) 315 else: 316 return path
317
318 -def iter_pristines(dir_name):
319 args = ('pristines', '--dir', dir_name) 320 return sequence_cmd(args)
321
322 -def add_pristine(dir_name, revision):
323 args = ('add-pristine', '--dir', dir_name, revision) 324 null_cmd(args)
325
326 -def find_pristine(dir_name, revision):
327 args = ('find-pristine', '--dir', dir_name, revision) 328 return one_cmd(args)
329 330 331 # Revision Library Commands 332
333 -def iter_revision_libraries():
334 args = ('my-revision-library', '--silent') 335 return sequence_cmd(args, expected=(0,1))
336
337 -def register_revision_library(dirname):
338 null_cmd(('my-revision-library', '--silent', dirname))
339
340 -def unregister_revision_library(dirname):
341 null_cmd(('my-revision-library', '--silent', '--delete', dirname))
342
343 -def library_archives():
344 return sequence_cmd(('library-archives',))
345
346 -def library_categories(archive):
347 return sequence_cmd(('library-categories', '--archive', archive))
348
349 -def library_branches(category):
350 return sequence_cmd(('library-branches', category))
351
352 -def library_versions(branch, reverse=False):
353 if not reverse: 354 return sequence_cmd(('library-versions', branch)) 355 else: 356 return sequence_cmd(('library-versions', '--reverse', branch))
357
358 -def library_revisions(version, reverse=False):
359 if not reverse: 360 return sequence_cmd(('library-revisions', version)) 361 else: 362 return sequence_cmd(('library-revisions', '--reverse', version))
363 364
365 -def library_add(revision):
366 null_cmd(('library-add', revision))
367
368 -def library_remove(revision):
369 null_cmd(('library-remove', revision))
370
371 -def library_find(revision):
372 return text_cmd(('library-find', revision))[:-1]
373 374 375 ### Pika escaping ### 376
377 -def tla_name_escape(text):
378 return text_cmd(('escape', text))
379
380 -def tla_name_unescape(text):
381 return text_cmd(('escape', '--unescaped', text))
382 383 384 ### Misc features ### 385
386 -def in_tree(dir):
387 """Return True if dir is, or is inside, a Arch source tree.""" 388 # Must use tree-root and not tree-version because the tree-version 389 # may be unset (after init-tree) 390 status = status_cmd(('tree-root', dir), expected=(0,1)) 391 return not status
392 393
394 -def has_explicit_id(path):
395 assert os.path.exists(path) 396 arch_ids = DirName('.arch-ids') 397 if os.path.isfile(path): 398 dir_, base = FileName(path).splitname() 399 return os.path.exists(dir_/arch_ids/(base+'.id')) 400 if os.path.isdir(path): 401 return os.path.exists(DirName(path)/arch_ids/'=id') 402 raise AssertionError, 'not regular file or directory: ' + path
403