Example #1
0
def _validate_yaml_project(project, yaml_file):
    """Validate project in clowder loaded from yaml file"""

    _validate_type_dict(project, 'project', yaml_file)

    if not project:
        error = fmt.invalid_entries_error('project', project, yaml_file)
        raise ClowderError(error)

    if 'name' not in project:
        error = fmt.missing_entry_error('name', 'project', yaml_file)
        raise ClowderError(error)
    _validate_type_str(project['name'], 'name', yaml_file)
    del project['name']

    if 'path' not in project:
        error = fmt.missing_entry_error('path', 'project', yaml_file)
        raise ClowderError(error)
    _validate_type_str(project['path'], 'path', yaml_file)
    del project['path']

    _validate_yaml_project_optional(project, yaml_file)

    if project:
        error = fmt.invalid_entries_error('project', project, yaml_file)
        raise ClowderError(error)
Example #2
0
def _validate_yaml_sources(sources, yaml_file):
    """Validate sources in clowder loaded from yaml file"""

    _validate_type_list(sources, 'sources', yaml_file)
    if not sources:
        error = fmt.invalid_entries_error('sources', sources, yaml_file)
        raise ClowderError(error)

    for source in sources:
        _validate_type_dict(source, 'source', yaml_file)
        if not source:
            error = fmt.invalid_entries_error('source', source, yaml_file)
            raise ClowderError(error)

        if 'name' not in source:
            error = fmt.missing_entry_error('name', 'source', yaml_file)
            raise ClowderError(error)
        _validate_type_str(source['name'], 'name', yaml_file)
        del source['name']

        if 'url' not in source:
            error = fmt.missing_entry_error('url', 'source', yaml_file)
            raise ClowderError(error)
        _validate_type_str(source['url'], 'url', yaml_file)
        del source['url']

        if source:
            error = fmt.invalid_entries_error('source', source, yaml_file)
            raise ClowderError(error)
Example #3
0
def _validate_yaml_import_defaults(defaults, yaml_file):
    """Validate clowder.yaml defaults with an import"""

    _validate_type_dict(defaults, 'defaults', yaml_file)
    if 'recursive' in defaults:
        _validate_type_bool(defaults['recursive'], 'recursive', yaml_file)
        del defaults['recursive']

    if 'ref' in defaults:
        _validate_type_str(defaults['ref'], 'ref', yaml_file)
        if not _valid_ref_type(defaults['ref']):
            error = fmt.invalid_ref_error(defaults['ref'], yaml_file)
            raise ClowderError(error)
        del defaults['ref']

    if 'remote' in defaults:
        _validate_type_str(defaults['remote'], 'remote', yaml_file)
        del defaults['remote']

    if 'source' in defaults:
        _validate_type_str(defaults['source'], 'source', yaml_file)
        del defaults['source']

    if 'depth' in defaults:
        _validate_type_depth(defaults['depth'], yaml_file)
        del defaults['depth']

    if 'timestamp_author' in defaults:
        _validate_type_str(defaults['timestamp_author'], 'timestamp_author', yaml_file)
        del defaults['timestamp_author']

    if defaults:
        error = fmt.invalid_entries_error('defaults', defaults, yaml_file)
        raise ClowderError(error)
Example #4
0
def validate_yaml_import(yaml_file):
    """Validate clowder.yaml with an import"""

    parsed_yaml = parse_yaml(yaml_file)
    _validate_type_dict(parsed_yaml, fmt.yaml_file('clowder.yaml'), yaml_file)

    if 'import' not in parsed_yaml:
        error = fmt.missing_entry_error('import', fmt.yaml_file('clowder.yaml'), yaml_file)
        raise ClowderError(error)
    _validate_type_str(parsed_yaml['import'], 'import', yaml_file)
    del parsed_yaml['import']

    if not parsed_yaml:
        error = fmt.empty_yaml_error(yaml_file)
        raise ClowderError(error)

    if 'defaults' in parsed_yaml:
        _validate_yaml_import_defaults(parsed_yaml['defaults'], yaml_file)
        del parsed_yaml['defaults']

    if 'sources' in parsed_yaml:
        _validate_yaml_sources(parsed_yaml['sources'], yaml_file)
        del parsed_yaml['sources']

    if 'groups' in parsed_yaml:
        _validate_yaml_import_groups(parsed_yaml['groups'], yaml_file)
        del parsed_yaml['groups']

    if parsed_yaml:
        error = fmt.invalid_entries_error(fmt.yaml_file('clowder.yaml'), parsed_yaml, yaml_file)
        raise ClowderError(error)
Example #5
0
def _validate_type_depth(value, yaml_file):
    """Validate depth value"""

    error = fmt.depth_error(value, yaml_file)
    if not isinstance(value, int):
        raise ClowderError(error)
    if int(value) < 0:
        raise ClowderError(error)
Example #6
0
def execute_command(command, path, **kwargs):
    """Execute command via thread

    .. py:function:: execute_command(command, path, shell=True, env=None, print_output=True)

    :param command: Command to run
    :type command: str or list[str]
    :param str path: Path to set as ``cwd``

    Keyword Args:
        shell (bool): Whether to execute subprocess as ``shell``
        env (dict): Enviroment to set as ``env``
        print_output (bool): Whether to print output

    :return: Command return code
    :rtype: int
    :raise ClowderError:
    """

    shell = kwargs.get('shell', True)
    env = kwargs.get('env', None)
    print_output = kwargs.get('print_output', True)

    cmd_env = os.environ.copy()
    if env:
        cmd_env.update(env)

    if print_output:
        pipe = None
    else:
        pipe = subprocess.PIPE

    pool = ThreadPool()

    try:
        result = pool.apply(execute_subprocess_command,
                            args=(command, path),
                            kwds={
                                'shell': shell,
                                'env': cmd_env,
                                'stdout': pipe,
                                'stderr': pipe
                            })
        pool.close()
        pool.join()
        return result
    except (KeyboardInterrupt, SystemExit):
        if pool:
            pool.close()
            pool.terminate()
        raise ClowderError(colored('- Command interrupted', 'red'))
    except Exception as err:
        if pool:
            pool.close()
            pool.terminate()
        raise ClowderError(
            colored('\n - Command failed', 'red') + str(err) + '\n')
Example #7
0
def _validate_yaml_import_group(group, yaml_file):
    """Validate group in clowder loaded from yaml file with import"""

    _validate_type_dict(group, 'group', yaml_file)

    if not group:
        error = fmt.invalid_entries_error('group', group, yaml_file)
        raise ClowderError(error)

    if 'name' not in group:
        error = fmt.missing_entry_error('name', 'group', yaml_file)
        raise ClowderError(error)
    _validate_type_str(group['name'], 'name', yaml_file)
    del group['name']

    if not group:
        error = fmt.invalid_entries_error('group', group, yaml_file)
        raise ClowderError(error)

    if 'projects' in group:
        _validate_yaml_projects(group['projects'], yaml_file, is_import=True)
        del group['projects']

    if 'recursive' in group:
        _validate_type_bool(group['recursive'], 'recursive', yaml_file)
        del group['recursive']

    if 'ref' in group:
        _validate_type_str(group['ref'], 'ref', yaml_file)
        if not _valid_ref_type(group['ref']):
            error = fmt.invalid_ref_error(group['ref'], yaml_file)
            raise ClowderError(error)
        del group['ref']

    if 'remote' in group:
        _validate_type_str(group['remote'], 'remote', yaml_file)
        del group['remote']

    if 'source' in group:
        _validate_type_str(group['source'], 'source', yaml_file)
        del group['source']

    if 'depth' in group:
        _validate_type_depth(group['depth'], yaml_file)
        del group['depth']

    if 'timestamp_author' in group:
        _validate_type_str(group['timestamp_author'], 'timestamp_author', yaml_file)
        del group['timestamp_author']

    if group:
        error = fmt.invalid_entries_error('group', group, yaml_file)
        raise ClowderError(error)
Example #8
0
def _validate_yaml_project_optional(project, yaml_file):
    """Validate optional args in project in clowder loaded from yaml file"""

    if 'remote' in project:
        _validate_type_str(project['remote'], 'remote', yaml_file)
        del project['remote']

    if 'recursive' in project:
        _validate_type_bool(project['recursive'], 'recursive', yaml_file)
        del project['recursive']

    if 'timestamp_author' in project:
        _validate_type_str(project['timestamp_author'], 'timestamp_author', yaml_file)
        del project['timestamp_author']

    if 'ref' in project:
        _validate_type_str(project['ref'], 'ref', yaml_file)
        if not _valid_ref_type(project['ref']):
            error = fmt.invalid_ref_error(project['ref'], yaml_file)
            raise ClowderError(error)
        del project['ref']

    if 'source' in project:
        _validate_type_str(project['source'], 'source', yaml_file)
        del project['source']

    if 'depth' in project:
        _validate_type_depth(project['depth'], yaml_file)
        del project['depth']

    if 'fork' in project:
        fork = project['fork']
        _validate_yaml_fork(fork, yaml_file)
        del project['fork']
Example #9
0
def _validate_yaml_groups(groups, yaml_file):
    """Validate groups in clowder loaded from yaml file"""

    _validate_type_list(groups, 'groups', yaml_file)

    if not groups:
        error = fmt.invalid_entries_error('groups', groups, yaml_file)
        raise ClowderError(error)

    for group in groups:
        _validate_yaml_group(group, yaml_file)
Example #10
0
def _validate_yaml_defaults(defaults, yaml_file):
    """Validate defaults in clowder loaded from yaml file"""

    _validate_type_dict(defaults, 'defaults', yaml_file)
    if not defaults:
        error = fmt.invalid_entries_error('defaults', defaults, yaml_file)
        raise ClowderError(error)

    if 'ref' not in defaults:
        error = fmt.missing_entry_error('ref', 'defaults', yaml_file)
        raise ClowderError(error)
    _validate_type_str(defaults['ref'], 'ref', yaml_file)
    if not _valid_ref_type(defaults['ref']):
        error = fmt.invalid_ref_error(defaults['ref'], yaml_file)
        raise ClowderError(error)
    del defaults['ref']

    if 'remote' not in defaults:
        error = fmt.missing_entry_error('remote', 'defaults', yaml_file)
        raise ClowderError(error)
    _validate_type_str(defaults['remote'], 'remote', yaml_file)
    del defaults['remote']

    if 'source' not in defaults:
        error = fmt.missing_entry_error('source', 'defaults', yaml_file)
        raise ClowderError(error)
    _validate_type_str(defaults['source'], 'source', yaml_file)
    del defaults['source']

    _validate_yaml_defaults_optional(defaults, yaml_file)

    if defaults:
        error = fmt.invalid_entries_error('defaults', defaults, yaml_file)
        raise ClowderError(error)
Example #11
0
def _validate_yaml_projects(projects, yaml_file, is_import):
    """Validate projects in clowder loaded from yaml file"""

    _validate_type_list(projects, 'projects', yaml_file)
    if not projects:
        error = fmt.invalid_entries_error('projects', projects, yaml_file)
        raise ClowderError(error)

    for project in projects:
        if is_import:
            _validate_yaml_import_project(project, yaml_file)
        else:
            _validate_yaml_project(project, yaml_file)
Example #12
0
def _validate_yaml_fork(fork, yaml_file):
    """Validate fork in clowder loaded from yaml file"""

    _validate_type_dict(fork, 'fork', yaml_file)

    if not fork:
        error = fmt.invalid_entries_error('fork', fork, yaml_file)
        raise ClowderError(error)

    if 'name' not in fork:
        error = fmt.missing_entry_error('name', 'fork', yaml_file)
        raise ClowderError(error)
    _validate_type_str(fork['name'], 'name', yaml_file)
    del fork['name']

    if 'remote' not in fork:
        error = fmt.missing_entry_error('remote', 'fork', yaml_file)
        raise ClowderError(error)
    _validate_type_str(fork['remote'], 'remote', yaml_file)
    del fork['remote']

    if fork:
        error = fmt.invalid_entries_error('fork', fork, yaml_file)
        raise ClowderError(error)
Example #13
0
def execute_subprocess_command(command, path, **kwargs):
    """Execute subprocess command

    .. py:function:: execute_subprocess_command(command, path, shell=True, env=None, stdout=None, stderr=None)

    :param command: Command to run
    :type command: str or list[str]
    :param str path: Path to set as ``cwd``

    Keyword Args:
        shell (bool): Whether to execute subprocess as ``shell``
        env (dict): Enviroment to set as ``env``
        stdout (int): Value to set as ``stdout``
        stderr (int): Value to set as ``stderr``

    :return: Subprocess return code
    :rtype: int
    :raise ClowderError:
    """

    shell = kwargs.get('shell', True)
    env = kwargs.get('env', None)
    stdout = kwargs.get('stdout', None)
    stderr = kwargs.get('stderr', None)

    if isinstance(command, list):
        cmd = ' '.join(command)
    else:
        cmd = command

    try:
        process = subprocess.Popen(cmd,
                                   shell=shell,
                                   env=env,
                                   cwd=path,
                                   stdout=stdout,
                                   stderr=stderr)
        atexit.register(subprocess_exit_handler, process)
        process.communicate()
        if process.returncode != 0:
            raise ClowderError
    except (KeyboardInterrupt, SystemExit):
        raise
    except Exception as err:
        raise ClowderError(err)
    def _validate_yaml(self, yaml_file, max_import_depth):
        """Validate clowder.yaml"""

        parsed_yaml = clowder_yaml.parse_yaml(yaml_file)
        if max_import_depth < 0:
            print(fmt.invalid_yaml_error())
            print(fmt.recursive_import_error(self._max_import_depth))
            print()
            sys.exit(1)

        if 'import' not in parsed_yaml:
            clowder_yaml.validate_yaml(yaml_file)
            return

        clowder_yaml.validate_yaml_import(yaml_file)
        imported_clowder = parsed_yaml['import']

        try:
            if imported_clowder == 'default':
                imported_yaml_file = os.path.join(self.root_directory,
                                                  '.clowder', 'clowder.yaml')
            else:
                imported_yaml_file = os.path.join(self.root_directory,
                                                  '.clowder', 'versions',
                                                  imported_clowder,
                                                  'clowder.yaml')
            if not os.path.isfile(imported_yaml_file):
                error = fmt.missing_imported_yaml_error(
                    imported_yaml_file, yaml_file)
                raise ClowderError(error)
            yaml_file = imported_yaml_file
            self._validate_yaml(yaml_file, max_import_depth - 1)
        except ClowderError as err:
            print(fmt.invalid_yaml_error())
            print(fmt.error(err))
            sys.exit(1)
        except (KeyboardInterrupt, SystemExit):
            sys.exit(1)
Example #15
0
    def _run_forall_command(self, command, env, ignore_errors, parallel):
        """Run command or script in project directory

        :param str command: Command to run
        :param dict env: Environment variables
        :param bool ignore_errors: Whether to exit if command returns a non-zero exit code
        :param bool parallel: Whether command is being run in parallel, affects output

        Raises:
            ClowderError
            ClowderExit
        """

        self._print(fmt.command(command))
        try:
            execute_forall_command(command, self.full_path(), env,
                                   self._print_output)
        except ClowderError:
            if not ignore_errors:
                err = fmt.command_failed_error(command)
                self._print(err)
                if parallel:
                    raise ClowderError(err)
                raise ClowderExit(1)
Example #16
0
def _validate_type_dict(value, name, yaml_file):
    """Validate value is a dict"""

    if not isinstance(value, dict):
        error = fmt.not_dictionary_error(name, yaml_file)
        raise ClowderError(error)
Example #17
0
    def _exit(message, parallel=False, return_code=1):
        """Exit based on serial or parallel job"""

        if parallel:
            raise ClowderError(message)
        sys.exit(return_code)
Example #18
0
def _validate_type_list(value, name, yaml_file):
    """Validate value is a list"""

    if not isinstance(value, list):
        error = fmt.not_list_error(name, yaml_file)
        raise ClowderError(error)
Example #19
0
def _validate_type_str(value, name, yaml_file):
    """Validate value is a str"""

    if not isinstance(value, str):
        error = fmt.not_string_error(name, yaml_file)
        raise ClowderError(error)
Example #20
0
def _validate_type_bool(value, name, yaml_file):
    """Validate value is a bool"""

    if not isinstance(value, bool):
        error = fmt.not_bool_error(name, yaml_file)
        raise ClowderError(error)