Example #1
0
def gen_categories():
    """Generate categories listing."""
    categories = glob('*-*') + ['virtual', ]
    dep(['profiles/categories', ], categories)
    with open('profiles/categories', 'w') as file:
        for cat in sorted(categories):
            if not os.path.isdir(cat):
                print(warn('Category match on %s, may cause problems with '
                           'portage' % cat))
                continue
            file.write(cat + '\n')
    print(success('categories list generated!'))
Example #2
0
def task_doc_check():
    """Check tasks are documented."""
    # This should be far easier to write, if only we could rely on the Sphinx
    # cache or mock the Sphinx extensions simply and use the docutils parser
    lines = open('doc/maintenance.rst').readlines()
    commands = []
    for n, line in enumerate(lines):
        if match("^'+\n$", line):
            commands.append(lines[n - 1][2:-3])

    for name in sorted(cli.commands):
        if name not in commands:
            print(warn('%s task undocumented' % name))
Example #3
0
def eclass_doc_check():
    """Check eclass documentation syntax."""
    p = Popen(['portageq', 'repos_config', '/'], stdout=PIPE)
    p.wait()
    conf = ConfigParser()
    conf.readfp(p.stdout)
    portdir = conf.get(conf.defaults()['main-repo'], 'location')
    awk_file = portdir + '/' + \
        'app-portage/eclass-manpages/files/eclass-to-manpage.awk'
    eclasses = glob('eclass/*.eclass')
    for eclass in eclasses:
        proc = Popen(['gawk', '-f', awk_file], stdin=PIPE, stdout=PIPE,
                     stderr=PIPE)
        _, err = proc.communicate(open(eclass, 'rb').read())
        if err:
            print(warn('>>> %s' % eclass))
            print(err)
Example #4
0
def gen_manifests():
    """Generate Manifest files."""
    packages = glob('*-*/*/*') + glob('virtual/*/*')
    dep(glob('*-*/*/Manifest') + glob('virtual/*/Manifest'), packages)
    base_dir = os.path.abspath(os.curdir)
    if not SIGN_KEY:
        print(warn('No GnuPG key set!'))
    for package in sorted(packages):
        try:
            os.chdir(package)
            if not any(map(lambda f: newer(f, 'Manifest'), glob('*'))):
                break
            check_call(['repoman', 'manifest'])
            if SIGN_KEY:
                check_call(['gpg', '--local-user', SIGN_KEY, '--clearsign',
                            'Manifest'])
                os.rename('Manifest.asc', 'Manifest')
        finally:
            os.chdir(base_dir)
Example #5
0
def check(ctx,
          files,
          check_proper_formatting=False,
          error_on_known_failures=False):
    """
    Check salt's docstrings
    """
    # CD into Salt's repo root directory
    ctx.cd(CODE_DIR)

    # Unfortunately invoke does not support nargs.
    # We migth have been passed --files="foo.py bar.py"
    # Turn that into a list of paths
    _files = []
    for path in files:
        if not path:
            continue
        _files.extend(path.split())
    if not _files:
        _files = SALT_CODE_DIR.rglob("*.py")
    else:
        _files = [pathlib.Path(fname) for fname in _files]

    _files = [path.resolve() for path in _files]

    errors = 0
    exitcode = 0
    warnings = 0
    for path in _files:
        contents = path.read_text()
        try:
            module = ast.parse(path.read_text(), filename=str(path))
            module_docstring = ast.get_docstring(module, clean=False)
            if module_docstring:
                error = _check_valid_versions_on_docstrings(module_docstring)
                if error:
                    errors += 1
                    exitcode = 1
                    utils.error(
                        "The module '{}' does not provide a proper `{}` version: {!r} is not valid.",
                        path.relative_to(CODE_DIR),
                        *error,
                    )

            for funcdef in [
                    node for node in module.body
                    if isinstance(node, ast.FunctionDef)
            ]:
                docstring = ast.get_docstring(funcdef, clean=False)
                if docstring:
                    error = _check_valid_versions_on_docstrings(docstring)
                    if error:
                        errors += 1
                        exitcode = 1
                        utils.error(
                            "The module '{}' does not provide a proper `{}` version: {!r} is not valid.",
                            path.relative_to(CODE_DIR),
                            *error,
                        )

                if not str(path).startswith(SALT_INTERNAL_LOADERS_PATHS):
                    # No further docstrings checks are needed
                    continue

                funcname = funcdef.name
                relpath = str(path.relative_to(CODE_DIR))

                # We're dealing with a salt loader module
                if funcname.startswith("_"):
                    # We're not interested in internal functions
                    continue

                if not docstring:
                    if (funcname in MISSING_DOCSTRINGS.get(relpath, ())
                            and error_on_known_failures is False):
                        warnings += 1
                        utils.warn(
                            "The function '{}' on '{}' does not have a docstring",
                            funcname,
                            relpath,
                        )
                        continue
                    errors += 1
                    exitcode = 1
                    utils.error(
                        "The function '{}' on '{}' does not have a docstring",
                        funcname,
                        relpath,
                    )
                    continue
                elif funcname in MISSING_DOCSTRINGS.get(relpath, ()):
                    # This was previously a know function with a missing docstring.
                    # Warn about it so that it get's removed from this list
                    warnings += 1
                    utils.warn(
                        "The function '{}' on '{}' was previously known to not have a docstring, "
                        "which is no longer the case. Please remove it from 'MISSING_DOCSTRINGS' ."
                        "in '{}'",
                        funcname,
                        relpath,
                        THIS_FILE,
                    )

                try:
                    salt_modules_relpath = path.relative_to(SALT_MODULES_PATH)
                    if str(salt_modules_relpath.parent) != ".":
                        # We don't want to check nested packages
                        continue
                    # But this is a module under salt/modules, let's check
                    # the CLI examples
                except ValueError:
                    # We're not checking CLI examples in any other salt loader modules
                    continue

                if _check_cli_example_present(docstring) is False:
                    if (funcname in MISSING_EXAMPLES.get(relpath, ())
                            and error_on_known_failures is False):
                        warnings += 1
                        utils.warn(
                            "The function '{}' on '{}' does not have a 'CLI Example:' in it's docstring",
                            funcname,
                            relpath,
                        )
                        continue
                    errors += 1
                    exitcode = 1
                    utils.error(
                        "The function '{}' on '{}' does not have a 'CLI Example:' in it's docstring",
                        funcname,
                        relpath,
                    )
                    continue
                elif funcname in MISSING_EXAMPLES.get(relpath, ()):
                    # This was previously a know function with a missing CLI example
                    # Warn about it so that it get's removed from this list
                    warnings += 1
                    utils.warn(
                        "The function '{}' on '{}' was previously known to not have a CLI Example, "
                        "which is no longer the case. Please remove it from 'MISSING_EXAMPLES'. "
                        "in '{}'",
                        funcname,
                        relpath,
                        THIS_FILE,
                    )

                if check_proper_formatting is False:
                    continue

                # By now we now this function has a docstring and it has a CLI Example section
                # Let's now check if it's properly formatted
                if _check_cli_example_proper_formatting(docstring) is False:
                    errors += 1
                    exitcode = 1
                    utils.error(
                        "The function {!r} on '{}' does not have a proper 'CLI Example:' section in "
                        "it's docstring. The proper format is:\n"
                        "CLI Example:\n"
                        "\n"
                        ".. code-block:: bash\n"
                        "\n"
                        "    salt '*' <insert example here>\n",
                        funcdef.name,
                        path.relative_to(CODE_DIR),
                    )
                    continue
        finally:
            if contents != path.read_text():
                path.write_text(contents)

    if warnings:
        utils.warn("Found {} warnings", warnings)
    if exitcode:
        utils.error("Found {} errors", errors)
    utils.exit_invoke(exitcode)