Exemple #1
0
def remove_patches(directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?")
        return 1
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "remove patches.")
            return 1
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        parent, spec = config['parent'], config['base']
        if None in [parent, spec]:
            error("Could not retrieve patches info.")
            return 1
        debug("Removing patches from " + current_branch + " back to base "
              "commit " + spec)
        # Reset this branch using git reset --hard spec
        execute_command('git reset --hard ' + spec, cwd=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
    return 0
def test_fuerte_package_repository(directory=None):
    """
    Release a single catkin stack (fuerte) repository.
    """
    directory = directory if directory is not None else os.getcwd()
    # Setup
    upstream_url = create_upstream_catkin_fuerte_repository('foo', directory)
    release_url = create_release_repo(upstream_url, 'git', 'fuerte_devel')
    release_dir = os.path.join(directory, 'foo_release_clone')
    release_client = VcsClient('git', release_dir)
    release_client.checkout(release_url)
    with change_directory(release_dir):
        ###
        ### Import upstream
        ###
        user('git-bloom-import-upstream --quiet')
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/0.1.0 tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/0.1.0') == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            assert os.path.exists('stack.xml'), \
                   "upstream did not import: '" + os.getcwd() + "': " + \
                   str(os.listdir(os.getcwd()))
            assert open('stack.xml').read().count('0.1.0'), "not right file"

        ###
        ### Release generator
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y release -s upstream --quiet')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/foo'), "no release/foo branch: " + \
                                             str(get_branches())
        assert branch_exists('patches/release/foo'), \
               "no patches/release/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/foo/0.1.0') == 1, "no release tag created"

        ###
        ### Release generator, again
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y release -s upstream --quiet')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/foo'), "no release/foo branch: " + \
                                             str(get_branches())
        assert branch_exists('patches/release/foo'), \
               "no patches/release/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/foo/0.1.0') == 1, "no release tag created"
Exemple #3
0
def upconvert_bloom_to_config_branch():
    global _has_checked_bloom_branch
    if _has_checked_bloom_branch:
        return
    # Assert that this repository does not have multiple remotes
    check_for_multiple_remotes()
    if get_root() is None:
        # Not a git repository
        return
    track_branches(['bloom', BLOOM_CONFIG_BRANCH])
    if show('bloom', PLACEHOLDER_FILE) is not None:
        return
    if show('bloom', 'bloom.conf') is not None:
        # Wait for the bloom.conf upconvert...
        return
    if not branch_exists('bloom'):
        return
    _has_checked_bloom_branch = True
    info("Moving configurations from deprecated 'bloom' branch "
         "to the '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
    tmp_dir = mkdtemp()
    git_root = get_root()
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch('bloom'):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            configs = os.path.join(tmp_dir, 'configs')
            my_copytree(git_root, configs, ignores)
            if [x for x in os.listdir(os.getcwd()) if x not in ignores]:
                execute_command('git rm -rf ./*')
            with open(PLACEHOLDER_FILE, 'w') as f:
                f.write("""\
This branch ('bloom') has been deprecated in favor of storing settings and overlay files in the master branch.

Please goto the master branch for anything which referenced the bloom branch.

You can delete this branch at your convenience.
""")
            execute_command('git add ' + PLACEHOLDER_FILE)
            if has_changes():
                execute_command('git commit -m "DEPRECATING BRANCH"')
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
            create_branch(BLOOM_CONFIG_BRANCH, orphaned=True)
        with inbranch(BLOOM_CONFIG_BRANCH):
            my_copytree(configs, git_root)
            execute_command('git add ./*')
            if has_changes():
                execute_command('git commit -m '
                                '"Moving configs from bloom branch"')
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Exemple #4
0
def upconvert_bloom_to_config_branch():
    global _has_checked_bloom_branch
    if _has_checked_bloom_branch:
        return
    # Assert that this repository does not have multiple remotes
    check_for_multiple_remotes()
    if get_root() is None:
        # Not a git repository
        return
    track_branches(['bloom', BLOOM_CONFIG_BRANCH])
    if show('bloom', PLACEHOLDER_FILE) is not None:
        return
    if show('bloom', 'bloom.conf') is not None:
        # Wait for the bloom.conf upconvert...
        return
    if not branch_exists('bloom'):
        return
    _has_checked_bloom_branch = True
    info("Moving configurations from deprecated 'bloom' branch "
         "to the '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
    tmp_dir = mkdtemp()
    git_root = get_root()
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch('bloom'):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            configs = os.path.join(tmp_dir, 'configs')
            my_copytree(git_root, configs, ignores)
            if [x for x in os.listdir(os.getcwd()) if x not in ignores]:
                execute_command('git rm -rf ./*')
            with open(PLACEHOLDER_FILE, 'w') as f:
                f.write("""\
This branch ('bloom') has been deprecated in favor of storing settings and overlay files in the master branch.

Please goto the master branch for anything which referenced the bloom branch.

You can delete this branch at your convenience.
""")
            execute_command('git add ' + PLACEHOLDER_FILE)
            if has_changes():
                execute_command('git commit -m "DEPRECATING BRANCH"')
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
            create_branch(BLOOM_CONFIG_BRANCH, orphaned=True)
        with inbranch(BLOOM_CONFIG_BRANCH):
            my_copytree(configs, git_root)
            execute_command('git add ./*')
            if has_changes():
                execute_command('git commit -m '
                                '"Moving configs from bloom branch"')
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Exemple #5
0
def import_patches(directory=None):
    # Get current branch
    current_branch = get_current_branch(directory)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists and is tracked
    if branch_exists(patches_branch, False, directory=directory):
        if not branch_exists(patches_branch, True, directory=directory):
            track_branches(patches_branch, directory)
    else:
        error("The patches branch ({0}) does not ".format(patches_branch) + \
              "exist, did you use git-bloom-branch?")
        return code.BRANCH_DOES_NOT_EXIST
    # Create a swap space
    tmp_dir = tempfile.mkdtemp()
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        parent_branch, commit = config['parent'], config['base']
        if commit != get_commit_hash(current_branch, directory):
            warning("The current commit is not the same as the most recent "
                    "rebase commit. This might mean that you have committed "
                    "since the last time you did 'git-bloom-patch export'.")
            return code.PATCHES_NOT_EXPORTED
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Copy the patches to a temp location
        patches = list_patches(directory)
        if len(patches) == 0:
            debug("No patches in the patches branch, nothing to do")
            return code.NOTHING_TO_DO
        tmp_dir_patches = []
        for patch in patches:
            tmp_dir_patches.append(os.path.join(tmp_dir, patch))
            if directory is not None:
                patch = os.path.join(directory, patch)
            shutil.copy(patch, tmp_dir)
        # Now checkout back to the original branch and import them
        checkout(current_branch, directory=directory)
        cmd = 'git am {0}*.patch'.format(tmp_dir + os.sep)
        execute_command(cmd, cwd=directory)
        # Notify the user
        info("Applied {0} patches".format(len(patches)))
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
    return 0
Exemple #6
0
def main(sysargs=None):
    if len(sysargs if sysargs is not None else sys.argv[1:]) == 0:
        # This means show me the current config, first check we have an env
        ensure_clean_working_env()
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            sys.exit("No {0} branch found".format(BLOOM_CONFIG_BRANCH))
        show_current()
        info("See: 'git-bloom-config -h' on how to change the configs")
        return 0

    parser = get_argument_parser()
    add_global_arguments(parser)
    args = parser.parse_args(sysargs)
    handle_global_arguments(args)

    # Also check to see if git has been init'ed
    check_git_init()
    # Check that the current directory is a serviceable git/bloom repo
    try:
        ensure_clean_working_env()
        ensure_git_root()
    except SystemExit:
        parser.print_usage()
        raise
    # Then call the verb
    try:
        args.func(args)
    except (KeyboardInterrupt, EOFError):
        error("\nUser sent a Keyboard Interrupt, aborting.", exit=True)
Exemple #7
0
def get_changelog_summary(release_tag):
    summary = ""
    for package in get_packages().values():
        release_branch = '/'.join(release_tag.split('/')[:-1]).format(package=package.name)
        if not branch_exists(release_branch):
            continue
        with inbranch(release_branch):
            changelog = get_changelog_from_path(os.getcwd())
            if changelog is None:
                continue
            for version, date, changes in changelog.foreach_version():
                if version == package.version:
                    msgs = []
                    for change in changes:
                        msgs.extend([i for i in to_unicode(change).splitlines()])
                    msg = '\n'.join(msgs)
                    summary += """
## {package.name}
""".format(**locals())
                    if msg:
                        summary += """
```
{msg}
```
""".format(**locals())
                    else:
                        summary += """
- No changes
"""
    return summary
Exemple #8
0
def main(sysargs=None):
    if len(sysargs if sysargs is not None else sys.argv[1:]) == 0:
        # This means show me the current config, first check we have an env
        ensure_clean_working_env()
        if not branch_exists('bloom'):
            sys.exit("No bloom branch found")
        show_current()
        info("See: 'git-bloom-config -h' on how to change the configs")
        return 0

    parser = get_argument_parser()
    add_global_arguments(parser)
    args = parser.parse_args(sysargs)
    handle_global_arguments(args)

    # Also check to see if git has been init'ed
    check_git_init()
    # Check that the current directory is a serviceable git/bloom repo
    try:
        ensure_clean_working_env()
        ensure_git_root()
    except SystemExit:
        parser.print_usage()
        raise
    # Then call the verb
    try:
        args.func(args)
    except (KeyboardInterrupt, EOFError):
        error("\nUser sent a Keyboard Interrupt, aborting.", exit=True)
Exemple #9
0
def set_upstream(upstream_repo, upstream_repo_type, upstream_repo_branch):
    # Check for a bloom branch
    if branch_exists('bloom', False):
        # Found a bloom branch
        debug("Found a bloom branch, checking out.")
        # Check out the bloom branch
        checkout('bloom')
    else:
        # No bloom branch found, create one
        create_branch('bloom', changeto=True)

    # Now set the upstream using the bloom config
    cmd = 'git config -f bloom.conf bloom.upstream "{0}"'.format(upstream_repo)
    execute_command(cmd)
    cmd = 'git config -f bloom.conf ' \
        + 'bloom.upstreamtype "{0}"'.format(upstream_repo_type)
    execute_command(cmd)
    cmd = 'git config -f bloom.conf ' \
        + 'bloom.upstreambranch "{0}"'.format(upstream_repo_branch)
    execute_command(cmd)

    execute_command('git add bloom.conf')
    if has_changes():
        cmd = 'git commit -m "bloom branch update by git-bloom-config"'
        execute_command(cmd)
    else:
        debug("No chages, nothing to commit.")
Exemple #10
0
def trim(sub_dir=None, force=False, undo=False, directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?")
        return code.NOT_ON_A_GIT_BRANCH
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "perform trim.")
            return code.BRANCH_DOES_NOT_EXIST
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        if config is None:
            error("Could not retrieve patches info.")
            return code.COULD_NOT_GET_PATCH_INFO
        # If sub_dir is set, try to set it
        new_config = _set_trim_sub_dir(sub_dir, force, config, directory)
        if new_config is None:
            return code.COULD_NOT_TRIM
        # Perform trime or undo
        if undo:
            new_config = _undo(new_config, directory)
            if new_config is None:
                return code.NOTHING_TO_DO
        else:
            new_config = _trim(new_config, force, directory)
        if new_config is None:
            return code.COULD_NOT_TRIM
        # Commit the new config
        set_patch_config(patches_branch, new_config, directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
    return code.OK
Exemple #11
0
def trim(sub_dir=None, force=False, undo=False, directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?",
              exit=True)
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "perform trim.",
                  exit=True)
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        if config is None:
            error("Could not retrieve patches info.", exit=True)
        # If sub_dir is set, try to set it
        new_config = _set_trim_sub_dir(sub_dir, force, config, directory)
        if new_config is None:
            sys.exit('Could not perform trim')
        # Perform trime or undo
        if undo:
            new_config = _undo(new_config, directory)
            if new_config is None:
                return -1  # Indicates that nothing was done
        else:
            new_config = _trim(new_config, force, directory)
        if new_config is None:
            sys.exit('Could not perform trim')
        # Commit the new config
        set_patch_config(patches_branch, new_config, directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #12
0
def export_upstream(uri, tag, vcs_type, output_dir, show_uri, name):
    tag = tag if tag != ":{none}" else None
    output_dir = output_dir or os.getcwd()
    if uri.startswith("git@"):
        uri_is_path = False
    else:
        uri_parsed = urlparse(uri)
        uri = uri if uri_parsed.scheme else uri_parsed.path
        uri_is_path = False if uri_parsed.scheme else True
    name = name or "upstream"
    with temporary_directory() as tmp_dir:
        info(
            "Checking out repository at '{0}'".format(show_uri or uri)
            + (" to reference '{0}'.".format(tag) if tag else ".")
        )
        if uri_is_path:
            upstream_repo = get_vcs_client(vcs_type, uri)
        else:
            repo_path = os.path.join(tmp_dir, "upstream")
            upstream_repo = get_vcs_client(vcs_type, repo_path)
            if not upstream_repo.checkout(uri, tag or ""):
                error(
                    "Failed to clone repository at '{0}'".format(uri)
                    + (" to reference '{0}'.".format(tag) if tag else "."),
                    exit=True,
                )
        if get_root() is not None and has_submodules(upstream_repo.get_path()):
            error(
                """\
bloom does not support exporting git repositories with submodules, see:

- https://github.com/ros-infrastructure/bloom/issues/202
- https://github.com/ros-infrastructure/bloom/issues/217
- https://github.com/vcstools/vcstools/issues/84
""",
                exit=True,
            )
        tarball_prefix = "{0}-{1}".format(name, tag) if tag else name
        tarball_path = os.path.join(output_dir, tarball_prefix)
        full_tarball_path = tarball_path + ".tar.gz"
        info("Exporting to archive: '{0}'".format(full_tarball_path))
        if not upstream_repo.export_repository(tag or "", tarball_path):
            error("Failed to create archive of upstream repository at '{0}'".format(show_uri))
            if tag and vcs_type == "git":  # can only check for git repos
                with change_directory(upstream_repo.get_path()):
                    if not tag_exists(tag):
                        warning("'{0}' is not a tag in the upstream repository...".format(tag))
                    if not branch_exists(tag):
                        warning("'{0}' is not a branch in the upstream repository...".format(tag))
        if not os.path.exists(full_tarball_path):
            error("Tarball was not created.", exit=True)
        info("md5: {0}".format(calculate_file_md5(full_tarball_path)))
def check_for_bloom():
    """
    Checks for the bloom branch, else looks for and converts the catkin branch.
    Then it checks for the bloom branch and that it contains a bloom.conf file.
    """
    if branch_exists('catkin') and not branch_exists('bloom'):
        # Found catkin branch, migrate it to bloom
        info('catkin branch detected, up converting to the bloom branch')
        convert_catkin_to_bloom()
        return
    # Check for bloom.conf
    if os.path.exists('bloom'):
        error("File or directory bloom prevents checking out to the bloom "
              "branch, remove it.")
        sys.exit(1)
    if not branch_exists('bloom'):
        debug('no bloom branch')
        not_a_bloom_release_repo()
    with inbranch('bloom'):
        if not os.path.exists(os.path.join(os.getcwd(), 'bloom.conf')):
            debug('no bloom.conf file')
            not_a_bloom_release_repo()
Exemple #14
0
def trim(sub_dir=None, force=False, undo=False, directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?",
              exit=True)
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "perform trim.", exit=True)
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        if config is None:
            error("Could not retrieve patches info.", exit=True)
        # If sub_dir is set, try to set it
        new_config = _set_trim_sub_dir(sub_dir, force, config, directory)
        if new_config is None:
            sys.exit('Could not perform trim')
        # Perform trime or undo
        if undo:
            new_config = _undo(new_config, directory)
            if new_config is None:
                return -1  # Indicates that nothing was done
        else:
            new_config = _trim(new_config, force, directory)
        if new_config is None:
            sys.exit('Could not perform trim')
        # Commit the new config
        set_patch_config(patches_branch, new_config, directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #15
0
def export_upstream(uri, tag, vcs_type, output_dir, show_uri, name):
    tag = tag if tag != ':{none}' else None
    output_dir = output_dir or os.getcwd()
    if uri.startswith('git@'):
        uri_is_path = False
    else:
        uri_parsed = urlparse(uri)
        uri = uri if uri_parsed.scheme else uri_parsed.path
        uri_is_path = False if uri_parsed.scheme else True
    name = name or 'upstream'
    with temporary_directory() as tmp_dir:
        info("Checking out repository at '{0}'".format(show_uri or uri) +
             (" to reference '{0}'.".format(tag) if tag else '.'))
        if uri_is_path:
            upstream_repo = get_vcs_client(vcs_type, uri)
        else:
            repo_path = os.path.join(tmp_dir, 'upstream')
            upstream_repo = get_vcs_client(vcs_type, repo_path)
            if not upstream_repo.checkout(uri, tag or ''):
                error("Failed to clone repository at '{0}'".format(uri) +
                      (" to reference '{0}'.".format(tag) if tag else '.'),
                      exit=True)
        if get_root() is not None and has_submodules(upstream_repo.get_path()):
            error("""\
bloom does not support exporting git repositories with submodules, see:

- https://github.com/ros-infrastructure/bloom/issues/202
- https://github.com/ros-infrastructure/bloom/issues/217
- https://github.com/vcstools/vcstools/issues/84
""",
                  exit=True)
        tarball_prefix = '{0}-{1}'.format(name, tag) if tag else name
        tarball_path = os.path.join(output_dir, tarball_prefix)
        full_tarball_path = tarball_path + '.tar.gz'
        info("Exporting to archive: '{0}'".format(full_tarball_path))
        if not upstream_repo.export_repository(tag or '', tarball_path):
            error("Failed to create archive of upstream repository at '{0}'".
                  format(show_uri))
            if tag and vcs_type == 'git':  # can only check for git repos
                with change_directory(upstream_repo.get_path()):
                    if not tag_exists(tag):
                        warning(
                            "'{0}' is not a tag in the upstream repository...".
                            format(tag))
                    if not branch_exists(tag):
                        warning(
                            "'{0}' is not a branch in the upstream repository..."
                            .format(tag))
        if not os.path.exists(full_tarball_path):
            error("Tarball was not created.", exit=True)
        info("md5: {0}".format(calculate_file_md5(full_tarball_path)))
Exemple #16
0
def remove_patches(directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?",
              exit=True)
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "remove patches.",
                  exit=True)
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        parent, spec = config['parent'], config['base']
        if None in [parent, spec]:
            error("Could not retrieve patches info.", exit=True)
        debug("Removing patches from " + current_branch + " back to base "
              "commit " + spec)
        # Reset this branch using git revert --no-edit spec
        current_commit = get_commit_hash(current_branch, directory)
        command_spec = spec + '..' + current_commit
        execute_command('git revert --no-edit -Xtheirs ' + command_spec,
                        cwd=directory)
        # Update the base
        config['base'] = get_commit_hash(current_branch, directory)
        set_patch_config(patches_branch, config, directory=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #17
0
def remove_patches(directory=None):
    # Get the current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Ensure the current branch is valid
    if current_branch is None:
        error("Could not determine current branch, are you in a git repo?",
              exit=True)
    # Construct the patches branch
    patches_branch = 'patches/' + current_branch
    try:
        # See if the patches branch exists
        if branch_exists(patches_branch, False, directory=directory):
            if not branch_exists(patches_branch, True, directory=directory):
                track_branches(patches_branch, directory)
        else:
            error("No patches branch (" + patches_branch + ") found, cannot "
                  "remove patches.", exit=True)
        # Get the parent branch from the patches branch
        config = get_patch_config(patches_branch, directory=directory)
        parent, spec = config['parent'], config['base']
        if None in [parent, spec]:
            error("Could not retrieve patches info.", exit=True)
        debug("Removing patches from " + current_branch + " back to base "
              "commit " + spec)
        # Reset this branch using git revert --no-edit spec
        current_commit = get_commit_hash(current_branch, directory)
        command_spec = spec + '..' + current_commit
        execute_command(
            'git revert --no-edit -Xtheirs ' + command_spec, cwd=directory
        )
        # Update the base
        config['base'] = get_commit_hash(current_branch, directory)
        set_patch_config(patches_branch, config, directory=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #18
0
def get_tracks_dict_raw(directory=None):
    upconvert_bloom_to_config_branch()
    if not branch_exists(BLOOM_CONFIG_BRANCH):
        info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
        create_branch(BLOOM_CONFIG_BRANCH, orphaned=True, directory=directory)
    tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw(
            {'tracks': {}}, 'Initial tracks.yaml', directory=directory
        )
        tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml',
                           directory=directory)
    tracks_dict = yaml.load(tracks_yaml)
    validate_track_versions(tracks_dict)
    return tracks_dict
Exemple #19
0
def get_tracks_dict_raw(directory=None):
    if not branch_exists('bloom'):
        info("Creating bloom branch.")
        create_branch('bloom', orphaned=True, directory=directory)
    tracks_yaml = show('bloom', 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw(
            {'tracks': {}}, 'Initial tracks.yaml', directory=directory
        )
        tracks_yaml = show('bloom', 'tracks.yaml', directory=directory)
    try:
        return yaml.load(tracks_yaml)
    except:
        # TODO handle yaml errors
        raise
Exemple #20
0
def get_tracks_dict_raw(directory=None):
    upconvert_bloom_to_config_branch()
    if not branch_exists(BLOOM_CONFIG_BRANCH):
        info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
        create_branch(BLOOM_CONFIG_BRANCH, orphaned=True, directory=directory)
    tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw(
            {'tracks': {}}, 'Initial tracks.yaml', directory=directory
        )
        tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml',
                           directory=directory)
    tracks_dict = yaml.load(tracks_yaml)
    validate_track_versions(tracks_dict)
    return tracks_dict
Exemple #21
0
def main(sysargs=None):
    if len(sysargs if sysargs is not None else sys.argv) == 1:
        retcode = ensure_clean_working_env()
        if retcode != 0:
            return retcode
        if branch_exists('bloom', False):
            show_current()
            info("See: 'git-bloom-config -h' on how to change the configs")
            return 0
        else:
            info("No bloom branch found")
    parser = get_argument_parser()
    parser = add_global_arguments(parser)
    args = parser.parse_args(sysargs)
    handle_global_arguments(args)

    # Check for freshly initialized repo
    ret = check_git_init()
    if ret != 0:
        return ret

    retcode = ensure_clean_working_env()
    if retcode != 0:
        return retcode

    # Summarize the requested operation
    summarize_arguments(args.upstream_repository, args.upstream_vcs_type,
                        args.upstream_branch)

    # Validate the arguments and repository
    if not validate_args(args.upstream_vcs_type):
        return 1

    # Store the current branch
    current_branch = get_current_branch()
    try:
        set_upstream(args.upstream_repository, args.upstream_vcs_type,
                     args.upstream_branch)
        info("Upstream successively set.")
        return 0
    finally:
        # Try to roll back to the branch the user was on before
        # this possibly failed.
        if current_branch:
            checkout(current_branch)

    return 1
Exemple #22
0
def get_tracks_dict_raw(directory=None):
    upconvert_bloom_to_config_branch()
    if not branch_exists(BLOOM_CONFIG_BRANCH):
        info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
        create_branch(BLOOM_CONFIG_BRANCH, orphaned=True, directory=directory)
    tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw(
            {'tracks': {}}, 'Initial tracks.yaml', directory=directory
        )
        tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml',
                           directory=directory)
    try:
        return yaml.load(tracks_yaml)
    except:
        # TODO handle yaml errors
        raise
Exemple #23
0
def export_patches(directory=None):
    ### Ensure a clean/valid working environment
    ensure_clean_working_env(git_status=True, directory=directory)
    # Get current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists
    if not branch_exists(patches_branch, False, directory=directory):
        error("The patches branch ({0}) does not ".format(patches_branch) +
              "exist, did you use git-bloom-branch?",
              exit=True)
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        if config is None:
            error("Failed to get patches information.", exit=True)
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Notify the user
        debug("Exporting patches from "
              "{0}...{1}".format(config['base'], current_branch))
        # Remove all the old patches
        if len(list_patches(directory)) > 0:
            cmd = 'git rm ./*.patch'
            execute_command(cmd, cwd=directory)
        # Create the patches using git format-patch
        cmd = "git format-patch -M -B " \
              "{0}...{1}".format(config['base'], current_branch)
        execute_command(cmd, cwd=directory)
        # Report of the number of patches created
        patches_list = list_patches(directory)
        debug("Created {0} patches".format(len(patches_list)))
        # Clean up and commit
        if len(patches_list) > 0:
            cmd = 'git add ./*.patch'
            execute_command(cmd, cwd=directory)
        if has_changes(directory):
            cmd = 'git commit -m "Updating patches."'
            execute_command(cmd, cwd=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #24
0
def get_tracks_dict_raw(directory=None):
    upconvert_bloom_to_config_branch()
    if not branch_exists(BLOOM_CONFIG_BRANCH):
        info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
        create_branch(BLOOM_CONFIG_BRANCH, orphaned=True, directory=directory)
    tracks_yaml = show(BLOOM_CONFIG_BRANCH, 'tracks.yaml', directory=directory)
    if not tracks_yaml:
        write_tracks_dict_raw({'tracks': {}},
                              'Initial tracks.yaml',
                              directory=directory)
        tracks_yaml = show(BLOOM_CONFIG_BRANCH,
                           'tracks.yaml',
                           directory=directory)
    try:
        return yaml.load(tracks_yaml)
    except:
        # TODO handle yaml errors
        raise
Exemple #25
0
def export_patches(directory=None):
    ### Ensure a clean/valid working environment
    ensure_clean_working_env(git_status=True, directory=directory)
    # Get current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists
    if not branch_exists(patches_branch, False, directory=directory):
        error("The patches branch ({0}) does not ".format(patches_branch) +
              "exist, did you use git-bloom-branch?", exit=True)
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        if config is None:
            error("Failed to get patches information.", exit=True)
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Notify the user
        debug("Exporting patches from "
              "{0}...{1}".format(config['base'], current_branch))
        # Remove all the old patches
        if len(list_patches(directory)) > 0:
            cmd = 'git rm ./*.patch'
            execute_command(cmd, cwd=directory)
        # Create the patches using git format-patch
        cmd = "git format-patch -M -B " \
              "{0}...{1}".format(config['base'], current_branch)
        execute_command(cmd, cwd=directory)
        # Report of the number of patches created
        patches_list = list_patches(directory)
        debug("Created {0} patches".format(len(patches_list)))
        # Clean up and commit
        if len(patches_list) > 0:
            cmd = 'git add ./*.patch'
            execute_command(cmd, cwd=directory)
        if has_changes(directory):
            cmd = 'git commit -m "Updating patches."'
            execute_command(cmd, cwd=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Exemple #26
0
def test_create_a_bloom_repository(directory=None):
    """
    Create a Bloom Repository:
        User creates a new release repository, and calls git-bloom-config new.

    actions:
        - user creates a folder
        - user calls 'git init .' in that folder
        - user calls 'git-bloom-config new <track name>'

    expects:
        - bloom to ask the user if initialization is desired
        - bloom prompts the user for input on the settings
        - bloom branch to be created
        - tracks.yaml to be in bloom branch with appropriate contents
    """
    # Setup
    user('mkdir new_repo')
    user('cd new_repo')
    user('git init .')
    # Test bloom command
    with bloom_answer(['', 'foo', 'https://github.com/bar/foo.git']):
        r = user('git-bloom-config new foo', return_io=True, silent=False)
        _, out, err = r
    assert out.count('ontinue') > 0, \
        "git-bloom-config didn't ask about git init:\n```\n" + out + "\n```"
    assert branch_exists(BLOOM_CONFIG_BRANCH), \
        "branch '{0}' does not exist".format(BLOOM_CONFIG_BRANCH)
    with inbranch(BLOOM_CONFIG_BRANCH):
        assert os.path.exists('tracks.yaml'), \
            "no tracks.yaml file in the 'bloom' branch"
        with open('tracks.yaml', 'r') as f:
            tracks_dict = yaml.safe_load(f.read())
        assert 'tracks' in tracks_dict, "bad bloom configurations"
        assert 'foo' in tracks_dict['tracks'], "bad bloom configurations"
        track = tracks_dict['tracks']['foo']
        assert 'vcs_uri' in track, "bad bloom configurations"
        assert 'https://github.com/bar/foo.git' == track['vcs_uri'], \
            "bad bloom configurations" + str(track)
    # Assert no question on the second attempt
    with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
        user('git-bloom-config')
Exemple #27
0
def test_create_a_bloom_repository(directory=None):
    """
    Create a Bloom Repository:
        User creates a new release repository, and calls git-bloom-config new.

    actions:
        - user creates a folder
        - user calls 'git init .' in that folder
        - user calls 'git-bloom-config new <track name>'

    expects:
        - bloom to ask the user if initialization is desired
        - bloom prompts the user for input on the settings
        - bloom branch to be created
        - tracks.yaml to be in bloom branch with appropriate contents
    """
    # Setup
    user('mkdir new_repo')
    user('cd new_repo')
    user('git init .')
    # Test bloom command
    with bloom_answer(['', 'foo', 'https://github.com/bar/foo.git']):
        r = user('git-bloom-config new foo', return_io=True, silent=False)
        _, out, err = r
    assert out.count('ontinue') > 0, \
        "git-bloom-config didn't ask about git init:\n```\n" + out + "\n```"
    assert branch_exists('bloom'), "branch 'bloom' does not exist"
    with inbranch('bloom'):
        assert os.path.exists('tracks.yaml'), \
            "no tracks.yaml file in the 'bloom' branch"
        with open('tracks.yaml', 'r') as f:
            tracks_dict = yaml.load(f.read())
        assert 'tracks' in tracks_dict, "bad bloom configurations"
        assert 'foo' in tracks_dict['tracks'], "bad bloom configurations"
        track = tracks_dict['tracks']['foo']
        assert 'vcs_uri' in track, "bad bloom configurations"
        assert 'https://github.com/bar/foo.git' == track['vcs_uri'], \
            "bad bloom configurations" + str(track)
    # Assert no question on the second attempt
    with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
        user('git-bloom-config')
Exemple #28
0
def export_upstream(uri, tag, vcs_type, output_dir, show_uri, name):
    tag = tag if tag != ':{none}' else None
    output_dir = output_dir or os.getcwd()
    if uri.startswith('git@'):
        uri_is_path = False
    else:
        uri_parsed = urlparse(uri)
        uri = uri if uri_parsed.scheme else uri_parsed.path
        uri_is_path = False if uri_parsed.scheme else True
    name = name or 'upstream'
    with temporary_directory() as tmp_dir:
        info("Checking out repository at '{0}'".format(show_uri or uri) +
            (" to reference '{0}'.".format(tag) if tag else '.'))
        if uri_is_path:
            upstream_repo = get_vcs_client(vcs_type, uri)
        else:
            repo_path = os.path.join(tmp_dir, 'upstream')
            upstream_repo = get_vcs_client(vcs_type, repo_path)
            if not upstream_repo.checkout(uri, tag or ''):
                error("Failed to clone repository at '{0}'".format(uri) +
                      (" to reference '{0}'.".format(tag) if tag else '.'),
                      exit=True)
        tarball_prefix = '{0}-{1}'.format(name, tag) if tag else name
        tarball_path = os.path.join(output_dir, tarball_prefix)
        full_tarball_path = tarball_path + '.tar.gz'
        info("Exporting to archive: '{0}'".format(full_tarball_path))
        if not upstream_repo.export_repository(tag or '', tarball_path):
            error("Failed to create archive of upstream repository at '{0}'"
                  .format(show_uri))
            if tag:
                with change_directory(upstream_repo.get_path()):
                    if not tag_exists(tag):
                        warning("'{0}' is not a tag in the upstream repository..."
                                .format(tag))
                    if not branch_exists(tag):
                        warning("'{0}' is not a branch in the upstream repository..."
                                .format(tag))
        if not os.path.exists(full_tarball_path):
            error("Tarball was not created.", exit=True)
        info("md5: {0}".format(calculate_file_md5(full_tarball_path)))
def main(sysargs=None):
    parser = get_argument_parser()
    parser = add_global_arguments(parser)
    args = parser.parse_args(sysargs)
    handle_global_arguments(args)

    # Check that the current directory is a serviceable git/bloom repo
    ret = ensure_clean_working_env()
    if ret != 0:
        parser.print_usage()
        return ret

    # Get the current git branch
    current_branch = get_current_branch()

    # Create a working temp directory
    tmp_dir = create_temporary_directory()

    cwd = os.getcwd()

    try:
        # Get off upstream branch
        if current_branch == 'upstream':
            checkout(get_commit_hash('upstream'), directory=cwd)

        retcode = import_upstream(cwd, tmp_dir, args)

        # Done!
        retcode = retcode if retcode is not None else 0
        if retcode == 0:
            info("I'm happy.  You should be too.")

        return retcode
    finally:
        # Change back to the original cwd
        os.chdir(cwd)
        # Clean up
        shutil.rmtree(tmp_dir)
        if current_branch and branch_exists(current_branch, True, cwd):
            checkout(current_branch, directory=cwd)
Exemple #30
0
def export_upstream(uri, tag, vcs_type, output_dir, show_uri, name):
    tag = tag if tag != ':{none}' else None
    output_dir = output_dir or os.getcwd()
    if uri.startswith('git@'):
        uri_is_path = False
    else:
        uri_parsed = urlparse(uri)
        uri = uri if uri_parsed.scheme else uri_parsed.path
        uri_is_path = False if uri_parsed.scheme else True
    name = name or 'upstream'
    with temporary_directory() as tmp_dir:
        info("Checking out repository at '{0}'".format(show_uri or uri) +
             (" to reference '{0}'.".format(tag) if tag else '.'))
        if uri_is_path:
            upstream_repo = get_vcs_client(vcs_type, uri)
        else:
            repo_path = os.path.join(tmp_dir, 'upstream')
            upstream_repo = get_vcs_client(vcs_type, repo_path)
            if not upstream_repo.checkout(uri, tag or ''):
                error("Failed to clone repository at '{0}'".format(uri) +
                      (" to reference '{0}'.".format(tag) if tag else '.'),
                      exit=True)
        tarball_prefix = '{0}-{1}'.format(name, tag) if tag else name
        tarball_path = os.path.join(output_dir, tarball_prefix)
        full_tarball_path = tarball_path + '.tar.gz'
        info("Exporting to archive: '{0}'".format(full_tarball_path))
        if not upstream_repo.export_repository(tag or '', tarball_path):
            error("Failed to create archive of upstream repository at '{0}'"
                  .format(show_uri))
            if tag and vcs_type == 'git':  # can only check for git repos
                with change_directory(upstream_repo.get_path()):
                    if not tag_exists(tag):
                        warning("'{0}' is not a tag in the upstream repository..."
                                .format(tag))
                    if not branch_exists(tag):
                        warning("'{0}' is not a branch in the upstream repository..."
                                .format(tag))
        if not os.path.exists(full_tarball_path):
            error("Tarball was not created.", exit=True)
        info("md5: {0}".format(calculate_file_md5(full_tarball_path)))
Exemple #31
0
def test_create_a_bloom_repository(directory=None):
    """
    Create a Bloom Repository:
        User creates a new release repository, and immediately calls
        git-bloom-config.

    actions:
        - user creates a folder
        - user calls 'git init .' in that folder
        - user calls 'git-bloom-config <url> <type> [<branch>]'

    expects:
        - bloom to ask the user if initialization is desired
        - bloom branch to be created
        - bloom.conf to be in bloom branch with appropriate contents
    """
    # Setup
    user('mkdir new_repo')
    assert os.getcwd() == directory, str(os.getcwd()) + " == " + str(directory)
    user('cd new_repo')
    assert os.getcwd() != directory, str(os.getcwd()) + " != " + str(directory)
    user('git init .')
    # Test bloom command
    with bloom_answer('y'):
        r = user('git-bloom-config https://github.com/foo/foo.git git devel',
                 return_io=True)
        _, out, err = r
    assert out.count('ontinue') > 0, \
           "git-bloom-config didn't ask about git init: \n`" + out + "`"
    assert branch_exists('bloom'), "branch 'bloom' does not exist"
    with inbranch('bloom'):
        assert os.path.exists('bloom.conf'), \
               "no bloom.conf file in the 'bloom' branch"
        bloom_file = open('bloom.conf').read()
        assert bloom_file.count('foo/foo.git') > 0, "bad content in bloom.conf"
        assert bloom_file.count(' git') > 0, "bad content in bloom.conf"
        assert bloom_file.count(' devel') > 0, "bad content in bloom.conf"
    # Assert no question on the second attempt
    with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
        user('git-bloom-config https://github.com/foo/foo.git git devel')
Exemple #32
0
def test_create_a_bloom_repository(directory=None):
    """
    Create a Bloom Repository:
        User creates a new release repository, and calls git-bloom-config new.

    actions:
        - user creates a folder
        - user calls 'git init .' in that folder
        - user calls 'git-bloom-config new <track name>'

    expects:
        - bloom to ask the user if initialization is desired
        - bloom prompts the user for input on the settings
        - bloom branch to be created
        - tracks.yaml to be in bloom branch with appropriate contents
    """
    # Setup
    user("mkdir new_repo")
    user("cd new_repo")
    user("git init .")
    # Test bloom command
    with bloom_answer(["", "foo", "https://github.com/bar/foo.git"]):
        r = user("git-bloom-config new foo", return_io=True, silent=False)
        _, out, err = r
    assert out.count("ontinue") > 0, "git-bloom-config didn't ask about git init:\n```\n" + out + "\n```"
    assert branch_exists(BLOOM_CONFIG_BRANCH), "branch '{0}' does not exist".format(BLOOM_CONFIG_BRANCH)
    with inbranch(BLOOM_CONFIG_BRANCH):
        assert os.path.exists("tracks.yaml"), "no tracks.yaml file in the 'bloom' branch"
        with open("tracks.yaml", "r") as f:
            tracks_dict = yaml.load(f.read())
        assert "tracks" in tracks_dict, "bad bloom configurations"
        assert "foo" in tracks_dict["tracks"], "bad bloom configurations"
        track = tracks_dict["tracks"]["foo"]
        assert "vcs_uri" in track, "bad bloom configurations"
        assert "https://github.com/bar/foo.git" == track["vcs_uri"], "bad bloom configurations" + str(track)
    # Assert no question on the second attempt
    with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
        user("git-bloom-config")
Exemple #33
0
def import_patches(directory=None):
    # Get current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists and is tracked
    if branch_exists(patches_branch, False, directory=directory):
        if not branch_exists(patches_branch, True, directory=directory):
            track_branches(patches_branch, directory)
    else:
        error("The patches branch ({0}) does not ".format(patches_branch) +
              "exist, did you use git-bloom-branch?", exit=True)
    # Create a swap space
    tmp_dir = tempfile.mkdtemp()
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        parent_branch, commit = config['parent'], config['base']
        if commit != get_commit_hash(current_branch, directory):
            debug(
                "commit != get_commit_hash(current_branch, directory)"
            )
            debug(
                "{0} != get_commit_hash({1}, {2}) != {3}".format(
                    commit, current_branch, directory,
                    get_commit_hash(current_branch, directory)
                )
            )
            os.system('git log')
            warning(
                "The current commit is not the same as the most recent "
                "rebase commit."
            )
            warning(
                "This might mean that you have committed since the last "
                "time you did:"
            )
            warning(
                "    'git-bloom-patch rebase' or 'git-bloom-patch remove'"
            )
            warning(
                "Make sure you export any commits you want to save first:"
            )
            warning("    'git-bloom-patch export'")
            error("Patches not exported", exit=True)
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Copy the patches to a temp location
        patches = list_patches(directory)
        if len(patches) == 0:
            debug("No patches in the patches branch, nothing to do")
            return -1  # Indicates that nothing was done
        tmp_dir_patches = []
        for patch in patches:
            tmp_dir_patches.append(os.path.join(tmp_dir, patch))
            if directory is not None:
                patch = os.path.join(directory, patch)
            shutil.copy(patch, tmp_dir)
        # Now checkout back to the original branch and import them
        checkout(current_branch, directory=directory)
        try:
            cmd = 'git am {0}*.patch'.format(tmp_dir + os.sep)
            execute_command(cmd, cwd=directory)
        except subprocess.CalledProcessError as e:
            warning("Failed to apply one or more patches for the "
                    "'{0}' branch.".format(str(e)))
            info('', use_prefix=False)
            info('', use_prefix=False)
            info(">>> Resolve any conflicts and when you have resolved this "
                 "problem run 'git am --resolved' and then exit the "
                 "shell using 'exit 0'. <<<", use_prefix=False)
            info("    To abort use 'exit 1'", use_prefix=False)
            if 'bash' in os.environ['SHELL']:
                ret = subprocess.call([
                    "/bin/bash", "-l", "-c",
                    """\
/bin/bash --rcfile <(echo "if [ -f /etc/bashrc ]; then source /etc/bashrc; fi; \
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi;PS1='(bloom)$PS1'") -i"""
                ])
            else:
                ret = subprocess.call("$SHELL", shell=True)
            if ret != 0:
                error("User failed to resolve patch conflicts, exiting.")
                sys.exit("'git-bloom-patch import' aborted.")
            info("User reports that conflicts have been resolved, continuing.")
        # Notify the user
        info("Applied {0} patches".format(len(patches)))
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Exemple #34
0
def import_upstream(tarball_path, patches_path, version, name, replace):
    # Check for a url and download it
    url = urlparse(tarball_path)
    if url.scheme:  # Some scheme like http, https, or file...
        tmp_dir = tempfile.mkdtemp()
        try:
            info("Fetching file from url: '{0}'".format(tarball_path))
            req = load_url_to_file_handle(tarball_path)
            tarball_path = os.path.join(tmp_dir, os.path.basename(url.path))
            with open(tarball_path, 'wb') as f:
                chunk_size = 16 * 1024
                while True:
                    chunk = req.read(chunk_size)
                    if not chunk:
                        break
                    f.write(chunk)
            return import_upstream(tarball_path, patches_path, version, name, replace)
        finally:
            shutil.rmtree(tmp_dir)

    # If there is not tarball at the given path, fail
    if not os.path.exists(tarball_path):
        error("Specified archive does not exists: '{0}'".format(tarball_path),
              exit=True)

    # If either version or name are not provided, guess from archive name
    if not version or not name:
        # Parse tarball name
        tarball_file = os.path.basename(tarball_path)
        ending = None
        if tarball_file.endswith('.tar.gz'):
            ending = '.tar.gz'
        elif tarball_file.endswith('.zip'):
            ending = '.zip'
        else:
            error("Cannot detect type of archive: '{0}'"
                  .format(tarball_file), exit=True)
        tarball_file = tarball_file[:-len(ending)]
        split_tarball_file = tarball_file.split('-')
        if len(split_tarball_file) < 2 and not version or len(split_tarball_file) < 1:
            error("Cannot detect name and/or version from archive: '{0}'"
                  .format(tarball_file), exit=True)
    if not name and len(split_tarball_file) == 1:
        name = split_tarball_file[0]
    elif not name and len(split_tarball_file) == 1:
        name = '-'.join(split_tarball_file[:-1])
    if not version and len(split_tarball_file) < 2:
        error("Cannot detect version from archive: '{0}'"
              .format(tarball_file) + " and the version was not spcified.",
              exit=True)
    version = version if version else split_tarball_file[-1]

    # Check if the patches_path (if given) exists
    patches_path_dict = None
    if patches_path:
        patches_path_dict = ls_tree(BLOOM_CONFIG_BRANCH, patches_path)
        if not patches_path_dict:
            error("Given patches path '{0}' does not exist in bloom branch."
                  .format(patches_path), exit=True)

    # Do version checking
    version_check(version)

    # Check for existing tags
    upstream_tag = 'upstream/{0}'.format(version)
    if tag_exists(upstream_tag):
        if not replace:
            error("Tag '{0}' already exists, use --replace to override it."
                  .format(upstream_tag), exit=True)
        warning("Removing tag: '{0}'".format(upstream_tag))
        delete_tag(upstream_tag)
        if not get_git_clone_state():
            delete_remote_tag(upstream_tag)
    name_tag = '{0}/{1}'.format(name or 'upstream', version)
    if name_tag != upstream_tag and tag_exists(name_tag):
        if not replace:
            error("Tag '{0}' already exists, use --replace to override it."
                  .format(name_tag), exit=True)
        warning("Removing tag: '{0}'".format(name_tag))
        delete_tag(name_tag)
        if not get_git_clone_state():
            delete_remote_tag(name_tag)

    # If there is not upstream branch, create one
    if not branch_exists('upstream'):
        info("Creating upstream branch.")
        create_branch('upstream', orphaned=True)
    else:
        track_branches(['upstream'])

    # Import the given tarball
    info("Importing archive into upstream branch...")
    import_tarball(tarball_path, 'upstream', version, name)

    # Handle patches_path
    if patches_path:
        import_patches(patches_path, patches_path_dict, 'upstream', version)

    # Create tags
    with inbranch('upstream'):
        info("Creating tag: '{0}'".format(upstream_tag))
        create_tag(upstream_tag)
        if name_tag != upstream_tag:
            info("Creating tag: '{0}'".format(name_tag))
            create_tag(name_tag)
def _test_unary_package_repository(release_dir, version, directory=None):
    print("Testing in {0} at version {1}".format(release_dir, version))
    with change_directory(release_dir):
        # First run everything
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            cmd = "git-bloom-release{0} groovy"
            if "BLOOM_VERBOSE" not in os.environ:
                cmd = cmd.format(" --quiet")
            else:
                cmd = cmd.format("")
            user(cmd, silent=False)
        ###
        ### Import upstream
        ###
        # does the upstream branch exist?
        assert branch_exists("upstream", local_only=True), "no upstream branch"
        # does the upstrea/<version> tag exist?
        ret, out, err = user("git tag", return_io=True)
        assert out.count("upstream/" + version) == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch("upstream"):
            assert os.path.exists("package.xml"), (
                "upstream did not import: '" + os.getcwd() + "': " + str(os.listdir(os.getcwd()))
            )
            with open("package.xml") as f:
                package_xml = f.read()
                assert package_xml.count(version), "not right file"

        ###
        ### Release generator
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists("release/groovy/foo"), "no release/groovy/foo branch"
        assert branch_exists("patches/release/groovy/foo"), "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user("git tag", return_io=True)
        assert out.count("release/groovy/foo/" + version + "-0") == 1, "no release tag created"

        ###
        ### Make patch
        ###
        with inbranch("release/groovy/foo"):
            if os.path.exists("include/foo.h"):
                user("git rm include/foo.h")
            else:
                if not os.path.exists("include"):
                    os.makedirs("include")
                user("touch include/foo.h")
                user("git add include/foo.h")
            user('git commit -m "A release patch" --allow-empty')

        ###
        ### Test import and export
        ###
        with inbranch("release/groovy/foo"):
            export_cmd.export_patches()
            remove_cmd.remove_patches()
            import_cmd.import_patches()

        ###
        ### Release generator, again
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists("release/groovy/foo"), "no release/groovy/foo branch"
        assert branch_exists("patches/release/groovy/foo"), "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user("git tag", return_io=True)
        assert out.count("release/groovy/foo/" + version) == 1, "no release tag created"
Exemple #36
0
def _test_unary_package_repository(release_dir, version, directory=None):
    print("Testing in {0} at version {1}".format(release_dir, version))
    with change_directory(release_dir):
        # First run everything
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            cmd = 'git-bloom-release{0} groovy'
            if 'BLOOM_VERBOSE' not in os.environ:
                cmd = cmd.format(' --quiet')
            else:
                cmd = cmd.format('')
            user(cmd, silent=False)
        ###
        ### Import upstream
        ###
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/<version> tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/' + version) == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            assert os.path.exists('package.xml'), \
                "upstream did not import: '" + os.getcwd() + "': " + \
                str(os.listdir(os.getcwd()))
            assert os.path.exists(os.path.join('debian', 'something.udev')), \
                "Lost the debian overlaid files in upstream branch"
            assert os.path.exists('white space.txt~'), \
                "Lost file with whitespace in name in upstream branch"
            with open('package.xml') as f:
                package_xml = f.read()
                assert package_xml.count(version), "not right file"

        ###
        ### Release generator
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/groovy/foo'), \
            "no release/groovy/foo branch"
        assert branch_exists('patches/release/groovy/foo'), \
            "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        expected = 'release/groovy/foo/' + version + '-0'
        assert out.count(expected) == 1, \
            "no release tag created, expected: '{0}'".format(expected)

        ###
        ### Make patch
        ###
        with inbranch('release/groovy/foo'):
            assert os.path.exists(os.path.join('debian', 'something.udev')), \
                "Lost the debian overlaid files in release branch"
            assert os.path.exists('white space.txt~'), \
                "Lost file with whitespace in name in release branch"
            assert os.path.islink('include/sym/foo.h'), "Symbolic link lost during pipeline"
            if os.path.exists('include/foo.h'):
                user('git rm include/foo.h')
            else:
                if not os.path.exists('include'):
                    os.makedirs('include')
                user('touch include/foo.h')
                user('git add include/foo.h')
            user('git commit -m "A release patch" --allow-empty')

        ###
        ### Test import and export
        ###
        with inbranch('release/groovy/foo'):
            export_cmd.export_patches()
            remove_cmd.remove_patches()
            import_cmd.import_patches()

        ###
        ### Release generator, again
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/groovy/foo'), \
            "no release/groovy/foo branch"
        assert branch_exists('patches/release/groovy/foo'), \
            "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/groovy/foo/' + version) == 1, \
            "no release tag created"
def _test_unary_package_repository(release_dir, version, directory=None):
    print("Testing in {0} at version {1}".format(release_dir, version))
    with change_directory(release_dir):
        ###
        ### Import upstream
        ###
        user('git-bloom-import-upstream --quiet')
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/<version> tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/' + version) == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            assert os.path.exists('package.xml'), \
                   "upstream did not import: '" + os.getcwd() + "': " + \
                   str(os.listdir(os.getcwd()))
            with open('package.xml') as f:
                package_xml = f.read()
                assert package_xml.count(version), "not right file"

        ###
        ### Release generator
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y release -s upstream --quiet')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/foo'), "no release/foo branch"
        assert branch_exists('patches/release/foo'), \
               "no patches/release/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/foo/' + version) == 1, \
               "no release tag created"

        ###
        ### Make patch
        ###
        with inbranch('release/foo'):
            if os.path.exists('include/foo.h'):
                user('git rm include/foo.h')
            else:
                if not os.path.exists('include'):
                    os.makedirs('include')
                user('touch include/foo.h')
                user('git add include/foo.h')
            user('git commit -m "A release patch"')

        ###
        ### Test import and export
        ###
        with inbranch('release/foo'):
            export_cmd.export_patches()
            remove_cmd.remove_patches()
            import_cmd.import_patches()

        ###
        ### Release generator, again
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y release -s upstream --quiet')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/foo'), "no release/foo branch"
        assert branch_exists('patches/release/foo'), \
               "no patches/release/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/foo/' + version) == 1, \
               "no release tag created"
def test_multi_package_repository(directory=None):
    """
    Release a multi package catkin (groovy) repository.
    """
    directory = directory if directory is not None else os.getcwd()
    # Setup
    pkgs = ['foo', 'bar', 'baz']
    upstream_dir = create_upstream_repository(pkgs, directory)
    upstream_url = 'file://' + upstream_dir
    release_url = create_release_repo(upstream_url, 'git', 'groovy_devel')
    release_dir = os.path.join(directory, 'foo_release_clone')
    release_client = get_vcs_client('git', release_dir)
    release_client.checkout(release_url)
    with change_directory(release_dir):
        ###
        ### Import upstream
        ###
        user('git-bloom-import-upstream --quiet')
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/0.1.0 tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/0.1.0') == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            for pkg in pkgs:
                with change_directory(pkg):
                    assert os.path.exists('package.xml'), \
                           "upstream did not import: " + os.listdir()
                    with open('package.xml') as f:
                        assert f.read().count('0.1.0'), "not right file"

        ###
        ### Release generator
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y release -s upstream --quiet')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/' + pkg), \
                   "no release/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/' + pkg), \
                   "no patches/release/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/' + pkg + '/0.1.0') == 1, \
                   "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/' + pkg):
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                package_xml = open('package.xml', 'r').read()
                assert package_xml.count('<name>' + pkg + '</name>'), \
                       "incorrect package.xml for " + str(pkg)

        # Make a patch
        with inbranch('release/' + pkgs[0]):
            user('echo "This is a change" >> README.md')
            user('git add README.md')
            user('git commit -m "added a readme"')

        ###
        ### Release generator, again
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user(
                'git-bloom-generate -y release -s upstream', silent=False
            )
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/' + pkg), \
                   "no release/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/' + pkg), \
                   "no patches/release/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/' + pkg + '/0.1.0') == 1, \
                   "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/' + pkg):
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    assert f.read().count('<name>' + pkg + '</name>'), \
                       "incorrect package.xml for " + str(pkg)

        ###
        ### ROSDebian Generator
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret, out, err = user('git-bloom-generate -y rosdebian '
                                 '-p release groovy', return_io=True,
                                 auto_assert=False)
            if ret != 0:
                print(out)
                print(err)
            assert ret == 0
        expected = "Debian Distributions: ['oneiric', 'precise', 'quantal']"
        assert out.count(expected) > 0, "not using expected ubuntu distros"
        # generator should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            for distro in ['oneiric', 'precise', 'quantal']:
                # Does the debian/distro/pkg branch exist?
                assert branch_exists('debian/groovy/' + distro + '/' + pkg), \
                       "no release/" + pkg + " branch"
                # Does the patches/debian/distro/pkg branch exist?
                patches_branch = 'patches/debian/groovy/' + distro + '/' + pkg
                assert branch_exists(patches_branch), \
                       "no patches/release/" + pkg + " branch"
                # Did the debian tag get created?
                tag = 'debian/ros-groovy-' + pkg + '_0.1.0-0_' + distro
                assert out.count(tag) == 1, \
                   "no release tag created for '" + pkg + "': `" + out + "`"
            # Is there a package.xml in the top level?
            with inbranch('debian/groovy/' + distro + '/' + pkg):
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    assert f.read().count('<name>' + pkg + '</name>'), \
                       "incorrect package.xml for " + str(pkg)
Exemple #39
0
def execute_branch(src, dst, interactive, directory=None):
    """
    Changes to the destination branch, creates branch and patches/branch
    if they do not exist.

    If the dst branch does not exist yet, then it is created by branching the
    current working branch or the specified SRC_BRANCH.

    If the patches/dst branch branch does not exist yet then it is created.

    If the branches are created successful, then the working branch will be
    set to the dst branch, otherwise the working branch will remain unchanged.

    :param src: source branch from which to copy
    :param dst: destination branch
    :param interactive: if True actions are summarized before committing
    :param directory: directory in which to preform this action

    :raises: subprocess.CalledProcessError if any git calls fail
    """
    # Determine if the srouce branch exists
    if src is None:
        error("No source specified and/or not a branch currently", exit=True)
    if branch_exists(src, local_only=False, directory=directory):
        if not branch_exists(src, local_only=True, directory=directory):
            debug("Tracking source branch: {0}".format(src))
            track_branches(src, directory)
    elif tag_exists(src):
        pass
    else:
        error("Specified source branch does not exist: {0}".format(src), exit=True)

    # Determine if the destination branch needs to be created
    create_dst_branch = False
    if branch_exists(dst, local_only=False, directory=directory):
        if not branch_exists(dst, local_only=True, directory=directory):
            debug("Tracking destination branch: {0}".format(dst))
            track_branches(dst, directory)
    else:
        create_dst_branch = True

    # Determine if the destination patches branch needs to be created
    create_dst_patches_branch = False
    dst_patches = "patches/" + dst
    if branch_exists(dst_patches, False, directory=directory):
        if not branch_exists(dst_patches, True, directory=directory):
            track_branches(dst_patches, directory)
    else:
        create_dst_patches_branch = True

    # Summarize
    if interactive:
        info("Summary of changes:")
        if create_dst_branch:
            info(
                " " * 22
                + "- The specified destination branch, "
                + ansi("boldon")
                + dst
                + ansi("reset")
                + ", does not exist; it will be created from the source "
                "branch " + ansi("boldon") + src + ansi("reset")
            )
        if create_dst_patches_branch:
            info(
                " " * 22
                + "- The destination patches branch, "
                + ansi("boldon")
                + dst_patches
                + ansi("reset")
                + ", does not exist; it will be created"
            )
        info(" " * 22 + "- The working branch will be set to " + ansi("boldon") + dst + ansi("reset"))
        if not maybe_continue():
            error("Answered no to continue, aborting.", exit=True)

    # Make changes to the layout
    current_branch = get_current_branch(directory)
    try:
        # Change to the src branch
        checkout(src, directory=directory)
        # Create the dst branch if needed
        if create_dst_branch:
            create_branch(dst, changeto=True, directory=directory)
        else:
            checkout(dst, directory=directory)
        # Create the dst patches branch if needed
        if create_dst_patches_branch:
            create_branch(dst_patches, orphaned=True, directory=directory)
        # Create the starting config data if it does not exist
        patches_ls = ls_tree(dst_patches, directory=directory)
        if "patches.conf" not in patches_ls:
            # Patches config not setup, set it up
            config = {
                "parent": src,
                "previous": "",
                "base": get_commit_hash(dst, directory=directory),
                "trim": "",
                "trimbase": "",
            }
            set_patch_config(dst_patches, config, directory=directory)
        else:
            config = get_patch_config(dst_patches, directory=directory)
            if config["parent"] != src:
                warning("Updated parent to '{0}' from '{1}'".format(src, config["parent"]))
                config["parent"] = src
                config["base"] = get_commit_hash(dst, directory=directory)
            set_patch_config(dst_patches, config, directory=directory)
        # Command successful, do not switch back to previous branch
        current_branch = None
    finally:
        if current_branch is not None:
            checkout(current_branch, directory=directory)
Exemple #40
0
def execute_branch(src, dst, interactive, directory=None):
    """
    Changes to the destination branch, creates branch and patches/branch
    if they do not exist.

    If the dst branch does not exist yet, then it is created by branching the
    current working branch or the specified SRC_BRANCH.

    If the patches/dst branch branch does not exist yet then it is created.

    If the branches are created successful, then the working branch will be
    set to the dst branch, otherwise the working branch will remain unchanged.

    :param src: source branch from which to copy
    :param dst: destination branch
    :param interactive: if True actions are summarized before committing
    :param directory: directory in which to preform this action

    :raises: subprocess.CalledProcessError if any git calls fail
    """
    # Determine if the srouce branch exists
    if src is None:
        error("No source specified and/or not a branch currently", exit=True)
    if branch_exists(src, local_only=False, directory=directory):
        if not branch_exists(src, local_only=True, directory=directory):
            debug("Tracking source branch: {0}".format(src))
            track_branches(src, directory)
    elif tag_exists(src):
        pass
    else:
        error("Specified source branch does not exist: {0}".format(src),
              exit=True)

    # Determine if the destination branch needs to be created
    create_dst_branch = False
    if branch_exists(dst, local_only=False, directory=directory):
        if not branch_exists(dst, local_only=True, directory=directory):
            debug("Tracking destination branch: {0}".format(dst))
            track_branches(dst, directory)
    else:
        create_dst_branch = True

    # Determine if the destination patches branch needs to be created
    create_dst_patches_branch = False
    dst_patches = 'patches/' + dst
    if branch_exists(dst_patches, False, directory=directory):
        if not branch_exists(dst_patches, True, directory=directory):
            track_branches(dst_patches, directory)
    else:
        create_dst_patches_branch = True

    # Summarize
    if interactive:
        info("Summary of changes:")
        if create_dst_branch:
            info(" " * 22 + "- The specified destination branch, " +
                 ansi('boldon') + dst + ansi('reset') +
                 ", does not exist; it will be created from the source "
                 "branch " + ansi('boldon') + src + ansi('reset'))
        if create_dst_patches_branch:
            info(" " * 22 + "- The destination patches branch, " +
                 ansi('boldon') + dst_patches + ansi('reset') +
                 ", does not exist; it will be created")
        info(" " * 22 + "- The working branch will be set to " +
             ansi('boldon') + dst + ansi('reset'))
        if not maybe_continue():
            error("Answered no to continue, aborting.", exit=True)

    # Make changes to the layout
    current_branch = get_current_branch(directory)
    try:
        # Change to the src branch
        checkout(src, directory=directory)
        # Create the dst branch if needed
        if create_dst_branch:
            create_branch(dst, changeto=True, directory=directory)
        else:
            checkout(dst, directory=directory)
        # Create the dst patches branch if needed
        if create_dst_patches_branch:
            create_branch(dst_patches, orphaned=True, directory=directory)
        # Create the starting config data if it does not exist
        patches_ls = ls_tree(dst_patches, directory=directory)
        if 'patches.conf' not in patches_ls:
            # Patches config not setup, set it up
            config = {
                'parent': src,
                'previous': '',
                'base': get_commit_hash(dst, directory=directory),
                'trim': '',
                'trimbase': ''
            }
            set_patch_config(dst_patches, config, directory=directory)
        else:
            config = get_patch_config(dst_patches, directory=directory)
            if config['parent'] != src:
                warning("Updated parent to '{0}' from '{1}'".format(
                    src, config['parent']))
                config['parent'] = src
                config['base'] = get_commit_hash(dst, directory=directory)
            set_patch_config(dst_patches, config, directory=directory)
        # Command successful, do not switch back to previous branch
        current_branch = None
    finally:
        if current_branch is not None:
            checkout(current_branch, directory=directory)
def test_multi_package_repository(directory=None):
    """
    Release a multi package catkin (groovy) repository.
    """
    directory = directory if directory is not None else os.getcwd()
    # Setup
    pkgs = ['foo', 'bar_ros', 'baz']
    upstream_dir = create_upstream_repository(pkgs,
                                              directory,
                                              format_versions=[1, 2, 3])
    upstream_url = 'file://' + upstream_dir
    release_url = create_release_repo(upstream_url, 'git', 'groovy_devel',
                                      'groovy')
    release_dir = os.path.join(directory, 'foo_release_clone')
    release_client = get_vcs_client('git', release_dir)
    assert release_client.checkout(release_url)
    with change_directory(release_dir):
        # First run everything
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            cmd = 'git-bloom-release{0} groovy'
            if 'BLOOM_VERBOSE' not in os.environ:
                cmd = cmd.format(' --quiet')
            else:
                cmd = cmd.format('')
            user(cmd, silent=False)
        ###
        ### Import upstream
        ###
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/0.1.0 tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/0.1.0') == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            for pkg in pkgs:
                with change_directory(pkg):
                    assert os.path.exists(
                        os.path.join('debian', 'something.udev')), \
                        "Lost the debian overlaid files in upstream branch"
                    assert os.path.exists('white space.txt~'), \
                        "Lost file with whitespace in name in upstream branch"
                    assert os.path.exists('package.xml'), \
                        "upstream did not import: " + os.listdir()
                    with open('package.xml') as f:
                        assert f.read().count('0.1.0'), "not right file"

        ###
        ### Release generator
        ###
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/groovy/' + pkg), \
                "no release/groovy/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/groovy/' + pkg), \
                "no patches/release/groovy/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/groovy/' + pkg + '/0.1.0-0') == 1, \
                "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/groovy/' + pkg):
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                package_xml = open('package.xml', 'r').read()
                assert package_xml.count('<name>' + pkg + '</name>'), \
                    "incorrect package.xml for " + str(pkg)

        # Make a patch
        with inbranch('release/groovy/' + pkgs[0]):
            user('echo "This is a change" >> README.md')
            user('git add README.md')
            user('git commit -m "added a readme" --allow-empty')

        ###
        ### Release generator, again
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y rosrelease groovy -s upstream')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/groovy/' + pkg), \
                "no release/groovy/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/groovy/' + pkg), \
                "no patches/release/groovy/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/groovy/' + pkg + '/0.1.0-0') == 1, \
                "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/groovy/' + pkg):
                assert os.path.exists(os.path.join('debian', 'something.udev')), \
                    "Lost the debian overlaid files in release branch"
                assert os.path.exists('white space.txt~'), \
                    "Lost file with whitespace in name in release branch"
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    assert f.read().count('<name>' + pkg + '</name>'), \
                        "incorrect package.xml for " + str(pkg)

        ###
        ### ROSDebian Generator
        ###
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            for distro in ['oneiric', 'precise', 'quantal']:
                pkg_san = sanitize_package_name(pkg)
                # Does the debian/distro/pkg branch exist?
                assert branch_exists('debian/groovy/' + distro + '/' + pkg), \
                    "no debian/groovy/" + pkg + " branch"
                # Does the patches/debian/distro/pkg branch exist?
                patches_branch = 'patches/debian/groovy/' + distro + '/' + pkg
                assert branch_exists(patches_branch), \
                    "no " + patches_branch + " branch"
                # Did the debian tag get created?
                tag = 'debian/ros-groovy-' + pkg_san + '_0.1.0-0_' + distro
                assert out.count(tag) == 1, \
                    "no '" + tag + "'' tag created for '" + pkg + "': `\n" + \
                    out + "\n`"
            # Is there a package.xml in the top level?
            with inbranch('debian/groovy/' + distro + '/' + pkg):
                assert os.path.exists(
                    os.path.join('debian', 'something.udev')), \
                    "Lost the debian overlaid files in debian branch"
                assert os.path.exists('white space.txt~'), \
                    "Lost file with whitespace in name in debian branch"
                assert os.path.exists('package.xml'), "debian branch invalid"
                # Is there blank lins due to no Conflicts/Replaces?
                # See: https://github.com/ros-infrastructure/bloom/pull/329
                with open(os.path.join('debian', 'control'), 'r') as f:
                    assert f.read().count('\n\nHomepage:') == 0, \
                        "Extra blank line before Homepage detected."
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    package_xml = f.read()
                    assert package_xml.count('<name>' + pkg + '</name>'), \
                        "incorrect package.xml for " + str(pkg)
                    format_version = int(
                        re.search('format="(\d+)"', package_xml).group(1))
                # Is there a copyright file for this pkg?
                if format_version <= 2:
                    assert not os.path.exists(
                        os.path.join('debian', 'copyright')), \
                        "debian/copyright should not be generated"
                else:
                    with open('debian/copyright', 'r') as f:
                        assert pkg + ' license' in f.read(), \
                            "debian/copyright does not include right license text"
def _test_unary_package_repository(release_dir, version, directory=None):
    print("Testing in {0} at version {1}".format(release_dir, version))
    with change_directory(release_dir):
        # First run everything
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            cmd = 'git-bloom-release{0} groovy'
            if 'BLOOM_VERBOSE' not in os.environ:
                cmd = cmd.format(' --quiet')
            else:
                cmd = cmd.format('')
            user(cmd, silent=False)
        ###
        ### Import upstream
        ###
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/<version> tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/' + version) == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            assert os.path.exists('package.xml'), \
                "upstream did not import: '" + os.getcwd() + "': " + \
                str(os.listdir(os.getcwd()))
            assert os.path.exists(os.path.join('debian', 'something.udev')), \
                "Lost the debian overlaid files in upstream branch"
            assert os.path.exists('white space.txt~'), \
                "Lost file with whitespace in name in upstream branch"
            with open('package.xml') as f:
                package_xml = f.read()
                assert package_xml.count(version), "not right file"

        ###
        ### Release generator
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/groovy/foo'), \
            "no release/groovy/foo branch"
        assert branch_exists('patches/release/groovy/foo'), \
            "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        expected = 'release/groovy/foo/' + version + '-0'
        assert out.count(expected) == 1, \
            "no release tag created, expected: '{0}'".format(expected)

        ###
        ### Make patch
        ###
        with inbranch('release/groovy/foo'):
            assert os.path.exists(os.path.join('debian', 'something.udev')), \
                "Lost the debian overlaid files in release branch"
            assert os.path.exists('white space.txt~'), \
                "Lost file with whitespace in name in release branch"
            assert os.path.islink(
                'include/sym/foo.h'), "Symbolic link lost during pipeline"
            if os.path.exists('include/foo.h'):
                user('git rm include/foo.h')
            else:
                if not os.path.exists('include'):
                    os.makedirs('include')
                user('touch include/foo.h')
                user('git add include/foo.h')
            user('git commit -m "A release patch" --allow-empty')

        ###
        ### Test import and export
        ###
        with inbranch('release/groovy/foo'):
            export_cmd.export_patches()
            remove_cmd.remove_patches()
            import_cmd.import_patches()

        ###
        ### Release generator, again
        ###
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # do the proper branches exist?
        assert branch_exists('release/groovy/foo'), \
            "no release/groovy/foo branch"
        assert branch_exists('patches/release/groovy/foo'), \
            "no patches/release/groovy/foo branch"
        # was the release tag created?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('release/groovy/foo/' + version) == 1, \
            "no release tag created"
Exemple #43
0
def test_multi_package_repository(directory=None):
    """
    Release a multi package catkin (groovy) repository.
    """
    directory = directory if directory is not None else os.getcwd()
    # Setup
    pkgs = ['foo', 'bar_ros', 'baz']
    upstream_dir = create_upstream_repository(pkgs, directory)
    upstream_url = 'file://' + upstream_dir
    release_url = create_release_repo(
        upstream_url,
        'git',
        'groovy_devel',
        'groovy')
    release_dir = os.path.join(directory, 'foo_release_clone')
    release_client = get_vcs_client('git', release_dir)
    assert release_client.checkout(release_url)
    with change_directory(release_dir):
        # First run everything
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            cmd = 'git-bloom-release{0} groovy'
            if 'BLOOM_VERBOSE' not in os.environ:
                cmd = cmd.format(' --quiet')
            else:
                cmd = cmd.format('')
            user(cmd, silent=False)
        ###
        ### Import upstream
        ###
        # does the upstream branch exist?
        assert branch_exists('upstream', local_only=True), "no upstream branch"
        # does the upstrea/0.1.0 tag exist?
        ret, out, err = user('git tag', return_io=True)
        assert out.count('upstream/0.1.0') == 1, "no upstream tag created"
        # Is the package.xml from upstream in the upstream branch now?
        with inbranch('upstream'):
            for pkg in pkgs:
                with change_directory(pkg):
                    assert os.path.exists(
                        os.path.join('debian', 'something.udev')), \
                        "Lost the debian overlaid files in upstream branch"
                    assert os.path.exists('white space.txt~'), \
                        "Lost file with whitespace in name in upstream branch"
                    assert os.path.exists('package.xml'), \
                        "upstream did not import: " + os.listdir()
                    with open('package.xml') as f:
                        assert f.read().count('0.1.0'), "not right file"

        ###
        ### Release generator
        ###
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/groovy/' + pkg), \
                "no release/groovy/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/groovy/' + pkg), \
                "no patches/release/groovy/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/groovy/' + pkg + '/0.1.0-0') == 1, \
                "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/groovy/' + pkg):
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                package_xml = open('package.xml', 'r').read()
                assert package_xml.count('<name>' + pkg + '</name>'), \
                    "incorrect package.xml for " + str(pkg)

        # Make a patch
        with inbranch('release/groovy/' + pkgs[0]):
            user('echo "This is a change" >> README.md')
            user('git add README.md')
            user('git commit -m "added a readme" --allow-empty')

        ###
        ### Release generator, again
        ###
        with bloom_answer(bloom_answer.ASSERT_NO_QUESTION):
            ret = user('git-bloom-generate -y rosrelease groovy -s upstream')
        # patch import should have reported OK
        assert ret == code.OK, "actually returned ({0})".format(ret)
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            # Does the release/pkg branch exist?
            assert branch_exists('release/groovy/' + pkg), \
                "no release/groovy/" + pkg + " branch"
            # Does the patches/release/pkg branch exist?
            assert branch_exists('patches/release/groovy/' + pkg), \
                "no patches/release/groovy/" + pkg + " branch"
            # Did the release tag get created?
            assert out.count('release/groovy/' + pkg + '/0.1.0-0') == 1, \
                "no release tag created for " + pkg
            # Is there a package.xml in the top level?
            with inbranch('release/groovy/' + pkg):
                assert os.path.exists(os.path.join('debian', 'something.udev')), \
                    "Lost the debian overlaid files in release branch"
                assert os.path.exists('white space.txt~'), \
                    "Lost file with whitespace in name in release branch"
                assert os.path.exists('package.xml'), "release branch invalid"
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    assert f.read().count('<name>' + pkg + '</name>'), \
                        "incorrect package.xml for " + str(pkg)

        ###
        ### ROSDebian Generator
        ###
        # Check the environment after the release generator
        ret, out, err = user('git tag', return_io=True)
        for pkg in pkgs:
            for distro in ['oneiric', 'precise', 'quantal']:
                pkg_san = sanitize_package_name(pkg)
                # Does the debian/distro/pkg branch exist?
                assert branch_exists('debian/groovy/' + distro + '/' + pkg), \
                    "no debian/groovy/" + pkg + " branch"
                # Does the patches/debian/distro/pkg branch exist?
                patches_branch = 'patches/debian/groovy/' + distro + '/' + pkg
                assert branch_exists(patches_branch), \
                    "no " + patches_branch + " branch"
                # Did the debian tag get created?
                tag = 'debian/ros-groovy-' + pkg_san + '_0.1.0-0_' + distro
                assert out.count(tag) == 1, \
                    "no '" + tag + "'' tag created for '" + pkg + "': `\n" + \
                    out + "\n`"
            # Is there a package.xml in the top level?
            with inbranch('debian/groovy/' + distro + '/' + pkg):
                assert os.path.exists(
                    os.path.join('debian', 'something.udev')), \
                    "Lost the debian overlaid files in debian branch"
                assert os.path.exists('white space.txt~'), \
                    "Lost file with whitespace in name in debian branch"
                assert os.path.exists('package.xml'), "debian branch invalid"
                # Is there blank lins due to no Conflicts/Replaces?
                # See: https://github.com/ros-infrastructure/bloom/pull/329
                with open(os.path.join('debian', 'control'), 'r') as f:
                    assert f.read().count('\n\nHomepage:') == 0, \
                        "Extra blank line before Homepage detected."
                # Is it the correct package.xml for this pkg?
                with open('package.xml', 'r') as f:
                    assert f.read().count('<name>' + pkg + '</name>'), \
                        "incorrect package.xml for " + str(pkg)
def import_upstream(cwd, tmp_dir, args):
    # Ensure the bloom and upstream branches are tracked locally
    track_branches(['bloom', 'upstream'])

    # Create a clone of the bloom_repo to help isolate the activity
    bloom_repo_clone_dir = os.path.join(tmp_dir, 'bloom_clone')
    os.makedirs(bloom_repo_clone_dir)
    os.chdir(bloom_repo_clone_dir)
    bloom_repo = get_vcs_client('git', bloom_repo_clone_dir)
    bloom_repo.checkout('file://{0}'.format(cwd))

    # Ensure the bloom and upstream branches are tracked from the original
    track_branches(['bloom', 'upstream'])

    ### Fetch the upstream tag
    upstream_repo = None
    upstream_repo_dir = os.path.join(tmp_dir, 'upstream_repo')
    # If explicit svn url just export and git-import-orig
    if args.explicit_svn_url is not None:
        if args.upstream_version is None:
            error("'--explicit-svn-url' must be specified with "
                  "'--upstream-version'")
            return 1
        info("Checking out upstream at version " + ansi('boldon') + \
             str(args.upstream_version) + ansi('reset') + \
             " from repository at " + ansi('boldon') + \
             str(args.explicit_svn_url) + ansi('reset'))
        upstream_repo = get_vcs_client('svn', upstream_repo_dir)
        retcode = try_vcstools_checkout(upstream_repo, args.explicit_svn_url)
        if retcode != 0:
            return retcode
        meta = {
            'name': None,
            'version': args.upstream_version,
            'type': 'manual'
        }
    # Else fetching from bloom configs
    else:
        # Check for a bloom branch
        check_for_bloom()
        # Parse the bloom config file
        upstream_url, upstream_type, upstream_branch = parse_bloom_conf()
        # If the upstream_tag is specified, don't search just fetch
        upstream_repo = get_vcs_client(upstream_type, upstream_repo_dir)
        if args.upstream_tag is not None:
            warning("Using specified upstream tag '" + args.upstream_tag + "'")
            if upstream_type == 'svn':
                upstream_url += '/tags/' + args.upstream_tag
                upstream_tag = ''
            else:
                upstream_tag = args.upstream_tag
            retcode = try_vcstools_checkout(upstream_repo,
                                            upstream_url,
                                            upstream_tag)
            if retcode != 0:
                return retcode
            meta = {
                'name': None,
                'version': args.upstream_tag,
                'type': 'manual'
            }
        # We have to search for the upstream tag
        else:
            if args.upstream_devel is not None:
                warning("Overriding the bloom.conf upstream branch with " +
                        args.upstream_devel)
                devel_branch = args.upstream_devel
            else:
                devel_branch = upstream_branch
            if args.upstream_version is None:
                meta = auto_upstream_checkout(
                    upstream_repo, upstream_url, devel_branch
                )
            else:
                meta = {
                    'version': args.upstream_version
                }
            if type(meta) not in [dict] and meta != 0:
                return meta

    ### Export the repository
    version = meta['version']

    # Export the repository to a tar ball
    tarball_prefix = 'upstream-' + str(version)
    info('Exporting version {0}'.format(version))
    tarball_path = os.path.join(tmp_dir, tarball_prefix)
    if upstream_repo.get_vcs_type_name() == 'svn':
        upstream_repo.export_repository('', tarball_path)
    else:
        if args.upstream_tag is not None:
            upstream_repo.export_repository(args.upstream_tag, tarball_path)
        else:
            upstream_repo.export_repository(version, tarball_path)

    # Get the gbp version elements from either the last tag or the default
    last_tag = get_last_tag_by_version()
    if last_tag == '':
        gbp_major, gbp_minor, gbp_patch = segment_version(version)
    else:
        gbp_major, gbp_minor, gbp_patch = \
            get_versions_from_upstream_tag(last_tag)
        info("The latest upstream tag in the release repository is "
              + ansi('boldon') + last_tag + ansi('reset'))
        # Ensure the new version is greater than the last tag
        last_tag_version = '.'.join([gbp_major, gbp_minor, gbp_patch])
        if parse_version(version) < parse_version(last_tag_version):
            warning("""\
Version discrepancy:
    The upstream version, {0}, is not newer than the previous \
release version, {1}.
""".format(version, last_tag_version))
        if parse_version(version) <= parse_version(last_tag_version):
            if args.replace:
                # Remove the conflicting tag first
                warning("""\
The upstream version, {0}, is equal to or less than a previous \
import version.
    Removing conflicting tag before continuing \
because the '--replace' options was specified.\
""".format(version))
            else:
                warning("""\
The upstream version, {0}, is equal to a previous import version. \
git-buildpackage will fail, if you want to replace the existing \
upstream import use the '--replace' option.\
""".format(version))
    if args.replace:
        if tag_exists('upstream/' + version):
            execute_command('git tag -d {0}'.format('upstream/' + version))
            execute_command('git push origin :refs/tags/'
                            '{0}'.format('upstream/' + version))

    # Look for upstream branch
    if not branch_exists('upstream', local_only=True):
        create_branch('upstream', orphaned=True, changeto=True)

    # Go to the bloom branch during import
    bloom_repo.update('bloom')

    # Detect if git-import-orig is installed
    tarball_path += '.tar.gz'
    import_orig(tarball_path, 'upstream', upstream_repo.get_url(), version)

    # Push changes back to the original bloom repo
    execute_command('git push --all -f')
    execute_command('git push --tags')