Пример #1
0
    def link_metadata(self, specs):
        metadata_visitor = SourceMergeVisitor()

        for spec in specs:
            src_prefix = os.path.join(spec.package.view_source(),
                                      spack.store.layout.metadata_dir)
            proj = os.path.join(self.get_relative_projection_for_spec(spec),
                                spack.store.layout.metadata_dir, spec.name)
            metadata_visitor.set_projection(proj)
            visit_directory_tree(src_prefix, metadata_visitor)

        # Check for conflicts in destination dir.
        visit_directory_tree(self._root,
                             DestinationMergeVisitor(metadata_visitor))

        # Throw on dir-file conflicts -- unlikely, but who knows.
        if metadata_visitor.fatal_conflicts:
            raise MergeConflictSummary(metadata_visitor.fatal_conflicts)

        # We are strict here for historical reasons
        if metadata_visitor.file_conflicts:
            raise MergeConflictSummary(metadata_visitor.file_conflicts)

        for dst in metadata_visitor.directories:
            os.mkdir(os.path.join(self._root, dst))

        for dst_relpath, (src_root,
                          src_relpath) in metadata_visitor.files.items():
            self.link(os.path.join(src_root, src_relpath),
                      os.path.join(self._root, dst_relpath))
Пример #2
0
def test_visit_directory_tree_follow_dirs(noncyclical_dir_structure):
    root = str(noncyclical_dir_structure)
    visitor = RegisterVisitor(root, follow_dirs=True, follow_symlink_dirs=False)
    fs.visit_directory_tree(root, visitor)
    j = os.path.join
    assert visitor.files == [
        j('a', 'file_1'),
        j('a', 'to_file_1'),
        j('c', 'dangling_link'),
        j('c', 'file_2'),
        j('file_3'),
    ]
    assert visitor.dirs_before == [
        j('a'),
        j('a', 'd'),
        j('c'),
    ]
    assert visitor.dirs_after == [
        j('a', 'd'),
        j('a'),
        j('c'),
    ]
    assert visitor.symlinked_dirs_before == [
        j('a', 'to_c'),
        j('b'),
    ]
    assert not visitor.symlinked_dirs_after
Пример #3
0
    def add_specs(self, *specs, **kwargs):
        assert all((s.concrete for s in specs))
        if len(specs) == 0:
            return

        # Drop externals
        for s in specs:
            if s.external:
                tty.warn('Skipping external package: ' + s.short_spec)
        specs = [s for s in specs if not s.external]

        if kwargs.get("exclude", None):
            specs = set(filter_exclude(specs, kwargs["exclude"]))

        # Ignore spack meta data folder.
        def skip_list(file):
            return os.path.basename(file) == spack.store.layout.metadata_dir

        visitor = SourceMergeVisitor(ignore=skip_list)

        # Gather all the directories to be made and files to be linked
        for spec in specs:
            src_prefix = spec.package.view_source()
            visitor.set_projection(self.get_relative_projection_for_spec(spec))
            visit_directory_tree(src_prefix, visitor)

        # Check for conflicts in destination dir.
        visit_directory_tree(self._root, DestinationMergeVisitor(visitor))

        # Throw on fatal dir-file conflicts.
        if visitor.fatal_conflicts:
            raise MergeConflictSummary(visitor.fatal_conflicts)

        # Inform about file-file conflicts.
        if visitor.file_conflicts:
            if self.ignore_conflicts:
                tty.debug("{0} file conflicts".format(
                    len(visitor.file_conflicts)))
            else:
                raise MergeConflictSummary(visitor.file_conflicts)

        tty.debug("Creating {0} dirs and {1} links".format(
            len(visitor.directories), len(visitor.files)))

        # Make the directory structure
        for dst in visitor.directories:
            os.mkdir(os.path.join(self._root, dst))

        # Then group the files to be linked by spec...
        # For compatibility, we have to create a merge_map dict mapping
        # full_src => full_dst
        files_per_spec = itertools.groupby(visitor.files.items(),
                                           key=lambda item: item[1][0])

        for (spec, (src_root, rel_paths)) in zip(specs, files_per_spec):
            merge_map = dict()
            for dst_rel, (_, src_rel) in rel_paths:
                full_src = os.path.join(src_root, src_rel)
                full_dst = os.path.join(self._root, dst_rel)
                merge_map[full_src] = full_dst
            spec.package.add_files_to_view(self,
                                           merge_map,
                                           skip_if_exists=False)

        # Finally create the metadata dirs.
        self.link_metadata(specs)