~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to baz2bzr

  • Committer: Aaron Bentley
  • Date: 2005-06-08 22:51:36 UTC
  • Revision ID: abentley@bruiser-20050608225136-c900df20f33fb550
Updated copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
import os.path
31
31
import shutil
32
32
import bzrlib
 
33
from bzrlib.errors import BzrError
33
34
import bzrlib.trace
34
35
import bzrlib.merge
35
36
import sys
61
62
    >>> os.path.exists(q)
62
63
    False
63
64
    """
64
 
    tdir = tempfile.mkdtemp(prefix="baz2bzr-")
 
65
    tdir = tempfile.mkdtemp(prefix="testdir-")
65
66
    os.environ["HOME"] = os.path.join(tdir, "home")
66
67
    os.mkdir(os.environ["HOME"])
67
68
    arch_dir = os.path.join(tdir, "archive_dir")
155
156
    add_file("ofile", "this is another file", "ofile by aaron")
156
157
    commit(tree, "altered mainfile")
157
158
 
 
159
 
 
160
def commit_more_test_revisions():
 
161
    """
 
162
    >>> q = test_environ()
 
163
    >>> commit_test_revisions()
 
164
    >>> commit_more_test_revisions()
 
165
    >>> a = pybaz.Archive("test@example.com")
 
166
    >>> revisions = list(a.iter_revisions("test--test--0"))
 
167
    >>> len(revisions)
 
168
    4
 
169
    >>> str(revisions[0])
 
170
    'test@example.com/test--test--0--patch-3'
 
171
    >>> teardown_environ(q)
 
172
    """
 
173
    tree = pybaz.tree_root(".")
 
174
    add_file("trainfile", "void train(void){}", "trainfile by aaron")
 
175
    commit(tree, "altered trainfile")
 
176
 
 
177
class NoSuchVersion(Exception):
 
178
    def __init__(self, version):
 
179
        Exception.__init__(self, "The version %s does not exist." % version)
 
180
        self.version = version
 
181
 
158
182
def version_ancestry(version):
159
183
    """
160
184
    >>> q = test_environ()
165
189
    'test@example.com/test--test--0--base-0'
166
190
    >>> str(ancestors[1])
167
191
    'test@example.com/test--test--0--patch-1'
 
192
    >>> version = pybaz.Version("test@example.com/test--test--0.5")
 
193
    >>> ancestors = version_ancestry(version)
 
194
    Traceback (most recent call last):
 
195
    NoSuchVersion: The version test@example.com/test--test--0.5 does not exist.
168
196
    >>> teardown_environ(q)
169
197
    """
170
 
    revision = version.iter_revisions(reverse=True).next()
 
198
    try:
 
199
        revision = version.iter_revisions(reverse=True).next()
 
200
    except:
 
201
        if not version.exists():
 
202
            raise NoSuchVersion(version)
 
203
        else:
 
204
            raise
171
205
    ancestors = list(revision.iter_ancestors(metoo=True))
172
206
    ancestors.reverse()
173
207
    return ancestors
174
208
 
 
209
def get_last_revision(branch):
 
210
    last_patch = branch.last_patch()
 
211
    try:
 
212
        return arch_revision(last_patch)
 
213
    except NotArchRevision:
 
214
        raise UserError(
 
215
            "Directory \"%s\" already exists, and the last revision is not"
 
216
            " an Arch revision (%s)" % (output_dir, last_patch))
 
217
 
 
218
 
175
219
def get_remaining_revisions(output_dir, version):
176
220
    last_patch = None
177
221
    old_revno = None
178
222
    if os.path.exists(output_dir):
179
223
        # We are starting from an existing directory, figure out what
180
224
        # the current version is
181
 
        branch = bzrlib.Branch(output_dir)
182
 
        last_patch = branch.last_patch()
183
 
        try:
184
 
            last_patch = arch_revision(last_patch)
185
 
        except NotArchRevision:
186
 
            raise UserError(
187
 
                "Directory \"%s\" already exists, and the last revision is not"
188
 
                " an Arch revision (%s)" % (output_dir, last_patch))
 
225
        branch = find_branch(output_dir)
 
226
        last_patch = get_last_revision(branch)
189
227
        if version is None:
190
228
            version = last_patch.version
191
229
    elif version is None:
192
230
        raise UserError("No version specified, and directory does not exist.")
193
231
 
194
 
    ancestors = version_ancestry(version)
 
232
    try:
 
233
        ancestors = version_ancestry(version)
 
234
    except NoSuchVersion, e:
 
235
        raise UserError(e)
195
236
 
196
237
    if last_patch:
197
238
        for i in range(len(ancestors)):
204
245
        # Strip off all of the ancestors which are already present
205
246
        # And get a directory starting with the latest ancestor
206
247
        latest_ancestor = ancestors[i]
207
 
        old_revno = bzrlib.Branch(output_dir).revno()
 
248
        old_revno = find_branch(output_dir).revno()
208
249
        ancestors = ancestors[i+1:]
209
250
    return ancestors, old_revno
210
251
 
214
255
    >>> q = test_environ()
215
256
    >>> result_path = os.path.join(q, "result")
216
257
    >>> commit_test_revisions()
 
258
    >>> version = pybaz.Version("test@example.com/test--test--0.1")
 
259
    >>> import_version('/', version, fancy=False, dry_run=True)
 
260
    Traceback (most recent call last):
 
261
    UserError: / exists, but is not a bzr branch.
 
262
    >>> import_version(result_path, version, fancy=False, dry_run=True)
 
263
    Traceback (most recent call last):
 
264
    UserError: The version test@example.com/test--test--0.1 does not exist.
217
265
    >>> version = pybaz.Version("test@example.com/test--test--0")
218
 
    >>> import_version(result_path, version, fancy=False)
219
 
    not fancy
220
 
    ....
 
266
    >>> import_version(result_path, version, fancy=False, dry_run=True)
 
267
    not fancy
 
268
    ....
 
269
    Dry run, not modifying output_dir
 
270
    Cleaning up
 
271
    >>> import_version(result_path, version, fancy=False)
 
272
    not fancy
 
273
    ....
 
274
    Cleaning up
 
275
    Import complete.
 
276
    >>> import_version(result_path, version, fancy=False)
 
277
    Tree is up-to-date with test@example.com/test--test--0--patch-2
 
278
    >>> commit_more_test_revisions()
 
279
    >>> import_version(result_path, version, fancy=False)
 
280
    not fancy
 
281
    ..
221
282
    Cleaning up
222
283
    Import complete.
223
284
    >>> teardown_environ(q)
224
285
    """
225
 
    ancestors, old_revno = get_remaining_revisions(output_dir, version)
 
286
    try:
 
287
        ancestors, old_revno = get_remaining_revisions(output_dir, version)
 
288
    except NotInABranch, e:
 
289
        raise UserError("%s exists, but is not a bzr branch." % e.path)
226
290
    if len(ancestors) == 0:
227
 
        print '* Tree is up-to-date with %s' % last_patch
228
 
        return 0
 
291
        last_revision = get_last_revision(find_branch(output_dir))
 
292
        print 'Tree is up-to-date with %s' % last_revision
 
293
        return
229
294
 
230
295
    progress_bar = ProgressBar()
231
296
    tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
233
298
    try:
234
299
        if not fancy:
235
300
            print "not fancy"
236
 
        for result in iter_import_version(output_dir, ancestors, tempdir,
237
 
                fast=fast, verbose=verbose, dry_run=dry_run, 
238
 
                max_count=max_count, skip_symlinks=skip_symlinks):
 
301
        try:
 
302
            for result in iter_import_version(output_dir, ancestors, tempdir,
 
303
                    fast=fast, verbose=verbose, dry_run=dry_run, 
 
304
                    max_count=max_count, skip_symlinks=skip_symlinks):
 
305
                if fancy:
 
306
                    progress_bar(result)
 
307
                else:
 
308
                    sys.stdout.write('.')
 
309
        finally:
239
310
            if fancy:
240
 
                progress_bar(result)
 
311
                clear_progress_bar()
241
312
            else:
242
 
                sys.stdout.write('.')
 
313
                sys.stdout.write('\n')
243
314
 
244
315
        if dry_run:
245
 
            print '**Dry run, not modifying output_dir'
246
 
            return 0
 
316
            print 'Dry run, not modifying output_dir'
 
317
            return
247
318
        if os.path.exists(output_dir):
248
319
            # Move the bzr control directory back, and update the working tree
249
320
            tmp_bzr_dir = os.path.join(tempdir, '.bzr')
254
325
            os.rename(bzr_dir, tmp_bzr_dir) # Move the original bzr out of the way
255
326
            os.rename(new_bzr_dir, bzr_dir)
256
327
            try:
257
 
                # bzrlib.merge that exists in mainline does not have a this_dir component,
258
 
                # so we have to work in the local directory
259
 
                try:
260
 
                    pwd = os.getcwd()
261
 
                    os.chdir(output_dir)
262
 
                    bzrlib.merge.merge(('.', -1), ('.', old_revno))
263
 
                finally:
264
 
                    os.chdir(pwd)
 
328
                bzrlib.merge.merge((output_dir, -1), (output_dir, old_revno), 
 
329
                                   check_clean=False, this_dir=output_dir, 
 
330
                                   ignore_zero=True)
265
331
            except:
266
332
                # If something failed, move back the original bzr directory
267
333
                os.rename(bzr_dir, new_bzr_dir)
268
334
                os.rename(tmp_bzr_dir, bzr_dir)
269
335
                raise
270
336
        else:
 
337
            revdir = os.path.join(tempdir, "rd")
271
338
            os.rename(revdir, output_dir)
272
339
 
273
340
    finally:
274
 
        if fancy:
275
 
            clear_progress_bar()
276
 
        else:
277
 
            sys.stdout.write('\n')
278
341
        print 'Cleaning up'
279
342
        shutil.rmtree(tempdir)
280
343
    print "Import complete."
308
371
 
309
372
def arch_revision(revision_id):
310
373
    """
311
 
    >>> str(arch_revision("Arch-x:jrandom@example.com/test--test--0"))
312
 
    'jrandom@example.com/test--test--0'
 
374
    >>> str(arch_revision("Arch-x:jrandom@example.com%test--test--0"))
 
375
    Traceback (most recent call last):
 
376
    NotArchRevision: The revision id Arch-x:jrandom@example.com%test--test--0 does not look like it came from Arch.
 
377
    >>> str(arch_revision("Arch-x:jrandom@example.com%test--test--0--base-5"))
 
378
    Traceback (most recent call last):
 
379
    NotArchRevision: The revision id Arch-x:jrandom@example.com%test--test--0--base-5 does not look like it came from Arch.
 
380
    >>> str(arch_revision("Arch-x:jrandom@example.com%test--test--0--patch-5"))
 
381
    'jrandom@example.com/test--test--0--patch-5'
313
382
    """
314
383
    if revision_id is None:
315
384
        return None
367
436
                shutil.copytree(bzr_dir, new_bzr_dir)
368
437
                # Now revdir should have a tree with the latest .bzr, and the
369
438
                # next revision of the baz tree
370
 
                branch = bzrlib.Branch(revdir)
 
439
                branch = find_branch(revdir)
371
440
            else:
372
441
                branch = bzrlib.Branch(revdir, init=True)
373
442
        else:
377
446
            baz_inv, log = apply_revision(revdir, revision, 
378
447
                                          skip_symlinks=skip_symlinks)
379
448
            os.rename(new, old)
380
 
            branch = bzrlib.Branch(revdir)
 
449
            branch = find_branch(revdir)
381
450
        timestamp = email.Utils.mktime_tz(log.date + (0,))
382
451
        rev_id = revision_id(revision)
383
452
        branch.lock_write()
479
548
                      dest="skip_symlinks", 
480
549
                      help="Ignore any symlinks present in the Arch tree.")
481
550
 
482
 
    g = optparse.OptionGroup(parser, 'Progress options', 'Control how progress is given')
483
 
    g.add_option('--not-fancy', dest='fancy', action='store_false')
484
 
    g.add_option('--fancy', dest='fancy', action='store_true', default=True
485
 
        , help='Fancy or simple progress bar. (default: fancy)')
486
 
    parser.add_option_group(g)
487
 
 
488
551
    g = optparse.OptionGroup(parser, 'Test options', 'Options useful while testing process.')
489
552
    g.add_option('--test', action='store_true'
490
553
        , help='Run the self-tests and exit.')
509
572
        else:
510
573
            return 0
511
574
    if len(args) == 2:
512
 
        output_dir = os.path.realpath(args[1]) 
513
 
        version = pybaz.Version(args[0])
 
575
        output_dir = os.path.realpath(args[1])
 
576
        try:
 
577
            version = pybaz.Version(args[0])
 
578
        except pybaz.errors.NamespaceError:
 
579
            print "%s is not a valid Arch branch." % args[0]
 
580
            return 1
 
581
            
514
582
    elif len(args) == 1:
515
583
        output_dir = os.path.realpath(args[0])
516
584
        version = None
522
590
        
523
591
        import_version(output_dir, version,
524
592
            verbose=opts.verbose, fast=opts.fast,
525
 
            fancy=opts.fancy, dry_run=opts.dry_run,
526
 
            max_count=opts.max_count, skip_symlinks=opts.skip_symlinks)
 
593
            dry_run=opts.dry_run, max_count=opts.max_count,
 
594
            skip_symlinks=opts.skip_symlinks)
527
595
        return 0
528
596
    except UserError, e:
529
597
        print e
532
600
        print "Aborted."
533
601
        return 1
534
602
 
 
603
class NotInABranch(Exception):
 
604
    def __init__(self, path):
 
605
        Exception.__init__(self, "%s is not in a branch." % path)
 
606
        self.path = path
 
607
 
 
608
 
 
609
def find_branch(path):
 
610
    """
 
611
    >>> find_branch('/')
 
612
    Traceback (most recent call last):
 
613
    NotInABranch: / is not in a branch.
 
614
    >>> sb = bzrlib.ScratchBranch()
 
615
    >>> isinstance(find_branch(sb.base), bzrlib.Branch)
 
616
    True
 
617
    """
 
618
    try:
 
619
        return bzrlib.Branch(path)
 
620
    except BzrError, e:
 
621
        if e.args[0].endswith("' is not in a branch"):
 
622
            raise NotInABranch(path)
 
623
        
535
624
 
536
625
if __name__ == '__main__':
537
626
    sys.exit(main(sys.argv[1:]))