forked from NixOS/nix
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathsource-path.hh
More file actions
146 lines (119 loc) · 3.66 KB
/
Copy pathsource-path.hh
File metadata and controls
146 lines (119 loc) · 3.66 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#pragma once
/**
* @file
*
* @brief SourcePath
*/
#include "nix/util/ref.hh"
#include "nix/util/canon-path.hh"
#include "nix/util/source-accessor.hh"
#include "nix/util/std-hash.hh"
namespace nix {
/**
* An abstraction for accessing source files during
* evaluation. Currently, it's just a wrapper around `CanonPath` that
* accesses files in the regular filesystem, but in the future it will
* support fetching files in other ways.
*/
struct SourcePath
{
ref<SourceAccessor> accessor;
CanonPath path;
SourcePath(ref<SourceAccessor> accessor, CanonPath path = CanonPath::root)
: accessor(std::move(accessor))
, path(std::move(path))
{
}
std::string_view baseName() const;
/**
* Construct the parent of this `SourcePath`. Aborts if `this`
* denotes the root.
*/
SourcePath parent() const;
/**
* If this `SourcePath` denotes a regular file (not a symlink),
* return its contents; otherwise throw an error.
*/
std::string readFile() const;
void readFile(Sink & sink, std::function<void(uint64_t)> sizeCallback = [](uint64_t size) {}) const
{
return accessor->readFile(path, sink, sizeCallback);
}
/**
* Return whether this `SourcePath` denotes a file (of any type)
* that exists
*/
bool pathExists() const;
/**
* Return stats about this `SourcePath`, or throw an exception if
* it doesn't exist.
*/
SourceAccessor::Stat lstat() const;
/**
* Return stats about this `SourcePath`, or std::nullopt if it
* doesn't exist.
*/
std::optional<SourceAccessor::Stat> maybeLstat() const;
/**
* If this `SourcePath` denotes a directory (not a symlink),
* return its directory entries; otherwise throw an error.
*/
SourceAccessor::DirEntries readDirectory() const;
/**
* If this `SourcePath` denotes a symlink, return its target;
* otherwise throw an error.
*/
std::string readLink() const;
/**
* Dump this `SourcePath` to `sink` as a NAR archive.
*/
void dumpPath(Sink & sink, PathFilter & filter = defaultPathFilter) const;
/**
* Return the location of this path in the "real" filesystem, if
* it has a physical location.
*/
std::optional<std::filesystem::path> getPhysicalPath() const;
std::string to_string() const;
/**
* Append a `CanonPath` to this path.
*/
SourcePath operator/(const CanonPath & x) const;
/**
* Append a single component `c` to this path. `c` must not
* contain a slash. A slash is implicitly added between this path
* and `c`.
*/
SourcePath operator/(std::string_view c) const;
bool operator==(const SourcePath & x) const noexcept;
std::strong_ordering operator<=>(const SourcePath & x) const noexcept;
/**
* Convenience wrapper around `SourceAccessor::resolveSymlinks()`.
*/
SourcePath resolveSymlinks(SymlinkResolution mode = SymlinkResolution::Full) const
{
return {accessor, accessor->resolveSymlinks(path, mode)};
}
void invalidateCache() const
{
accessor->invalidateCache(path);
}
friend class std::hash<nix::SourcePath>;
};
std::ostream & operator<<(std::ostream & str, const SourcePath & path);
inline std::size_t hash_value(const SourcePath & path)
{
std::size_t hash = 0;
boost::hash_combine(hash, path.accessor->number);
boost::hash_combine(hash, path.path);
return hash;
}
} // namespace nix
template<>
struct std::hash<nix::SourcePath>
{
using is_avalanching = std::true_type;
std::size_t operator()(const nix::SourcePath & s) const noexcept
{
return nix::hash_value(s);
}
};