def mkdirp()

in lib/ramble/llnl/util/filesystem.py [0:0]


def mkdirp(*paths, **kwargs):
    """Creates a directory, as well as parent directories if needed.

    Arguments:
        paths (str): paths to create with mkdirp

    Keyword Aguments:
        mode (permission bits or None): optional permissions to set
            on the created directory -- use OS default if not provided
        group (group name or None): optional group for permissions of
            final created directory -- use OS default if not provided. Only
            used if world write permissions are not set
        default_perms (str or None): one of 'parents' or 'args'. The default permissions
            that are set for directories that are not themselves an argument
            for mkdirp. 'parents' means intermediate directories get the
            permissions of their direct parent directory, 'args' means
            intermediate get the same permissions specified in the arguments to
            mkdirp -- default value is 'args'
    """
    mode = kwargs.get('mode', None)
    group = kwargs.get('group', None)
    default_perms = kwargs.get('default_perms', 'args')
    paths = path_to_os_path(*paths)
    for path in paths:
        if not os.path.exists(path):
            try:
                # detect missing intermediate folders
                intermediate_folders = []
                last_parent = ''

                intermediate_path = os.path.dirname(path)

                while intermediate_path:
                    if os.path.exists(intermediate_path):
                        last_parent = intermediate_path
                        break

                    intermediate_folders.append(intermediate_path)
                    intermediate_path = os.path.dirname(intermediate_path)

                # create folders
                os.makedirs(path)

                # leaf folder permissions
                if mode is not None:
                    os.chmod(path, mode)
                if group:
                    chgrp_if_not_world_writable(path, group)
                    if mode is not None:
                        os.chmod(path, mode)  # reset sticky grp bit post chgrp

                # for intermediate folders, change mode just for newly created
                # ones and if mode_intermediate has been specified, otherwise
                # intermediate folders list is not populated at all and default
                # OS mode will be used
                if default_perms == 'args':
                    intermediate_mode = mode
                    intermediate_group = group
                elif default_perms == 'parents':
                    stat_info = os.stat(last_parent)
                    intermediate_mode = stat_info.st_mode
                    intermediate_group = stat_info.st_gid
                else:
                    msg = "Invalid value: '%s'. " % default_perms
                    msg += "Choose from 'args' or 'parents'."
                    raise ValueError(msg)

                for intermediate_path in reversed(intermediate_folders):
                    if intermediate_mode is not None:
                        os.chmod(intermediate_path, intermediate_mode)
                    if intermediate_group is not None:
                        chgrp_if_not_world_writable(intermediate_path,
                                                    intermediate_group)
                        os.chmod(intermediate_path,
                                 intermediate_mode)  # reset sticky bit after

            except OSError as e:
                if e.errno != errno.EEXIST or not os.path.isdir(path):
                    raise e
        elif not os.path.isdir(path):
            raise OSError(errno.EEXIST, "File already exists", path)