示例#1
0
    def take_action(self, parsed_args):
        LOG.debug('determining repository name from .gitreview')
        gitreview_filename = os.path.join(parsed_args.repo_dir, '.gitreview')
        cp = configparser.ConfigParser()
        cp.read(gitreview_filename)
        gerrit = cp['gerrit']
        repo = gerrit['project']
        if repo.endswith('.git'):
            repo = repo[:-4]
        LOG.info('working on %s', repo)

        in_repo = find_project_settings_in_repo(parsed_args.repo_dir)
        in_tree_file, in_tree_project, in_tree_settings = in_repo
        if not in_tree_file:
            raise RuntimeError('Could not find project settings in {}'.format(
                parsed_args.repo_dir))

        changed = update_docs_job(in_tree_project)

        if not changed:
            LOG.info('No updates needed for %s', repo)
            return 2

        LOG.info('# {} switch docs jobs'.format(repo))
        yaml = projectconfig_ruamellib.YAML()
        # yaml.dump([in_tree_project], self.app.stdout)
        LOG.info('updating %s', in_tree_file)
        with open(in_tree_file, 'w', encoding='utf-8') as f:
            yaml.dump(in_tree_settings, f)
示例#2
0
def find_project_settings_in_repo(repo_dir):
    yaml = projectconfig_ruamellib.YAML()
    candidate_bases = [
        '.zuul.yaml',
        'zuul.yaml',
        '.zuul.d/*.yaml',
        'zuul.d/*.yaml',
    ]
    for base in candidate_bases:
        pattern = os.path.join(repo_dir, base)
        for candidate in glob.glob(pattern):
            LOG.debug('looking for zuul config in %s', candidate)
            with open(candidate, 'r', encoding='utf-8') as f:
                settings = yaml.load(f) or []
            for block in settings:
                if 'project' in block:
                    LOG.debug('using zuul config from %s', candidate)
                    return (candidate, block, settings)
    LOG.debug('did not find in-tree project settings')
    return (None, {}, [])
示例#3
0
    def take_action(self, parsed_args):
        yaml = projectconfig_ruamellib.YAML()

        gov_dat = governance.Governance(url=parsed_args.project_list)
        all_repos = set(gov_dat.get_repos())
        if not all_repos:
            raise ValueError('found no governed repositories')

        project_filename = os.path.join(
            parsed_args.project_config_dir,
            'zuul.d',
            'projects.yaml',
        )
        LOG.debug('loading project settings from %s', project_filename)
        with open(project_filename, 'r', encoding='utf-8') as f:
            project_settings = yaml.load(f)

        for entry in project_settings:
            if 'project' not in entry:
                continue
            project = entry['project']
            if project['name'] not in all_repos:
                continue
            if 'templates' not in project:
                continue
            templates = project['templates']
            for candidate in self.CANDIDATES:
                try:
                    idx = templates.index(candidate)
                except (ValueError, IndexError):
                    pass
                else:
                    LOG.info('updating %s', project['name'])
                    templates[idx] = 'publish-to-pypi-python3'

        with open(project_filename, 'w', encoding='utf-8') as f:
            yaml.dump(project_settings, f)
示例#4
0
    def take_action(self, parsed_args):
        LOG.debug('determining repository name from .gitreview')
        gitreview_filename = os.path.join(parsed_args.repo_dir, '.gitreview')
        cp = configparser.ConfigParser()
        cp.read(gitreview_filename)
        gerrit = cp['gerrit']
        repo = gerrit['project']
        if repo.endswith('.git'):
            repo = repo[:-4]
        LOG.info('working on %s', repo)

        in_repo = find_project_settings_in_repo(parsed_args.repo_dir)
        in_tree_file, in_tree_project, in_tree_settings = in_repo
        if not in_tree_file:
            raise RuntimeError('Could not find project settings in {}'.format(
                parsed_args.repo_dir))

        changed = False
        templates = in_tree_project['project'].get('templates', [])
        has_lib_job = 'lib-forward-testing' in templates
        tests_py3 = 'lib-forward-testing-python3' in templates
        if has_lib_job and not tests_py3:
            idx = templates.index('lib-forward-testing')
            templates.insert(idx + 1, 'lib-forward-testing-python3')
            changed = True

        if not changed:
            LOG.info('No updates needed for %s', repo)
            return 2

        LOG.info('# {} add lib-forward-testing-python3 jobs'.format(repo))
        yaml = projectconfig_ruamellib.YAML()
        # yaml.dump([in_tree_project], self.app.stdout)
        LOG.info('updating %s', in_tree_file)
        with open(in_tree_file, 'w', encoding='utf-8') as f:
            yaml.dump(in_tree_settings, f)
示例#5
0
    def take_action(self, parsed_args):
        yaml = projectconfig_ruamellib.YAML()

        project_filename = os.path.join(
            parsed_args.project_config_dir,
            'zuul.d',
            'projects.yaml',
        )
        LOG.debug('loading project settings from %s', project_filename)
        with open(project_filename, 'r', encoding='utf-8') as f:
            project_settings = yaml.load(f)

        zuul_templates_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'project-templates.yaml',
        )
        LOG.debug('loading project templates from %s', zuul_templates_filename)
        with open(zuul_templates_filename, 'r', encoding='utf-8') as f:
            zuul_templates_raw = yaml.load(f)
        zuul_templates = {
            pt['project-template']['name']: pt['project-template']
            for pt in zuul_templates_raw if 'project-template' in pt
        }

        zuul_jobs_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'jobs.yaml',
        )
        LOG.debug('loading jobs from %s', zuul_jobs_filename)
        with open(zuul_jobs_filename, 'r', encoding='utf-8') as f:
            zuul_jobs_raw = yaml.load(f)
        zuul_jobs = {
            job['job']['name']: job['job']
            for job in zuul_jobs_raw if 'job' in job
        }

        repos = parsed_args.repos
        if not repos:
            gov_dat = governance.Governance(url=parsed_args.project_list)
            repos = gov_dat.get_repos_for_team(parsed_args.team)

        for repo in repos:
            LOG.debug('looking for settings for %s', repo)
            for idx, entry in enumerate(project_settings):
                if 'project' not in entry:
                    continue
                if entry['project'].get('name') == repo:
                    break
            else:
                LOG.warning('Could not find {} in {}'.format(
                    repo, project_filename))
                continue

            find_templates_to_retain(
                entry['project'],
                zuul_templates,
                zuul_jobs,
            )

            find_jobs_to_retain(entry['project'])

            print()
            if need_to_keep(entry):
                yaml.dump([entry], self.app.stdout)
            else:
                print('# No settings to retain for {}.\n'.format(repo))
                del project_settings[idx]

        if parsed_args.dry_run:
            LOG.debug('not writing project settings to %s', project_filename)
            return 0

        LOG.debug('writing project settings to %s', project_filename)
        # The YAML representation removes existing blank lines between
        # the "- project:" blocks. This code reformats the YAML output
        # to restore the blank lines and ensure that the file always
        # ends in a newline.
        buffer = io.StringIO()
        yaml.dump(project_settings, buffer)
        body = buffer.getvalue()
        parts = body.split('- project:')
        body = '\n\n- project:'.join(p.rstrip() for p in parts) + '\n'
        with open(project_filename, 'w', encoding='utf-8') as f:
            f.write(body)
示例#6
0
    def take_action(self, parsed_args):
        repo = None
        branch = None

        gitreview_filename = os.path.join(parsed_args.repo_dir, '.gitreview')
        cp = configparser.ConfigParser()
        were_read = cp.read(gitreview_filename)
        if were_read:
            LOG.debug('determining repository name from .gitreview')
            try:
                gerrit = cp['gerrit']
            except KeyError:
                pass
            else:
                repo = gerrit['project']
                if repo.endswith('.git'):
                    repo = repo[:-4]
                branch = gerrit.get('defaultbranch', None)
        else:
            LOG.debug('could not read %s', gitreview_filename)

        if not repo:
            LOG.debug('guessing repository name from directory name')
            repo = os.sep.join(
                parsed_args.repo_dir.rstrip(os.sep).split(os.sep)[-2:])

        # If we are given a branch on the command line, use it.
        # Otherwise, try to use what we read from .gitreview.
        # Fall back to using 'master'.
        branch = parsed_args.branch or branch or 'master'

        LOG.info('working on %s @ %s', repo, branch)

        in_repo = find_project_settings_in_repo(parsed_args.repo_dir)
        in_tree_file, in_tree_project, in_tree_settings = in_repo

        yaml = projectconfig_ruamellib.YAML()

        project_filename = os.path.join(
            parsed_args.project_config_dir,
            'zuul.d',
            'projects.yaml',
        )
        LOG.debug('loading project settings from %s', project_filename)
        with open(project_filename, 'r', encoding='utf-8') as f:
            project_settings = yaml.load(f)

        zuul_templates_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'project-templates.yaml',
        )
        LOG.debug('loading project templates from %s', zuul_templates_filename)
        with open(zuul_templates_filename, 'r', encoding='utf-8') as f:
            zuul_templates_raw = yaml.load(f)
        zuul_templates = {
            pt['project-template']['name']: pt['project-template']
            for pt in zuul_templates_raw if 'project-template' in pt
        }

        zuul_jobs_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'jobs.yaml',
        )
        LOG.debug('loading jobs from %s', zuul_jobs_filename)
        with open(zuul_jobs_filename, 'r', encoding='utf-8') as f:
            zuul_jobs_raw = yaml.load(f)
        zuul_jobs = {
            job['job']['name']: job['job']
            for job in zuul_jobs_raw if 'job' in job
        }

        LOG.debug('looking for settings for %s', repo)
        for entry in project_settings:
            if 'project' not in entry:
                continue
            if entry['project'].get('name') == repo:
                break
        else:
            LOG.warning('Could not find {} in {}'.format(
                repo, project_filename))
            return 2

        # Remove the items that need to stay in project-config.
        find_templates_to_extract(entry['project'], zuul_templates, zuul_jobs)

        filter_jobs_on_branch(entry['project'], branch)

        # Remove the 'name' value in case we can copy the results
        # directly into a new file.
        if 'name' in entry['project']:
            del entry['project']['name']

        merge_project_settings(
            in_tree_project,
            entry,
        )

        normalize_project_settings(in_tree_project)

        if not in_tree_project.get('project'):
            LOG.info('no settings to write')
            return 2

        if not in_tree_settings:
            in_tree_settings.append(in_tree_project)

        LOG.info('# {} @ {}'.format(repo, branch))
        # yaml.dump([in_tree_project], self.app.stdout)

        if not in_tree_file:
            in_tree_file = os.path.join(
                parsed_args.repo_dir,
                parsed_args.default_zuul_file,
            )
            out_dir = os.path.dirname(in_tree_file)
            if not os.path.exists(out_dir):
                os.makedirs(out_dir)
            LOG.info('creating %s', in_tree_file)
        else:
            LOG.info('updating %s', in_tree_file)
        with open(in_tree_file, 'w', encoding='utf-8') as f:
            yaml.dump(in_tree_settings, f)
示例#7
0
    def take_action(self, parsed_args):
        yaml = projectconfig_ruamellib.YAML()

        project_filename = os.path.join(
            parsed_args.project_config_dir,
            'zuul.d',
            'projects.yaml',
        )
        LOG.debug('loading project settings from %s', project_filename)
        with open(project_filename, 'r', encoding='utf-8') as f:
            project_settings = yaml.load(f)

        zuul_templates_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'project-templates.yaml',
        )
        LOG.debug('loading project templates from %s', zuul_templates_filename)
        with open(zuul_templates_filename, 'r', encoding='utf-8') as f:
            zuul_templates_raw = yaml.load(f)
        zuul_templates = {
            pt['project-template']['name']: pt['project-template']
            for pt in zuul_templates_raw if 'project-template' in pt
        }

        zuul_jobs_filename = os.path.join(
            parsed_args.openstack_zuul_jobs_dir,
            'zuul.d',
            'jobs.yaml',
        )
        LOG.debug('loading jobs from %s', zuul_jobs_filename)
        with open(zuul_jobs_filename, 'r', encoding='utf-8') as f:
            zuul_jobs_raw = yaml.load(f)
        zuul_jobs = {
            job['job']['name']: job['job']
            for job in zuul_jobs_raw if 'job' in job
        }

        LOG.debug('looking for settings for %s', parsed_args.repo)
        for entry in project_settings:
            if 'project' not in entry:
                continue
            if entry['project'].get('name') == parsed_args.repo:
                break
        else:
            raise ValueError('Could not find {} in {}'.format(
                parsed_args.repo, project_filename))

        # Remove the items that need to stay in project-config.
        find_templates_to_extract(entry['project'], zuul_templates, zuul_jobs)

        for branch in parsed_args.branch:
            to_update = copy.deepcopy(entry)
            filter_jobs_on_branch(to_update['project'], parsed_args.branch)

            # Remove the 'name' value in case we can copy the results
            # directly into a new file.
            if 'name' in to_update['project']:
                del to_update['project']['name']

            print()
            print('# {} @ {}'.format(parsed_args.repo, branch))
            yaml.dump([to_update], self.app.stdout)