Exemplo n.º 1
0
def test_verify_files_parsable():
    url = 'file://' + FILES_DIR + '/index.yaml'
    index = get_index(url)
    release_file = get_release_file(index, 'foo')
    data = yaml_from_release_file(release_file)
    with open(os.path.join(FILES_DIR, 'foo', 'release.yaml'), 'r') as f:
        expected = f.read()
    assert data == expected, get_diff(expected, data)
Exemplo n.º 2
0
def open_pull_request(track, repository, distro):
    # Get the diff
    release_file = get_release_file(distro)
    if repository in release_file.repositories:
        orig_version = release_file.repositories[repository].version
    else:
        orig_version = None
    updated_release_file = generate_ros_distro_diff(track, repository, distro)
    if updated_release_file is None:
        # There were no changes, no pull request required
        return None
    version = updated_release_file.repositories[repository].version
    updated_distro_file = yaml_from_release_file(updated_release_file)
    # Determine if the distro file is hosted on github...
    gh_org, gh_repo, gh_branch, gh_path = get_gh_info(get_release_file_url(distro))
    if None in [gh_org, gh_repo, gh_branch, gh_path]:
        warning("Automated pull request only available via github.com")
        return
    # Get the github user name
    gh_username = None
    bloom_user_path = os.path.join(os.path.expanduser("~"), ".bloom_user")
    if os.path.exists(bloom_user_path):
        with open(bloom_user_path, "r") as f:
            gh_username = f.read().strip()
    gh_username = gh_username or getpass.getuser()
    response = raw_input("github user name [{0}]: ".format(gh_username))
    if response:
        gh_username = response
        info("Would you like bloom to store your github user name (~/.bloom_user)?")
        if maybe_continue():
            with open(bloom_user_path, "w") as f:
                f.write(gh_username)
        else:
            with open(bloom_user_path, "w") as f:
                f.write(" ")
            warning("If you want to have bloom store it in the future remove the ~/.bloom_user file.")
    # Get the github password
    gh_password = getpass.getpass("github password (This is not stored):")
    if not gh_password or not gh_username:
        error("Either the github username or github password is not set.")
        warning("Skipping the pull request...")
        return
    # Check for fork
    info(fmt("@{bf}@!==> @|@!Checking for rosdistro fork on github..."))
    gh_user_repos = fetch_github_api("https://api.github.com/users/{0}/repos".format(gh_username), use_pagination=True)
    if gh_user_repos is None:
        error("Failed to get a list of repositories for user: '******'".format(gh_username))
        warning("Skipping the pull request...")
        return
    if "rosdistro" not in [x["name"] for x in gh_user_repos if "name" in x]:
        warning(
            "Github user '{0}' does not have a fork ".format(gh_username)
            + "of the {0}:{1} repository, create one?".format(gh_org, gh_repo)
        )
        if not maybe_continue():
            warning("Skipping the pull request...")
            return
        # Create a fork
        create_fork(gh_org, gh_repo, gh_username, gh_password)
    # Clone the fork
    info(fmt("@{bf}@!==> @|@!" + "Cloning {0}/{1}...".format(gh_username, gh_repo)))
    temp_dir = tempfile.mkdtemp()
    new_branch = None
    title = "{0}: {1} in '{2}' [bloom]".format(repository, version, gh_path)
    body = """\
Increasing version of package(s) in repository `{0}`:
- previous version: `{1}`
- new version: `{2}`
- distro file: `{3}`
- bloom version: `{4}`
""".format(
        repository, orig_version or "null", version, gh_path, bloom.__version__
    )
    with change_directory(temp_dir):

        def _my_run(cmd):
            info(fmt("@{bf}@!==> @|@!" + str(cmd)))
            # out = check_output(cmd, stderr=subprocess.STDOUT, shell=True)
            out = None
            from subprocess import call

            call(cmd, shell=True)
            if out:
                info(out, use_prefix=False)

        _my_run("git clone https://github.com/{0}/{1}.git".format(gh_username, gh_repo))
        with change_directory(gh_repo):
            _my_run("git remote add bloom https://github.com/{0}/{1}.git".format(gh_org, gh_repo))
            _my_run("git remote update")
            _my_run("git fetch")
            track_branches()
            branches = get_branches()
            new_branch = "bloom-{repository}-{count}"
            count = 0
            while new_branch.format(repository=repository, count=count) in branches:
                count += 1
            new_branch = new_branch.format(repository=repository, count=count)
            # Final check
            info(fmt("@{cf}Pull Request Title: @{yf}" + title))
            info(fmt("@{cf}Pull Request Body : \n@{yf}" + body))
            msg = fmt(
                "@!Open a @|@{cf}pull request@| @!@{kf}from@| @!'@|@!@{bf}"
                + "{gh_username}/{gh_repo}:{new_branch}".format(**locals())
                + "@|@!' @!@{kf}into@| @!'@|@!@{bf}"
                + "{gh_org}/{gh_repo}:{gh_branch}".format(**locals())
                + "@|@!'?"
            )
            info(msg)
            if not maybe_continue():
                warning("Skipping the pull request...")
                return
            _my_run("git checkout -b {0} bloom/{1}".format(new_branch, gh_branch))
            with open("{0}".format(gh_path), "w") as f:
                info(fmt("@{bf}@!==> @|@!Writing new distribution file: ") + str(gh_path))
                f.write(updated_distro_file)
            _my_run("git add {0}".format(gh_path))
            _my_run('git commit -m "{0}"'.format(title))
            _my_run("git push origin {0}".format(new_branch))
    # Open the pull request
    return create_pull_request(gh_org, gh_repo, gh_username, gh_password, gh_branch, new_branch, title, body)
Exemplo n.º 3
0
def generate_ros_distro_diff(track, repository, distro):
    release_dict = get_release_file(distro).get_data()
    # Get packages
    packages = get_packages()
    if len(packages) == 0:
        warning("No packages found, will not generate 'package: path' entries for rosdistro.")
    # Get version
    track_dict = get_tracks_dict_raw()["tracks"][track]
    last_version = track_dict["last_version"]
    release_inc = track_dict["release_inc"]
    version = "{0}-{1}".format(last_version, release_inc)
    # Create a repository if there isn't already one
    if repository not in release_dict["repositories"]:
        global _user_provided_release_url
        release_dict["repositories"][repository] = {"url": _user_provided_release_url}
    # Update the repository
    repo = release_dict["repositories"][repository]
    if "tags" not in repo:
        repo["tags"] = {}
    repo["tags"]["release"] = "release/%s/{package}/{version}" % distro
    repo["version"] = version
    if "packages" not in repo:
        repo["packages"] = {}
    for path, pkg in packages.items():
        if pkg.name not in repo["packages"]:
            repo["packages"][pkg.name] = {}
        repo["packages"][pkg.name]["subfolder"] = path  # This will be shortened
    # Remove any missing packages
    for pkg_name in dict(repo["packages"]):
        if pkg_name not in [p.name for p in packages.values()]:
            if pkg_name in repo["packages"]:
                del repo["packages"][pkg_name]
    # Do the diff
    distro_file_name = get_relative_release_file_path(distro)
    updated_release_file = rosdistro.ReleaseFile("distro", release_dict)
    distro_dump = yaml_from_release_file(updated_release_file)
    distro_file_raw = load_url_to_file_handle(get_release_file_url(distro)).read()
    if distro_file_raw != distro_dump:
        udiff = difflib.unified_diff(
            distro_file_raw.splitlines(), distro_dump.splitlines(), fromfile=distro_file_name, tofile=distro_file_name
        )
        temp_dir = tempfile.mkdtemp()
        udiff_file = os.path.join(temp_dir, repository + "-" + version + ".patch")
        udiff_raw = ""
        info("Unified diff for the ROS distro file located at '{0}':".format(udiff_file))
        for line in udiff:
            if line.startswith("@@"):
                udiff_raw += line
                line = fmt("@{cf}" + sanitize(line))
            if line.startswith("+"):
                if not line.startswith("+++"):
                    line += "\n"
                udiff_raw += line
                line = fmt("@{gf}" + sanitize(line))
            if line.startswith("-"):
                if not line.startswith("---"):
                    line += "\n"
                udiff_raw += line
                line = fmt("@{rf}" + sanitize(line))
            if line.startswith(" "):
                line += "\n"
                udiff_raw += line
            info(line, use_prefix=False, end="")
        with open(udiff_file, "w+") as f:
            f.write(udiff_raw)
        return updated_release_file
    else:
        warning("This release resulted in no changes to the ROS distro file...")
    return None
Exemplo n.º 4
0
def generate_ros_distro_diff(track, repository, distro):
    release_dict = get_release_file(distro).get_data()
    # Get packages
    packages = get_packages()
    if len(packages) == 0:
        warning("No packages found, will not generate 'package: path' entries for rosdistro.")
    # Get version
    track_dict = get_tracks_dict_raw()['tracks'][track]
    last_version = track_dict['last_version']
    release_inc = track_dict['release_inc']
    version = '{0}-{1}'.format(last_version, release_inc)
    # Create a repository if there isn't already one
    if repository not in release_dict['repositories']:
        global _user_provided_release_url
        release_dict['repositories'][repository] = {
            'url': _user_provided_release_url
        }
    # Update the repository
    repo = release_dict['repositories'][repository]
    if 'tags' not in repo:
        repo['tags'] = {}
    repo['tags']['release'] = 'release/%s/{package}/{version}' % distro
    repo['version'] = version
    if 'packages' not in repo:
        repo['packages'] = {}
    for path, pkg in packages.items():
        if pkg.name not in repo['packages']:
            repo['packages'][pkg.name] = {}
        repo['packages'][pkg.name]['subfolder'] = path  # This will be shortened
    # Remove any missing packages
    for pkg_name in dict(repo['packages']):
        if pkg_name not in [p.name for p in packages.values()]:
            if pkg_name in repo['packages']:
                del repo['packages'][pkg_name]
    # Do the diff
    distro_file_name = get_relative_release_file_path(distro)
    updated_release_file = rosdistro.ReleaseFile('distro', release_dict)
    distro_dump = yaml_from_release_file(updated_release_file)
    distro_file_raw = load_url_to_file_handle(get_release_file_url(distro)).read()
    if distro_file_raw != distro_dump:
        udiff = difflib.unified_diff(distro_file_raw.splitlines(), distro_dump.splitlines(),
                                     fromfile=distro_file_name, tofile=distro_file_name)
        temp_dir = tempfile.mkdtemp()
        udiff_file = os.path.join(temp_dir, repository + '-' + version + '.patch')
        udiff_raw = ''
        info("Unified diff for the ROS distro file located at '{0}':".format(udiff_file))
        for line in udiff:
            if line.startswith('@@'):
                udiff_raw += line
                line = fmt('@{cf}' + sanitize(line))
            if line.startswith('+'):
                if not line.startswith('+++'):
                    line += '\n'
                udiff_raw += line
                line = fmt('@{gf}' + sanitize(line))
            if line.startswith('-'):
                if not line.startswith('---'):
                    line += '\n'
                udiff_raw += line
                line = fmt('@{rf}' + sanitize(line))
            if line.startswith(' '):
                line += '\n'
                udiff_raw += line
            info(line, use_prefix=False, end='')
        with open(udiff_file, 'w+') as f:
            f.write(udiff_raw)
        return updated_release_file
    else:
        warning("This release resulted in no changes to the ROS distro file...")
    return None
Exemplo n.º 5
0
def open_pull_request(track, repository, distro):
    # Get the diff
    release_file = get_release_file(distro)
    if repository in release_file.repositories:
        orig_version = release_file.repositories[repository].version
    else:
        orig_version = None
    updated_release_file = generate_ros_distro_diff(track, repository, distro)
    if updated_release_file is None:
        # There were no changes, no pull request required
        return None
    version = updated_release_file.repositories[repository].version
    updated_distro_file = yaml_from_release_file(updated_release_file)
    # Determine if the distro file is hosted on github...
    gh_org, gh_repo, gh_branch, gh_path = get_gh_info(
        get_release_file_url(distro))
    if None in [gh_org, gh_repo, gh_branch, gh_path]:
        warning("Automated pull request only available via github.com")
        return
    # Get the github user name
    gh_username = None
    bloom_user_path = os.path.join(os.path.expanduser('~'), '.bloom_user')
    if os.path.exists(bloom_user_path):
        with open(bloom_user_path, 'r') as f:
            gh_username = f.read().strip()
    gh_username = gh_username or getpass.getuser()
    response = raw_input("github user name [{0}]: ".format(gh_username))
    if response:
        gh_username = response
        info(
            "Would you like bloom to store your github user name (~/.bloom_user)?"
        )
        if maybe_continue():
            with open(bloom_user_path, 'w') as f:
                f.write(gh_username)
        else:
            with open(bloom_user_path, 'w') as f:
                f.write(' ')
            warning(
                "If you want to have bloom store it in the future remove the ~/.bloom_user file."
            )
    # Get the github password
    gh_password = getpass.getpass("github password (This is not stored):")
    if not gh_password or not gh_username:
        error("Either the github username or github password is not set.")
        warning("Skipping the pull request...")
        return
    # Check for fork
    info(fmt("@{bf}@!==> @|@!Checking for rosdistro fork on github..."))
    gh_user_repos = fetch_github_api(
        'https://api.github.com/users/{0}/repos'.format(gh_username),
        use_pagination=True)
    if gh_user_repos is None:
        error("Failed to get a list of repositories for user: '******'".format(
            gh_username))
        warning("Skipping the pull request...")
        return
    if 'rosdistro' not in [x['name'] for x in gh_user_repos if 'name' in x]:
        warning(
            "Github user '{0}' does not have a fork ".format(gh_username) +
            "of the {0}:{1} repository, create one?".format(gh_org, gh_repo))
        if not maybe_continue():
            warning("Skipping the pull request...")
            return
        # Create a fork
        create_fork(gh_org, gh_repo, gh_username, gh_password)
    # Clone the fork
    info(
        fmt("@{bf}@!==> @|@!" +
            "Cloning {0}/{1}...".format(gh_username, gh_repo)))
    temp_dir = tempfile.mkdtemp()
    new_branch = None
    title = "{0}: {1} in '{2}' [bloom]".format(repository, version, gh_path)
    body = """\
Increasing version of package(s) in repository `{0}`:
- previous version: `{1}`
- new version: `{2}`
- distro file: `{3}`
- bloom version: `{4}`
""".format(repository, orig_version or 'null', version, gh_path,
           bloom.__version__)
    with change_directory(temp_dir):

        def _my_run(cmd):
            info(fmt("@{bf}@!==> @|@!" + str(cmd)))
            # out = check_output(cmd, stderr=subprocess.STDOUT, shell=True)
            out = None
            from subprocess import call
            call(cmd, shell=True)
            if out:
                info(out, use_prefix=False)

        _my_run('git clone https://github.com/{0}/{1}.git'.format(
            gh_username, gh_repo))
        with change_directory(gh_repo):
            _my_run(
                'git remote add bloom https://github.com/{0}/{1}.git'.format(
                    gh_org, gh_repo))
            _my_run('git remote update')
            _my_run('git fetch')
            track_branches()
            branches = get_branches()
            new_branch = 'bloom-{repository}-{count}'
            count = 0
            while new_branch.format(repository=repository,
                                    count=count) in branches:
                count += 1
            new_branch = new_branch.format(repository=repository, count=count)
            # Final check
            info(fmt("@{cf}Pull Request Title: @{yf}" + title))
            info(fmt("@{cf}Pull Request Body : \n@{yf}" + body))
            msg = fmt(
                "@!Open a @|@{cf}pull request@| @!@{kf}from@| @!'@|@!@{bf}" +
                "{gh_username}/{gh_repo}:{new_branch}".format(**locals()) +
                "@|@!' @!@{kf}into@| @!'@|@!@{bf}" +
                "{gh_org}/{gh_repo}:{gh_branch}".format(**locals()) + "@|@!'?")
            info(msg)
            if not maybe_continue():
                warning("Skipping the pull request...")
                return
            _my_run('git checkout -b {0} bloom/{1}'.format(
                new_branch, gh_branch))
            with open('{0}'.format(gh_path), 'w') as f:
                info(
                    fmt("@{bf}@!==> @|@!Writing new distribution file: ") +
                    str(gh_path))
                f.write(updated_distro_file)
            _my_run('git add {0}'.format(gh_path))
            _my_run('git commit -m "{0}"'.format(title))
            _my_run('git push origin {0}'.format(new_branch))
    # Open the pull request
    return create_pull_request(gh_org, gh_repo, gh_username, gh_password,
                               gh_branch, new_branch, title, body)
Exemplo n.º 6
0
def generate_ros_distro_diff(track, repository, distro):
    release_dict = get_release_file(distro).get_data()
    # Get packages
    packages = get_packages()
    if len(packages) == 0:
        warning(
            "No packages found, will not generate 'package: path' entries for rosdistro."
        )
    # Get version
    track_dict = get_tracks_dict_raw()['tracks'][track]
    last_version = track_dict['last_version']
    release_inc = track_dict['release_inc']
    version = '{0}-{1}'.format(last_version, release_inc)
    # Create a repository if there isn't already one
    if repository not in release_dict['repositories']:
        global _user_provided_release_url
        release_dict['repositories'][repository] = {
            'url': _user_provided_release_url
        }
    # Update the repository
    repo = release_dict['repositories'][repository]
    if 'tags' not in repo:
        repo['tags'] = {}
    repo['tags']['release'] = 'release/%s/{package}/{version}' % distro
    repo['version'] = version
    if 'packages' not in repo:
        repo['packages'] = {}
    for path, pkg in packages.items():
        if pkg.name not in repo['packages']:
            repo['packages'][pkg.name] = {}
        repo['packages'][
            pkg.name]['subfolder'] = path  # This will be shortened
    # Remove any missing packages
    for pkg_name in dict(repo['packages']):
        if pkg_name not in [p.name for p in packages.values()]:
            if pkg_name in repo['packages']:
                del repo['packages'][pkg_name]
    # Do the diff
    distro_file_name = get_relative_release_file_path(distro)
    updated_release_file = rosdistro.ReleaseFile('distro', release_dict)
    distro_dump = yaml_from_release_file(updated_release_file)
    distro_file_raw = load_url_to_file_handle(
        get_release_file_url(distro)).read()
    if distro_file_raw != distro_dump:
        udiff = difflib.unified_diff(distro_file_raw.splitlines(),
                                     distro_dump.splitlines(),
                                     fromfile=distro_file_name,
                                     tofile=distro_file_name)
        temp_dir = tempfile.mkdtemp()
        udiff_file = os.path.join(temp_dir,
                                  repository + '-' + version + '.patch')
        udiff_raw = ''
        info("Unified diff for the ROS distro file located at '{0}':".format(
            udiff_file))
        for line in udiff:
            if line.startswith('@@'):
                udiff_raw += line
                line = fmt('@{cf}' + sanitize(line))
            if line.startswith('+'):
                if not line.startswith('+++'):
                    line += '\n'
                udiff_raw += line
                line = fmt('@{gf}' + sanitize(line))
            if line.startswith('-'):
                if not line.startswith('---'):
                    line += '\n'
                udiff_raw += line
                line = fmt('@{rf}' + sanitize(line))
            if line.startswith(' '):
                line += '\n'
                udiff_raw += line
            info(line, use_prefix=False, end='')
        with open(udiff_file, 'w+') as f:
            f.write(udiff_raw)
        return updated_release_file
    else:
        warning(
            "This release resulted in no changes to the ROS distro file...")
    return None