예제 #1
0
def generate_ros_distro_diff(track, repository, distro):
    distribution_dict = get_distribution_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 distribution_dict['repositories']:
        global _user_provided_release_url
        distribution_dict['repositories'][repository] = {}
    # Create a release entry if there isn't already one
    if 'release' not in distribution_dict['repositories'][repository]:
        distribution_dict['repositories'][repository]['release'] = {
            'url': _user_provided_release_url
        }
    # Update the repository
    repo = distribution_dict['repositories'][repository]['release']
    if 'tags' not in repo:
        repo['tags'] = {}
    repo['tags']['release'] = generate_release_tag(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'].append(pkg.name)
    # Remove any missing packages
    packages_being_released = [p.name for p in packages.values()]
    for pkg_name in list(repo['packages']):
        if pkg_name not in packages_being_released:
            repo['packages'].remove(pkg_name)
    repo['packages'].sort()

    # Do the diff
    distro_file_name = get_relative_distribution_file_path(distro)
    updated_distribution_file = rosdistro.DistributionFile(distro, distribution_dict)
    distro_dump = yaml_from_distribution_file(updated_distribution_file)
    distro_file_raw = load_url_to_file_handle(get_disitrbution_file_url(distro)).read()
    if distro_file_raw != distro_dump:
        # Calculate the diff
        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='')
        # Assert that only this repository is being changed
        distro_file_yaml = yaml.load(distro_file_raw)
        distro_yaml = yaml.load(distro_dump)
        if 'repositories' in distro_file_yaml:
            distro_file_repos = distro_file_yaml['repositories']
            for repo in distro_yaml['repositories']:
                if repo == repository:
                    continue
                if repo not in distro_file_repos or distro_file_repos[repo] != distro_yaml['repositories'][repo]:
                    error("This generated pull request modifies a repository entry other than the one being released.")
                    error("This likely occured because the upstream rosdistro changed during this release.")
                    error("This pull request will abort, please re-run this command with the -p option to try again.",
                          exit=True)
        # Write the diff out to file
        with open(udiff_file, 'w+') as f:
            f.write(udiff_raw)
        # Return the diff
        return updated_distribution_file
    else:
        warning("This release resulted in no changes to the ROS distro file...")
    return None
예제 #2
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)
예제 #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
예제 #4
0
파일: release.py 프로젝트: davidhodo/bloom
def generate_ros_distro_diff(track, repository, distro):
    distribution_dict = get_distribution_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).encode('utf-8')
    # Create a repository if there isn't already one
    if repository not in distribution_dict['repositories']:
        global _user_provided_release_url
        distribution_dict['repositories'][repository] = {}
    # Create a release entry if there isn't already one
    if 'release' not in distribution_dict['repositories'][repository]:
        distribution_dict['repositories'][repository]['release'.encode('utf-8')] = {
            'url'.encode('utf-8'): _user_provided_release_url
        }
    # Update the repository
    repo = distribution_dict['repositories'][repository]['release']
    if 'tags' not in repo:
        repo['tags'.encode('utf-8')] = {}
    repo['tags']['release'.encode('utf-8')] = generate_release_tag(distro)
    repo['version'.encode('utf-8')] = version
    if 'packages' not in repo:
        repo['packages'.encode('utf-8')] = []
    for path, pkg in packages.items():
        if pkg.name not in repo['packages']:
            repo['packages'].append(pkg.name)
    # Remove any missing packages
    packages_being_released = [p.name for p in packages.values()]
    for pkg_name in list(repo['packages']):
        if pkg_name not in packages_being_released:
            repo['packages'].remove(pkg_name)
    repo['packages'].sort()

    def get_repository_info_from_user():
        data = {}
        while True:
            vcs_type = safe_input('VCS type [git, svn, hg, bzr]: ')
            if vcs_type in ['git', 'svn', 'hg', 'bzr']:
                break
            error("'{0}' is not a valid vcs type.".format(vcs_type))
            if not maybe_continue(msg='Try again'):
                return {}
        data['type'] = vcs_type
        while True:
            url = safe_input('VCS url: ')
            if url:
                break
            error("Nothing entered for url.")
            if not maybe_continue(msg='Try again'):
                return {}
        data['url'] = url
        while True:
            version = safe_input('VCS version [commit, tag, branch, etc]: ')
            if version:
                break
            error("Nothing entered for version.")
            if not maybe_continue(msg='Try again'):
                return {}
        data['version'] = version
        return data

    # Ask for doc entry
    if 'BLOOM_DONT_ASK_FOR_DOCS' not in os.environ:
        docs = distribution_dict['repositories'][repository].get('doc', {})
        if not docs and maybe_continue(msg='Would you like to add documentation information for this repository?'):
            info("Please enter your repository information for the doc generation job.")
            info("This information should point to the repository from which documentation should be generated.")
            docs = get_repository_info_from_user()
        distribution_dict['repositories'][repository]['doc'] = docs

    # Ask for source entry
    if 'BLOOM_DONT_ASK_FOR_SOURCE' not in os.environ:
        source = distribution_dict['repositories'][repository].get('source', {})
        if not source and maybe_continue(msg='Would you like to add source information for this repository?'):
            info("Please enter information which points ot the active development branch for this repository.")
            info("This information is used to run continuous integration jobs and for developers to checkout from.")
            source = get_repository_info_from_user()
        distribution_dict['repositories'][repository]['source'] = source

    # Ask for maintainership information
    if 'BLOOM_DONT_ASK_FOR_MAINTENANCE_STATUS' not in os.environ:
        status = distribution_dict['repositories'][repository].get('status', None)
        description = distribution_dict['repositories'][repository].get('status_description', None)
        if status is None and maybe_continue(msg='Would you like to add a maintenance status for this repository?'):
            info("Please enter a maintenance status.")
            info("Valid maintenance statuses:")
            info("- developed: active development is in progress")
            info("- maintained: no new development, but bug fixes and pull requests are addressed")
            info("- end-of-life: should not be used, will disapear at some point")
            while True:
                status = safe_input('Status: ')
                if status in ['developed', 'maintained', 'end-of-life']:
                    break
                error("'{0}' is not a valid status.".format(status))
                if not maybe_continue(msg='Try again'):
                    status = None
                    break
            if status is not None:
                info("You can also enter a status description.")
                info("This is usually reserved for giving a reason when a status is 'end-of-life'.")
                if description is not None:
                    info("Current status description: {0}".format(description))
                description_in = safe_input('Status Description [press Enter for no change]: ')
                if description_in:
                    description = description_in
        if status is not None:
            distribution_dict['repositories'][repository]['status'] = status
            if description is not None:
                distribution_dict['repositories'][repository]['status_description'] = description

    # Do the diff
    distro_file_name = get_relative_distribution_file_path(distro)
    updated_distribution_file = rosdistro.DistributionFile(distro, distribution_dict)
    distro_dump = yaml_from_distribution_file(updated_distribution_file)
    distro_file_raw = load_url_to_file_handle(get_disitrbution_file_url(distro)).read()
    if distro_file_raw != distro_dump:
        # Calculate the diff
        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='')
        # Assert that only this repository is being changed
        distro_file_yaml = yaml.load(distro_file_raw)
        distro_yaml = yaml.load(distro_dump)
        if 'repositories' in distro_file_yaml:
            distro_file_repos = distro_file_yaml['repositories']
            for repo in distro_yaml['repositories']:
                if repo == repository:
                    continue
                if repo not in distro_file_repos or distro_file_repos[repo] != distro_yaml['repositories'][repo]:
                    error("This generated pull request modifies a repository entry other than the one being released.")
                    error("This likely occured because the upstream rosdistro changed during this release.")
                    error("This pull request will abort, please re-run this command with the -p option to try again.",
                          exit=True)
        # Write the diff out to file
        with open(udiff_file, 'w+') as f:
            f.write(udiff_raw)
        # Return the diff
        return updated_distribution_file
    else:
        warning("This release resulted in no changes to the ROS distro file...")
    return None
예제 #5
0
def generate_ros_distro_diff(track, repository, distro):
    distribution_dict = get_distribution_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 distribution_dict['repositories']:
        global _user_provided_release_url
        distribution_dict['repositories'][repository] = {}
    # Create a release entry if there isn't already one
    if 'release' not in distribution_dict['repositories'][repository]:
        distribution_dict['repositories'][repository]['release'] = {
            'url': _user_provided_release_url
        }
    # Update the repository
    repo = distribution_dict['repositories'][repository]['release']
    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'].append(pkg.name)
    # Remove any missing packages
    packages_being_released = [p.name for p in packages.values()]
    for pkg_name in list(repo['packages']):
        if pkg_name not in packages_being_released:
            repo['packages'].remove(pkg_name)
    repo['packages'].sort()

    # Do the diff
    distro_file_name = get_relative_distribution_file_path(distro)
    updated_distribution_file = rosdistro.DistributionFile(distro, distribution_dict)
    distro_dump = yaml_from_distribution_file(updated_distribution_file)
    distro_file_raw = load_url_to_file_handle(get_disitrbution_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_distribution_file
    else:
        warning("This release resulted in no changes to the ROS distro file...")
    return None
예제 #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