aboutsummaryrefslogtreecommitdiff
path: root/nix/libstore/misc.cc
blob: d4e6d1b4afc43699110b2475bd3c771df263068f (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "misc.hh"
#include "store-api.hh"
#include "local-store.hh"
#include "globals.hh"


namespace nix {


Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
{
    assertStorePath(drvPath);
    store.ensurePath(drvPath);
    return readDerivation(drvPath);
}


void computeFSClosure(StoreAPI & store, const Path & path,
    PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
{
    if (paths.find(path) != paths.end()) return;
    paths.insert(path);

    PathSet edges;

    if (flipDirection) {
        store.queryReferrers(path, edges);

        if (includeOutputs) {
            PathSet derivers = store.queryValidDerivers(path);
            foreach (PathSet::iterator, i, derivers)
                edges.insert(*i);
        }

        if (includeDerivers && isDerivation(path)) {
            PathSet outputs = store.queryDerivationOutputs(path);
            foreach (PathSet::iterator, i, outputs)
                if (store.isValidPath(*i) && store.queryDeriver(*i) == path)
                    edges.insert(*i);
        }

    } else {
        store.queryReferences(path, edges);

        if (includeOutputs && isDerivation(path)) {
            PathSet outputs = store.queryDerivationOutputs(path);
            foreach (PathSet::iterator, i, outputs)
                if (store.isValidPath(*i)) edges.insert(*i);
        }

        if (includeDerivers) {
            Path deriver = store.queryDeriver(path);
            if (store.isValidPath(deriver)) edges.insert(deriver);
        }
    }

    foreach (PathSet::iterator, i, edges)
        computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
}


static void dfsVisit(StoreAPI & store, const PathSet & paths,
    const Path & path, PathSet & visited, Paths & sorted,
    PathSet & parents)
{
    if (parents.find(path) != parents.end())
        throw BuildError(format("cycle detected in the references of `%1%'") % path);

    if (visited.find(path) != visited.end()) return;
    visited.insert(path);
    parents.insert(path);

    PathSet references;
    if (store.isValidPath(path))
        store.queryReferences(path, references);

    foreach (PathSet::iterator, i, references)
        /* Don't traverse into paths that don't exist.  That can
           happen due to substitutes for non-existent paths. */
        if (*i != path && paths.find(*i) != paths.end())
            dfsVisit(store, paths, *i, visited, sorted, parents);

    sorted.push_front(path);
    parents.erase(path);
}


Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
{
    Paths sorted;
    PathSet visited, parents;
    foreach (PathSet::const_iterator, i, paths)
        dfsVisit(store, paths, *i, visited, sorted, parents);
    return sorted;
}


}
ibuting.texi?id=1b1a61f86a258c417a061da0dca18a969a19b28e'>doc: Discourage ambiguous package names....Tobias Geerinckx-Rice via Bug reports for GNU Guix 2021-03-18doc: Document the guidelines for removing inactive committers....Leo Famulari 2021-03-15services/qemu-binfmt: Use the F flag and the static output of QEMU....Maxim Cournoyer 2021-03-10doc: Fix grammar....Tobias Geerinckx-Rice 2021-02-13doc: Try again to the improve the branching workflow....Leo Famulari 2021-02-11doc: Try to improve the branching workflow....Leo Famulari 2021-01-29doc: Update guidance about Rust package naming....Hartmut Goebel 2021-01-20doc: Replace TP with Weblate mentions....Julien Lepiller 2021-01-03doc: Running Guix Before It Is Installed: mention ./bootstrap...Rovanion Luckey 2020-12-17doc: Emacs Packages: Fix typos....Nicolas Goaziou 2020-12-17doc: Add Emacs packaging guidelines....Maxim Cournoyer 2020-12-14doc: Note different texlive-tiny & texline-union natures....Tobias Geerinckx-Rice 2020-12-14doc: Link to "Pattern Matching" in Guile....Ludovic Courtès 2020-11-12maint: update-guix-package: Optionally add sources to store....Maxim Cournoyer 2020-10-24build: Add GUIX_GIT_KEYRING variable for make authenticate....Miguel Ángel Arruga Vivas 2020-10-20doc: More uses of @lisp instead of @example....Ludovic Courtès 2020-10-19maint: update-guix-package: Prevent accidentally breaking guix pull....Maxim Cournoyer 2020-10-08doc: Clarify that guix-daemon doesn't have to be launched from the checkout....Ludovic Courtès 2020-10-08doc: Developers don't need to run "make install" in Guix....Ludovic Courtès 2020-09-18doc: Fix broken hyperlinks in the contribution instructions....Greg Hogan 2020-09-12doc: Document the use of snippets vs phases....Maxim Cournoyer 2020-08-27doc: Improve the instructions regarding `guix git authenticate`....Joshua Branson 2020-07-23doc: Recommend running 'guix git authenticate' when cloning the repo....Ludovic Courtès 2020-07-09doc: Fix typo....Tobias Geerinckx-Rice 2020-06-20doc: Make issues.guix.gnu.org more visible....Ludovic Courtès 2020-06-16doc: Recommend "make authenticate" after ./bootstrap....Ludovic Courtès 2020-06-14doc: Adjust branching and rebuilding strategy to match reality....Marius Bakke