Ejemplo n.º 1
0
def test_simple_release(d, repo):
    banner('TEST SIMPLE RELEASE')
    banner('Check out build tree, and stamp it as a release', 2)
    with NewCountedDirectory('build1') as build1:
        r = 'git+file://{repo}/main'.format(repo=repo)
        d = 'builds/01.py'
        v = '{root}/versions'.format(root=r)
        muddle(['init', r, d])
        muddle(['checkout', '_all'])
        muddle(['stamp', 'release', 'simple', 'v1.0'])

        rfile = os.path.join(build1.where, 'versions', 'simple_v1.0.release')
        check_release_file_starts(rfile, 'simple', 'v1.0', 'tar', 'gzip', r, d,
                                  v)

        UNSET = '(unset)'
        muddle_env = read_env_as_dict('first_pkg{x86}')
        if not (muddle_env['MUDDLE_RELEASE_NAME'] == UNSET
                and muddle_env['MUDDLE_RELEASE_VERSION'] == UNSET
                and muddle_env['MUDDLE_RELEASE_HASH'] == UNSET):
            print 'MUDDLE_RELEASE_NAME=%s' % muddle_env['MUDDLE_RELEASE_NAME']
            print 'MUDDLE_RELEASE_VERSION=%s' % muddle_env[
                'MUDDLE_RELEASE_VERSION']
            print 'MUDDLE_RELEASE_HASH=%s' % muddle_env['MUDDLE_RELEASE_HASH']
            raise GiveUp(
                'Expected the MUDDLE_RELEASE_ values to be all (unset)')

    banner('Try "muddle release" using that stamp', 2)
    with NewCountedDirectory('build2') as build2:
        muddle(['release', rfile])
        check_release_directory(build2)
Ejemplo n.º 2
0
def test_unstamp_update_2(repo, first_stamp):
    """Test the "unstamp -update" operation a bit more
    """
    banner('TESTING UNSTAMP -UPDATE -- TEST 2')
    with NewCountedDirectory('build5') as d:
        muddle([
            'init', 'git+file://{repo}/main'.format(repo=repo), 'builds/01.py'
        ])
        muddle(['checkout', '_all'])
        old_revisions = capture_revisions()

        # Make some amdendments and check them in
        with Directory('src'):
            with Directory('first_co'):
                append('Makefile.muddle', '\n# A comment\n')
                git('commit Makefile.muddle -m "Add a comment"')
                muddle(['push'])
            with Directory('second_co'):
                append('Makefile.muddle', '\n# A comment\n')
                bzr('commit Makefile.muddle -m "Add a comment"')
                muddle(['push'])

        with Directory('domains'):
            with Directory('subdomain1'):
                with Directory('src'):
                    with Directory('builds'):
                        append('01.py', '\n# A comment\n')
                        git('commit 01.py -m "Add a comment"')
                        muddle(['push'])

        new_revisions = capture_revisions()

        # Keep this state for later on
        muddle(['stamp', 'save', 'new_state.stamp'])

        # Revert to the original
        muddle(['unstamp', '-update', first_stamp])
        current_revisions = capture_revisions()
        if revisions_differ(current_revisions, old_revisions):
            raise GiveUp('Update back to original failed')

        # And back (forwards) again
        muddle(['unstamp', '-update', 'new_state.stamp'])
        current_revisions = capture_revisions()
        if revisions_differ(current_revisions, new_revisions):
            raise GiveUp('Update forward again failed')

        # One of the points of using "muddle pull" internally in the
        # "muddle unstamp -update" command is that we want our "just pulled"
        # list to be available. So check that.
        just_pulled = read_just_pulled()
        if just_pulled != set([
                'checkout:first_co/checked_out',
                'checkout:second_co/checked_out',
                'checkout:(subdomain1)builds/checked_out'
        ]):
            print 'Read _just_pulled as:'
            print just_pulled
            raise GiveUp('Just pulled list does not match')
Ejemplo n.º 3
0
def test_stamping_branches(repo):
    """Test we cope with branches.
    """

    banner('TESTING STAMPING BRANCHES')
    with NewCountedDirectory('build6') as d:
        muddle([
            'init', 'git+file://{repo}/main'.format(repo=repo), 'builds/01.py'
        ])
        muddle(['checkout', '_all'])

        with Directory('src'):
            with Directory('first_co'):
                git('checkout -b branch1')
                muddle(['push'])

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

    with NewCountedDirectory('build7'):
        muddle(['unstamp', d.join('01.stamp')])

        # We should have got the branch for first_co, even though it's not
        # the branch in the build description
        # Check we're working with the expected branches
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds master <none> <not following>",
            "first_co branch1 <none> <not following>",
            "main_co master <none> <not following>",
            "second_co <not supported> ... ...",
            "(subdomain1)builds master <none> <not following>",
            "(subdomain1)first_co master <none> <not following>",
            "(subdomain1)main_co master <none> <not following>",
            "(subdomain1)second_co master <none> <not following>",
            "(subdomain1(subdomain3))builds master <none> <not following>",
            "(subdomain1(subdomain3))first_co master <none> <not following>",
            "(subdomain1(subdomain3))main_co master <none> <not following>",
            "(subdomain1(subdomain3))second_co master <none> <not following>",
            "(subdomain2)builds master <none> <not following>",
            "(subdomain2)first_co master <none> <not following>",
            "(subdomain2)main_co master <none> <not following>",
            "(subdomain2)second_co master <none> <not following>"
        ],
                                 fold_whitespace=True)
Ejemplo n.º 4
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]))
Ejemplo n.º 5
0
def test_builds_bad_upstream_2(root):
    with NewCountedDirectory('builds_bad_upstream_2') as d:
        banner(
            'CHECK REPOSITORIES OUT (BAD UPSTREAM 2) illegal upstream names')
        text = captured_muddle([
            'init', 'git+file://{repo}/main'.format(repo=root.join('repo')),
            'builds_bad_upstream_2/01.py'
        ],
                               error_fails=False)
        check_text_endswith(
            text, """\
GiveUp: Upstream repository name '$@~#sausage' is not allowed
""".format(root_dir=root.where))
Ejemplo n.º 6
0
def test_stamp_unstamp(root_dir):
    """Simple test of stamping and then unstamping

    Returns the path to the stamp file it creates
    """
    banner('TEST BASIC STAMP AND UNSTAMP')
    with NewCountedDirectory('build') as d:
        banner('CHECK REPOSITORIES OUT', 2)
        checkout_build_descriptions(root_dir, d)
        muddle(['checkout', '_all'])
        check_checkout_files(d)

        banner('STAMP', 2)
        muddle(['stamp', 'version'])

        first_stamp = os.path.join(d.where, 'versions', '01.stamp')

    with NewCountedDirectory('build2') as d2:
        banner('UNSTAMP', 2)
        muddle(['unstamp', os.path.join(d.where, 'versions', '01.stamp')])
        check_checkout_files(d2)

    return first_stamp
Ejemplo n.º 7
0
def test_issue_249_single_digit_version_number(d, repo):
    banner('TEST ISSUE 249')
    banner('Check out build tree, and stamp it as release version 1', 2)
    with NewCountedDirectory('build.version-number') as build:
        r = 'git+file://{repo}/main'.format(repo=repo)
        d = 'builds/01.py'
        v = '{root}/versions'.format(root=r)
        muddle(['init', r, d])
        muddle(['checkout', '_all'])
        muddle(['stamp', 'release', 'simple', '1'])
        with Directory('versions'):
            check_specific_files_in_this_dir(['.git', 'simple_1.release'])
            check_release_file_starts('simple_1.release', 'simple', '1', 'tar',
                                      'gzip', r, d, v)
Ejemplo n.º 8
0
def test_unstamp_update_identity_operation(repo, first_stamp):
    """Test the "unstamp -update" identity operation
    """
    banner('TESTING UNSTAMP -UPDATE -- TEST 1 (IDENTITY)')
    with NewCountedDirectory('build4') as d2:
        muddle([
            'init', 'git+file://{repo}/main'.format(repo=repo), 'builds/01.py'
        ])
        muddle(['checkout', '_all'])
        old_revisions = capture_revisions()
        # And check the "null" operation
        muddle(['unstamp', '-update', first_stamp])
        new_revisions = capture_revisions()
        if revisions_differ(old_revisions, new_revisions):
            raise GiveUp('Null update changed stuff!')
        else:
            print 'The tree was not changed by the "null" update'
Ejemplo n.º 9
0
def test_builds_ok_upstream_3(root):
    with NewCountedDirectory('builds_ok_upstream_3') as d:
        banner(
            'CHECK REPOSITORIES OUT (OK UPSTREAM 3) subdomain has extra upstream names'
        )
        muddle([
            'init', 'git+file://{repo}/main'.format(repo=root.join('repo')),
            'builds_ok_upstream_3/01.py'
        ])

        text = captured_muddle(['query', 'upstream-repos'])
        check_text_endswith(
            text, """\
> Upstream repositories ..
Repository('git', 'file://{root_dir}/repo/main', 'repo1') used by checkout:co_repo1/*, checkout:(subdomain_ok_upstream_3)co_repo1/*
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.1')  rhubarb, wombat
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.2', push=False)  insignificance, manhattan, platypus, wombat
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.3', pull=False)  platypus, rhubarb
Repository('git', 'http://example.com', 'repo99')
    Repository('git', 'http://example.com', 'repo99-upstream')  abacus
""".format(root_dir=root.where))
Ejemplo n.º 10
0
def test_builds_bad_upstream_1(root):
    with NewCountedDirectory('builds_bad_upstream_1') as d:
        banner(
            'CHECK REPOSITORIES OUT (BAD UPSTREAM 1) subdomain has extra upstreams'
        )
        text = captured_muddle([
            'init', 'git+file://{repo}/main'.format(repo=root.join('repo')),
            'builds_bad_upstream_1/01.py'
        ],
                               error_fails=False)
        check_text_endswith(
            text, """\
Subdomain subdomain_bad_upstream_1 adds a new upstream to
  Repository('git', 'file://{root_dir}/repo/main', 'repo1')
  (used by checkout:co_repo1/*, checkout:(subdomain_bad_upstream_1)co_repo1/*)
  Original upstreams:
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.1')  rhubarb, wombat
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.2', push=False)  insignificance, wombat
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.3', pull=False)  platypus, rhubarb
  Subdomain subdomain_bad_upstream_1 has:
    Repository('git', 'file://{root_dir}/repo/main', 'repo1.X')  fruitbat, rhubarb, wombat
""".format(root_dir=root.where))
Ejemplo n.º 11
0
def test_lifecycle(root_d):
    """A linear sequence of plausible actions...
    """

    # Repositories
    with NewCountedDirectory('repos') as d0:
        with NewDirectory('builds'):
            git('init --bare')
        with NewDirectory('co1'):
            git('init --bare')
        with NewDirectory('versions'):
            git('init --bare')

        repo_url = 'git+file://%s' % d0.where

    build_name = 'TestBuild'

    # First build tree
    with NewCountedDirectory('build1') as d1:
        muddle(['bootstrap', repo_url, build_name])
        with Directory('src'):
            with Directory('builds'):
                os.remove('01.py')
                os.remove('01.pyc')
                touch('01.py', BUILD_DESC.format(build_name=build_name))
                git('add 01.py'
                    )  # Because we changed it since the last 'git add'
                git('commit -m "First commit of build description"')
                muddle(['push'])
            with NewDirectory('co1'):
                touch('Makefile.muddle', MUDDLE_MAKEFILE)
                git('init')
                git('add Makefile.muddle')
                git('commit Makefile.muddle -m "A checkout needs a makefile"')
                muddle(['import'])
                muddle(['push'])

        muddle(['stamp', 'version'])
        with Directory('versions'):
            check_specific_files_in_this_dir(['.git', 'TestBuild.stamp'])
            git('add TestBuild.stamp')
            git('commit -m "First stamp"')
            muddle(['stamp', 'push'])

        builds_rev_1 = captured_muddle(['query', 'checkout-id',
                                        'builds']).strip()
        checkout_rev_1 = captured_muddle(['query', 'checkout-id',
                                          'co1']).strip()

        # Add some more revisions, so we have something to work with
        with Directory('src'):
            with Directory('builds'):
                append('01.py', '# Additional comment number 1\n')
                git('add 01.py')
                git('commit -m "Add comment number 1"')
                builds_rev_2 = captured_muddle(['query',
                                                'checkout-id']).strip()
                append('01.py', '# Additional comment number 2\n')
                git('commit -a -m "Add comment number 2"')
                builds_rev_3 = captured_muddle(['query',
                                                'checkout-id']).strip()
                muddle(['push'])
            with Directory('co1'):
                append('Makefile.muddle', '# Additional comment number 1\n')
                git('add Makefile.muddle')
                git('commit -m "Add comment number 1"')
                checkout_rev_2 = captured_muddle(['query',
                                                  'checkout-id']).strip()
                append('Makefile.muddle', '# Additional comment number 2\n')
                git('commit -a -m "Add comment number 2"')
                checkout_rev_3 = captured_muddle(['query',
                                                  'checkout-id']).strip()
                muddle(['push'])

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds master <none> <not following>",
            "co1 master <none> <not following>"
        ],
                                 fold_whitespace=True)

    print 'builds/'
    print '  ', builds_rev_1
    print '  ', builds_rev_2
    print '  ', builds_rev_3
    print 'co1/'
    print '  ', checkout_rev_1
    print '  ', checkout_rev_2
    print '  ', checkout_rev_3

    # Second build tree, where the build description gives a specific revision
    # for a checkout.
    with NewCountedDirectory('build2') as d2:
        muddle(['init', repo_url, 'builds/01.py'])
        # But we want to specify the revision for our source checkout
        with Directory(d2.join('src', 'builds')):
            # Note we don't need to specify ALL of the SHA1 string, we can
            # just specify some non-ambiguous subset...
            touch(
                '01.py',
                BUILD_DESC_WITH_REVISION.format(revision=checkout_rev_2[:8],
                                                build_name=build_name))
            # Then remove the .pyc file, because Python probably won't realise
            # that this new 01.py is later than the previous version
            os.remove('01.pyc')
        muddle(['checkout', '_all'])

        check_revision('co1', checkout_rev_2)

        # If we attempt to 'muddle pull' in the checkout, that should fail
        # because we are already at the requested revision
        text = captured_muddle(['pull', 'co1'], error_fails=False).strip()
        if not text.endswith('checkout past the specified revision.'):
            raise GiveUp(
                'Expected muddle pull to fail trying to go "past" revision:\n%s'
                % text)

        # Merging should behave just the same
        text = captured_muddle(['merge', 'co1'], error_fails=False).strip()
        if not text.endswith('checkout past the specified revision.'):
            raise GiveUp(
                'Expected muddle pull to fail trying to go "past" revision:\n%s'
                % text)

        # What if the checkout is at the wrong revision? (e.g., someone used
        # git explicitly to change it, or equally we changed the build description
        # itself).
        # All muddle can really do is go to the revision specified in the
        # build description...
        with Directory(d2.join('src', 'co1')):
            git('checkout %s' % checkout_rev_1)
            muddle(['pull'])
            check_revision('co1', checkout_rev_2)

            git('checkout %s' % checkout_rev_1)
            muddle(['merge'])
            check_revision('co1', checkout_rev_2)

        # What if we try to do work on that specified revision
        # (and, in git terms, at a detached HEAD)
        with Directory(d2.join('src', 'co1')):
            append('Makefile.muddle', '# Additional comment number 3\n')
            git('commit -a -m "Add comment number 3"')
            checkout_rev_4 = captured_muddle(['query', 'checkout-id']).strip()
            # We're not on a branch, so that commit is likely to get lost,
            # so we'd better allow the user ways of being told that
            # - muddle status should say something
            rc, text = captured_muddle2(['status'])
            if 'Note that this checkout has a detached HEAD' not in text:
                raise GiveUp('Expected to be told checkout is in detached'
                             ' HEAD state, instead got:\n%s' % text)
            # And trying to push should fail
            rc, text = captured_muddle2(['push'])
            text = text.strip()
            if 'This checkout is in "detached HEAD" state' not in text:
                raise GiveUp('Expected to be told checkout is in detached'
                             ' HEAD state, instead got:\n%s' % text)
        print 'co1/'
        print '  ', checkout_rev_1
        print '  ', checkout_rev_2
        print '  ', checkout_rev_3
        print '  ', checkout_rev_4

        # So fix that by using a branch
        checkout_branch = 'this-is-a-branch'
        with Directory('src'):
            with Directory('builds'):
                touch(
                    '01.py',
                    BUILD_DESC_WITH_BRANCH.format(branch=checkout_branch,
                                                  build_name=build_name))
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
            with Directory('co1'):
                git('checkout -b %s' % checkout_branch)
                muddle(['status'])
                muddle(['push'])

        check_revision('co1', checkout_rev_4)

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds master <none> <not following>",
            "co1 this-is-a-branch this-is-a-branch <not following>"
        ],
                                 fold_whitespace=True)

        # What happens if we specify a revision on a branch?
        # First, choose the revision before the branch
        with Directory('src'):
            with Directory('builds'):
                touch(
                    '01.py',
                    BUILD_DESC_WITH_REVISION.format(revision=checkout_rev_3,
                                                    build_name=build_name))
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
            with Directory('co1'):
                muddle(['status'])
                # Doing 'muddle pull' is the obvious way to get us back to
                # the right revision
                muddle(['pull'])
                check_revision('co1', checkout_rev_3)
                # Because we specified an exact revision, we should be detached
                if not is_detached_head():
                    raise GiveUp('Expected to have a detached HEAD')

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds master <none> <not following>",
            "co1 <none> <none> <not following>"
        ],
                                 fold_whitespace=True)

        # Then the revision after the branch
        with Directory('src'):
            with Directory('builds'):
                touch(
                    '01.py',
                    BUILD_DESC_WITH_REVISION.format(revision=checkout_rev_4,
                                                    build_name=build_name))
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
            with Directory('co1'):
                # We're still on the old revision, and detached
                check_revision('co1', checkout_rev_3)
                # Because we specified an exact revision, we should be detached
                if not is_detached_head():
                    raise GiveUp('Expected to have a detached HEAD')
                rc, text = captured_muddle2(['status'])
                if 'Note that this checkout has a detached HEAD' not in text:
                    raise GiveUp('Expected to be told checkout is in detached'
                                 ' HEAD state, instead got:\n%s' % text)

                # Doing 'muddle pull' is the obvious way to get us back to
                # the right revision
                muddle(['pull'])
                check_revision('co1', checkout_rev_4)
                # Because we specified an exact revision, we should be detached
                if not is_detached_head():
                    raise GiveUp('Expected to have a detached HEAD')

                # But what if we go to "the same place" by a different means?
                git('checkout %s' % checkout_branch)
                muddle(['status'])
                # We're still at the requested revision
                check_revision('co1', checkout_rev_4)
                # But we're no longer a detached HEAD
                if is_detached_head():
                    raise GiveUp('Surprised to have a detached HEAD')
                # muddle pull shouldn't need to do anything...
                text = captured_muddle(['pull'], error_fails=False).strip()
                if not text.endswith('checkout past the specified revision.'):
                    raise GiveUp(
                        'Expected muddle pull to fail trying to go "past" revision:\n%s'
                        % text)

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds master <none> <not following>",
            "co1 this-is-a-branch <none> <not following>"
        ],
                                 fold_whitespace=True)

    # Third build tree, investigating use of "muddle branch-tree"
    with NewCountedDirectory('build3') as d3:
        muddle(['init', repo_url, 'builds/01.py'])
        muddle(['checkout', '_all'])

        # Check the branches of our checkouts
        check_branch('src/builds', 'master')
        check_branch('src/co1', 'master')

        # And change it
        muddle(['branch-tree', 'test-v0.1'])

        # Check the branches of our checkouts - since this isn't using muddle,
        # it should still show both at the new branch
        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')

        # Doing a "mudddle sync" on the checkout should put it back to the
        # master branch, as that's what is (implicitly) asked for in the
        # build description. It shouldn't affect the build description.
        muddle(['sync', 'co1'])
        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'master')

        # If we amend the build description, though:
        print 'Setting build description for "follow my branch"'
        with Directory('src'):
            with Directory('builds'):
                append('01.py',
                       '    builder.follow_build_desc_branch = True\n')
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
        # and sync again, our checkout should now follow the build
        # description's branch
        muddle(['sync', 'co1'])
        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')

        # Let's commit and push...
        with Directory('src'):
            with Directory('builds'):
                git('commit -a -m "Branched"')
                muddle(['push'])
            with Directory('co1'):
                # We hadn't changed any files in our checkout
                muddle(['push'])

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds test-v0.1 <none> <it's own>",
            "co1 test-v0.1 <none> test-v0.1"
        ],
                                 fold_whitespace=True)

    # And a variant like the documentation
    with NewCountedDirectory('build4') as d4:
        muddle(['init', repo_url, 'builds/01.py'])
        muddle(['checkout', '_all'])

        # And change it
        muddle(['branch-tree', 'Widget-v0.1-maintenance'])
        with Directory('src'):
            with Directory('builds'):
                append('01.py',
                       '    builder.follow_build_desc_branch = True\n')
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')

        muddle([
            'runin', '_all_checkouts',
            'git commit -a -m "Create maintenance branch"'
        ])
        muddle(['push', '_all'])

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds Widget-v0.1-maintenance <none> <it's own>",
            "co1 Widget-v0.1-maintenance <none> Widget-v0.1-maintenance"
        ],
                                 fold_whitespace=True)

        muddle(['stamp', 'version'])
        with Directory('versions'):
            check_specific_files_in_this_dir(
                ['.git', 'TestBuild.Widget-v0.1-maintenance.stamp'])

    with NewCountedDirectory('build4a') as d4a:
        muddle([
            'unstamp',
            d4.join('versions', 'TestBuild.Widget-v0.1-maintenance.stamp')
        ])

        # Check we're working with the expected branches
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds Widget-v0.1-maintenance Widget-v0.1-maintenance <it's own>",
            "co1 Widget-v0.1-maintenance <none> Widget-v0.1-maintenance"
        ],
                                 fold_whitespace=True)

        muddle(['stamp', 'version'])
        with Directory('versions'):
            check_specific_files_in_this_dir(
                ['.git', 'TestBuild.Widget-v0.1-maintenance.stamp'])

        # And that stamp file should be identical to the one we had before
        # (if we ignore the first few lines with the timestamp comments)
        with open(
                d4.join('versions',
                        'TestBuild.Widget-v0.1-maintenance.stamp')) as fd:
            that = fd.readlines()
        with open(
                os.path.join('versions',
                             'TestBuild.Widget-v0.1-maintenance.stamp')) as fd:
            this = fd.readlines()
        check_text_lines_v_lines(actual_lines=this[3:], wanted_lines=that[3:])

    with NewCountedDirectory('build5') as d5:
        muddle([
            'init', '-branch', 'Widget-v0.1-maintenance', repo_url,
            'builds/01.py'
        ])
        muddle(['checkout', '_all'])

        # Find out what branches we are working with
        text = captured_muddle(['query', 'checkout-branches'])
        lines = text.splitlines()
        lines = lines[3:]  # ignore the header lines
        check_text_lines_v_lines(lines, [
            "builds Widget-v0.1-maintenance Widget-v0.1-maintenance <it's own>",
            "co1 Widget-v0.1-maintenance <none> Widget-v0.1-maintenance"
        ],
                                 fold_whitespace=True)

        muddle(['stamp', 'version'])
        with Directory('versions'):
            check_specific_files_in_this_dir(
                ['.git', 'TestBuild.Widget-v0.1-maintenance.stamp'])

        # And that stamp file should also be identical to the one we had before
        # (if we ignore the first few lines with the timestamp comments)
        with open(
                d4.join('versions',
                        'TestBuild.Widget-v0.1-maintenance.stamp')) as fd:
            that = fd.readlines()
        with open(
                os.path.join('versions',
                             'TestBuild.Widget-v0.1-maintenance.stamp')) as fd:
            this = fd.readlines()
        check_text_lines_v_lines(actual_lines=this[3:], wanted_lines=that[3:])

        # Now let's push a change
        with Directory('src'):
            with Directory('co1'):
                append('Makefile.muddle', '# This, this is not a change\n')
                git('commit Makefile.muddle -m "But a small thing"')
                muddle(['push'])

        co1_revision_id = captured_muddle(['query', 'checkout-id',
                                           'co1']).strip()

    # And pull it elsewhere
    with Directory(d4a.join('src', 'co1')):
        old_revision_id = captured_muddle(['query', 'checkout-id']).strip()
        muddle(['pull'])
        new_revision_id = captured_muddle(['query', 'checkout-id']).strip()

        if old_revision_id == new_revision_id:
            raise GiveUp('Pull did nothing')

        if new_revision_id != co1_revision_id:
            raise GiveUp('Result of pull was unexpected\n'
                         'got: %s\nnot: %s' %
                         (new_revision_id, co1_revision_id))

    # And let's be really awkward...
    with Directory(d4.join('src', 'co1')):
        git('checkout master')
        rv, text = run2('git branch')
        check_text_v_lines(text, ['  Widget-v0.1-maintenance', '* master'])
        old_revision_id = captured_muddle(['query', 'checkout-id']).strip()

        # We're fondly expecting "muddle pull" to put us back onto the
        # "following" branch
        muddle(['pull'])

        rv, text = run2('git branch')
        check_text_v_lines(text, ['* Widget-v0.1-maintenance', '  master'])
        new_revision_id = captured_muddle(['query', 'checkout-id']).strip()

        if old_revision_id == new_revision_id:
            raise GiveUp('Pull did nothing')

        if new_revision_id != co1_revision_id:
            raise GiveUp('Result of pull was unexpected\n'
                         'got: %s\nnot: %s' %
                         (new_revision_id, co1_revision_id))
Ejemplo n.º 12
0
def test_branch_tree(root_d):
    """Test doing "muddle branch-tree".
    """

    with NewCountedDirectory('branch-tree.repo') as d:
        repo = create_multiplex_repo('test-build')

    with Directory(repo):
        with Directory('co.fred'):
            co_fred_revision = captured_muddle(['query',
                                                'checkout-id']).strip()
        with Directory('co.branch1.fred'):
            co_branch1_fred_revision = captured_muddle(
                ['query', 'checkout-id']).strip()

    with NewCountedDirectory('branch-tree.branch'):
        muddle([
            'init', '-branch', 'branch0', 'git+file://' + repo, 'builds/01.py'
        ])
        muddle(['checkout', '_all'])

        # Our checkouts should be as in the build description
        check_branch('src/builds', 'branch0')
        check_branch('src/co1', 'master')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)
        # This branch of the build description doesn't have co.bzr

        retcode, text = captured_muddle2(['branch-tree', 'test-v0.1'])
        if retcode != 1:
            raise GiveUp("Expected 'muddle branch-tree test-v0.1 to fail with"
                         " retcode 1, got %d" % retcode)
        check_text_endswith(
            text, """\
Unable to branch-tree to test-v0.1, because:
  checkout:co.branch1.fred/checked_out explicitly specifies revision "fred" in the build description
  checkout:co.branch1/checked_out explicitly specifies branch "branch1" in the build description
  checkout:co.fred/checked_out explicitly specifies revision "fred" in the build description
""")

        # OK, force it
        muddle(['branch-tree', '-f', 'test-v0.1'])

        # And those checkouts without explicit branch/revision should now be
        # branched
        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        # But if we sync...
        muddle(['sync', '_all'])
        # We should undo that...
        check_branch('src/builds', 'branch0')
        check_branch('src/co1', 'master')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        # Try again
        muddle(['branch-tree', '-f', 'test-v0.1'])

        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        # Now amend the build description so things follow it
        with Directory('src'):
            with Directory('builds'):
                touch('01.py', NO_BZR_BUILD_DESC + FOLLOW_LINE)
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')

        muddle(['sync', '-v', '_all'])

        # And this time, things should follow the build description if they're
        # allowed to
        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        # If we make amendments to the checkouts that are "following", can
        # we push them?
        with Directory('src'):
            with Directory('builds'):
                append('01.py', '# This should make no difference\n')
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
                git('commit -a -m "Add a comment at the end"')
                muddle(['push'])
            with Directory('co1'):
                append('Makefile.muddle', '# This should make no difference\n')
                git('commit -a -m "Add a comment at the end"')
                muddle(['push'])

    # Let's see if that took
    with NewCountedDirectory('branch-tree.cloned'):
        muddle([
            'init', '-branch', 'test-v0.1', 'git+file://' + repo,
            'builds/01.py'
        ])
        muddle(['checkout', '_all'])

        check_branch('src/builds', 'test-v0.1')
        check_branch('src/co1', 'test-v0.1')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        with Directory('src'):
            with Directory('builds'):
                with open('01.py') as fd:
                    text = fd.read()
                check_text_endswith(text, '# This should make no difference\n')
            with Directory('co1'):
                with open('Makefile.muddle') as fd:
                    text = fd.read()
                check_text_endswith(text, '# This should make no difference\n')

    # And another variation
    with NewCountedDirectory('branch-tree.cloned'):
        muddle([
            'init', '-branch', 'branch.follow', 'git+file://' + repo,
            'builds/01.py'
        ])
        muddle(['checkout', '_all'])

        check_branch('src/builds', 'branch.follow')
        check_branch('src/co1', 'branch.follow')
        check_branch('src/co.branch1', 'branch1')
        check_revision('co.fred', co_fred_revision)
        check_revision('co.branch1.fred', co_branch1_fred_revision)

        muddle(['branch-tree', '-f', 'test-v0.1'])

        with Directory('src'):
            with Directory('builds'):
                with open('01.py') as fd:
                    text = fd.read()
                check_text_endswith(text, '# This should make no difference\n')
            with Directory('co1'):
                with open('Makefile.muddle') as fd:
                    text = fd.read()
                check_text_endswith(text, '# This should make no difference\n')
Ejemplo n.º 13
0
def test_init_with_branch(root_d):
    """Test muddle init:

    * without a branch name
    * with a branch name, but not following the build description
    * with a branch name, and following the build description
    """

    with NewCountedDirectory('init.branch.repo') as d:
        repo = create_multiplex_repo('test-build')

    with NewCountedDirectory('init.with.no.branch'):
        muddle(['init', 'git+file://' + repo, 'builds/01.py'])
        muddle(['checkout', '_all'])
        with Directory('src'):
            with Directory('builds'):
                check_file_v_text('01.py', EMPTY_BUILD_DESC)
            # And our empty build description should not have checked any
            # of our checkouts out
            for name in ('co1', 'co.branch1', 'co.fred', 'co.branch1.fred'):
                if os.path.isdir(name):
                    raise GiveUp('Unexpectedly found "%s" directory' % name)

    with NewCountedDirectory('init.with.branch1.no.follow'):
        muddle([
            'init', '-branch', 'branch1', 'git+file://' + repo, 'builds/01.py'
        ])
        muddle(['checkout', '_all'])
        with Directory('src'):
            with Directory('builds'):
                check_file_v_text('01.py', NONFOLLOW_BUILD_DESC)
            # The build description did not ask us to follow it
            with Directory('co1'):
                # -- root
                check_specific_files_in_this_dir(['.git', 'Makefile.muddle'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
            with Directory('co.branch1'):
                # -- branch1
                check_specific_files_in_this_dir(
                    ['.git', 'Makefile.muddle', 'README.txt'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
                check_file_v_text('README.txt', EMPTY_README_TEXT)
            with Directory('co.fred'):
                # Revision 'fred' == tag on branch 'branch.follow'
                check_specific_files_in_this_dir(
                    ['.git', 'Makefile.muddle', 'README.txt', 'program3.c'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
                check_file_v_text('README.txt', EMPTY_README_TEXT)
                check_file_v_text('program3.c', EMPTY_C_FILE)
                # If we attempt to 'muddle pull' in the checkout, that should
                # fail because we are already at the requested revision
                # (even though that revision was specified as a tag)
                text = captured_muddle(['pull', 'co.fred'],
                                       error_fails=False).strip()
                if not text.endswith('checkout past the specified revision.'):
                    raise GiveUp(
                        'Expected muddle pull to fail trying to go "past" revision:\n%s'
                        % text)
            with Directory('co.branch1.fred'):
                # Revision 'fred' and branch 'branch1' - the revision wins
                # -- fred
                check_specific_files_in_this_dir(
                    ['.git', 'Makefile.muddle', 'README.txt', 'program4.c'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
                check_file_v_text('README.txt', EMPTY_README_TEXT)
                check_file_v_text('program4.c', EMPTY_C_FILE)
                # If we attempt to 'muddle pull' in the checkout, that should
                # fail because we are already at the requested revision
                # (even though that revision was specified as a tag)
                text = captured_muddle(['pull', 'co.fred'],
                                       error_fails=False).strip()
                if not text.endswith('checkout past the specified revision.'):
                    raise GiveUp(
                        'Expected muddle pull to fail trying to go "past" revision:\n%s'
                        % text)
            with Directory('co.bzr'):
                # Since this is using bzr, we always get HEAD
                check_specific_files_in_this_dir(
                    ['.bzr', 'Makefile.muddle', 'README.txt', 'program5.c'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
                check_file_v_text('README.txt', EMPTY_README_TEXT)
                check_file_v_text('program5.c', EMPTY_C_FILE)

    with NewCountedDirectory('init.branch.with.branch1.follow'):
        muddle([
            'init', '-branch', 'branch.follow', 'git+file://' + repo,
            'builds/01.py'
        ])
        muddle(['checkout', '_all'])
        with Directory('src'):
            with Directory('builds'):
                check_file_v_text('01.py', FOLLOW_BUILD_DESC)
            with Directory('co1'):
                # The build description asked us to follow it
                check_specific_files_in_this_dir(
                    ['.git', 'Makefile.muddle', 'README.txt', 'program1.c'])
                check_file_v_text('Makefile.muddle', MUDDLE_MAKEFILE)
                check_file_v_text('README.txt', EMPTY_README_TEXT)
                check_file_v_text('program1.c', EMPTY_C_FILE)

    with NewCountedDirectory('init.branch.with.branch1.bzr.follow.error'):
        muddle([
            'init', '-branch', 'branch.follow', 'git+file://' + repo,
            'builds/01.py'
        ])
        # Now let us make the build description erroneous, by changing it so
        # that the Bazaar checkout is also required to follow the build
        # description
        with Directory('src'):
            with Directory('builds'):
                touch('01.py', NONFOLLOW_BUILD_DESC + FOLLOW_LINE)
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
        # And our checkout all should now fail...
        retcode, text = captured_muddle2(['checkout', '_all'])
        if retcode != 1:
            raise GiveUp(
                'Expected retcode 1 from "muddle checkout _all", got %d' %
                retcode)
        check_text_endswith(
            text, """\
The build description wants checkouts to follow branch 'branch.follow',
but checkout co.bzr uses VCS Bazaar for which we do not support branching.
The build description should specify a revision for checkout co.bzr,
or specify the 'no_follow' option.
""")

    with NewCountedDirectory('init.branch.with.branch1.bzr.no_follow.option'):
        muddle([
            'init', '-branch', 'branch.follow', 'git+file://' + repo,
            'builds/01.py'
        ])
        # Now let us make a build description in which our Bazaar checkout
        # specifically says it should not follow the build description
        with Directory('src'):
            with Directory('builds'):
                touch('01.py',
                      NO_BZR_BUILD_DESC + BZR_CO_NO_FOLLOW + FOLLOW_LINE)
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
        # And our checkout _all should now be OK...
        muddle(['checkout', '_all'])

    with NewCountedDirectory(
            'init.branch.with.branch1.nobranch.follow.error') as d:
        muddle([
            'init', '-branch', 'branch.follow', 'git+file://' + repo,
            'builds/01.py'
        ])
        # Now let us make the build description erroneous, by changing it so
        # that we have co6, which does not have branch branch.follow
        # description
        with Directory('src'):
            with Directory('builds'):
                touch('01.py',
                      FOLLOW_BUILD_DESC + CO6_WHICH_HAS_NO_BRANCH_FOLLOW)
                # Then remove the .pyc file, because Python probably won't realise
                # that this new 01.py is later than the previous version
                os.remove('01.pyc')
        # And our checkout all should now fail...
        retcode, text = captured_muddle2(['checkout', '_all'])
        if retcode != 1:
            raise GiveUp(
                'Expected retcode 1 from "muddle checkout _all", got %d' %
                retcode)
        # The error text we get isn't particularly friendly, but should do
        check_text_endswith(
            text, """\
Cloning into 'co6'...
fatal: Remote branch branch.follow not found in upstream origin
fatal: The remote end hung up unexpectedly

Failure checking out checkout:co6/checked_out in {where}/src:
Command 'git clone -b branch.follow file://{repo}/co6 co6' failed with retcode 128
""".format(where=d.where, repo=repo))
Ejemplo n.º 14
0
def main(args):

    keep = False
    if args:
        if len(args) == 1 and args[0] == '-keep':
            keep = True
        else:
            print __doc__
            raise GiveUp('Unexpected arguments %s' % ' '.join(args))

    # Working in a local transient directory seems to work OK
    # although if it's anyone other than me they might prefer
    # somewhere in $TMPDIR...
    root_dir = normalise_dir(os.path.join(os.getcwd(), 'transient'))

    with TransientDirectory(root_dir, keep_on_error=True,
                            keep_anyway=keep) as root_d:
        banner('MAKE REPOSITORIES')
        make_repos_with_subdomain(root_dir)

        with NewCountedDirectory('build.original') as d1:
            banner('CHECK REPOSITORIES OUT INTO FIRST BUILD')
            checkout_build_descriptions(root_dir, d1)
            muddle(['checkout', '_all'])
            orig_dir = d1.where

        banner('TEST A SIMPLE CHANGE')
        # With an insignificant change, this should work identically by
        # both mechanisms

        with NewCountedDirectory('build.simple.noreload.pull') as d2:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_build_descriptions(root_dir, d2)
            muddle(['checkout', '_all'])
            pass1_noreload_dir = d2.where

        with NewCountedDirectory('build.simple.default.pull') as d3:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_build_descriptions(root_dir, d3)
            muddle(['checkout', '_all'])
            pass1_default_dir = d3.where

        with Directory(orig_dir) as d:
            banner('AMEND SUB1 BUILD DESCRIPTION AND PUSH', 2)
            amend_sub1_build_desc_and_push(root_dir, d)

        with Directory(pass1_noreload_dir) as d:
            banner('PULL IN THE ORIGINAL MANNER', 2)
            muddle(['pull', '-noreload', '_all'])
            check_original_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)builds/checked_out\n',
            ])

        with Directory(pass1_default_dir) as d:
            banner('PULL WITH BUILD DESCRIPTIONS PULLED FIRST', 2)
            muddle(['pull', '_all'])
            check_original_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)builds/checked_out\n',
            ])

        banner('TEST A MORE COMPLICATED CHANGE')
        # Since we're changing the layout of the build, this should
        # work substantially differently by the two mechanisms

        with NewCountedDirectory('build.swap.noreload.pull') as d2:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_build_descriptions(root_dir, d2)
            muddle(['checkout', '_all'])
            pass2_noreload_dir = d2.where

        with NewCountedDirectory('build.swap.default.pull') as d3:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_build_descriptions(root_dir, d3)
            muddle(['checkout', '_all'])
            pass2_default_dir = d3.where

        with Directory(orig_dir) as d:
            banner('SWAP SUBDOMAIN BUILD DESCRIPTIONS AND PUSH', 2)
            swap_subdomains_and_push(root_dir, d)

        with Directory(pass2_noreload_dir) as d:
            banner('PULL IN THE ORIGINAL MANNER', 2)
            banner('PULL THE FIRST', 3)
            muddle(['pull', '-noreload', '_all'])
            check_original_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)builds/checked_out\n',
                'checkout:(sub2)builds/checked_out\n',
            ])
            banner('PULL THE SECOND', 3)
            # Our *second* pull should bring us to the same place as the
            # single pull with the "slow" mechanism would achieve.
            #
            # Note that it shouldn't matter where in the build tree we
            # do this command from...
            with Directory('src'):
                with Directory('builds'):
                    muddle(['pull', '-noreload', '_all'])
            # We should have files following the amended build description
            check_amended_build_descs(d)
            # But we have not deleted the files from the original description
            check_original_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1(sub4))co0/checked_out\n',
                'checkout:(sub1(sub5))co0/checked_out\n',
                'checkout:(sub2(sub3))co0/checked_out\n',
            ])

        with Directory(pass2_default_dir) as d:
            banner('PULL WITH BUILD DESCRIPTIONS PULLED FIRST', 2)
            # Note that it shouldn't matter where in the build tree we
            # do this command from...
            with Directory('src'):
                with Directory('builds'):
                    muddle(['pull', '_all'])
            # We should have files following the amended build description
            check_amended_build_descs(d)
            # But we have not deleted the files from the original description
            check_original_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)builds/checked_out\n',
                'checkout:(sub1(sub4))builds/checked_out\n',
                'checkout:(sub1(sub4))co0/checked_out\n',
                'checkout:(sub1(sub5))builds/checked_out\n',
                'checkout:(sub1(sub5))co0/checked_out\n',
                'checkout:(sub2)builds/checked_out\n',
                'checkout:(sub2(sub3))builds/checked_out\n',
                'checkout:(sub2(sub3))co0/checked_out\n',
            ])

        banner('TEST NOT CHANGING THE BUILD DESCRIPTIONS')
        # This should work identically by both mechanisms

        with NewCountedDirectory('build.nodesc.noreload.pull') as d2:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_amended_build_descriptions(root_dir, d2)
            muddle(['checkout', '_all'])
            pass3_noreload_dir = d2.where

        with NewCountedDirectory('build.nodesc.default.pull') as d3:
            banner('CHECK REPOSITORIES OUT', 2)
            checkout_amended_build_descriptions(root_dir, d3)
            muddle(['checkout', '_all'])
            pass3_default_dir = d3.where

        with Directory(orig_dir) as d:
            banner('CHANGE SOMETHING NOT A BUILD DESCRIPTION AND PUSH', 2)
            change_something_else_and_push(root_dir, d)

        with Directory(pass3_noreload_dir) as d:
            banner('PULL IN THE ORIGINAL MANNER', 2)
            muddle(['pull', '-noreload', '_all'])
            check_amended_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)co0/checked_out\n',
            ])

        with Directory(pass3_default_dir) as d:
            banner('PULL WITH BUILD DESCRIPTIONS PULLED FIRST', 2)
            muddle(['pull', '_all'])
            check_amended_build_descs(d)
            check_file_v_text(d.join('.muddle', '_just_pulled'), [
                'checkout:(sub1)co0/checked_out\n',
            ])
Ejemplo n.º 15
0
def test_guess_version_number(d, repo):
    banner('TEST GUESS VERSION NUMBER')
    banner('Check out build tree, and stamp it as a release', 2)
    with NewCountedDirectory('build.version-number') as build1:
        r = 'git+file://{repo}/main'.format(repo=repo)
        d = 'builds/01.py'
        v = '{root}/versions'.format(root=r)
        muddle(['init', r, d])
        muddle(['checkout', '_all'])
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir(['.git', 'simple_v0.0.release'])

        touch('versions/simple_v0.01.release', '')
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir([
                '.git',
                'simple_v0.0.release',
                'simple_v0.01.release',
                'simple_v0.2.release',
            ])

        # Whilst 0.03 and 0.3 are "the same" version, that doesn't matter
        # if they already exist - we only care about the next version
        touch('versions/simple_v0.3.release', '')
        touch('versions/simple_v0.03.release', '')
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir([
                '.git',
                'simple_v0.0.release',
                'simple_v0.01.release',
                'simple_v0.2.release',
                'simple_v0.03.release',
                'simple_v0.3.release',
                'simple_v0.03.release',
                'simple_v0.4.release',
            ])

        # We require major.minor, not any other variation - we won't
        # take notice of a file that doesn't match
        touch('versions/simple_v3.release', '')
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir([
                '.git',
                'simple_v0.0.release',
                'simple_v0.01.release',
                'simple_v0.2.release',
                'simple_v0.03.release',
                'simple_v0.3.release',
                'simple_v0.03.release',
                'simple_v0.4.release',
                'simple_v0.5.release',
                'simple_v3.release',
            ])
        touch('versions/simple_v3.1.1.release', '')
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir([
                '.git',
                'simple_v0.0.release',
                'simple_v0.01.release',
                'simple_v0.2.release',
                'simple_v0.03.release',
                'simple_v0.3.release',
                'simple_v0.03.release',
                'simple_v0.4.release',
                'simple_v0.5.release',
                'simple_v0.6.release',
                'simple_v3.release',
                'simple_v3.1.1.release',
            ])

        touch('versions/simple_v1.999999999.release', '')
        muddle(['stamp', 'release', 'simple', '-next'])
        with Directory('versions'):
            check_specific_files_in_this_dir([
                '.git',
                'simple_v0.0.release',
                'simple_v0.01.release',
                'simple_v0.2.release',
                'simple_v0.03.release',
                'simple_v0.3.release',
                'simple_v0.03.release',
                'simple_v0.4.release',
                'simple_v0.5.release',
                'simple_v0.6.release',
                'simple_v3.release',
                'simple_v3.1.1.release',
                'simple_v1.999999999.release',
                'simple_v1.1000000000.release',
            ])
Ejemplo n.º 16
0
def main(args):

    keep = False
    if args:
        if len(args) == 1 and args[0] == '-keep':
            keep = True
        else:
            print __doc__
            raise GiveUp('Unexpected arguments %s' % ' '.join(args))

    # Working in a local transient directory seems to work OK
    # although if it's anyone other than me they might prefer
    # somewhere in $TMPDIR...
    root_dir = normalise_dir(os.path.join(os.getcwd(), 'transient'))

    with TransientDirectory(root_dir, keep_on_error=True,
                            keep_anyway=keep) as root:

        banner('MAKE REPOSITORIES')
        make_repos(root_dir)

        with NewCountedDirectory('build') as d:
            banner('CHECK REPOSITORIES OUT')
            muddle([
                'init',
                'git+file://{repo}/main'.format(repo=root.join('repo')),
                'builds/01.py'
            ])
            muddle(['checkout', '_all'])
            banner('BUILD')
            muddle([])
            banner('STAMP VERSION')
            muddle(['stamp', 'version'])

            with Directory(g_UPSTREAMS['repo1.1']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master'])
            with Directory(g_UPSTREAMS['repo1.2']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master'])
            with Directory(g_UPSTREAMS['repo1.3']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master'])

            banner('CHECK USING UPSTREAMS')
            test_using_upstreams(root_dir)

            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds master <none> <not following>",
                "co_repo1 master <none> <not following>",
                "(subdomain1)builds master <none> <not following>",
                "(subdomain1)co_repo1 master <none> <not following>",
                "(subdomain2)builds master <none> <not following>",
                "(subdomain2)co_repo1.1 master <none> <not following>"
            ],
                                     fold_whitespace=True)

            # What happens if we try to "follow" a subdomain?
            with Directory('domains'):
                with Directory('subdomain1'):
                    with Directory('src'):
                        with Directory('builds'):
                            append(
                                '01.py',
                                '    builder.follow_build_desc_branch = True\n'
                            )
                            # Then remove the .pyc file, because Python probably won't realise
                            # that this new 01.py is later than the previous version
                            os.remove('01.pyc')

            # It shouldn't make a difference - only the top-level build
            # description gets followed
            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds master <none> <not following>",
                "co_repo1 master <none> <not following>",
                "(subdomain1)builds master <none> <not following>",
                "(subdomain1)co_repo1 master <none> <not following>",
                "(subdomain2)builds master <none> <not following>",
                "(subdomain2)co_repo1.1 master <none> <not following>"
            ],
                                     fold_whitespace=True)

            # Even if we branch that build description...
            with Directory('domains'):
                with Directory('subdomain1'):
                    with Directory('src'):
                        with Directory('builds'):
                            git('branch Fred')

            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds master <none> <not following>",
                "co_repo1 master <none> <not following>",
                "(subdomain1)builds master <none> <not following>",
                "(subdomain1)co_repo1 master <none> <not following>",
                "(subdomain2)builds master <none> <not following>",
                "(subdomain2)co_repo1.1 master <none> <not following>"
            ],
                                     fold_whitespace=True)

            banner('BRANCH TREE')
            muddle(['branch-tree', 'v1-maintenance'])
            print 'Setting build description for "follow my branch"'
            with Directory('src'):
                with Directory('builds'):
                    append('01.py',
                           '    builder.follow_build_desc_branch = True\n')
                    # Then remove the .pyc file, because Python probably won't realise
                    # that this new 01.py is later than the previous version
                    os.remove('01.pyc')

            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds v1-maintenance <none> <it's own>",
                "co_repo1 v1-maintenance <none> v1-maintenance",
                "(subdomain1)builds v1-maintenance <none> v1-maintenance",
                "(subdomain1)co_repo1 v1-maintenance <none> v1-maintenance",
                "(subdomain2)builds v1-maintenance <none> v1-maintenance",
                "(subdomain2)co_repo1.1 v1-maintenance <none> v1-maintenance"
            ],
                                     fold_whitespace=True)

            muddle([
                'runin', '_all_checkouts',
                'git commit -a -m "Create maintenance branch"'
            ])
            muddle(['push', '_all'])

        # The push causes "(subdomain2)co_repo1.1" to push to our "repo1.1",
        # which it is using as its "local" repository, so we see our branch
        # already there
        with Directory(g_UPSTREAMS['repo1.1']):
            text = get_stdout('git branch -a')
            check_text_v_lines(text, ['* master', '  v1-maintenance'])
        with Directory(g_UPSTREAMS['repo1.2']):
            text = get_stdout('git branch -a')
            check_text_v_lines(text, ['* master'])
        with Directory(g_UPSTREAMS['repo1.3']):
            text = get_stdout('git branch -a')
            check_text_v_lines(text, ['* master'])

        with NewCountedDirectory('rebuild') as d:
            banner('CHECK REPOSITORIES OUT BRANCHED')
            muddle([
                'init', '-branch', 'v1-maintenance',
                'git+file://{repo}/main'.format(repo=root.join('repo')),
                'builds/01.py'
            ])

            # The subdomain build descriptions should be following the
            # top level build description
            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds v1-maintenance v1-maintenance <it's own>",
                "co_repo1 <can't tell> <none> v1-maintenance",
                "(subdomain1)builds v1-maintenance <none> v1-maintenance",
                "(subdomain1)co_repo1 <can't tell> <none> v1-maintenance",
                "(subdomain2)builds v1-maintenance <none> v1-maintenance",
                "(subdomain2)co_repo1.1 <can't tell> <none> v1-maintenance"
            ],
                                     fold_whitespace=True)

            muddle(['checkout', '_all'])
            text = captured_muddle(['query', 'checkout-branches'])
            lines = text.splitlines()
            lines = lines[3:]  # ignore the header lines
            check_text_lines_v_lines(lines, [
                "builds v1-maintenance v1-maintenance <it's own>",
                "co_repo1 v1-maintenance <none> v1-maintenance",
                "(subdomain1)builds v1-maintenance <none> v1-maintenance",
                "(subdomain1)co_repo1 v1-maintenance <none> v1-maintenance",
                "(subdomain2)builds v1-maintenance <none> v1-maintenance",
                "(subdomain2)co_repo1.1 v1-maintenance <none> v1-maintenance"
            ],
                                     fold_whitespace=True)

            # What happens if we push upstream?
            muddle(['push-upstream', 'co_repo1', '-u', 'rhubarb', 'platypus'])
            # That should succeed, as we're allowed to push to both of those
            # And now we should see our branch on repo1.3 as well
            with Directory(g_UPSTREAMS['repo1.1']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master', '  v1-maintenance'])
            with Directory(g_UPSTREAMS['repo1.2']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master'])
            with Directory(g_UPSTREAMS['repo1.3']):
                text = get_stdout('git branch -a')
                check_text_v_lines(text, ['* master', '  v1-maintenance'])

            # If we try to pull upstream from wombat, we should fail
            # as it does not have our branch
            retcode, text = captured_muddle2(
                ['pull-upstream', 'co_repo1', '-u', 'wombat'])
            if not retcode:
                raise GiveUp("Expected error trying to pull from wombat, but"
                             " got %d:\n%s" % (retcode, text))
            if "fatal: remotes/wombat/v1-maintenance - not something we can merge" not in text:
                raise GiveUp(
                    "Expected error 'fatal: remotes/wombat/v1-maintenance"
                    " - not something we can merge' trying to pull from"
                    " wombat, but got:\n%s" % text)