예제 #1
0
def test_stamp_is_current_working_set(first_stamp):
    """Check we are stamping the current working set
    """
    with NewCountedDirectory('build3') as d2:
        banner('TESTING STAMP CURRENT WORKING SET')
        muddle(['unstamp', first_stamp])
        # So, we've selected specific revisions for all of our checkouts
        # and thus they are all in "detached HEAD" state
        revisions = capture_revisions()

        # XXX To be considered XXX
        # Here, we are deliberately making a change that we do not push to the
        # remote repository. Thus our stamp file will contain a revision id
        # that no-one else can make sense of. This may be a Bad Thing.
        # Indeed, if we try to do this with a bzr repository, our own code
        # in 'muddle query checkout-id' would use 'bzr missing' and notice that
        # the revision was not present at the far end, and give up with a
        # complaint at that point.

        with Directory('src'):
            with Directory('first_co'):
                append('Makefile.muddle', '\n# A comment\n')
                git('commit Makefile.muddle -m "Add a comment"')

        # Don't forget that ".strip()" to remove the trailing newline!
        first_co_rev2 = captured_muddle(['query', 'checkout-id',
                                         'first_co']).strip()

        if first_co_rev2 == revisions['first_co']:
            raise GiveUp('The revision of first_co did not change')

        revisions['first_co'] = first_co_rev2

        muddle(['stamp', 'save', 'amended.stamp'])

        stamp = VersionStamp.from_file('amended.stamp')
        if len(stamp.checkouts) != len(revisions):
            raise GiveUp('Stamp file has %d checkouts, build tree %d' %
                         (len(stamp.checkouts), len(revisions)))

        for co in stamp.checkouts:
            if co.domain:
                dom_plus_name = '(%s)%s' % (co.domain, co.name)
            else:
                dom_plus_name = co.name
            repo = stamp.checkouts[co][
                -1]  # ah, named tuples would be good here
            #print dom_plus_name
            #print '  S:',repo.revision
            #print '  D:',revisions[dom_plus_name]
            if repo.revision != revisions[dom_plus_name]:
                raise GiveUp(
                    'Checkout %s is revision %s in stamp file,'
                    ' %s on disk' %
                    (dom_plus_name, repo.revision, revisions[dom_plus_name]))
예제 #2
0
def test_options():
    """Test we can read back options from a stamp file.
    """
    fname = 'test_options.stamp'
    touch(fname, OPTIONS_TEST)
    v = VersionStamp.from_file(fname)

    if len(v.problems) != 4:
        raise GiveUp('Expected 4 problems reading %s, got %d' %
                     (fname, len(v.problems)))

    # Make the problem order deterministic
    v.problems.sort()

    check_problem(
        v.problems[0],
        "Cannot convert value to integer, for 'option~BadFred = int:ThreadNeedle'"
    )
    check_problem(
        v.problems[1],
        "No datatype (no colon in value), for 'option~Aha~There = No colons here'"
    )
    check_problem(
        v.problems[2],
        "Unrecognised datatype 'what' (not bool, int or str), for 'option~AhaTwo = what:pardon'"
    )
    check_problem(
        v.problems[3],
        "Value is not True or False, for 'option~BadJim = bool:Immensity'")

    co_label = Label(LabelType.Checkout, 'co_name', None, LabelTag.CheckedOut)
    co_dir, co_leaf, repo = v.checkouts[co_label]
    options = v.options[co_label]

    expected_repo = 'file:///Users/tibs/sw/m3/tests/transient/repo/second_co'
    if co_dir is not None or co_leaf != 'co_name' or \
       str(repo) != expected_repo:
        raise GiveUp('Error in reading checkout back\n'
                     '  co_dir %s, expected None\n'
                     '  co_leaf %s, expected co_name\n'
                     '  repo     %s\n'
                     '  expected %s' % (co_dir, co_leaf, repo, expected_repo))

    if len(options) != 3 or \
            options['Jim'] != False or \
            options['Bill'] != 'Some sort of string' or \
            options['Fred'] != 99:
        raise GiveUp(
            'Error in reading checkout options back\n'
            "  expected {'Jim': False, 'Bill': 'Some sort of string', 'Fred': 99}\n"
            '  got      %s' % options)
예제 #3
0
def test_stamp_is_current_working_set(first_stamp):
    """Check we are stamping the current working set
    """
    with NewCountedDirectory('build3') as d2:
        banner('TESTING STAMP CURRENT WORKING SET')
        muddle(['unstamp', first_stamp])
        # So, we've selected specific revisions for all of our checkouts
        # and thus they are all in "detached HEAD" state
        revisions = capture_revisions()

        # XXX To be considered XXX
        # Here, we are deliberately making a change that we do not push to the
        # remote repository. Thus our stamp file will contain a revision id
        # that no-one else can make sense of. This may be a Bad Thing.
        # Indeed, if we try to do this with a bzr repository, our own code
        # in 'muddle query checkout-id' would use 'bzr missing' and notice that
        # the revision was not present at the far end, and give up with a
        # complaint at that point.

        with Directory('src'):
            with Directory('first_co'):
                append('Makefile.muddle', '\n# A comment\n')
                git('commit Makefile.muddle -m "Add a comment"')

        # Don't forget that ".strip()" to remove the trailing newline!
        first_co_rev2 = captured_muddle(['query', 'checkout-id', 'first_co']).strip()

        if first_co_rev2 == revisions['first_co']:
            raise GiveUp('The revision of first_co did not change')

        revisions['first_co'] = first_co_rev2

        muddle(['stamp', 'save', 'amended.stamp'])

        stamp = VersionStamp.from_file('amended.stamp')
        if len(stamp.checkouts) != len(revisions):
            raise GiveUp('Stamp file has %d checkouts, build tree %d'%(len(stamp.checkouts),
                                                                       len(revisions)))

        for co in stamp.checkouts:
            if co.domain:
                dom_plus_name = '(%s)%s'%(co.domain, co.name)
            else:
                dom_plus_name = co.name
            repo = stamp.checkouts[co][-1]      # ah, named tuples would be good here
            #print dom_plus_name
            #print '  S:',repo.revision
            #print '  D:',revisions[dom_plus_name]
            if repo.revision != revisions[dom_plus_name]:
                raise GiveUp('Checkout %s is revision %s in stamp file,'
                        ' %s on disk'%(dom_plus_name, repo.revision, revisions[dom_plus_name]))
예제 #4
0
def test_options():
    """Test we can read back options from a stamp file.
    """
    fname = 'test_options.stamp'
    touch(fname, OPTIONS_TEST)
    v = VersionStamp.from_file(fname)

    if len(v.problems) != 4:
        raise GiveUp('Expected 4 problems reading %s, got %d'%(fname, len(v.problems)))

    # Make the problem order deterministic
    v.problems.sort()

    check_problem(v.problems[0], "Cannot convert value to integer, for 'option~BadFred = int:ThreadNeedle'")
    check_problem(v.problems[1], "No datatype (no colon in value), for 'option~Aha~There = No colons here'")
    check_problem(v.problems[2], "Unrecognised datatype 'what' (not bool, int or str), for 'option~AhaTwo = what:pardon'")
    check_problem(v.problems[3], "Value is not True or False, for 'option~BadJim = bool:Immensity'")

    co_label = Label(LabelType.Checkout, 'co_name', None, LabelTag.CheckedOut)
    co_dir, co_leaf, repo = v.checkouts[co_label]
    options = v.options[co_label]

    expected_repo = 'file:///Users/tibs/sw/m3/tests/transient/repo/second_co'
    if co_dir is not None or co_leaf != 'co_name' or \
       str(repo) != expected_repo:
        raise GiveUp('Error in reading checkout back\n'
                     '  co_dir %s, expected None\n'
                     '  co_leaf %s, expected co_name\n'
                     '  repo     %s\n'
                     '  expected %s'%(co_dir, co_leaf, repo, expected_repo))

    if len(options) != 3 or \
            options['Jim'] != False or \
            options['Bill'] != 'Some sort of string' or \
            options['Fred'] != 99:
        raise GiveUp('Error in reading checkout options back\n'
                     "  expected {'Jim': False, 'Bill': 'Some sort of string', 'Fred': 99}\n"
                     '  got      %s'%options)
예제 #5
0
def test_ReleaseStamp_basics(d):
    banner('RELEASE STAMP BASICS')

    banner('Write "empty" release file', 2)
    r0 = ReleaseStamp()
    r0.write_to_file('r1.release')
    check_release_file_starts('r1.release', '<REPLACE THIS>', '<REPLACE THIS>',
                              'tar', 'gzip', '', '', '')

    # We can read that as a normal VersionStamp
    banner('Read "empty" release file as stamp', 2)
    s = VersionStamp.from_file('r1.release')
    s.write_to_file('r1.stamp')
    check_stamp_file_starts('r1.stamp', '', '', '')

    # We can't read in r1.release as a release, because of the name and version
    banner('Read "empty" release file as release (it should fail)', 2)
    try:
        r1 = ReleaseStamp.from_file('r1.release')
    except GiveUp as e:
        if 'Release name "<REPLACE THIS>" is not allowed' not in str(e):
            raise GiveUp('Unexpected error reading r1.release: %s'%e)

    # We can't read in r1.stamp as a release, because of the name and version
    banner('Read "empty" stamp file as release (it should fail)', 2)
    try:
        r1 = ReleaseStamp.from_file('r1.stamp')
    except NoSectionError as e:
        if e.section != 'RELEASE':
            raise GiveUp('Expected section "RELEASE" to be missing, but got'
                         ' NoSectionError for "%s"'%e.section)
    except Exception as e:
        raise GiveUp('Unexpected error reading r1.stamp: %s'%e)

    # We can't set a bad name, version, archive or compression
    try:
        r0.release_spec.name = '+++'
    except GiveUp as e:
        if 'Release name "+++" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad name: %s'%e)
    r0.release_spec.name = 'project99'
    try:
        r0.release_spec.version = '+++'
    except GiveUp as e:
        if 'Release version "+++" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s'%e)
    r0.release_spec.version = '1.2.3'
    try:
        r0.release_spec.archive = 'fred'
    except GiveUp as e:
        if 'Release archive "fred" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s'%e)
    r0.release_spec.archive = 'tar'
    try:
        r0.release_spec.compression = 'fred'
    except GiveUp as e:
        if 'Release compression "fred" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s'%e)
    r0.release_spec.compression = 'bzip2'
    r0.write_to_file('r2.release')

    # But when we get it right, it is OK
    check_release_file_starts('r2.release', 'project99', '1.2.3',
                              'tar', 'bzip2', '', '', '')
예제 #6
0
def write(our_stamp_file, far_stamp_file, output_dir_name):

    current_dir = os.getcwd()

    output_dir = os.path.join(current_dir, output_dir_name)
    output_dir = canonical_path(output_dir)
    if os.path.exists(output_dir):
        raise LocalError('Output directory %s already exists'%output_dir)

    if our_stamp_file == '-':
        our_stamp, problems = determine_our_stamp(current_dir)
    else:
        our_stamp = VersionStamp.from_file(our_stamp_file)

    far_stamp = VersionStamp.from_file(far_stamp_file)

    # Determine what has changed with respect to the "far" stamp
    # - those changes are what we need to apply to make it the same as us...
    deleted, new, changed, problems = far_stamp.compare_checkouts(our_stamp)

    # deleted  = [ (label, co_dir, co_leaf, repo), ... ]
    # new      = [ (label, co_dir, co_leaf, repo), ... ]
    # changed  = [ (label, revision1, revision2), ... ]
    # problems = [ (label, summary-string), ... ]

    print
    print 'Summary: deleted %d, new %d, changed %d, problems %d'%(len(deleted),
            len(new), len(changed), len(problems))
    print

    os.mkdir(output_dir)
    manifest_filename = os.path.join(output_dir, 'MANIFEST.txt')

    for label, rev1, rev2 in changed:
        print "-- Determining changes for checkout %s, %s..%s"%(label, rev1, rev2)
        co_dir, co_leaf, repo = our_stamp.checkouts[label]
        vcs = repo.vcs
        if vcs == 'bzr':
            bzr_send(label, co_dir, co_leaf, repo, rev1, rev2, output_dir, manifest_filename)
        elif vcs == 'svn':
            svn_diff(label, co_dir, co_leaf, repo, rev1, rev2, output_dir, manifest_filename)
        elif vcs == 'git':
            git_format_patch(label, co_dir, co_leaf, repo, rev1, rev2, output_dir, manifest_filename)
        else:
            print 'Unable to deal with VCS %s'%vcs
            continue

    # For deleted checkouts, we definitely don't want to do anything
    # - if they're not being used anymore, leaving them around will not
    # hurt, and it is the simplest and safest option.
    if deleted:
        print
        print 'The following checkouts were deleted'
        for label, co_dir, co_leaf, repo in deleted:
            print '  %s'%label
            if co_leaf:
                print '  %s'%(os.path.join(co_dir, co_leaf))
            else:
                print '  %s'%co_dir
            print '  %s'%repo
            if repo.branch:
                print '  branch %s'%repo.branch
            if repo.revision:
                print '  branch %s'%repo.revision

    # TODO: For new checkouts, the best we can do is just to TAR up the
    # directory and copy it directly, and cross our fingers. We might as
    # well leave any VCS metadata intact. When restoring, it's probably
    # sensible to leave it up to the user to do a "muddle assert" of the
    # checked_out label, rather than try to second guess things...
    # ...so must remember to add a MANIFEST entry!
    # (if, at the other end, we're untarring a new checkout, we must check
    # if the directory already exists, and perhaps refuse to do it if so?)
    if new:
        for label, co_dir, co_leaf, repo in new:
            print "-- Saving tarfile for new checkout %s"%label
            print "   Originally from"
            if co_leaf:
                print '    %s'%(os.path.join(co_dir, co_leaf))
            else:
                print '    %s'%co_dir
            print '    %s'%repo
            if repo.branch:
                print '    branch %s'%repo.branch
            if repo.revision:
                print '    revision %s'%repo.revision
            tar_pack(label, co_dir, co_leaf, repo, output_dir, manifest_filename)

    if problems:
        print
        print 'There were the following problems'
        for tup in problems:
            print ' ',tup
예제 #7
0
def determine_our_stamp(current_dir, quiet=False):
    if not quiet:
        print '-- Determining stamp for this build tree'
    builder = find_builder(current_dir)
    # I *think* we're best off with force=True (equivalent of -f)
    return VersionStamp.from_builder(builder, force=True, quiet=quiet)
예제 #8
0
def write(our_stamp_file, far_stamp_file, output_dir_name):

    current_dir = os.getcwd()

    output_dir = os.path.join(current_dir, output_dir_name)
    output_dir = canonical_path(output_dir)
    if os.path.exists(output_dir):
        raise LocalError('Output directory %s already exists' % output_dir)

    if our_stamp_file == '-':
        our_stamp, problems = determine_our_stamp(current_dir)
    else:
        our_stamp = VersionStamp.from_file(our_stamp_file)

    far_stamp = VersionStamp.from_file(far_stamp_file)

    # Determine what has changed with respect to the "far" stamp
    # - those changes are what we need to apply to make it the same as us...
    deleted, new, changed, problems = far_stamp.compare_checkouts(our_stamp)

    # deleted  = [ (label, co_dir, co_leaf, repo), ... ]
    # new      = [ (label, co_dir, co_leaf, repo), ... ]
    # changed  = [ (label, revision1, revision2), ... ]
    # problems = [ (label, summary-string), ... ]

    print
    print 'Summary: deleted %d, new %d, changed %d, problems %d' % (
        len(deleted), len(new), len(changed), len(problems))
    print

    os.mkdir(output_dir)
    manifest_filename = os.path.join(output_dir, 'MANIFEST.txt')

    for label, rev1, rev2 in changed:
        print "-- Determining changes for checkout %s, %s..%s" % (label, rev1,
                                                                  rev2)
        co_dir, co_leaf, repo = our_stamp.checkouts[label]
        vcs = repo.vcs
        if vcs == 'bzr':
            bzr_send(label, co_dir, co_leaf, repo, rev1, rev2, output_dir,
                     manifest_filename)
        elif vcs == 'svn':
            svn_diff(label, co_dir, co_leaf, repo, rev1, rev2, output_dir,
                     manifest_filename)
        elif vcs == 'git':
            git_format_patch(label, co_dir, co_leaf, repo, rev1, rev2,
                             output_dir, manifest_filename)
        else:
            print 'Unable to deal with VCS %s' % vcs
            continue

    # For deleted checkouts, we definitely don't want to do anything
    # - if they're not being used anymore, leaving them around will not
    # hurt, and it is the simplest and safest option.
    if deleted:
        print
        print 'The following checkouts were deleted'
        for label, co_dir, co_leaf, repo in deleted:
            print '  %s' % label
            if co_leaf:
                print '  %s' % (os.path.join(co_dir, co_leaf))
            else:
                print '  %s' % co_dir
            print '  %s' % repo
            if repo.branch:
                print '  branch %s' % repo.branch
            if repo.revision:
                print '  branch %s' % repo.revision

    # TODO: For new checkouts, the best we can do is just to TAR up the
    # directory and copy it directly, and cross our fingers. We might as
    # well leave any VCS metadata intact. When restoring, it's probably
    # sensible to leave it up to the user to do a "muddle assert" of the
    # checked_out label, rather than try to second guess things...
    # ...so must remember to add a MANIFEST entry!
    # (if, at the other end, we're untarring a new checkout, we must check
    # if the directory already exists, and perhaps refuse to do it if so?)
    if new:
        for label, co_dir, co_leaf, repo in new:
            print "-- Saving tarfile for new checkout %s" % label
            print "   Originally from"
            if co_leaf:
                print '    %s' % (os.path.join(co_dir, co_leaf))
            else:
                print '    %s' % co_dir
            print '    %s' % repo
            if repo.branch:
                print '    branch %s' % repo.branch
            if repo.revision:
                print '    revision %s' % repo.revision
            tar_pack(label, co_dir, co_leaf, repo, output_dir,
                     manifest_filename)

    if problems:
        print
        print 'There were the following problems'
        for tup in problems:
            print ' ', tup
예제 #9
0
def determine_our_stamp(current_dir, quiet=False):
    if not quiet:
        print '-- Determining stamp for this build tree'
    builder = find_builder(current_dir)
    # I *think* we're best off with force=True (equivalent of -f)
    return VersionStamp.from_builder(builder, force=True, quiet=quiet)
예제 #10
0
def test_ReleaseStamp_basics(d):
    banner('RELEASE STAMP BASICS')

    banner('Write "empty" release file', 2)
    r0 = ReleaseStamp()
    r0.write_to_file('r1.release')
    check_release_file_starts('r1.release', '<REPLACE THIS>', '<REPLACE THIS>',
                              'tar', 'gzip', '', '', '')

    # We can read that as a normal VersionStamp
    banner('Read "empty" release file as stamp', 2)
    s = VersionStamp.from_file('r1.release')
    s.write_to_file('r1.stamp')
    check_stamp_file_starts('r1.stamp', '', '', '')

    # We can't read in r1.release as a release, because of the name and version
    banner('Read "empty" release file as release (it should fail)', 2)
    try:
        r1 = ReleaseStamp.from_file('r1.release')
    except GiveUp as e:
        if 'Release name "<REPLACE THIS>" is not allowed' not in str(e):
            raise GiveUp('Unexpected error reading r1.release: %s' % e)

    # We can't read in r1.stamp as a release, because of the name and version
    banner('Read "empty" stamp file as release (it should fail)', 2)
    try:
        r1 = ReleaseStamp.from_file('r1.stamp')
    except NoSectionError as e:
        if e.section != 'RELEASE':
            raise GiveUp('Expected section "RELEASE" to be missing, but got'
                         ' NoSectionError for "%s"' % e.section)
    except Exception as e:
        raise GiveUp('Unexpected error reading r1.stamp: %s' % e)

    # We can't set a bad name, version, archive or compression
    try:
        r0.release_spec.name = '+++'
    except GiveUp as e:
        if 'Release name "+++" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad name: %s' % e)
    r0.release_spec.name = 'project99'
    try:
        r0.release_spec.version = '+++'
    except GiveUp as e:
        if 'Release version "+++" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s' %
                         e)
    r0.release_spec.version = '1.2.3'
    try:
        r0.release_spec.archive = 'fred'
    except GiveUp as e:
        if 'Release archive "fred" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s' %
                         e)
    r0.release_spec.archive = 'tar'
    try:
        r0.release_spec.compression = 'fred'
    except GiveUp as e:
        if 'Release compression "fred" is not allowed' not in str(e):
            raise GiveUp('Unexpected error trying to write bad version: %s' %
                         e)
    r0.release_spec.compression = 'bzip2'
    r0.write_to_file('r2.release')

    # But when we get it right, it is OK
    check_release_file_starts('r2.release', 'project99', '1.2.3', 'tar',
                              'bzip2', '', '', '')