Beispiel #1
0
def check_config_integrity(config_file: Union[str, pathlib.Path]) -> None:
    """Raise an exception if the configuration file contains syntactical
    errors, or if the defaults are misconfigured. Note that plugin options are
    not checked.

    Args:
        config_file: path to the config file.
    """
    config_file = pathlib.Path(config_file)
    if not config_file.is_file():
        raise exception.FileError(
            "no config file found, expected location: " + str(config_file)
        )

    try:
        defaults = _read_defaults(config_file)
    except configparser.ParsingError as exc:
        errors = ", ".join(
            f"(line {line_nr}: {line})" for line_nr, line in exc.errors
        )
        raise exception.FileError(
            msg=(
                f"config file at {config_file} contains syntax errors: "
                f"{errors}"
            )
        )
    check_defaults(defaults, config_file)
Beispiel #2
0
def _extract_groups(args: argparse.Namespace) -> List[plug.StudentTeam]:
    """Extract groups from args namespace.`

    Args:
        args: A namespace object.

    Returns:
        a list of student usernames, or None of neither `students` or
        `students_file` is in the namespace.
    """
    if "students" in args and args.students:
        students = [plug.StudentTeam(members=[s]) for s in args.students]
    elif "students_file" in args and args.students_file:
        students_file = pathlib.Path(args.students_file).resolve()
        if not students_file.is_file():
            raise exception.FileError(
                "'{!s}' is not a file".format(students_file))
        if not students_file.stat().st_size:
            raise exception.FileError("'{!s}' is empty".format(students_file))
        students = [
            plug.StudentTeam(members=[s for s in group.strip().split()])
            for group in students_file.read_text(
                encoding=sys.getdefaultencoding()).split(os.linesep)
            if group  # skip blank lines
        ]
    else:
        students = []

    return students
Beispiel #3
0
def _extract_groups(args: argparse.Namespace) -> List[plug.StudentTeam]:
    """Extract groups from args namespace.`

    Args:
        args: A namespace object.

    Returns:
        a list of student usernames, or None of neither `students` or
        `students_file` is in the namespace.
    """
    if "students" in args and args.students:
        students = [plug.StudentTeam(members=[s]) for s in args.students]
    elif "students_file" in args and args.students_file:
        students_file = pathlib.Path(args.students_file).resolve()
        if not students_file.is_file():
            raise exception.FileError(f"'{students_file}' is not a file")
        if not students_file.stat().st_size:
            raise exception.FileError(f"'{students_file}' is empty")

        students = list(
            plug.manager.hook.parse_students_file(students_file=students_file))
    else:
        students = []

    return students
Beispiel #4
0
def setup_logging(terminal_level: int = logging.WARNING) -> None:
    """Setup logging by creating the required log directory and setting up
    the logger.

    Args:
        terminal_level: The logging level to use for printing to stderr.
    """
    logfile = constants.LOG_DIR / f"{_repobee._external_package_name}.log"
    _ensure_size_less(logfile, max_size=constants.MAX_LOGFILE_SIZE)
    try:
        os.makedirs(str(constants.LOG_DIR), exist_ok=True)
    except Exception as exc:
        raise exception.FileError(
            f"can't create log directory at {constants.LOG_DIR}") from exc

    daiquiri.setup(
        level=logging.DEBUG,
        outputs=(
            daiquiri.output.Stream(
                sys.stderr,
                formatter=daiquiri.formatter.ColorFormatter(
                    fmt="%(color)s[%(levelname)s] %(message)s%(color_stop)s"),
                level=terminal_level,
            ),
            daiquiri.output.File(
                filename=str(logfile),
                formatter=daiquiri.formatter.ColorFormatter(
                    fmt="%(asctime)s [PID %(process)d] [%(levelname)s] "
                    "%(name)s -> %(message)s"),
                level=logging.DEBUG,
            ),
        ),
    )

    _filter_tokens()
Beispiel #5
0
def _read_config(config_file: pathlib.Path) -> configparser.ConfigParser:
    config_parser = configparser.ConfigParser()
    try:
        config_parser.read(str(config_file))
    except configparser.MissingSectionHeaderError:
        pass  # handled by the next check

    if constants.CORE_SECTION_HDR not in config_parser:
        raise exception.FileError(
            "config file at '{!s}' does not contain the required "
            "[repobee] header".format(config_file))

    return config_parser
Beispiel #6
0
def _read_config(config_file: pathlib.Path) -> configparser.ConfigParser:
    config_parser = configparser.ConfigParser()
    try:
        config_parser.read(str(config_file))
    except configparser.MissingSectionHeaderError:
        pass  # handled by the next check

    if plug.Config.CORE_SECTION_NAME not in config_parser:
        raise exception.FileError(
            f"config file at '{str(config_file)}' does not contain the "
            f"required [repobee] header")

    return config_parser
Beispiel #7
0
def _check_defaults(defaults: Mapping[str, str],
                    config_file: Union[str, pathlib.Path]):
    """Raise an exception if defaults contain keys that are not configurable
    arguments.

    Args:
        defaults: A dictionary of defaults.
        config_file: Path to the config file.
    """
    configured = defaults.keys()
    if (configured -
            constants.CONFIGURABLE_ARGS):  # there are surpluss arguments
        raise exception.FileError(
            f"config file at {config_file} contains invalid default keys: "
            f"{', '.join(configured - constants.CONFIGURABLE_ARGS)}")