Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f717a37448 | ||
|
|
017327eeb3 | ||
|
|
7ef1b1cc82 | ||
|
|
37a84d424b |
No files matched your search
@@ -407,7 +407,7 @@ void createOutLinks(const std::filesystem::path & outLink, const BuiltPaths & bu
|
||||
struct MixOutLinkBase : virtual Args
|
||||
{
|
||||
/** Prefix for any output symlinks. Empty means do not write an output symlink. */
|
||||
Path outLink;
|
||||
std::filesystem::path outLink;
|
||||
|
||||
MixOutLinkBase(const std::string & defaultOutLink)
|
||||
: outLink(defaultOutLink)
|
||||
@@ -435,7 +435,7 @@ struct MixOutLinkByDefault : MixOutLinkBase, virtual Args
|
||||
addFlag({
|
||||
.longName = "no-link",
|
||||
.description = "Do not create symlinks to the build results.",
|
||||
.handler = {&outLink, Path("")},
|
||||
.handler = {&outLink, std::filesystem::path{}},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,7 +157,7 @@ MixFlakeOptions::MixFlakeOptions()
|
||||
.category = category,
|
||||
.labels = {"flake-lock-path"},
|
||||
.handler = {[&](std::string lockFilePath) {
|
||||
lockFlags.referenceLockFilePath = {getFSSourceAccessor(), CanonPath(absPath(lockFilePath))};
|
||||
lockFlags.referenceLockFilePath = {getFSSourceAccessor(), CanonPath(absPath(lockFilePath).string())};
|
||||
}},
|
||||
.completer = completePath,
|
||||
});
|
||||
|
||||
@@ -113,7 +113,7 @@ ReadlineLikeInteracter::Guard ReadlineLikeInteracter::init(detail::ReplCompleter
|
||||
// Allow nix-repl specific settings in .inputrc
|
||||
rl_readline_name = "nix-repl";
|
||||
try {
|
||||
createDirs(dirOf(historyFile));
|
||||
createDirs(std::filesystem::path(historyFile).parent_path());
|
||||
} catch (SystemError & e) {
|
||||
logWarning(e.info());
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ struct AttrDb
|
||||
{
|
||||
auto state(_state->lock());
|
||||
|
||||
auto cacheDir = std::filesystem::path(getCacheDir()) / "eval-cache-v6";
|
||||
auto cacheDir = getCacheDir() / "eval-cache-v6";
|
||||
createDirs(cacheDir);
|
||||
|
||||
auto dbPath = cacheDir / (fingerprint.to_string(HashFormat::Base16, false) + ".sqlite");
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
#include "nix/expr/eval-error.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/expr/value.hh"
|
||||
#include "nix/store/store-api.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
InvalidPathError::InvalidPathError(EvalState & state, const StorePath & path)
|
||||
: EvalError(state, "path '%s' is not valid", state.store->printStorePath(path))
|
||||
, path{path}
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withExitStatus(unsigned int exitStatus)
|
||||
{
|
||||
|
||||
@@ -70,7 +70,7 @@ Strings EvalSettings::getDefaultNixPath()
|
||||
}
|
||||
};
|
||||
|
||||
add(std::filesystem::path{getNixDefExpr()} / "channels");
|
||||
add(getNixDefExpr() / "channels");
|
||||
auto profilesDirOpts = settings.getProfileDirsOptions();
|
||||
add(rootChannelsDir(profilesDirOpts) / "nixpkgs", "nixpkgs");
|
||||
add(rootChannelsDir(profilesDirOpts));
|
||||
|
||||
+1
-1
@@ -432,7 +432,7 @@ void EvalState::checkURI(const std::string & uri)
|
||||
|
||||
/* If the URI is a path, then check it against allowedPaths as
|
||||
well. */
|
||||
if (isAbsolute(uri)) {
|
||||
if (std::filesystem::path(uri).is_absolute()) {
|
||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
||||
rootFS2->checkAccess(CanonPath(uri));
|
||||
return;
|
||||
|
||||
@@ -73,12 +73,9 @@ MakeError(IFDError, EvalBaseError);
|
||||
struct InvalidPathError : public EvalError
|
||||
{
|
||||
public:
|
||||
Path path;
|
||||
StorePath path;
|
||||
|
||||
InvalidPathError(EvalState & state, const Path & path)
|
||||
: EvalError(state, "path '%s' is not valid", path)
|
||||
{
|
||||
}
|
||||
InvalidPathError(EvalState & state, const StorePath & path);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -388,7 +388,8 @@ path_start
|
||||
});
|
||||
}
|
||||
|
||||
Path path(absPath(literal, state->basePath.path.abs()));
|
||||
auto basePath = std::filesystem::path(state->basePath.path.abs());
|
||||
Path path(absPath(literal, &basePath).string());
|
||||
/* add back in the trailing '/' to the first segment */
|
||||
if (literal.size() > 1 && literal.back() == '/')
|
||||
path += '/';
|
||||
|
||||
@@ -12,7 +12,7 @@ SourcePath EvalState::rootPath(CanonPath path)
|
||||
|
||||
SourcePath EvalState::rootPath(PathView path)
|
||||
{
|
||||
return {rootFS, CanonPath(absPath(path))};
|
||||
return {rootFS, CanonPath(absPath(std::filesystem::path{path}).string())};
|
||||
}
|
||||
|
||||
SourcePath EvalState::storePath(const StorePath & path)
|
||||
|
||||
@@ -74,7 +74,7 @@ StringMap EvalState::realiseContext(const NixStringContext & context, StorePathS
|
||||
for (auto & c : context) {
|
||||
auto ensureValid = [&](const StorePath & p) {
|
||||
if (!store->isValidPath(p))
|
||||
error<InvalidPathError>(store->printStorePath(p)).debugThrow();
|
||||
error<InvalidPathError>(p).debugThrow();
|
||||
};
|
||||
std::visit(
|
||||
overloaded{
|
||||
@@ -503,7 +503,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
try {
|
||||
auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
|
||||
} catch (InvalidPathError & e) {
|
||||
state.error<EvalError>("cannot execute '%1%', since path '%2%' is not valid", program, e.path)
|
||||
state.error<EvalError>("cannot execute '%1%', since path '%2%' is not valid", program, e.path.to_string())
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
@@ -1931,7 +1931,7 @@ static void prim_storePath(EvalState & state, const PosIdx pos, Value ** args, V
|
||||
directly in the store. The latter condition is necessary so
|
||||
e.g. nix-push does the right thing. */
|
||||
if (!state.store->isStorePath(path.abs()))
|
||||
path = CanonPath(canonPath(path.abs(), true));
|
||||
path = CanonPath(canonPath(path.abs(), true).string());
|
||||
if (!state.store->isInStore(path.abs()))
|
||||
state.error<EvalError>("path '%1%' is not in the Nix store", path).atPos(pos).debugThrow();
|
||||
auto path2 = state.store->toStorePath(path.abs()).first;
|
||||
@@ -2152,7 +2152,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value ** args, Va
|
||||
auto rewrites = state.realiseContext(context);
|
||||
path = rewriteStrings(std::move(path), rewrites);
|
||||
} catch (InvalidPathError & e) {
|
||||
state.error<EvalError>("cannot find '%1%', since path '%2%' is not valid", path, e.path)
|
||||
state.error<EvalError>("cannot find '%1%', since path '%2%' is not valid", path, state.store->printStorePath(e.path))
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ struct CacheImpl : Cache
|
||||
{
|
||||
auto state(_state.lock());
|
||||
|
||||
auto dbPath = (getCacheDir() / "fetcher-cache-v4.sqlite").string();
|
||||
createDirs(dirOf(dbPath));
|
||||
auto dbPath = getCacheDir() / "fetcher-cache-v4.sqlite";
|
||||
createDirs(dbPath.parent_path());
|
||||
|
||||
state->db = SQLite(dbPath, {.useWAL = nix::settings.useSQLiteWAL});
|
||||
state->db.isCache();
|
||||
|
||||
@@ -268,10 +268,10 @@ void Fetch::fetch(
|
||||
return;
|
||||
}
|
||||
|
||||
std::filesystem::path cacheDir = getCacheDir() / "git-lfs";
|
||||
auto cacheDir = getCacheDir() / "git-lfs";
|
||||
std::string key = hashString(HashAlgorithm::SHA256, pointerFilePath.rel()).to_string(HashFormat::Base16, false)
|
||||
+ "/" + pointer->oid;
|
||||
std::filesystem::path cachePath = cacheDir / key;
|
||||
auto cachePath = cacheDir / key;
|
||||
if (pathExists(cachePath)) {
|
||||
debug("using cache entry %s -> %s", key, PathFmt(cachePath));
|
||||
sink(readFile(cachePath));
|
||||
|
||||
@@ -666,7 +666,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||
.program = "git",
|
||||
.args =
|
||||
{"-c",
|
||||
"gpg.ssh.allowedSignersFile=" + allowedSignersFile,
|
||||
"gpg.ssh.allowedSignersFile=" + allowedSignersFile.string(),
|
||||
"-C",
|
||||
path.string(),
|
||||
"verify-commit",
|
||||
|
||||
@@ -44,8 +44,9 @@ static bool isCacheFileWithinTtl(const Settings & settings, time_t now, const Po
|
||||
|
||||
std::filesystem::path getCachePath(std::string_view key, bool shallow)
|
||||
{
|
||||
return getCacheDir() / "gitv3"
|
||||
/ (hashString(HashAlgorithm::SHA256, key).to_string(HashFormat::Nix32, false) + (shallow ? "-shallow" : ""));
|
||||
auto name =
|
||||
hashString(HashAlgorithm::SHA256, key).to_string(HashFormat::Nix32, false) + (shallow ? "-shallow" : "");
|
||||
return getCacheDir() / "gitv3" / std::move(name);
|
||||
}
|
||||
|
||||
// Returns the name of the HEAD branch.
|
||||
@@ -629,7 +630,7 @@ struct GitInputScheme : InputScheme
|
||||
if (url.scheme == "file" && !forceHttp && !isBareRepository(renderUrlPathEnsureLegal(url.path))) {
|
||||
auto path = renderUrlPathEnsureLegal(url.path);
|
||||
|
||||
if (!isAbsolute(path)) {
|
||||
if (!std::filesystem::path(path).is_absolute()) {
|
||||
warn(
|
||||
"Fetching Git repository '%s', which uses a path relative to the current directory. "
|
||||
"This is not supported and will stop working in a future release. "
|
||||
|
||||
@@ -302,7 +302,7 @@ struct MercurialInputScheme : InputScheme
|
||||
}
|
||||
}
|
||||
} else {
|
||||
createDirs(dirOf(cacheDir.string()));
|
||||
createDirs(cacheDir.parent_path());
|
||||
runHg({"clone", "--noupdate", "--", actualUrl, cacheDir.string()});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ struct PathInputScheme : InputScheme
|
||||
std::optional<std::string> isRelative(const Input & input) const override
|
||||
{
|
||||
auto path = getStrAttr(input.attrs, "path");
|
||||
if (isAbsolute(path))
|
||||
if (std::filesystem::path(path).is_absolute())
|
||||
return std::nullopt;
|
||||
else
|
||||
return path;
|
||||
@@ -132,7 +132,7 @@ struct PathInputScheme : InputScheme
|
||||
{
|
||||
auto path = getStrAttr(input.attrs, "path");
|
||||
|
||||
if (isAbsolute(path))
|
||||
if (std::filesystem::path(path).is_absolute())
|
||||
return canonPath(path);
|
||||
|
||||
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
|
||||
|
||||
@@ -147,13 +147,13 @@ static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, St
|
||||
return Registry::read(
|
||||
settings,
|
||||
[&] -> SourcePath {
|
||||
if (!isAbsolute(path)) {
|
||||
if (!std::filesystem::path(path).is_absolute()) {
|
||||
auto storePath = downloadFile(store, settings, path, "flake-registry.json").storePath;
|
||||
if (auto store2 = dynamic_cast<LocalFSStore *>(&store))
|
||||
store2->addPermRoot(storePath, (getCacheDir() / "flake-registry.json").string());
|
||||
return {store.requireStoreObjectAccessor(storePath)};
|
||||
} else {
|
||||
return SourcePath{getFSSourceAccessor(), CanonPath{path}}.resolveSymlinks();
|
||||
return SourcePath{makeFSSourceAccessor(path)}.resolveSymlinks();
|
||||
}
|
||||
}(),
|
||||
Registry::Global);
|
||||
|
||||
@@ -179,7 +179,7 @@ static DownloadTarballResult downloadTarball_(
|
||||
auto [fdTemp, path] = createTempFile("nix-zipfile");
|
||||
cleanupTemp.cancel();
|
||||
cleanupTemp = {path};
|
||||
debug("downloading '%s' into '%s'...", url, path);
|
||||
debug("downloading '%s' into %s...", url, PathFmt(path));
|
||||
{
|
||||
FdSink sink(fdTemp.get());
|
||||
source->drainInto(sink);
|
||||
|
||||
@@ -13,7 +13,7 @@ struct nix_flake_settings
|
||||
|
||||
struct nix_flake_reference_parse_flags
|
||||
{
|
||||
std::optional<nix::Path> baseDirectory;
|
||||
std::optional<std::filesystem::path> baseDirectory;
|
||||
};
|
||||
|
||||
struct nix_flake_reference
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace nix::flake {
|
||||
// setting name -> setting value -> allow or ignore.
|
||||
typedef std::map<std::string, std::map<std::string, bool>> TrustedList;
|
||||
|
||||
std::filesystem::path trustedListPath()
|
||||
static std::filesystem::path trustedListPath()
|
||||
{
|
||||
return getDataDir() / "trusted-settings.json";
|
||||
}
|
||||
|
||||
@@ -121,19 +121,23 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
to 'baseDir'). If so, search upward to the root of the
|
||||
repo (i.e. the directory containing .git). */
|
||||
|
||||
path = absPath(path, baseDir->string(), true);
|
||||
{
|
||||
auto baseDirPath = *baseDir;
|
||||
path = absPath(path, &baseDirPath, true).string();
|
||||
}
|
||||
|
||||
if (isFlake) {
|
||||
|
||||
if (!S_ISDIR(lstat(path).st_mode)) {
|
||||
if (baseNameOf(path) == "flake.nix") {
|
||||
// Be gentle with people who accidentally write `/foo/bar/flake.nix` instead of `/foo/bar`
|
||||
auto parentPath = std::filesystem::path(path).parent_path().string();
|
||||
warn(
|
||||
"Path '%s' should point at the directory containing the 'flake.nix' file, not the file itself. "
|
||||
"Pretending that you meant '%s'",
|
||||
path,
|
||||
dirOf(path));
|
||||
path = dirOf(path);
|
||||
parentPath);
|
||||
path = parentPath;
|
||||
} else {
|
||||
throw BadURL("path '%s' is not a flake (because it's not a directory)", path);
|
||||
}
|
||||
@@ -157,7 +161,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
if (lstat(path).st_dev != device)
|
||||
throw Error("unable to find a flake before encountering filesystem boundary at '%s'", path);
|
||||
}
|
||||
path = dirOf(path);
|
||||
path = std::filesystem::path(path).parent_path().string();
|
||||
}
|
||||
if (!found)
|
||||
throw BadURL("could not find a flake.nix file");
|
||||
@@ -192,12 +196,12 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
}
|
||||
|
||||
subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir);
|
||||
flakeRoot = dirOf(flakeRoot);
|
||||
flakeRoot = std::filesystem::path(flakeRoot).parent_path().string();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!preserveRelativePaths && !isAbsolute(path))
|
||||
if (!preserveRelativePaths && !std::filesystem::path(path).is_absolute())
|
||||
throw BadURL("flake reference '%s' is not an absolute path", url);
|
||||
}
|
||||
|
||||
@@ -251,8 +255,10 @@ std::optional<std::pair<FlakeRef, std::string>> parseURLFlakeRef(
|
||||
if (baseDir && (parsed.scheme == "path" || parsed.scheme == "git+file")) {
|
||||
/* Here we know that the path must not contain encoded '/' or NUL bytes. */
|
||||
auto path = renderUrlPathEnsureLegal(parsed.path);
|
||||
if (!isAbsolute(path))
|
||||
parsed.path = splitString<std::vector<std::string>>(absPath(path, baseDir->string()), "/");
|
||||
if (!std::filesystem::path(path).is_absolute()) {
|
||||
auto baseDirPath = *baseDir;
|
||||
parsed.path = splitString<std::vector<std::string>>(absPath(path, &baseDirPath).string(), "/");
|
||||
}
|
||||
}
|
||||
return fromParsedURL(fetchSettings, std::move(parsed), isFlake);
|
||||
} catch (BadURL &) {
|
||||
|
||||
@@ -51,7 +51,7 @@ protected:
|
||||
// resolve any symlinks in i.e. on macOS /tmp -> /private/tmp
|
||||
// because this is not allowed for a nix store.
|
||||
auto tmpl =
|
||||
nix::absPath(std::filesystem::path(nix::defaultTempDir()) / "tests_nix-store.XXXXXX", std::nullopt, true);
|
||||
nix::absPath(std::filesystem::path(nix::defaultTempDir()) / "tests_nix-store.XXXXXX", nullptr, true);
|
||||
nixDir = mkdtemp((char *) tmpl.c_str());
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,10 +13,6 @@ using testing::Eq;
|
||||
using testing::Field;
|
||||
using testing::SizeIs;
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
TEST(machines, getMachinesWithEmptyBuilders)
|
||||
|
||||
@@ -28,7 +28,7 @@ BinaryCacheStore::BinaryCacheStore(Config & config)
|
||||
: config{config}
|
||||
{
|
||||
if (config.secretKeyFile != "")
|
||||
signers.push_back(std::make_unique<LocalSigner>(SecretKey{readFile(config.secretKeyFile)}));
|
||||
signers.push_back(std::make_unique<LocalSigner>(SecretKey{readFile(config.secretKeyFile.get())}));
|
||||
|
||||
if (config.secretKeyFiles != "") {
|
||||
std::stringstream ss(config.secretKeyFiles);
|
||||
|
||||
@@ -1052,15 +1052,15 @@ LogFile::LogFile(Store & store, const StorePath & drvPath, const LogFileSettings
|
||||
|
||||
auto baseName = std::string(baseNameOf(store.printStorePath(drvPath)));
|
||||
|
||||
Path logDir;
|
||||
std::filesystem::path logDir;
|
||||
if (auto localStore = dynamic_cast<LocalStore *>(&store))
|
||||
logDir = localStore->config->logDir;
|
||||
logDir = localStore->config->logDir.get();
|
||||
else
|
||||
logDir = logSettings.nixLogDir.string();
|
||||
Path dir = fmt("%s/%s/%s/", logDir, LocalFSStore::drvsLogDir, baseName.substr(0, 2));
|
||||
logDir = logSettings.nixLogDir;
|
||||
auto dir = logDir / LocalFSStore::drvsLogDir / baseName.substr(0, 2);
|
||||
createDirs(dir);
|
||||
|
||||
Path logFileName = fmt("%s/%s%s", dir, baseName.substr(2), logSettings.compressLog ? ".bz2" : "");
|
||||
auto logFileName = dir / (baseName.substr(2) + (logSettings.compressLog ? ".bz2" : ""));
|
||||
|
||||
fd = openNewFileForWrite(
|
||||
logFileName,
|
||||
@@ -1070,7 +1070,7 @@ LogFile::LogFile(Store & store, const StorePath & drvPath, const LogFileSettings
|
||||
.followSymlinksOnTruncate = true, /* FIXME: Probably shouldn't follow symlinks. */
|
||||
});
|
||||
if (!fd)
|
||||
throw SysError("creating log file '%1%'", logFileName);
|
||||
throw SysError("creating log file %1%", PathFmt(logFileName));
|
||||
|
||||
fileSink = std::make_shared<FdSink>(fd.get());
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ void checkOutputs(
|
||||
const decltype(DerivationOptions<StorePath>::outputChecks) & outputChecks,
|
||||
const std::map<std::string, ValidPathInfo> & outputs)
|
||||
{
|
||||
std::map<Path, const ValidPathInfo &> outputsByPath;
|
||||
std::map<std::filesystem::path, const ValidPathInfo &> outputsByPath;
|
||||
for (auto & output : outputs)
|
||||
outputsByPath.emplace(store.printStorePath(output.second.path), output.second);
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@ namespace {
|
||||
|
||||
struct State
|
||||
{
|
||||
std::map<Path, int> priorities;
|
||||
std::map<std::filesystem::path, int> priorities;
|
||||
unsigned long symlinks = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/* For each activated package, create symlinks */
|
||||
static void createLinks(State & state, const Path & srcDir, const Path & dstDir, int priority)
|
||||
static void createLinks(State & state, const std::filesystem::path & srcDir, const std::filesystem::path & dstDir, int priority)
|
||||
{
|
||||
DirectoryIterator srcFiles;
|
||||
|
||||
@@ -35,7 +35,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||
srcFiles = DirectoryIterator{srcDir};
|
||||
} catch (SystemError & e) {
|
||||
if (e.is(std::errc::not_a_directory)) {
|
||||
warn("not including '%s' in the user environment because it's not a directory", srcDir);
|
||||
warn("not including %s in the user environment because it's not a directory", PathFmt(srcDir));
|
||||
return;
|
||||
}
|
||||
throw;
|
||||
@@ -78,9 +78,9 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||
} else if (S_ISLNK(dstSt.st_mode)) {
|
||||
auto target = canonPath(dstFile, true);
|
||||
if (!S_ISDIR(lstat(target).st_mode))
|
||||
throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target);
|
||||
throw Error("collision between %1% and non-directory %2%", PathFmt(srcFile), PathFmt(target));
|
||||
if (unlink(dstFile.c_str()) == -1)
|
||||
throw SysError("unlinking '%1%'", dstFile);
|
||||
throw SysError("unlinking %1%", PathFmt(dstFile));
|
||||
if (mkdir(
|
||||
dstFile.c_str()
|
||||
#ifndef _WIN32 // TODO abstract mkdir perms for Windows
|
||||
@@ -108,7 +108,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||
if (prevPriority < priority)
|
||||
continue;
|
||||
if (unlink(dstFile.c_str()) == -1)
|
||||
throw SysError("unlinking '%1%'", dstFile);
|
||||
throw SysError("unlinking %1%", PathFmt(dstFile));
|
||||
} else if (S_ISDIR(dstSt.st_mode))
|
||||
throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile);
|
||||
}
|
||||
@@ -120,13 +120,13 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
||||
}
|
||||
}
|
||||
|
||||
void buildProfile(const Path & out, Packages && pkgs)
|
||||
void buildProfile(const std::filesystem::path & out, Packages && pkgs)
|
||||
{
|
||||
State state;
|
||||
|
||||
PathSet done, postponed;
|
||||
|
||||
auto addPkg = [&](const Path & pkgDir, int priority) {
|
||||
auto addPkg = [&](const std::filesystem::path & pkgDir, int priority) {
|
||||
if (!done.insert(pkgDir).second)
|
||||
return;
|
||||
createLinks(state, pkgDir, out, priority);
|
||||
|
||||
@@ -680,21 +680,21 @@ static void performOp(
|
||||
"you are not privileged to create perm roots\n\n"
|
||||
"hint: you can just do this client-side without special privileges, and probably want to do that instead.");
|
||||
auto storePath = WorkerProto::Serialise<StorePath>::read(*store, rconn);
|
||||
Path gcRoot = absPath(readString(conn.from));
|
||||
std::filesystem::path gcRoot = absPath(readString(conn.from));
|
||||
logger->startWork();
|
||||
auto & localFSStore = require<LocalFSStore>(*store);
|
||||
localFSStore.addPermRoot(storePath, gcRoot);
|
||||
localFSStore.addPermRoot(storePath, gcRoot.string());
|
||||
logger->stopWork();
|
||||
conn.to << gcRoot;
|
||||
conn.to << gcRoot.string();
|
||||
break;
|
||||
}
|
||||
|
||||
case WorkerProto::Op::AddIndirectRoot: {
|
||||
Path path = absPath(readString(conn.from));
|
||||
std::filesystem::path path = absPath(readString(conn.from));
|
||||
|
||||
logger->startWork();
|
||||
auto & indirectRootStore = require<IndirectRootStore>(*store);
|
||||
indirectRootStore.addIndirectRoot(path);
|
||||
indirectRootStore.addIndirectRoot(path.string());
|
||||
logger->stopWork();
|
||||
|
||||
conn.to << 1;
|
||||
|
||||
+37
-36
@@ -40,8 +40,8 @@ static std::string gcRootsDir = "gcroots";
|
||||
void LocalStore::addIndirectRoot(const Path & path)
|
||||
{
|
||||
std::string hash = hashString(HashAlgorithm::SHA1, path).to_string(HashFormat::Nix32, false);
|
||||
Path realRoot = canonPath(fmt("%1%/%2%/auto/%3%", config->stateDir, gcRootsDir, hash));
|
||||
makeSymlink(realRoot, path);
|
||||
auto realRoot = canonPath(config->stateDir.get() / gcRootsDir / "auto" / hash);
|
||||
makeSymlink(realRoot.string(), path);
|
||||
}
|
||||
|
||||
void LocalStore::createTempRootsFile()
|
||||
@@ -60,7 +60,7 @@ void LocalStore::createTempRootsFile()
|
||||
|
||||
*fdTempRoots = openLockFile(fnTempRoots, true);
|
||||
|
||||
debug("acquiring write lock on '%s'", fnTempRoots);
|
||||
debug("acquiring write lock on %s", PathFmt(fnTempRoots));
|
||||
lockFile(fdTempRoots->get(), ltWrite, true);
|
||||
|
||||
/* Check whether the garbage collector didn't get in our
|
||||
@@ -165,11 +165,11 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor)
|
||||
// those to keep the directory alive.
|
||||
continue;
|
||||
}
|
||||
Path path = i.path().string();
|
||||
auto path = i.path();
|
||||
|
||||
pid_t pid = std::stoi(name);
|
||||
|
||||
debug("reading temporary root file '%1%'", path);
|
||||
debug("reading temporary root file %1%", PathFmt(path));
|
||||
AutoCloseFD fd(toDescriptor(open(
|
||||
path.c_str(),
|
||||
#ifndef _WIN32
|
||||
@@ -181,14 +181,14 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor)
|
||||
/* It's okay if the file has disappeared. */
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
throw SysError("opening temporary roots file '%1%'", path);
|
||||
throw SysError("opening temporary roots file %1%", PathFmt(path));
|
||||
}
|
||||
|
||||
/* Try to acquire a write lock without blocking. This can
|
||||
only succeed if the owning process has died. In that case
|
||||
we don't care about its temporary roots. */
|
||||
if (lockFile(fd.get(), ltWrite, false)) {
|
||||
printInfo("removing stale temporary roots file '%1%'", path);
|
||||
printInfo("removing stale temporary roots file %1%", PathFmt(path));
|
||||
unlink(path.c_str());
|
||||
writeFull(fd.get(), "d");
|
||||
continue;
|
||||
@@ -201,7 +201,7 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor)
|
||||
std::string::size_type pos = 0, end;
|
||||
|
||||
while ((end = contents.find((char) 0, pos)) != std::string::npos) {
|
||||
Path root(contents, pos, end - pos);
|
||||
std::string root(contents, pos, end - pos);
|
||||
debug("got temporary root '%s'", root);
|
||||
tempRoots[parseStorePath(root)].emplace(censor ? censored : fmt("{temp:%d}", pid));
|
||||
pos = end + 1;
|
||||
@@ -211,13 +211,13 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor)
|
||||
|
||||
void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, Roots & roots)
|
||||
{
|
||||
auto foundRoot = [&](const Path & path, const Path & target) {
|
||||
auto foundRoot = [&](const std::filesystem::path & path, const std::filesystem::path & target) {
|
||||
try {
|
||||
auto storePath = toStorePath(target).first;
|
||||
auto storePath = toStorePath(target.string()).first;
|
||||
if (isValidPath(storePath))
|
||||
roots[std::move(storePath)].emplace(path);
|
||||
roots[std::move(storePath)].emplace(path.string());
|
||||
else
|
||||
printInfo("skipping invalid root from '%1%' to '%2%'", path, target);
|
||||
printInfo("skipping invalid root from %1% to %2%", PathFmt(path), PathFmt(target));
|
||||
} catch (BadStorePath &) {
|
||||
}
|
||||
};
|
||||
@@ -235,23 +235,24 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R
|
||||
}
|
||||
|
||||
else if (type == std::filesystem::file_type::symlink) {
|
||||
Path target = readLink(path);
|
||||
if (isInStore(target))
|
||||
auto target = readLink(path);
|
||||
if (isInStore(target.string()))
|
||||
foundRoot(path, target);
|
||||
|
||||
/* Handle indirect roots. */
|
||||
else {
|
||||
target = absPath(target, dirOf(path));
|
||||
if (!pathExists(target)) {
|
||||
auto parentPath = std::filesystem::path(path).parent_path();
|
||||
target = absPath(target, &parentPath);
|
||||
if (!pathExists(target.string())) {
|
||||
if (isInDir(path, std::filesystem::path{config->stateDir.get()} / gcRootsDir / "auto")) {
|
||||
printInfo("removing stale link from '%1%' to '%2%'", path, target);
|
||||
printInfo("removing stale link from %1% to %2%", PathFmt(path), PathFmt(target));
|
||||
unlink(path.c_str());
|
||||
}
|
||||
} else {
|
||||
if (!std::filesystem::is_symlink(target))
|
||||
return;
|
||||
Path target2 = readLink(target);
|
||||
if (isInStore(target2))
|
||||
auto target2 = readLink(target);
|
||||
if (isInStore(target2.string()))
|
||||
foundRoot(target, target2);
|
||||
}
|
||||
}
|
||||
@@ -287,8 +288,8 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R
|
||||
void LocalStore::findRootsNoTemp(Roots & roots, bool censor)
|
||||
{
|
||||
/* Process direct roots in {gcroots,profiles}. */
|
||||
findRoots(config->stateDir + "/" + gcRootsDir, std::filesystem::file_type::unknown, roots);
|
||||
findRoots(config->stateDir + "/profiles", std::filesystem::file_type::unknown, roots);
|
||||
findRoots((config->stateDir.get() / gcRootsDir).string(), std::filesystem::file_type::unknown, roots);
|
||||
findRoots((config->stateDir.get() / "profiles").string(), std::filesystem::file_type::unknown, roots);
|
||||
|
||||
/* Add additional roots returned by different platforms-specific
|
||||
heuristics. This is typically used to add running programs to
|
||||
@@ -374,7 +375,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
|
||||
/* Start the server for receiving new roots. */
|
||||
auto socketPath = config->stateDir.get() + gcSocketPath;
|
||||
createDirs(dirOf(socketPath));
|
||||
createDirs(std::filesystem::path(socketPath).parent_path());
|
||||
auto fdServer = createUnixDomainSocket(socketPath, 0666);
|
||||
|
||||
// TODO nonblocking socket on windows?
|
||||
@@ -513,26 +514,26 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
/* Helper function that deletes a path from the store and throws
|
||||
GCLimitReached if we've deleted enough garbage. */
|
||||
auto deleteFromStore = [&](std::string_view baseName, bool isKnownPath) {
|
||||
Path path = storeDir + "/" + std::string(baseName);
|
||||
Path realPath = config->realStoreDir + "/" + std::string(baseName);
|
||||
auto path = std::filesystem::path{storeDir} / std::string(baseName);
|
||||
auto realPath = config->realStoreDir.get() / std::string(baseName);
|
||||
|
||||
/* There may be temp directories in the store that are still in use
|
||||
by another process. We need to be sure that we can acquire an
|
||||
exclusive lock before deleting them. */
|
||||
if (baseName.find("tmp-", 0) == 0) {
|
||||
AutoCloseFD tmpDirFd = openDirectory(realPath);
|
||||
AutoCloseFD tmpDirFd = openDirectory(realPath.string());
|
||||
if (!tmpDirFd || !lockFile(tmpDirFd.get(), ltWrite, false)) {
|
||||
debug("skipping locked tempdir '%s'", realPath);
|
||||
debug("skipping locked tempdir %s", PathFmt(realPath));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printInfo("deleting '%1%'", path);
|
||||
printInfo("deleting %1%", PathFmt(path));
|
||||
|
||||
results.paths.insert(path);
|
||||
results.paths.insert(path.string());
|
||||
|
||||
uint64_t bytesFreed;
|
||||
deleteStorePath(realPath, bytesFreed, isKnownPath);
|
||||
deleteStorePath(realPath.string(), bytesFreed, isKnownPath);
|
||||
|
||||
results.bytesFreed += bytesFreed;
|
||||
|
||||
@@ -689,12 +690,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
try {
|
||||
AutoCloseDir dir(opendir(config->realStoreDir.get().c_str()));
|
||||
if (!dir)
|
||||
throw SysError("opening directory '%1%'", config->realStoreDir);
|
||||
throw SysError("opening directory %1%", PathFmt(config->realStoreDir.get()));
|
||||
|
||||
/* Read the store and delete all paths that are invalid or
|
||||
unreachable. We don't use readDirectory() here so that
|
||||
GCing can start faster. */
|
||||
auto linksName = baseNameOf(linksDir);
|
||||
auto linksName = linksDir.filename().string();
|
||||
struct dirent * dirent;
|
||||
while (errno = 0, dirent = readdir(dir.get())) {
|
||||
checkInterrupt();
|
||||
@@ -733,7 +734,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
|
||||
AutoCloseDir dir(opendir(linksDir.c_str()));
|
||||
if (!dir)
|
||||
throw SysError("opening directory '%1%'", linksDir);
|
||||
throw SysError("opening directory %1%", PathFmt(linksDir));
|
||||
|
||||
int64_t actualSize = 0, unsharedSize = 0;
|
||||
|
||||
@@ -743,9 +744,9 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
std::string name = dirent->d_name;
|
||||
if (name == "." || name == "..")
|
||||
continue;
|
||||
Path path = linksDir + "/" + name;
|
||||
auto path = linksDir / name;
|
||||
|
||||
auto st = lstat(path);
|
||||
auto st = lstat(path.string());
|
||||
|
||||
if (st.st_nlink != 1) {
|
||||
actualSize += st.st_size;
|
||||
@@ -753,10 +754,10 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
continue;
|
||||
}
|
||||
|
||||
printMsg(lvlTalkative, "deleting unused link '%1%'", path);
|
||||
printMsg(lvlTalkative, "deleting unused link %1%", PathFmt(path));
|
||||
|
||||
if (unlink(path.c_str()) == -1)
|
||||
throw SysError("deleting '%1%'", path);
|
||||
throw SysError("deleting %1%", PathFmt(path));
|
||||
|
||||
/* Do not account for deleted file here. Rely on deletePath()
|
||||
accounting. */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
///@file
|
||||
|
||||
#include "nix/store/store-api.hh"
|
||||
#include "nix/util/fmt.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -10,11 +11,11 @@ namespace nix {
|
||||
*/
|
||||
struct Package
|
||||
{
|
||||
Path path;
|
||||
std::filesystem::path path;
|
||||
bool active;
|
||||
int priority;
|
||||
|
||||
Package(const Path & path, bool active, int priority)
|
||||
Package(const std::filesystem::path & path, bool active, int priority)
|
||||
: path{path}
|
||||
, active{active}
|
||||
, priority{priority}
|
||||
@@ -25,18 +26,18 @@ struct Package
|
||||
class BuildEnvFileConflictError : public Error
|
||||
{
|
||||
public:
|
||||
const Path fileA;
|
||||
const Path fileB;
|
||||
const std::filesystem::path fileA;
|
||||
const std::filesystem::path fileB;
|
||||
int priority;
|
||||
|
||||
BuildEnvFileConflictError(const Path fileA, const Path fileB, int priority)
|
||||
BuildEnvFileConflictError(const std::filesystem::path fileA, const std::filesystem::path fileB, int priority)
|
||||
: Error(
|
||||
"Unable to build profile. There is a conflict for the following files:\n"
|
||||
"\n"
|
||||
" %1%\n"
|
||||
" %2%",
|
||||
fileA,
|
||||
fileB)
|
||||
PathFmt(fileA),
|
||||
PathFmt(fileB))
|
||||
, fileA(fileA)
|
||||
, fileB(fileB)
|
||||
, priority(priority)
|
||||
@@ -46,6 +47,6 @@ public:
|
||||
|
||||
typedef std::vector<Package> Packages;
|
||||
|
||||
void buildProfile(const Path & out, Packages && pkgs);
|
||||
void buildProfile(const std::filesystem::path & out, Packages && pkgs);
|
||||
|
||||
} // namespace nix
|
||||
@@ -10,7 +10,8 @@ namespace nix {
|
||||
struct LocalFSStoreConfig : virtual StoreConfig
|
||||
{
|
||||
private:
|
||||
static OptionalPathSetting makeRootDirSetting(LocalFSStoreConfig & self, std::optional<Path> defaultValue)
|
||||
static Setting<std::optional<std::filesystem::path>>
|
||||
makeRootDirSetting(LocalFSStoreConfig & self, std::optional<Path> defaultValue)
|
||||
{
|
||||
return {
|
||||
&self,
|
||||
@@ -32,7 +33,7 @@ public:
|
||||
*/
|
||||
LocalFSStoreConfig(PathView path, const Params & params);
|
||||
|
||||
OptionalPathSetting rootDir = makeRootDirSetting(*this, std::nullopt);
|
||||
Setting<std::optional<std::filesystem::path>> rootDir = makeRootDirSetting(*this, std::nullopt);
|
||||
|
||||
private:
|
||||
|
||||
@@ -50,19 +51,19 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
PathSetting stateDir{
|
||||
Setting<std::filesystem::path> stateDir{
|
||||
this,
|
||||
rootDir.get() ? *rootDir.get() + "/nix/var/nix" : getDefaultStateDir(),
|
||||
"state",
|
||||
"Directory where Nix stores state."};
|
||||
|
||||
PathSetting logDir{
|
||||
Setting<std::filesystem::path> logDir{
|
||||
this,
|
||||
rootDir.get() ? *rootDir.get() + "/nix/var/log/nix" : getDefaultLogDir(),
|
||||
"log",
|
||||
"directory where Nix stores log files."};
|
||||
|
||||
PathSetting realStoreDir{
|
||||
Setting<std::filesystem::path> realStoreDir{
|
||||
this, rootDir.get() ? *rootDir.get() + "/nix/store" : storeDir, "real", "Physical path of the Nix store."};
|
||||
};
|
||||
|
||||
@@ -77,7 +78,7 @@ struct alignas(8) /* Work around ASAN failures on i686-linux. */
|
||||
|
||||
inline static std::string operationName = "Local Filesystem Store";
|
||||
|
||||
const static std::string drvsLogDir;
|
||||
const static std::filesystem::path drvsLogDir;
|
||||
|
||||
LocalFSStore(const Config & params);
|
||||
|
||||
@@ -100,7 +101,7 @@ struct alignas(8) /* Work around ASAN failures on i686-linux. */
|
||||
*/
|
||||
virtual Path addPermRoot(const StorePath & storePath, const Path & gcRoot) = 0;
|
||||
|
||||
virtual Path getRealStoreDir()
|
||||
virtual std::filesystem::path getRealStoreDir()
|
||||
{
|
||||
return config.realStoreDir;
|
||||
}
|
||||
|
||||
@@ -207,12 +207,12 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
const Path dbDir;
|
||||
const Path linksDir;
|
||||
const Path reservedPath;
|
||||
const Path schemaPath;
|
||||
const Path tempRootsDir;
|
||||
const Path fnTempRoots;
|
||||
const std::filesystem::path dbDir;
|
||||
const std::filesystem::path linksDir;
|
||||
const std::filesystem::path reservedPath;
|
||||
const std::filesystem::path schemaPath;
|
||||
const std::filesystem::path tempRootsDir;
|
||||
const std::filesystem::path fnTempRoots;
|
||||
|
||||
private:
|
||||
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
/**
|
||||
* Hack for build-remote.cc.
|
||||
*/
|
||||
PathSet locksHeld;
|
||||
PathSetNG locksHeld;
|
||||
|
||||
/**
|
||||
* Initialise the local store, upgrading the schema if
|
||||
|
||||
@@ -34,7 +34,7 @@ private:
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
Pid sshMaster;
|
||||
#endif
|
||||
Path socketPath;
|
||||
std::filesystem::path socketPath;
|
||||
};
|
||||
|
||||
Sync<State> state_;
|
||||
@@ -43,7 +43,7 @@ private:
|
||||
bool isMasterRunning();
|
||||
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
Path startMaster();
|
||||
std::filesystem::path startMaster();
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -5,11 +5,11 @@ namespace nix {
|
||||
void IndirectRootStore::makeSymlink(const Path & link, const Path & target)
|
||||
{
|
||||
/* Create directories up to `gcRoot'. */
|
||||
createDirs(dirOf(link));
|
||||
createDirs(std::filesystem::path(link).parent_path());
|
||||
|
||||
/* Create the new symlink. */
|
||||
Path tempLink = fmt("%1%.tmp-%2%-%3%", link, getpid(), rand());
|
||||
createSymlink(target, tempLink);
|
||||
auto tempLink = std::filesystem::path(link).concat(fmt(".tmp-%1%-%2%", getpid(), rand()));
|
||||
createSymlink(target, tempLink.string());
|
||||
|
||||
/* Atomically replace the old one. */
|
||||
std::filesystem::rename(tempLink, link);
|
||||
@@ -17,13 +17,13 @@ void IndirectRootStore::makeSymlink(const Path & link, const Path & target)
|
||||
|
||||
Path IndirectRootStore::addPermRoot(const StorePath & storePath, const Path & _gcRoot)
|
||||
{
|
||||
Path gcRoot(canonPath(_gcRoot));
|
||||
auto gcRoot = canonPath(_gcRoot);
|
||||
|
||||
if (isInStore(gcRoot))
|
||||
if (isInStore(gcRoot.string()))
|
||||
throw Error(
|
||||
"creating a garbage collector root (%1%) in the Nix store is forbidden "
|
||||
"(are you running nix-build inside the store?)",
|
||||
gcRoot);
|
||||
PathFmt(gcRoot));
|
||||
|
||||
/* Register this root with the garbage collector, if it's
|
||||
running. This should be superfluous since the caller should
|
||||
@@ -33,13 +33,13 @@ Path IndirectRootStore::addPermRoot(const StorePath & storePath, const Path & _g
|
||||
|
||||
/* Don't clobber the link if it already exists and doesn't
|
||||
point to the Nix store. */
|
||||
if (pathExists(gcRoot) && (!std::filesystem::is_symlink(gcRoot) || !isInStore(readLink(gcRoot))))
|
||||
throw Error("cannot create symlink '%1%'; already exists", gcRoot);
|
||||
if (pathExists(gcRoot.string()) && (!std::filesystem::is_symlink(gcRoot) || !isInStore(readLink(gcRoot).string())))
|
||||
throw Error("cannot create symlink %1%; already exists", PathFmt(gcRoot));
|
||||
|
||||
makeSymlink(gcRoot, printStorePath(storePath));
|
||||
addIndirectRoot(gcRoot);
|
||||
makeSymlink(gcRoot.string(), printStorePath(storePath));
|
||||
addIndirectRoot(gcRoot.string());
|
||||
|
||||
return gcRoot;
|
||||
return gcRoot.string();
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
@@ -112,7 +112,7 @@ std::shared_ptr<SourceAccessor> LocalFSStore::getFSAccessor(const StorePath & pa
|
||||
return std::make_shared<PosixSourceAccessor>(std::move(absPath));
|
||||
}
|
||||
|
||||
const std::string LocalFSStore::drvsLogDir = "drvs";
|
||||
const std::filesystem::path LocalFSStore::drvsLogDir = "drvs";
|
||||
|
||||
std::optional<std::string> LocalFSStore::getBuildLogExact(const StorePath & path)
|
||||
{
|
||||
@@ -120,10 +120,10 @@ std::optional<std::string> LocalFSStore::getBuildLogExact(const StorePath & path
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
|
||||
Path logPath =
|
||||
j == 0 ? fmt("%s/%s/%s/%s", config.logDir.get(), drvsLogDir, baseName.substr(0, 2), baseName.substr(2))
|
||||
: fmt("%s/%s/%s", config.logDir.get(), drvsLogDir, baseName);
|
||||
Path logBz2Path = logPath + ".bz2";
|
||||
auto logPath = config.logDir.get()
|
||||
/ (j == 0 ? drvsLogDir / baseName.substr(0, 2) / baseName.substr(2) : drvsLogDir / baseName);
|
||||
auto logBz2Path = logPath;
|
||||
logBz2Path += ".bz2";
|
||||
|
||||
if (pathExists(logPath))
|
||||
return readFile(logPath);
|
||||
|
||||
@@ -35,7 +35,7 @@ StoreReference LocalOverlayStoreConfig::getReference() const
|
||||
|
||||
Path LocalOverlayStoreConfig::toUpperPath(const StorePath & path) const
|
||||
{
|
||||
return upperLayer + "/" + path.to_string();
|
||||
return (upperLayer.get() / path.to_string()).string();
|
||||
}
|
||||
|
||||
LocalOverlayStore::LocalOverlayStore(ref<const Config> config)
|
||||
@@ -49,7 +49,7 @@ LocalOverlayStore::LocalOverlayStore(ref<const Config> config)
|
||||
std::smatch match;
|
||||
std::string mountInfo;
|
||||
auto mounts = readFile(std::filesystem::path{"/proc/self/mounts"});
|
||||
auto regex = std::regex(R"((^|\n)overlay )" + config->realStoreDir.get() + R"( .*(\n|$))");
|
||||
auto regex = std::regex(R"((^|\n)overlay )" + config->realStoreDir.get().string() + R"( .*(\n|$))");
|
||||
|
||||
// Mount points can be stacked, so there might be multiple matching entries.
|
||||
// Loop until the last match, which will be the current state of the mount point.
|
||||
@@ -58,16 +58,16 @@ LocalOverlayStore::LocalOverlayStore(ref<const Config> config)
|
||||
mounts = match.suffix();
|
||||
}
|
||||
|
||||
auto checkOption = [&](std::string option, std::string value) {
|
||||
return std::regex_search(mountInfo, std::regex("\\b" + option + "=" + value + "( |,)"));
|
||||
auto checkOption = [&](std::string_view option, const std::filesystem::path & value) {
|
||||
return std::regex_search(mountInfo, std::regex("\\b" + option + "=" + value.string() + "( |,)"));
|
||||
};
|
||||
|
||||
auto expectedLowerDir = lowerStore->config.realStoreDir.get();
|
||||
if (!checkOption("lowerdir", expectedLowerDir) || !checkOption("upperdir", config->upperLayer)) {
|
||||
debug("expected lowerdir: %s", expectedLowerDir);
|
||||
debug("expected upperdir: %s", config->upperLayer);
|
||||
if (!checkOption("lowerdir", expectedLowerDir) || !checkOption("upperdir", config->upperLayer.get())) {
|
||||
debug("expected lowerdir: %s", PathFmt(lowerStore->config.realStoreDir.get()));
|
||||
debug("expected upperdir: %s", PathFmt(config->upperLayer.get()));
|
||||
debug("actual mount: %s", mountInfo);
|
||||
throw Error("overlay filesystem '%s' mounted incorrectly", config->realStoreDir.get());
|
||||
throw Error("overlay filesystem %s mounted incorrectly", PathFmt(config->realStoreDir.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,9 +281,9 @@ void LocalOverlayStore::remountIfNecessary()
|
||||
return;
|
||||
|
||||
if (config->remountHook.get().empty()) {
|
||||
warn("'%s' needs remounting, set remount-hook to do this automatically", config->realStoreDir.get());
|
||||
warn("%s needs remounting, set remount-hook to do this automatically", PathFmt(config->realStoreDir.get()));
|
||||
} else {
|
||||
runProgram(config->remountHook, false, {config->realStoreDir});
|
||||
runProgram(config->remountHook.get(), false, {config->realStoreDir.get().string()});
|
||||
}
|
||||
|
||||
_remountRequired = false;
|
||||
|
||||
+20
-19
@@ -119,12 +119,12 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
, LocalFSStore{*config}
|
||||
, config{config}
|
||||
, _state(make_ref<Sync<State>>())
|
||||
, dbDir(config->stateDir + "/db")
|
||||
, linksDir(config->realStoreDir + "/.links")
|
||||
, reservedPath(dbDir + "/reserved")
|
||||
, schemaPath(dbDir + "/schema")
|
||||
, tempRootsDir(config->stateDir + "/temproots")
|
||||
, fnTempRoots(fmt("%s/%d", tempRootsDir, getpid()))
|
||||
, dbDir(config->stateDir.get() / "db")
|
||||
, linksDir(config->realStoreDir.get() / ".links")
|
||||
, reservedPath(dbDir / "reserved")
|
||||
, schemaPath(dbDir / "schema")
|
||||
, tempRootsDir(config->stateDir.get() / "temproots")
|
||||
, fnTempRoots(tempRootsDir / std::to_string(getpid()))
|
||||
{
|
||||
auto state(_state->lock());
|
||||
state->stmts = std::make_unique<State::Stmts>();
|
||||
@@ -137,19 +137,19 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
makeStoreWritable();
|
||||
}
|
||||
createDirs(linksDir);
|
||||
Path profilesDir = config->stateDir + "/profiles";
|
||||
auto profilesDir = config->stateDir.get() / "profiles";
|
||||
createDirs(profilesDir);
|
||||
createDirs(tempRootsDir);
|
||||
createDirs(dbDir);
|
||||
Path gcRootsDir = config->stateDir + "/gcroots";
|
||||
auto gcRootsDir = config->stateDir.get() / "gcroots";
|
||||
const auto & localSettings = config->getLocalSettings();
|
||||
const auto & gcSettings = localSettings.getGCSettings();
|
||||
if (!pathExists(gcRootsDir)) {
|
||||
createDirs(gcRootsDir);
|
||||
replaceSymlink(profilesDir, gcRootsDir + "/profiles");
|
||||
replaceSymlink(profilesDir.string(), (gcRootsDir / "profiles").string());
|
||||
}
|
||||
|
||||
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
|
||||
for (auto & perUserDir : {profilesDir / "per-user", gcRootsDir / "per-user"}) {
|
||||
createDirs(perUserDir);
|
||||
if (!config->readOnly) {
|
||||
// Skip chmod call if the directory already has the correct permissions (0755).
|
||||
@@ -233,7 +233,7 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
/* Acquire the big fat lock in shared mode to make sure that no
|
||||
schema upgrade is in progress. */
|
||||
if (!config->readOnly) {
|
||||
Path globalLockPath = dbDir + "/big-lock";
|
||||
auto globalLockPath = dbDir / "big-lock";
|
||||
try {
|
||||
globalLock = openLockFile(globalLockPath.c_str(), true);
|
||||
} catch (SystemError & e) {
|
||||
@@ -395,7 +395,7 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
|
||||
AutoCloseFD LocalStore::openGCLock()
|
||||
{
|
||||
Path fnGCLock = config->stateDir + "/gc.lock";
|
||||
auto fnGCLock = config->stateDir.get() / "gc.lock";
|
||||
auto fdGCLock = open(
|
||||
fnGCLock.c_str(),
|
||||
O_RDWR | O_CREAT
|
||||
@@ -405,7 +405,7 @@ AutoCloseFD LocalStore::openGCLock()
|
||||
,
|
||||
0600);
|
||||
if (!fdGCLock)
|
||||
throw SysError("opening global GC lock '%1%'", fnGCLock);
|
||||
throw SysError("opening global GC lock %1%", PathFmt(fnGCLock));
|
||||
return toDescriptor(fdGCLock);
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ int LocalStore::getSchema()
|
||||
auto s = readFile(schemaPath);
|
||||
auto n = string2Int<int>(s);
|
||||
if (!n)
|
||||
throw Error("'%1%' is corrupt", schemaPath);
|
||||
throw Error("%1% is corrupt", PathFmt(schemaPath));
|
||||
curSchema = *n;
|
||||
}
|
||||
return curSchema;
|
||||
@@ -498,14 +498,14 @@ void LocalStore::openDB(State & state, bool create)
|
||||
}
|
||||
|
||||
if (access(dbDir.c_str(), R_OK | (config->readOnly ? 0 : W_OK)))
|
||||
throw SysError("Nix database directory '%1%' is not writable", dbDir);
|
||||
throw SysError("Nix database directory %1% is not writable", PathFmt(dbDir));
|
||||
|
||||
/* Open the Nix database. */
|
||||
auto & db(state.db);
|
||||
auto openMode = config->readOnly ? SQLiteOpenMode::Immutable
|
||||
: create ? SQLiteOpenMode::Normal
|
||||
: SQLiteOpenMode::NoCreate;
|
||||
state.db = SQLite(std::filesystem::path(dbDir) / "db.sqlite", {.mode = openMode, .useWAL = settings.useSQLiteWAL});
|
||||
state.db = SQLite(dbDir / "db.sqlite", {.mode = openMode, .useWAL = settings.useSQLiteWAL});
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* The cygwin version of sqlite3 has a patch which calls
|
||||
@@ -1585,14 +1585,15 @@ void LocalStore::addBuildLog(const StorePath & drvPath, std::string_view log)
|
||||
|
||||
auto baseName = drvPath.to_string();
|
||||
|
||||
auto logPath = fmt("%s/%s/%s/%s.bz2", config->logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2));
|
||||
auto logPath =
|
||||
config->logDir.get() / drvsLogDir / baseName.substr(0, 2) / (std::string(baseName.substr(2)) + ".bz2");
|
||||
|
||||
if (pathExists(logPath))
|
||||
return;
|
||||
|
||||
createDirs(dirOf(logPath));
|
||||
createDirs(std::filesystem::path(logPath).parent_path());
|
||||
|
||||
auto tmpFile = fmt("%s.tmp.%d", logPath, getpid());
|
||||
auto tmpFile = fmt("%s.tmp.%d", logPath.string(), getpid());
|
||||
|
||||
writeFile(tmpFile, compress(CompressionAlgo::bzip2, log));
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ struct NarInfoDiskCacheImpl : NarInfoDiskCache
|
||||
{
|
||||
auto state(_state.lock());
|
||||
|
||||
createDirs(dirOf(dbPath));
|
||||
createDirs(std::filesystem::path(dbPath).parent_path());
|
||||
|
||||
state->db = SQLite(dbPath, SQLite::Settings{sqliteSettings});
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||
|
||||
AutoCloseDir dir(opendir(linksDir.c_str()));
|
||||
if (!dir)
|
||||
throw SysError("opening directory '%1%'", linksDir);
|
||||
throw SysError("opening directory %1%", PathFmt(linksDir));
|
||||
|
||||
struct dirent * dirent;
|
||||
while (errno = 0, dirent = readdir(dir.get())) { /* sic */
|
||||
@@ -61,7 +61,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||
inodeHash.insert(dirent->d_ino);
|
||||
}
|
||||
if (errno)
|
||||
throw SysError("reading directory '%1%'", linksDir);
|
||||
throw SysError("reading directory %1%", PathFmt(linksDir));
|
||||
|
||||
printMsg(lvlTalkative, "loaded %1% hash inodes", inodeHash.size());
|
||||
|
||||
@@ -227,7 +227,7 @@ void LocalStore::optimisePath_(
|
||||
/* Make the containing directory writable, but only if it's not
|
||||
the store itself (we don't want or need to mess with its
|
||||
permissions). */
|
||||
const Path dirOfPath(dirOf(path));
|
||||
const Path dirOfPath(std::filesystem::path(path).parent_path());
|
||||
bool mustToggle = dirOfPath != config->realStoreDir.get();
|
||||
if (mustToggle)
|
||||
makeWritable(dirOfPath);
|
||||
@@ -305,7 +305,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
|
||||
continue; /* path was GC'ed, probably */
|
||||
{
|
||||
Activity act(*logger, lvlTalkative, actUnknown, fmt("optimising path '%s'", printStorePath(i)));
|
||||
optimisePath_(&act, stats, config->realStoreDir + "/" + std::string(i.to_string()), inodeHash, NoRepair);
|
||||
optimisePath_(&act, stats, (config->realStoreDir.get() / i.to_string()).string(), inodeHash, NoRepair);
|
||||
}
|
||||
done++;
|
||||
act.progress(done, paths.size());
|
||||
|
||||
@@ -293,8 +293,7 @@ std::string optimisticLockProfile(const std::filesystem::path & profile)
|
||||
|
||||
std::filesystem::path profilesDir(ProfileDirsOptions settings)
|
||||
{
|
||||
auto profileRoot =
|
||||
isRootUser() ? rootProfilesDir(settings) : std::filesystem::path{createNixStateDir()} / "profiles";
|
||||
auto profileRoot = isRootUser() ? rootProfilesDir(settings) : createNixStateDir() / "profiles";
|
||||
createDirs(profileRoot);
|
||||
return profileRoot;
|
||||
}
|
||||
@@ -306,9 +305,8 @@ std::filesystem::path rootProfilesDir(ProfileDirsOptions settings)
|
||||
|
||||
std::filesystem::path getDefaultProfile(ProfileDirsOptions settings)
|
||||
{
|
||||
std::filesystem::path profileLink = settings.useXDGBaseDirectories
|
||||
? std::filesystem::path{createNixStateDir()} / "profile"
|
||||
: std::filesystem::path{getHome()} / ".nix-profile";
|
||||
std::filesystem::path profileLink =
|
||||
settings.useXDGBaseDirectories ? createNixStateDir() / "profile" : getHome() / ".nix-profile";
|
||||
try {
|
||||
auto profile = profilesDir(settings) / "profile";
|
||||
if (!pathExists(profileLink)) {
|
||||
|
||||
@@ -53,7 +53,7 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor
|
||||
{
|
||||
}
|
||||
|
||||
Path getRealStoreDir() override
|
||||
std::filesystem::path getRealStoreDir() override
|
||||
{
|
||||
return next->config->realStoreDir;
|
||||
}
|
||||
|
||||
+4
-4
@@ -98,7 +98,7 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
|
||||
args.insert(args.end(), {"-i", keyFile});
|
||||
if (!sshPublicHostKey.empty()) {
|
||||
std::filesystem::path fileName = tmpDir->path() / "host-key";
|
||||
writeFile(fileName.string(), authority.host + " " + sshPublicHostKey + "\n");
|
||||
writeFile(fileName, authority.host + " " + sshPublicHostKey + "\n");
|
||||
args.insert(args.end(), {"-oUserKnownHostsFile=" + fileName.string()});
|
||||
}
|
||||
if (compress)
|
||||
@@ -150,7 +150,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(Strings && comman
|
||||
#ifdef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
throw UnimplementedError("cannot yet SSH on windows because spawning processes is not yet implemented");
|
||||
#else
|
||||
Path socketPath = startMaster();
|
||||
std::filesystem::path socketPath = startMaster();
|
||||
|
||||
Pipe in, out;
|
||||
in.create();
|
||||
@@ -228,7 +228,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(Strings && comman
|
||||
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
|
||||
Path SSHMaster::startMaster()
|
||||
std::filesystem::path SSHMaster::startMaster()
|
||||
{
|
||||
if (!useMaster)
|
||||
return "";
|
||||
@@ -238,7 +238,7 @@ Path SSHMaster::startMaster()
|
||||
if (state->sshMaster != INVALID_DESCRIPTOR)
|
||||
return state->socketPath;
|
||||
|
||||
state->socketPath = (Path) *tmpDir + "/ssh.sock";
|
||||
state->socketPath = tmpDir->path() / "ssh.sock";
|
||||
|
||||
Pipe out;
|
||||
out.create();
|
||||
|
||||
@@ -65,13 +65,13 @@ std::pair<StorePath, Path> StoreDirConfig::toStorePath(PathView path) const
|
||||
|
||||
Path Store::followLinksToStore(std::string_view _path) const
|
||||
{
|
||||
Path path = absPath(std::string(_path));
|
||||
auto path = absPath(std::string(_path));
|
||||
|
||||
// Limit symlink follows to prevent infinite loops
|
||||
unsigned int followCount = 0;
|
||||
const unsigned int maxFollow = 1024;
|
||||
|
||||
while (!isInStore(path)) {
|
||||
while (!isInStore(path.string())) {
|
||||
if (!std::filesystem::is_symlink(path))
|
||||
break;
|
||||
|
||||
@@ -79,12 +79,13 @@ Path Store::followLinksToStore(std::string_view _path) const
|
||||
throw Error("too many symbolic links encountered while resolving '%s'", _path);
|
||||
|
||||
auto target = readLink(path);
|
||||
path = absPath(target, dirOf(path));
|
||||
auto parentPath = path.parent_path();
|
||||
path = absPath(target, &parentPath);
|
||||
}
|
||||
|
||||
if (!isInStore(path))
|
||||
throw BadStorePath("path '%1%' is not in the Nix store", path);
|
||||
return path;
|
||||
if (!isInStore(path.string()))
|
||||
throw BadStorePath("path %1% is not in the Nix store", PathFmt(path));
|
||||
return path.string();
|
||||
}
|
||||
|
||||
StorePath Store::followLinksToStorePath(std::string_view path) const
|
||||
|
||||
@@ -20,9 +20,9 @@ StorePath StoreDirConfig::parseStorePath(std::string_view path) const
|
||||
canonPath(std::string(path))
|
||||
#endif
|
||||
;
|
||||
if (dirOf(p) != storeDir)
|
||||
throw BadStorePath("path '%s' is not in the Nix store", p);
|
||||
return StorePath(baseNameOf(p));
|
||||
if (p.parent_path() != storeDir)
|
||||
throw BadStorePath("path %s is not in the Nix store", PathFmt(p));
|
||||
return StorePath(p.filename().string());
|
||||
}
|
||||
|
||||
std::optional<StorePath> StoreDirConfig::maybeParseStorePath(std::string_view path) const
|
||||
|
||||
@@ -42,17 +42,18 @@ ref<StoreConfig> resolveStoreConfig(StoreReference && storeURI)
|
||||
/* If /nix doesn't exist, there is no daemon socket, and
|
||||
we're not root, then automatically set up a chroot
|
||||
store in ~/.local/share/nix/root. */
|
||||
auto chrootStore = getDataDir() + "/root";
|
||||
auto chrootStore = getDataDir() / "root";
|
||||
if (!pathExists(chrootStore)) {
|
||||
try {
|
||||
createDirs(chrootStore);
|
||||
} catch (SystemError & e) {
|
||||
return make_ref<LocalStore::Config>(params);
|
||||
}
|
||||
warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
||||
warn("%s does not exist, so Nix will use %s as a chroot store", stateDir, PathFmt(chrootStore));
|
||||
} else
|
||||
debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
|
||||
return make_ref<LocalStore::Config>("local", chrootStore, params);
|
||||
debug(
|
||||
"%s does not exist, so Nix will use %s as a chroot store", stateDir, PathFmt(chrootStore));
|
||||
return make_ref<LocalStore::Config>("local", chrootStore.string(), params);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
||||
@@ -475,7 +475,7 @@ private:
|
||||
};
|
||||
|
||||
static void handleDiffHook(
|
||||
const Path & diffHook,
|
||||
const std::filesystem::path & diffHook,
|
||||
uid_t uid,
|
||||
uid_t gid,
|
||||
const std::filesystem::path & tryA,
|
||||
|
||||
@@ -60,9 +60,10 @@ TEST(absPath, usesOptionalBasePathWhenGiven)
|
||||
OsChar _cwd[PATH_MAX + 1];
|
||||
OsChar * cwd = GET_CWD((OsChar *) &_cwd, PATH_MAX);
|
||||
|
||||
auto p = absPath(std::filesystem::path{""}.string(), std::filesystem::path{cwd}.string());
|
||||
auto cwdPath = std::filesystem::path{cwd};
|
||||
auto p = absPath(std::filesystem::path{""}.string(), &cwdPath);
|
||||
|
||||
ASSERT_EQ(p, std::filesystem::path{cwd}.string());
|
||||
ASSERT_EQ(p, cwdPath.string());
|
||||
}
|
||||
|
||||
TEST(absPath, isIdempotent)
|
||||
@@ -121,29 +122,6 @@ TEST(canonPath, requiresAbsolutePath)
|
||||
ASSERT_DEATH({ canonPath(""sv); }, "path != \"\"");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* dirOf
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(dirOf, returnsEmptyStringForRoot)
|
||||
{
|
||||
auto p = dirOf("/");
|
||||
|
||||
ASSERT_EQ(p, "/");
|
||||
}
|
||||
|
||||
TEST(dirOf, returnsFirstPathComponent)
|
||||
{
|
||||
auto p1 = dirOf("/dir/");
|
||||
ASSERT_EQ(p1, "/dir");
|
||||
auto p2 = dirOf("/dir");
|
||||
ASSERT_EQ(p2, "/");
|
||||
auto p3 = dirOf("/dir/..");
|
||||
ASSERT_EQ(p3, "/dir");
|
||||
auto p4 = dirOf("/dir/../");
|
||||
ASSERT_EQ(p4, "/dir/..");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* baseNameOf
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
@@ -32,7 +32,7 @@ static ArchiveSettings archiveSettings;
|
||||
|
||||
static GlobalConfig::Register rArchiveSettings(&archiveSettings);
|
||||
|
||||
PathFilter defaultPathFilter = [](const Path &) { return true; };
|
||||
PathFilter defaultPathFilter = [](const std::string &) { return true; };
|
||||
|
||||
void SourceAccessor::dumpPath(const CanonPath & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
@@ -101,14 +101,14 @@ void SourceAccessor::dumpPath(const CanonPath & path, Sink & sink, PathFilter &
|
||||
}(path);
|
||||
}
|
||||
|
||||
time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter)
|
||||
time_t dumpPathAndGetMtime(const std::filesystem::path & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
auto path2 = PosixSourceAccessor::createAtRoot(path, /*trackLastModified=*/true);
|
||||
path2.dumpPath(sink, filter);
|
||||
return path2.accessor->getLastModified().value();
|
||||
}
|
||||
|
||||
void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
|
||||
void dumpPath(const std::filesystem::path & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
dumpPathAndGetMtime(path, sink, filter);
|
||||
}
|
||||
@@ -201,7 +201,7 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath
|
||||
|
||||
else if (type == "directory") {
|
||||
sink.createDirectory(path, [&](FileSystemObjectSink & dirSink, const CanonPath & relDirPath) {
|
||||
std::map<Path, int, CaseInsensitiveCompare> names;
|
||||
std::map<std::string, int, CaseInsensitiveCompare> names;
|
||||
|
||||
std::string prevName;
|
||||
|
||||
|
||||
+3
-3
@@ -284,7 +284,7 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang)
|
||||
// executable file, and it starts with "#!".
|
||||
Strings savedArgs;
|
||||
if (allowShebang) {
|
||||
auto script = *cmdline.begin();
|
||||
std::filesystem::path script = *cmdline.begin();
|
||||
try {
|
||||
std::ifstream stream(script);
|
||||
char shebang[3] = {0, 0, 0};
|
||||
@@ -310,8 +310,8 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang)
|
||||
for (const auto & word : parseShebangContent(shebangContent)) {
|
||||
cmdline.push_back(word);
|
||||
}
|
||||
cmdline.push_back(script);
|
||||
commandBaseDir = dirOf(script);
|
||||
cmdline.push_back(script.string());
|
||||
commandBaseDir = script.parent_path();
|
||||
for (auto pos = savedArgs.begin(); pos != savedArgs.end(); pos++)
|
||||
cmdline.push_back(*pos);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ void Config::getSettings(std::map<std::string, SettingInfo> & res, bool overridd
|
||||
*/
|
||||
static void parseConfigFiles(
|
||||
const std::string & contents,
|
||||
const std::string & path,
|
||||
const std::filesystem::path & path,
|
||||
std::vector<std::pair<std::string, std::string>> & parsedContents)
|
||||
{
|
||||
unsigned int pos = 0;
|
||||
@@ -122,7 +122,7 @@ static void parseConfigFiles(
|
||||
continue;
|
||||
|
||||
if (tokens.size() < 2)
|
||||
throw UsageError("syntax error in configuration line '%1%' in '%2%'", line, path);
|
||||
throw UsageError("syntax error in configuration line '%1%' in %s", line, PathFmt(path));
|
||||
|
||||
auto include = false;
|
||||
auto ignoreMissing = false;
|
||||
@@ -135,8 +135,9 @@ static void parseConfigFiles(
|
||||
|
||||
if (include) {
|
||||
if (tokens.size() != 2)
|
||||
throw UsageError("syntax error in configuration line '%1%' in '%2%'", line, path);
|
||||
auto p = absPath(tokens[1], dirOf(path));
|
||||
throw UsageError("syntax error in configuration line '%1%' in %s", line, PathFmt(path));
|
||||
auto parent = path.parent_path();
|
||||
auto p = absPath(std::filesystem::path{tokens[1]}, &parent);
|
||||
if (pathExists(p)) {
|
||||
try {
|
||||
std::string includedContents = readFile(p);
|
||||
@@ -145,13 +146,13 @@ static void parseConfigFiles(
|
||||
// TODO: Do we actually want to ignore this? Or is it better to fail?
|
||||
}
|
||||
} else if (!ignoreMissing) {
|
||||
throw Error("file '%1%' included from '%2%' not found", p, path);
|
||||
throw Error("file %s included from %s not found", PathFmt(p), PathFmt(path));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tokens[1] != "=")
|
||||
throw UsageError("syntax error in configuration line '%1%' in '%2%'", line, path);
|
||||
throw UsageError("syntax error in configuration line '%1%' in %s", line, PathFmt(path));
|
||||
|
||||
std::string name = std::move(tokens[0]);
|
||||
|
||||
@@ -456,7 +457,7 @@ std::string BaseSetting<StringMap>::to_string() const
|
||||
[](const auto & kvpair) { return kvpair.first + "=" + kvpair.second; });
|
||||
}
|
||||
|
||||
static Path parsePath(const AbstractSetting & s, const std::string & str)
|
||||
static std::filesystem::path parsePath(const AbstractSetting & s, const std::string & str)
|
||||
{
|
||||
if (str == "")
|
||||
throw UsageError("setting '%s' is a path and paths cannot be empty", s.name);
|
||||
@@ -522,7 +523,7 @@ PathSetting::PathSetting(
|
||||
|
||||
Path PathSetting::parse(const std::string & str) const
|
||||
{
|
||||
return parsePath(*this, str);
|
||||
return parsePath(*this, str).string();
|
||||
}
|
||||
|
||||
OptionalPathSetting::OptionalPathSetting(
|
||||
@@ -541,7 +542,7 @@ std::optional<Path> OptionalPathSetting::parse(const std::string & str) const
|
||||
if (str == "")
|
||||
return std::nullopt;
|
||||
else
|
||||
return parsePath(*this, str);
|
||||
return parsePath(*this, str).string();
|
||||
}
|
||||
|
||||
void OptionalPathSetting::operator=(const std::optional<Path> & v)
|
||||
|
||||
@@ -120,9 +120,9 @@ void restoreProcessContext(bool restoreMounts)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::optional<Path> getSelfExe()
|
||||
std::optional<std::filesystem::path> getSelfExe()
|
||||
{
|
||||
static auto cached = []() -> std::optional<Path> {
|
||||
static auto cached = []() -> std::optional<std::filesystem::path> {
|
||||
#if defined(__linux__) || defined(__GNU__)
|
||||
return readLink(std::filesystem::path{"/proc/self/exe"});
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
@@ -20,17 +20,23 @@ ExecutablePath ExecutablePath::load()
|
||||
}
|
||||
|
||||
ExecutablePath ExecutablePath::parse(const OsString & path)
|
||||
{
|
||||
ExecutablePath ret;
|
||||
ret.parseAppend(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ExecutablePath::parseAppend(const OsString & path)
|
||||
{
|
||||
auto strings = path.empty() ? (std::list<OsString>{})
|
||||
: basicSplitString<std::list<OsString>, OsChar>(path, path_var_separator);
|
||||
|
||||
std::vector<std::filesystem::path> ret;
|
||||
ret.reserve(strings.size());
|
||||
directories.reserve(directories.size() + strings.size());
|
||||
|
||||
std::transform(
|
||||
std::make_move_iterator(strings.begin()),
|
||||
std::make_move_iterator(strings.end()),
|
||||
std::back_inserter(ret),
|
||||
std::back_inserter(directories),
|
||||
[](OsString && str) {
|
||||
return std::filesystem::path{
|
||||
str.empty()
|
||||
@@ -45,13 +51,11 @@ ExecutablePath ExecutablePath::parse(const OsString & path)
|
||||
: std::move(str),
|
||||
};
|
||||
});
|
||||
|
||||
return {ret};
|
||||
}
|
||||
|
||||
OsString ExecutablePath::render() const
|
||||
{
|
||||
std::vector<PathViewNG> path2;
|
||||
std::vector<PathView> path2;
|
||||
path2.reserve(directories.size());
|
||||
for (auto & p : directories)
|
||||
path2.push_back(p.native());
|
||||
|
||||
@@ -75,7 +75,7 @@ void dumpPath(const SourcePath & path, Sink & sink, FileSerialisationMethod meth
|
||||
}
|
||||
}
|
||||
|
||||
void restorePath(const Path & path, Source & source, FileSerialisationMethod method, bool startFsync)
|
||||
void restorePath(const std::filesystem::path & path, Source & source, FileSerialisationMethod method, bool startFsync)
|
||||
{
|
||||
switch (method) {
|
||||
case FileSerialisationMethod::Flat:
|
||||
|
||||
+63
-94
@@ -64,21 +64,14 @@ DirectoryIterator & DirectoryIterator::operator++()
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isAbsolute(PathView path)
|
||||
std::filesystem::path
|
||||
absPath(const std::filesystem::path & path0, const std::filesystem::path * dir, bool resolveSymlinks)
|
||||
{
|
||||
return std::filesystem::path{path}.is_absolute();
|
||||
}
|
||||
std::filesystem::path path = path0;
|
||||
|
||||
Path absPath(PathView path, std::optional<PathView> dir, bool resolveSymlinks)
|
||||
{
|
||||
std::string scratch;
|
||||
|
||||
if (!isAbsolute(path)) {
|
||||
if (!path.is_absolute()) {
|
||||
// In this case we need to call `canonPath` on a newly-created
|
||||
// string. We set `scratch` to that string first, and then set
|
||||
// `path` to `scratch`. This ensures the newly-created string
|
||||
// lives long enough for the call to `canonPath`, and allows us
|
||||
// to just accept a `std::string_view`.
|
||||
// string.
|
||||
if (!dir) {
|
||||
#ifdef __GNU__
|
||||
/* GNU (aka. GNU/Hurd) doesn't have any limitation on path
|
||||
@@ -90,30 +83,22 @@ Path absPath(PathView path, std::optional<PathView> dir, bool resolveSymlinks)
|
||||
if (!getcwd(buf, sizeof(buf)))
|
||||
#endif
|
||||
throw SysError("cannot get cwd");
|
||||
scratch = concatStrings(buf, "/", path);
|
||||
path = std::filesystem::path{buf} / path;
|
||||
#ifdef __GNU__
|
||||
free(buf);
|
||||
#endif
|
||||
} else
|
||||
scratch = concatStrings(*dir, "/", path);
|
||||
path = scratch;
|
||||
path = *dir / path;
|
||||
}
|
||||
return canonPath(path, resolveSymlinks);
|
||||
}
|
||||
|
||||
std::filesystem::path
|
||||
absPath(const std::filesystem::path & path, const std::filesystem::path * dir_, bool resolveSymlinks)
|
||||
std::filesystem::path canonPath(const std::filesystem::path & path, bool resolveSymlinks)
|
||||
{
|
||||
std::optional<std::string> dir = dir_ ? std::optional<std::string>{dir_->string()} : std::nullopt;
|
||||
return absPath(PathView{path.string()}, dir.transform([](auto & p) { return PathView(p); }), resolveSymlinks);
|
||||
}
|
||||
assert(!path.empty());
|
||||
|
||||
Path canonPath(PathView path, bool resolveSymlinks)
|
||||
{
|
||||
assert(path != "");
|
||||
|
||||
if (!isAbsolute(path))
|
||||
throw Error("not an absolute path: '%1%'", path);
|
||||
if (!path.is_absolute())
|
||||
throw Error("not an absolute path: %s", PathFmt(path));
|
||||
|
||||
/* This just exists because we cannot set the target of `remaining`
|
||||
(the callback parameter) directly to a newly-constructed string,
|
||||
@@ -125,18 +110,19 @@ Path canonPath(PathView path, bool resolveSymlinks)
|
||||
unsigned int followCount = 0, maxFollow = 1024;
|
||||
|
||||
auto ret = canonPathInner<OsPathTrait<char>>(
|
||||
path, [&followCount, &temp, maxFollow, resolveSymlinks](std::string & result, std::string_view & remaining) {
|
||||
path.string(),
|
||||
[&followCount, &temp, maxFollow, resolveSymlinks](std::string & result, std::string_view & remaining) {
|
||||
if (resolveSymlinks && std::filesystem::is_symlink(result)) {
|
||||
if (++followCount >= maxFollow)
|
||||
throw Error("infinite symlink recursion in path '%1%'", remaining);
|
||||
remaining = (temp = concatStrings(readLink(result), remaining));
|
||||
if (isAbsolute(remaining)) {
|
||||
remaining = (temp = concatStrings(readLink(result).string(), remaining));
|
||||
if (std::filesystem::path(remaining).is_absolute()) {
|
||||
/* restart for symlinks pointing to absolute path */
|
||||
result.clear();
|
||||
} else {
|
||||
result = dirOf(result);
|
||||
result = std::filesystem::path(result).parent_path().string();
|
||||
if (result == "/") {
|
||||
/* we don’t want trailing slashes here, which `dirOf`
|
||||
/* we don't want trailing slashes here, which `dirOf`
|
||||
only produces if `result = /` */
|
||||
result.clear();
|
||||
}
|
||||
@@ -147,19 +133,6 @@ Path canonPath(PathView path, bool resolveSymlinks)
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::filesystem::path canonPath(const std::filesystem::path & path, bool resolveSymlinks)
|
||||
{
|
||||
return {canonPath(path.string(), resolveSymlinks)};
|
||||
}
|
||||
|
||||
Path dirOf(const PathView path)
|
||||
{
|
||||
Path::size_type pos = OsPathTrait<char>::rfindPathSep(path);
|
||||
if (pos == path.npos)
|
||||
return ".";
|
||||
return std::filesystem::path{path}.parent_path().string();
|
||||
}
|
||||
|
||||
std::string_view baseNameOf(std::string_view path)
|
||||
{
|
||||
if (path.empty())
|
||||
@@ -262,13 +235,13 @@ std::optional<PosixStat> maybeLstat(const std::filesystem::path & path)
|
||||
|
||||
bool pathExists(const std::filesystem::path & path)
|
||||
{
|
||||
return maybeLstat(path.string()).has_value();
|
||||
return maybeLstat(path).has_value();
|
||||
}
|
||||
|
||||
bool pathAccessible(const std::filesystem::path & path)
|
||||
{
|
||||
try {
|
||||
return pathExists(path.string());
|
||||
return pathExists(path);
|
||||
} catch (SystemError & e) {
|
||||
// swallow EPERM
|
||||
if (e.is(std::errc::operation_not_permitted))
|
||||
@@ -283,16 +256,6 @@ std::filesystem::path readLink(const std::filesystem::path & path)
|
||||
return std::filesystem::read_symlink(path);
|
||||
}
|
||||
|
||||
Path readLink(const Path & path)
|
||||
{
|
||||
return readLink(std::filesystem::path{path}).string();
|
||||
}
|
||||
|
||||
std::string readFile(const Path & path)
|
||||
{
|
||||
return readFile(std::filesystem::path(path));
|
||||
}
|
||||
|
||||
std::string readFile(const std::filesystem::path & path)
|
||||
{
|
||||
AutoCloseFD fd = openFileReadonly(path);
|
||||
@@ -301,32 +264,32 @@ std::string readFile(const std::filesystem::path & path)
|
||||
return readFile(fd.get());
|
||||
}
|
||||
|
||||
void readFile(const Path & path, Sink & sink, bool memory_map)
|
||||
void readFile(const std::filesystem::path & path, Sink & sink, bool memory_map)
|
||||
{
|
||||
// Memory-map the file for faster processing where possible.
|
||||
if (memory_map) {
|
||||
try {
|
||||
boost::iostreams::mapped_file_source mmap(path);
|
||||
boost::iostreams::mapped_file_source mmap(path.string());
|
||||
if (mmap.is_open()) {
|
||||
sink({mmap.data(), mmap.size()});
|
||||
return;
|
||||
}
|
||||
} catch (const boost::exception & e) {
|
||||
}
|
||||
debug("memory-mapping failed for path: %s", path);
|
||||
debug("memory-mapping failed for path: %s", PathFmt(path));
|
||||
}
|
||||
|
||||
// Stream the file instead if memory-mapping fails or is disabled.
|
||||
AutoCloseFD fd = openFileReadonly(std::filesystem::path(path));
|
||||
if (!fd)
|
||||
throw NativeSysError("opening file %s", path);
|
||||
throw NativeSysError("opening file %s", PathFmt(path));
|
||||
drainFD(fd.get(), sink);
|
||||
}
|
||||
|
||||
void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(
|
||||
path.c_str(),
|
||||
path.string().c_str(),
|
||||
O_WRONLY | O_TRUNC | O_CREAT
|
||||
#ifdef O_CLOEXEC
|
||||
| O_CLOEXEC
|
||||
@@ -334,15 +297,15 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
,
|
||||
mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
throw SysError("opening file %s", PathFmt(path));
|
||||
|
||||
writeFile(fd, path, s, mode, sync);
|
||||
writeFile(fd, path.string(), s, mode, sync);
|
||||
|
||||
/* Close explicitly to propagate the exceptions. */
|
||||
fd.close();
|
||||
}
|
||||
|
||||
void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
void writeFile(AutoCloseFD & fd, const std::filesystem::path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
assert(fd);
|
||||
try {
|
||||
@@ -352,15 +315,15 @@ void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode
|
||||
fd.fsync();
|
||||
|
||||
} catch (Error & e) {
|
||||
e.addTrace({}, "writing file '%1%'", origPath);
|
||||
e.addTrace({}, "writing file %s", PathFmt(origPath));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
void writeFile(const std::filesystem::path & path, Source & source, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(
|
||||
path.c_str(),
|
||||
path.string().c_str(),
|
||||
O_WRONLY | O_TRUNC | O_CREAT
|
||||
#ifdef O_CLOEXEC
|
||||
| O_CLOEXEC
|
||||
@@ -368,7 +331,7 @@ void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
,
|
||||
mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
throw SysError("opening file %s", PathFmt(path));
|
||||
|
||||
std::array<char, 64 * 1024> buf;
|
||||
|
||||
@@ -382,7 +345,7 @@ void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
}
|
||||
}
|
||||
} catch (Error & e) {
|
||||
e.addTrace({}, "writing file '%1%'", path);
|
||||
e.addTrace({}, "writing file %s", PathFmt(path));
|
||||
throw;
|
||||
}
|
||||
if (sync == FsSync::Yes)
|
||||
@@ -393,22 +356,22 @@ void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
syncParent(path);
|
||||
}
|
||||
|
||||
void syncParent(const Path & path)
|
||||
void syncParent(const std::filesystem::path & path)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(dirOf(path).c_str(), O_RDONLY, 0));
|
||||
AutoCloseFD fd = toDescriptor(open(path.parent_path().c_str(), O_RDONLY, 0));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
throw SysError("opening file %s", PathFmt(path));
|
||||
fd.fsync();
|
||||
}
|
||||
|
||||
void recursiveSync(const Path & path)
|
||||
void recursiveSync(const std::filesystem::path & path)
|
||||
{
|
||||
/* If it's a file or symlink, just fsync and return. */
|
||||
auto st = lstat(path);
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY, 0));
|
||||
AutoCloseFD fd = toDescriptor(open(path.string().c_str(), O_RDONLY, 0));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
throw SysError("opening file %s", PathFmt(path));
|
||||
fd.fsync();
|
||||
return;
|
||||
} else if (S_ISLNK(st.st_mode))
|
||||
@@ -445,17 +408,17 @@ void recursiveSync(const Path & path)
|
||||
}
|
||||
}
|
||||
|
||||
void createDir(const Path & path, mode_t mode)
|
||||
void createDir(const std::filesystem::path & path, mode_t mode)
|
||||
{
|
||||
if (mkdir(
|
||||
path.c_str()
|
||||
path.string().c_str()
|
||||
#ifndef _WIN32
|
||||
,
|
||||
mode
|
||||
#endif
|
||||
)
|
||||
== -1)
|
||||
throw SysError("creating directory '%1%'", path);
|
||||
throw SysError("creating directory '%s'", PathFmt(path));
|
||||
}
|
||||
|
||||
void createDirs(const std::filesystem::path & path)
|
||||
@@ -615,7 +578,7 @@ AutoCloseFD createAnonymousTempFile()
|
||||
# endif
|
||||
auto [fd2, path] = createTempFile("nix-anonymous");
|
||||
if (!fd2)
|
||||
throw SysError("creating temporary file '%s'", path);
|
||||
throw SysError("creating temporary file %s", PathFmt(path));
|
||||
fd = std::move(fd2);
|
||||
unlink(requireCString(path)); /* We only care about the file descriptor. */
|
||||
#endif
|
||||
@@ -623,14 +586,21 @@ AutoCloseFD createAnonymousTempFile()
|
||||
return fd;
|
||||
}
|
||||
|
||||
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
|
||||
std::pair<AutoCloseFD, std::filesystem::path> createTempFile(const std::filesystem::path & prefix)
|
||||
{
|
||||
Path tmpl(defaultTempDir().string() + "/" + prefix + ".XXXXXX");
|
||||
std::filesystem::path tmpl(defaultTempDir() / (prefix.string() + ".XXXXXX"));
|
||||
// Strictly speaking, this is UB, but who cares...
|
||||
// FIXME: use O_TMPFILE.
|
||||
AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str()));
|
||||
AutoCloseFD fd = toDescriptor(
|
||||
#ifdef _WIN32
|
||||
_wmkstemp(tmpl.c_str())
|
||||
#else
|
||||
mkstemp(const_cast<char *>(tmpl.c_str()))
|
||||
#endif
|
||||
);
|
||||
|
||||
if (!fd)
|
||||
throw SysError("creating temporary file '%s'", tmpl);
|
||||
throw SysError("creating temporary file %s", PathFmt(tmpl));
|
||||
#ifndef _WIN32
|
||||
unix::closeOnExec(fd.get());
|
||||
#endif
|
||||
@@ -642,15 +612,15 @@ std::filesystem::path makeTempPath(const std::filesystem::path & root, const std
|
||||
// start the counter at a random value to minimize issues with preexisting temp paths
|
||||
static std::atomic<uint32_t> counter(std::random_device{}());
|
||||
auto tmpRoot = canonPath(root.empty() ? defaultTempDir().string() : root.string(), true);
|
||||
return fmt("%1%/%2%-%3%-%4%", tmpRoot, suffix, getpid(), counter.fetch_add(1, std::memory_order_relaxed));
|
||||
return tmpRoot / fmt("%2%-%3%-%4%", suffix, getpid(), counter.fetch_add(1, std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void createSymlink(const Path & target, const Path & link)
|
||||
void createSymlink(const std::filesystem::path & target, const std::filesystem::path & link)
|
||||
{
|
||||
std::error_code ec;
|
||||
std::filesystem::create_symlink(target, link, ec);
|
||||
if (ec)
|
||||
throw SysError(ec.value(), "creating symlink '%1%' -> '%2%'", link, target);
|
||||
throw SysError(ec.value(), "creating symlink %s -> %s", PathFmt(link), PathFmt(target));
|
||||
}
|
||||
|
||||
void replaceSymlink(const std::filesystem::path & target, const std::filesystem::path & link)
|
||||
@@ -708,7 +678,7 @@ void copyFile(const std::filesystem::path & from, const std::filesystem::path &
|
||||
throw Error("file %s has an unsupported type", PathFmt(from));
|
||||
}
|
||||
|
||||
setWriteTime(to, lstat(from.string().c_str()));
|
||||
setWriteTime(to, lstat(from));
|
||||
if (andDelete) {
|
||||
if (!std::filesystem::is_symlink(fromStatus))
|
||||
std::filesystem::permissions(
|
||||
@@ -719,13 +689,13 @@ void copyFile(const std::filesystem::path & from, const std::filesystem::path &
|
||||
}
|
||||
}
|
||||
|
||||
void moveFile(const Path & oldName, const Path & newName)
|
||||
void moveFile(const std::filesystem::path & oldName, const std::filesystem::path & newName)
|
||||
{
|
||||
try {
|
||||
std::filesystem::rename(oldName, newName);
|
||||
} catch (std::filesystem::filesystem_error & e) {
|
||||
auto oldPath = std::filesystem::path(oldName);
|
||||
auto newPath = std::filesystem::path(newName);
|
||||
auto oldPath = oldName;
|
||||
auto newPath = newName;
|
||||
// For the move to be as atomic as possible, copy to a temporary
|
||||
// directory
|
||||
std::filesystem::path temp =
|
||||
@@ -734,7 +704,7 @@ void moveFile(const Path & oldName, const Path & newName)
|
||||
auto tempCopyTarget = temp / "copy-target";
|
||||
if (e.code().value() == EXDEV) {
|
||||
std::filesystem::remove(newPath);
|
||||
warn("can’t rename %s as %s, copying instead", oldName, newName);
|
||||
warn("can't rename %s as %s, copying instead", PathFmt(oldName), PathFmt(newName));
|
||||
copyFile(oldPath, tempCopyTarget, true);
|
||||
std::filesystem::rename(
|
||||
os_string_to_string(PathViewNG{tempCopyTarget}), os_string_to_string(PathViewNG{newPath}));
|
||||
@@ -792,8 +762,7 @@ void chmod(const std::filesystem::path & path, mode_t mode)
|
||||
|
||||
bool chmodIfNeeded(const std::filesystem::path & path, mode_t mode, mode_t mask)
|
||||
{
|
||||
auto pathString = path.string();
|
||||
auto prevMode = lstat(pathString).st_mode;
|
||||
auto prevMode = lstat(path).st_mode;
|
||||
|
||||
if (((prevMode ^ mode) & mask) == 0)
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -369,7 +369,7 @@ Hash hashString(HashAlgorithm ha, std::string_view s, const ExperimentalFeatureS
|
||||
return hash;
|
||||
}
|
||||
|
||||
Hash hashFile(HashAlgorithm ha, const Path & path)
|
||||
Hash hashFile(HashAlgorithm ha, const std::filesystem::path & path)
|
||||
{
|
||||
HashSink sink(ha);
|
||||
readFile(path, sink);
|
||||
|
||||
@@ -55,12 +55,12 @@ namespace nix {
|
||||
* `+` denotes string concatenation.
|
||||
* ```
|
||||
*/
|
||||
void dumpPath(const Path & path, Sink & sink, PathFilter & filter = defaultPathFilter);
|
||||
void dumpPath(const std::filesystem::path & path, Sink & sink, PathFilter & filter = defaultPathFilter);
|
||||
|
||||
/**
|
||||
* Same as dumpPath(), but returns the last modified date of the path.
|
||||
*/
|
||||
time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter = defaultPathFilter);
|
||||
time_t dumpPathAndGetMtime(const std::filesystem::path & path, Sink & sink, PathFilter & filter = defaultPathFilter);
|
||||
|
||||
/**
|
||||
* Dump an archive with a single file with these contents.
|
||||
|
||||
@@ -134,6 +134,7 @@ DECLARE_CONFIG_SERIALISER(bool)
|
||||
DECLARE_CONFIG_SERIALISER(Strings)
|
||||
DECLARE_CONFIG_SERIALISER(StringSet)
|
||||
DECLARE_CONFIG_SERIALISER(StringMap)
|
||||
DECLARE_CONFIG_SERIALISER(std::filesystem::path)
|
||||
DECLARE_CONFIG_SERIALISER(std::set<ExperimentalFeature>)
|
||||
DECLARE_CONFIG_SERIALISER(std::filesystem::path)
|
||||
DECLARE_CONFIG_SERIALISER(std::optional<std::filesystem::path>)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
///@file
|
||||
|
||||
#include <cassert>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
||||
@@ -42,6 +42,6 @@ void restoreProcessContext(bool restoreMounts = true);
|
||||
/**
|
||||
* @return the path of the current executable.
|
||||
*/
|
||||
std::optional<Path> getSelfExe();
|
||||
std::optional<std::filesystem::path> getSelfExe();
|
||||
|
||||
} // namespace nix
|
||||
@@ -33,6 +33,12 @@ struct ExecutablePath
|
||||
*/
|
||||
static ExecutablePath parse(const OsString & path);
|
||||
|
||||
/**
|
||||
* Like `parse` but appends new entries to the end of an existing
|
||||
* `ExecutablePath`.
|
||||
*/
|
||||
void parseAppend(const OsString & path);
|
||||
|
||||
/**
|
||||
* Load the `PATH` environment variable and `parse` it.
|
||||
*/
|
||||
|
||||
@@ -64,7 +64,8 @@ void dumpPath(
|
||||
*
|
||||
* \todo use an arbitrary `FileSystemObjectSink`.
|
||||
*/
|
||||
void restorePath(const Path & path, Source & source, FileSerialisationMethod method, bool startFsync = false);
|
||||
void restorePath(
|
||||
const std::filesystem::path & path, Source & source, FileSerialisationMethod method, bool startFsync = false);
|
||||
|
||||
/**
|
||||
* Compute the hash of the given file system object according to the
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "nix/util/file-descriptor.hh"
|
||||
#include "nix/util/file-path.hh"
|
||||
|
||||
#include <filesystem>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
@@ -37,11 +38,6 @@ namespace nix {
|
||||
struct Sink;
|
||||
struct Source;
|
||||
|
||||
/**
|
||||
* Return whether the path denotes an absolute path.
|
||||
*/
|
||||
bool isAbsolute(PathView path);
|
||||
|
||||
/**
|
||||
* @return An absolutized path, resolving paths relative to the
|
||||
* specified directory, or the current directory otherwise. The path
|
||||
@@ -49,13 +45,6 @@ bool isAbsolute(PathView path);
|
||||
*
|
||||
* In the process of being deprecated for `std::filesystem::absolute`.
|
||||
*/
|
||||
Path absPath(PathView path, std::optional<PathView> dir = {}, bool resolveSymlinks = false);
|
||||
|
||||
inline Path absPath(const Path & path, std::optional<PathView> dir = {}, bool resolveSymlinks = false)
|
||||
{
|
||||
return absPath(PathView{path}, dir, resolveSymlinks);
|
||||
}
|
||||
|
||||
std::filesystem::path
|
||||
absPath(const std::filesystem::path & path, const std::filesystem::path * dir = nullptr, bool resolveSymlinks = false);
|
||||
|
||||
@@ -70,26 +59,8 @@ absPath(const std::filesystem::path & path, const std::filesystem::path * dir =
|
||||
* false` case), and `std::filesystem::weakly_canonical` (for the
|
||||
* `resolveSymlinks = true` case).
|
||||
*/
|
||||
Path canonPath(PathView path, bool resolveSymlinks = false);
|
||||
|
||||
static inline Path canonPath(const Path & path, bool resolveSymlinks = false)
|
||||
{
|
||||
return canonPath(PathView{path}, resolveSymlinks);
|
||||
}
|
||||
|
||||
std::filesystem::path canonPath(const std::filesystem::path & path, bool resolveSymlinks = false);
|
||||
|
||||
/**
|
||||
* @return The directory part of the given canonical path, i.e.,
|
||||
* everything before the final `/`. If the path is the root or an
|
||||
* immediate child thereof (e.g., `/foo`), this means `/`
|
||||
* is returned.
|
||||
*
|
||||
* In the process of being deprecated for
|
||||
* `std::filesystem::path::parent_path`.
|
||||
*/
|
||||
Path dirOf(const PathView path);
|
||||
|
||||
/**
|
||||
* @return the base name of the given canonical path, i.e., everything
|
||||
* following the final `/` (trailing slashes are removed).
|
||||
@@ -171,15 +142,6 @@ std::filesystem::path makeParentCanonical(const std::filesystem::path & path);
|
||||
*/
|
||||
bool pathAccessible(const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* Read the contents (target) of a symbolic link. The result is not
|
||||
* in any way canonicalised.
|
||||
*
|
||||
* In the process of being deprecated for
|
||||
* `std::filesystem::read_symlink`.
|
||||
*/
|
||||
Path readLink(const Path & path);
|
||||
|
||||
/**
|
||||
* Read the contents (target) of a symbolic link. The result is not
|
||||
* in any way canonicalised.
|
||||
@@ -240,43 +202,34 @@ Descriptor openNewFileForWrite(const std::filesystem::path & path, mode_t mode,
|
||||
/**
|
||||
* Read the contents of a file into a string.
|
||||
*/
|
||||
std::string readFile(const Path & path);
|
||||
std::string readFile(const std::filesystem::path & path);
|
||||
void readFile(const Path & path, Sink & sink, bool memory_map = true);
|
||||
void readFile(const std::filesystem::path & path, Sink & sink, bool memory_map = true);
|
||||
|
||||
enum struct FsSync { Yes, No };
|
||||
|
||||
/**
|
||||
* Write a string to a file.
|
||||
*/
|
||||
void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
|
||||
static inline void
|
||||
writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), s, mode, sync);
|
||||
}
|
||||
|
||||
void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
|
||||
static inline void
|
||||
writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), source, mode, sync);
|
||||
}
|
||||
void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
|
||||
void writeFile(
|
||||
AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
AutoCloseFD & fd,
|
||||
const std::filesystem::path & origPath,
|
||||
std::string_view s,
|
||||
mode_t mode = 0666,
|
||||
FsSync sync = FsSync::No);
|
||||
|
||||
/**
|
||||
* Flush a path's parent directory to disk.
|
||||
*/
|
||||
void syncParent(const Path & path);
|
||||
void syncParent(const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* Flush a file or entire directory tree to disk.
|
||||
*/
|
||||
void recursiveSync(const Path & path);
|
||||
void recursiveSync(const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* Delete a path; i.e., in the case of a directory, it is deleted
|
||||
@@ -297,7 +250,7 @@ void createDirs(const std::filesystem::path & path);
|
||||
/**
|
||||
* Create a single directory.
|
||||
*/
|
||||
void createDir(const Path & path, mode_t mode = 0755);
|
||||
void createDir(const std::filesystem::path & path, mode_t mode = 0755);
|
||||
|
||||
/**
|
||||
* Set the access and modification times of the given path, not
|
||||
@@ -327,18 +280,13 @@ void setWriteTime(const std::filesystem::path & path, const PosixStat & st);
|
||||
* Create a symlink.
|
||||
*
|
||||
*/
|
||||
void createSymlink(const Path & target, const Path & link);
|
||||
void createSymlink(const std::filesystem::path & target, const std::filesystem::path & link);
|
||||
|
||||
/**
|
||||
* Atomically create or replace a symlink.
|
||||
*/
|
||||
void replaceSymlink(const std::filesystem::path & target, const std::filesystem::path & link);
|
||||
|
||||
inline void replaceSymlink(const Path & target, const Path & link)
|
||||
{
|
||||
return replaceSymlink(std::filesystem::path{target}, std::filesystem::path{link});
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to 'renameFile', but fallback to a copy+remove if `src` and `dst`
|
||||
* are on a different filesystem.
|
||||
@@ -346,7 +294,7 @@ inline void replaceSymlink(const Path & target, const Path & link)
|
||||
* Beware that this might not be atomic because of the copy that happens behind
|
||||
* the scenes
|
||||
*/
|
||||
void moveFile(const Path & src, const Path & dst);
|
||||
void moveFile(const std::filesystem::path & src, const std::filesystem::path & dst);
|
||||
|
||||
/**
|
||||
* Recursively copy the content of `oldPath` to `newPath`. If `andDelete` is
|
||||
@@ -453,7 +401,7 @@ AutoCloseFD createAnonymousTempFile();
|
||||
/**
|
||||
* Create a temporary file, returning a file handle and its path.
|
||||
*/
|
||||
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix = "nix");
|
||||
std::pair<AutoCloseFD, std::filesystem::path> createTempFile(const std::filesystem::path & prefix = "nix");
|
||||
|
||||
/**
|
||||
* Return `TMPDIR`, or the default temporary directory if unset or empty.
|
||||
@@ -478,8 +426,10 @@ std::filesystem::path makeTempPath(const std::filesystem::path & root, const std
|
||||
|
||||
/**
|
||||
* Used in various places.
|
||||
*
|
||||
* @todo type
|
||||
*/
|
||||
typedef std::function<bool(const Path & path)> PathFilter;
|
||||
typedef std::function<bool(const std::string & path)> PathFilter;
|
||||
|
||||
extern PathFilter defaultPathFilter;
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ Hash hashString(
|
||||
*
|
||||
* (Metadata, such as the executable permission bit, is ignored.)
|
||||
*/
|
||||
Hash hashFile(HashAlgorithm ha, const Path & path);
|
||||
Hash hashFile(HashAlgorithm ha, const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* The final hash and the number of bytes digested.
|
||||
|
||||
@@ -105,7 +105,7 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = P
|
||||
* shell backtick operator).
|
||||
*/
|
||||
std::string runProgram(
|
||||
Path program,
|
||||
std::filesystem::path program,
|
||||
bool lookupPath = false,
|
||||
const Strings & args = Strings(),
|
||||
const std::optional<std::string> & input = {},
|
||||
@@ -113,7 +113,7 @@ std::string runProgram(
|
||||
|
||||
struct RunOptions
|
||||
{
|
||||
Path program;
|
||||
std::filesystem::path program;
|
||||
bool lookupPath = true;
|
||||
Strings args;
|
||||
#ifndef _WIN32
|
||||
|
||||
@@ -19,12 +19,12 @@ AutoCloseFD createUnixDomainSocket();
|
||||
/**
|
||||
* Create a Unix domain socket in listen mode.
|
||||
*/
|
||||
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode);
|
||||
AutoCloseFD createUnixDomainSocket(const std::filesystem::path & path, mode_t mode);
|
||||
|
||||
/**
|
||||
* Bind a Unix domain socket to a path.
|
||||
*/
|
||||
void bind(Socket fd, const std::string & path);
|
||||
void bind(Socket fd, const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* Connect to a Unix domain socket.
|
||||
|
||||
@@ -265,7 +265,7 @@ std::string percentEncode(std::string_view s, std::string_view keep = "");
|
||||
* paths have no escape sequences --- file names cannot contain a
|
||||
* `/`.
|
||||
*/
|
||||
Path renderUrlPathEnsureLegal(const std::vector<std::string> & urlPath);
|
||||
std::string renderUrlPathEnsureLegal(const std::vector<std::string> & urlPath);
|
||||
|
||||
/**
|
||||
* Percent encode path. `%2F` for "interior slashes" is the most
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
///@file
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "nix/util/types.hh"
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "nix/util/types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string getUserName();
|
||||
|
||||
@@ -22,13 +22,13 @@ bool userNamespacesSupported()
|
||||
return false;
|
||||
}
|
||||
|
||||
Path maxUserNamespaces = "/proc/sys/user/max_user_namespaces";
|
||||
std::filesystem::path maxUserNamespaces = "/proc/sys/user/max_user_namespaces";
|
||||
if (!pathExists(maxUserNamespaces) || trim(readFile(maxUserNamespaces)) == "0") {
|
||||
debug("user namespaces appear to be disabled; check '/proc/sys/user/max_user_namespaces'");
|
||||
return false;
|
||||
}
|
||||
|
||||
Path procSysKernelUnprivilegedUsernsClone = "/proc/sys/kernel/unprivileged_userns_clone";
|
||||
std::filesystem::path procSysKernelUnprivilegedUsernsClone = "/proc/sys/kernel/unprivileged_userns_clone";
|
||||
if (pathExists(procSysKernelUnprivilegedUsernsClone)
|
||||
&& trim(readFile(procSysKernelUnprivilegedUsernsClone)) == "0") {
|
||||
debug("user namespaces appear to be disabled; check '/proc/sys/kernel/unprivileged_userns_clone'");
|
||||
|
||||
@@ -74,9 +74,9 @@ static Cache cache;
|
||||
|
||||
std::optional<PosixStat> PosixSourceAccessor::cachedLstat(const CanonPath & path)
|
||||
{
|
||||
// Note: we convert std::filesystem::path to Path because the
|
||||
// Note: we convert std::filesystem::path to std::string because the
|
||||
// former is not hashable on libc++.
|
||||
Path absPath = makeAbsPath(path).string();
|
||||
std::string absPath = makeAbsPath(path).string();
|
||||
|
||||
if (auto res = getConcurrent(cache, absPath))
|
||||
return *res;
|
||||
|
||||
@@ -112,7 +112,7 @@ CanonPath SourceAccessor::resolveSymlinks(const CanonPath & path, SymlinkResolut
|
||||
if (!linksAllowed--)
|
||||
throw Error("infinite symlink recursion in path '%s'", showPath(path));
|
||||
auto target = readLink(res);
|
||||
if (isAbsolute(target)) {
|
||||
if (std::filesystem::path(target).is_absolute()) {
|
||||
res = CanonPath::root;
|
||||
} else {
|
||||
res.pop();
|
||||
|
||||
@@ -32,7 +32,7 @@ AutoCloseFD createUnixDomainSocket()
|
||||
return fdSocket;
|
||||
}
|
||||
|
||||
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
|
||||
AutoCloseFD createUnixDomainSocket(const std::filesystem::path & path, mode_t mode)
|
||||
{
|
||||
auto fdSocket = nix::createUnixDomainSocket();
|
||||
|
||||
@@ -41,11 +41,14 @@ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
|
||||
chmod(path, mode);
|
||||
|
||||
if (listen(toSocket(fdSocket.get()), 100) == -1)
|
||||
throw SysError("cannot listen on socket '%1%'", path);
|
||||
throw SysError("cannot listen on socket %s", PathFmt(path));
|
||||
|
||||
return fdSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use string for path, because no `struct sockaddr_un` variant supports native wide character paths.
|
||||
*/
|
||||
static void
|
||||
bindConnectProcHelper(std::string_view operationName, auto && operation, Socket fd, const std::string & path)
|
||||
{
|
||||
@@ -68,9 +71,9 @@ bindConnectProcHelper(std::string_view operationName, auto && operation, Socket
|
||||
Pid pid = startProcess([&] {
|
||||
try {
|
||||
pipe.readSide.close();
|
||||
Path dir = dirOf(path);
|
||||
auto dir = std::filesystem::path(path).parent_path();
|
||||
if (chdir(dir.c_str()) == -1)
|
||||
throw SysError("chdir to '%s' failed", dir);
|
||||
throw SysError("chdir to %s failed", PathFmt(dir));
|
||||
std::string base(baseNameOf(path));
|
||||
if (base.size() + 1 >= sizeof(addr.sun_path))
|
||||
throw Error("socket path '%s' is too long", base);
|
||||
@@ -100,11 +103,11 @@ bindConnectProcHelper(std::string_view operationName, auto && operation, Socket
|
||||
}
|
||||
}
|
||||
|
||||
void bind(Socket fd, const std::string & path)
|
||||
void bind(Socket fd, const std::filesystem::path & path)
|
||||
{
|
||||
unlink(path.c_str());
|
||||
|
||||
bindConnectProcHelper("bind", ::bind, fd, path);
|
||||
bindConnectProcHelper("bind", ::bind, fd, path.string());
|
||||
}
|
||||
|
||||
void connect(Socket fd, const std::filesystem::path & path)
|
||||
|
||||
@@ -8,14 +8,9 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::optional<std::filesystem::path> maybePath(PathView path)
|
||||
{
|
||||
return {path};
|
||||
}
|
||||
|
||||
std::filesystem::path pathNG(PathView path)
|
||||
{
|
||||
return path;
|
||||
return {std::string{path}};
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
@@ -267,7 +267,11 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options)
|
||||
}
|
||||
|
||||
std::string runProgram(
|
||||
Path program, bool lookupPath, const Strings & args, const std::optional<std::string> & input, bool isInteractive)
|
||||
std::filesystem::path program,
|
||||
bool lookupPath,
|
||||
const Strings & args,
|
||||
const std::optional<std::string> & input,
|
||||
bool isInteractive)
|
||||
{
|
||||
auto res = runProgram(
|
||||
RunOptions{
|
||||
@@ -278,7 +282,7 @@ std::string runProgram(
|
||||
.isInteractive = isInteractive});
|
||||
|
||||
if (!statusOk(res.first))
|
||||
throw ExecError(res.first, "program '%1%' %2%", program, statusToString(res.first));
|
||||
throw ExecError(res.first, "program %s %s", PathFmt(program), statusToString(res.first));
|
||||
|
||||
return res.second;
|
||||
}
|
||||
@@ -364,7 +368,7 @@ void runProgram2(const RunOptions & options)
|
||||
else
|
||||
execv(options.program.c_str(), stringsToCharPtrs(args_).data());
|
||||
|
||||
throw SysError("executing '%1%'", options.program);
|
||||
throw SysError("executing %s", PathFmt(options.program));
|
||||
},
|
||||
processOptions);
|
||||
|
||||
@@ -412,7 +416,7 @@ void runProgram2(const RunOptions & options)
|
||||
promise.get_future().get();
|
||||
|
||||
if (status)
|
||||
throw ExecError(status, "program '%1%' %2%", options.program, statusToString(status));
|
||||
throw ExecError(status, "program %s %s", PathFmt(options.program), statusToString(status));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
+1
-1
@@ -321,7 +321,7 @@ std::string encodeQuery(const StringMap & ss)
|
||||
return res;
|
||||
}
|
||||
|
||||
Path renderUrlPathEnsureLegal(const std::vector<std::string> & urlPath)
|
||||
std::string renderUrlPathEnsureLegal(const std::vector<std::string> & urlPath)
|
||||
{
|
||||
for (const auto & comp : urlPath) {
|
||||
/* This is only really valid for UNIX. Windows has more restrictions. */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/util/users.hh"
|
||||
#include "nix/util/environment-variables.hh"
|
||||
#include "nix/util/executable-path.hh"
|
||||
#include "nix/util/file-system.hh"
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -13,7 +14,7 @@ namespace nix {
|
||||
|
||||
std::filesystem::path getCacheDir()
|
||||
{
|
||||
auto dir = getEnv("NIX_CACHE_HOME");
|
||||
auto dir = getEnvOs(OS_STR("NIX_CACHE_HOME"));
|
||||
if (dir)
|
||||
return *dir;
|
||||
#ifndef _WIN32
|
||||
@@ -25,7 +26,7 @@ std::filesystem::path getCacheDir()
|
||||
|
||||
std::filesystem::path getConfigDir()
|
||||
{
|
||||
auto dir = getEnv("NIX_CONFIG_HOME");
|
||||
auto dir = getEnvOs(OS_STR("NIX_CONFIG_HOME"));
|
||||
if (dir)
|
||||
return *dir;
|
||||
#ifndef _WIN32
|
||||
@@ -51,7 +52,7 @@ std::vector<std::filesystem::path> getConfigDirs()
|
||||
|
||||
std::filesystem::path getDataDir()
|
||||
{
|
||||
auto dir = getEnv("NIX_DATA_HOME");
|
||||
auto dir = getEnvOs(OS_STR("NIX_DATA_HOME"));
|
||||
if (dir)
|
||||
return *dir;
|
||||
#ifndef _WIN32
|
||||
@@ -63,7 +64,7 @@ std::filesystem::path getDataDir()
|
||||
|
||||
std::filesystem::path getStateDir()
|
||||
{
|
||||
auto dir = getEnv("NIX_STATE_HOME");
|
||||
auto dir = getEnvOs(OS_STR("NIX_STATE_HOME"));
|
||||
if (dir)
|
||||
return *dir;
|
||||
#ifndef _WIN32
|
||||
@@ -85,7 +86,7 @@ std::string expandTilde(std::string_view path)
|
||||
// TODO: expand ~user ?
|
||||
auto tilde = path.substr(0, 2);
|
||||
if (tilde == "~/" || tilde == "~")
|
||||
return getHome().string() + std::string(path.substr(1));
|
||||
return (getHome() / std::string(path.substr(1))).string();
|
||||
else
|
||||
return std::string(path);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::optional<std::filesystem::path> maybePath(PathView path)
|
||||
static std::optional<std::filesystem::path> maybePath(PathView path)
|
||||
{
|
||||
if (path.length() >= 3 && (('A' <= path[0] && path[0] <= 'Z') || ('a' <= path[0] && path[0] <= 'z'))
|
||||
&& path[1] == ':' && WindowsPathTrait<char>::isPathSep(path[2])) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string os_string_to_string(PathViewNG::string_view path)
|
||||
std::string os_string_to_string(PathView::string_view path)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.to_bytes(std::filesystem::path::string_type{path});
|
||||
|
||||
@@ -104,7 +104,7 @@ std::string runProgram(
|
||||
return res.second;
|
||||
}
|
||||
|
||||
std::optional<Path> getProgramInterpreter(const Path & program)
|
||||
std::optional<std::filesystem::path> getProgramInterpreter(const std::filesystem::path & program)
|
||||
{
|
||||
// These extensions are automatically handled by Windows and don't require an interpreter.
|
||||
static constexpr const char * exts[] = {".exe", ".cmd", ".bat"};
|
||||
|
||||
@@ -37,9 +37,9 @@ std::string getUserName()
|
||||
std::filesystem::path getHome()
|
||||
{
|
||||
static std::filesystem::path homeDir = []() {
|
||||
std::filesystem::path homeDir = getEnv("USERPROFILE").value_or("C:\\Users\\Default");
|
||||
std::filesystem::path homeDir = getEnvOs(L"USERPROFILE").value_or(L"C:\\Users\\Default");
|
||||
assert(!homeDir.empty());
|
||||
return canonPath(homeDir.string());
|
||||
return std::filesystem::path{canonPath(homeDir.string())};
|
||||
}();
|
||||
return homeDir;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using namespace nix;
|
||||
|
||||
struct CmdAddToStore : MixDryRun, StoreCommand
|
||||
{
|
||||
Path path;
|
||||
std::filesystem::path path;
|
||||
std::optional<std::string> namePart;
|
||||
ContentAddressMethod caMethod = ContentAddressMethod::Raw::NixArchive;
|
||||
HashAlgorithm hashAlgo = HashAlgorithm::SHA256;
|
||||
@@ -36,7 +36,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
if (!namePart)
|
||||
namePart = baseNameOf(path);
|
||||
namePart = path.filename().filename().string();
|
||||
|
||||
auto sourcePath = PosixSourceAccessor::createAtRoot(makeParentCanonical(path));
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ static int main_build_remote(int argc, char ** argv)
|
||||
that gets cleared on reboot, but it wouldn't work on macOS. */
|
||||
auto currentLoadName = "/current-load";
|
||||
if (auto localStore = store.dynamic_pointer_cast<LocalFSStore>())
|
||||
currentLoad = std::string{localStore->config.stateDir} + currentLoadName;
|
||||
currentLoad = (localStore->config.stateDir.get() / currentLoadName).string();
|
||||
else
|
||||
currentLoad = settings.nixStateDir + currentLoadName;
|
||||
|
||||
|
||||
+2
-6
@@ -7,16 +7,12 @@
|
||||
#include "nix/expr/eval-inline.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
struct CmdBundle : InstallableValueCommand
|
||||
{
|
||||
std::string bundler = "github:NixOS/bundlers";
|
||||
std::optional<Path> outLink;
|
||||
std::optional<std::filesystem::path> outLink;
|
||||
|
||||
CmdBundle()
|
||||
{
|
||||
@@ -130,7 +126,7 @@ struct CmdBundle : InstallableValueCommand
|
||||
}
|
||||
|
||||
// TODO: will crash if not a localFSStore?
|
||||
store.dynamic_pointer_cast<LocalFSStore>()->addPermRoot(outPath, absPath(*outLink));
|
||||
store.dynamic_pointer_cast<LocalFSStore>()->addPermRoot(outPath, absPath(*outLink).string());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#include "nix/util/executable-path.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
namespace {
|
||||
|
||||
+11
-15
@@ -21,10 +21,6 @@
|
||||
|
||||
#include "nix/util/strings.hh"
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
struct DevelopSettings : Config
|
||||
@@ -335,7 +331,7 @@ struct Common : InstallableCommand, MixProfile
|
||||
"UID",
|
||||
};
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> redirects;
|
||||
std::vector<std::pair<std::string, std::filesystem::path>> redirects;
|
||||
|
||||
Common()
|
||||
{
|
||||
@@ -343,7 +339,7 @@ struct Common : InstallableCommand, MixProfile
|
||||
.longName = "redirect",
|
||||
.description = "Redirect a store path to a mutable location.",
|
||||
.labels = {"installable", "outputs-dir"},
|
||||
.handler = {[&](std::string installable, std::string outputsDir) {
|
||||
.handler = {[&](std::string installable, std::filesystem::path outputsDir) {
|
||||
redirects.push_back({installable, outputsDir});
|
||||
}},
|
||||
});
|
||||
@@ -407,7 +403,7 @@ struct Common : InstallableCommand, MixProfile
|
||||
|
||||
/* Substitute redirects. */
|
||||
for (auto & [installable_, dir_] : redirects) {
|
||||
auto dir = absPath(dir_);
|
||||
auto dir = std::filesystem::absolute(dir_);
|
||||
auto installable = parseInstallable(store, installable_);
|
||||
auto builtPaths =
|
||||
Installable::toStorePathSet(getEvalStore(), store, Realise::Nothing, OperateOn::Output, {installable});
|
||||
@@ -416,8 +412,8 @@ struct Common : InstallableCommand, MixProfile
|
||||
if (script.find(from) == std::string::npos)
|
||||
warn("'%s' (path '%s') is not used by this build environment", installable->what(), from);
|
||||
else {
|
||||
printInfo("redirecting '%s' to '%s'", from, dir);
|
||||
rewrites.insert({from, dir});
|
||||
printInfo("redirecting '%s' to '%s'", from, dir.string());
|
||||
rewrites.insert({from, dir.string()});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -600,7 +596,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||
if (verbosity >= lvlDebug)
|
||||
script += "set -x\n";
|
||||
|
||||
script += fmt("command rm -f '%s'\n", rcFilePath);
|
||||
script += fmt("command rm -f '%s'\n", rcFilePath.string());
|
||||
|
||||
if (phase) {
|
||||
if (!command.empty())
|
||||
@@ -637,7 +633,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||
// prevent garbage collection until shell exits
|
||||
setEnv("NIX_GCROOT", store->printStorePath(gcroot).c_str());
|
||||
|
||||
Path shell = "bash";
|
||||
std::filesystem::path shell = "bash";
|
||||
bool foundInteractive = false;
|
||||
|
||||
try {
|
||||
@@ -680,9 +676,9 @@ struct CmdDevelop : Common, MixEnvironment
|
||||
|
||||
// Override SHELL with the one chosen for this environment.
|
||||
// This is to make sure the system shell doesn't leak into the build environment.
|
||||
setEnv("SHELL", shell.c_str());
|
||||
setEnv("SHELL", shell.string().c_str());
|
||||
// https://github.com/NixOS/nix/issues/5873
|
||||
script += fmt("SHELL=\"%s\"\n", shell);
|
||||
script += fmt("SHELL=%s\n", PathFmt(shell));
|
||||
if (foundInteractive)
|
||||
script += fmt("PATH=\"%s${PATH:+:$PATH}\"\n", std::filesystem::path(shell).parent_path().string());
|
||||
writeFull(rcFileFd.get(), script);
|
||||
@@ -692,8 +688,8 @@ struct CmdDevelop : Common, MixEnvironment
|
||||
#else
|
||||
// If running a phase or single command, don't want an interactive shell running after
|
||||
// Ctrl-C, so don't pass --rcfile
|
||||
auto args = phase || !command.empty() ? Strings{std::string(baseNameOf(shell)), rcFilePath}
|
||||
: Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};
|
||||
auto args = phase || !command.empty() ? Strings{shell.filename().string(), rcFilePath}
|
||||
: Strings{shell.filename().string(), "--rcfile", rcFilePath};
|
||||
|
||||
// Need to chdir since phases assume in flake directory
|
||||
if (phase) {
|
||||
|
||||
@@ -39,7 +39,7 @@ static auto rDumpPath = registerCommand2<CmdDumpPath>({"store", "dump-path"});
|
||||
|
||||
struct CmdDumpPath2 : Command
|
||||
{
|
||||
Path path;
|
||||
std::filesystem::path path;
|
||||
|
||||
CmdDumpPath2()
|
||||
{
|
||||
@@ -61,7 +61,7 @@ struct CmdDumpPath2 : Command
|
||||
void run() override
|
||||
{
|
||||
auto sink = getNarSink();
|
||||
dumpPath(path, sink);
|
||||
dumpPath(path.string(), sink);
|
||||
sink.flush();
|
||||
}
|
||||
};
|
||||
|
||||
+1
-5
@@ -10,10 +10,6 @@
|
||||
|
||||
using namespace nix;
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
|
||||
{
|
||||
bool raw = false;
|
||||
@@ -89,7 +85,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
|
||||
state->forceValue(v, pos);
|
||||
if (v.type() == nString)
|
||||
// FIXME: disallow strings with contexts?
|
||||
writeFile(path.string(), v.string_view());
|
||||
writeFile(path, v.string_view());
|
||||
else if (v.type() == nAttrs) {
|
||||
[[maybe_unused]] bool directoryCreated = std::filesystem::create_directory(path);
|
||||
// Directory should not already exist
|
||||
|
||||
+4
-8
@@ -29,10 +29,6 @@
|
||||
// FIXME is this supposed to be private or not?
|
||||
#include "flake-command.hh"
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
using namespace nix::flake;
|
||||
using json = nlohmann::json;
|
||||
@@ -857,7 +853,7 @@ static Strings defaultTemplateAttrPaths = {"templates.default", "defaultTemplate
|
||||
struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||
{
|
||||
std::string templateUrl = "templates";
|
||||
Path destDir;
|
||||
std::filesystem::path destDir;
|
||||
|
||||
const LockFlags lockFlags{.writeLockFile = false};
|
||||
|
||||
@@ -883,7 +879,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||
|
||||
void run(nix::ref<nix::Store> store) override
|
||||
{
|
||||
auto flakeDir = absPath(destDir);
|
||||
auto flakeDir = std::filesystem::weakly_canonical(destDir);
|
||||
|
||||
auto evalState = getEvalState();
|
||||
|
||||
@@ -950,7 +946,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||
}
|
||||
continue;
|
||||
} else
|
||||
createSymlink(target, os_string_to_string(PathViewNG{to2}));
|
||||
createSymlink(target, to2.string());
|
||||
} else
|
||||
throw Error(
|
||||
"path '%s' needs to be a symlink, file, or directory but instead is a %s",
|
||||
@@ -962,7 +958,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||
}(templateDir, flakeDir);
|
||||
|
||||
if (!changedFiles.empty() && std::filesystem::exists(std::filesystem::path{flakeDir} / ".git")) {
|
||||
Strings args = {"-C", flakeDir, "add", "--intent-to-add", "--force", "--"};
|
||||
Strings args = {"-C", flakeDir.string(), "add", "--intent-to-add", "--force", "--"};
|
||||
for (auto & s : changedFiles)
|
||||
args.emplace_back(s.string());
|
||||
runProgram("git", true, args);
|
||||
|
||||
@@ -140,7 +140,7 @@ static void main_nix_build(int argc, char ** argv)
|
||||
auto myName = isNixShell ? "nix-shell" : "nix-build";
|
||||
|
||||
auto inShebang = false;
|
||||
std::string script;
|
||||
std::filesystem::path script;
|
||||
std::vector<std::string> savedArgs;
|
||||
|
||||
AutoDelete tmpDir(createTempDir("", myName));
|
||||
@@ -200,9 +200,9 @@ static void main_nix_build(int argc, char ** argv)
|
||||
{
|
||||
using LegacyArgs::LegacyArgs;
|
||||
|
||||
void setBaseDir(Path baseDir)
|
||||
void setBaseDir(std::filesystem::path baseDir)
|
||||
{
|
||||
commandBaseDir = baseDir;
|
||||
commandBaseDir = baseDir.string();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -284,11 +284,15 @@ static void main_nix_build(int argc, char ** argv)
|
||||
fmt("exec %1% %2% -e 'load(ARGV.shift)' -- %3% %4%",
|
||||
execArgs,
|
||||
interpreter,
|
||||
escapeShellArgAlways(script),
|
||||
escapeShellArgAlways(script.string()),
|
||||
joined.view());
|
||||
} else {
|
||||
envCommand =
|
||||
fmt("exec %1% %2% %3% %4%", execArgs, interpreter, escapeShellArgAlways(script), joined.view());
|
||||
fmt("exec %1% %2% %3% %4%",
|
||||
execArgs,
|
||||
interpreter,
|
||||
escapeShellArgAlways(script.string()),
|
||||
joined.view());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +325,7 @@ static void main_nix_build(int argc, char ** argv)
|
||||
buildMode = bmRepair;
|
||||
|
||||
if (inShebang && compatibilitySettings.nixShellShebangArgumentsRelativeToScript) {
|
||||
myArgs.setBaseDir(absPath(dirOf(script)));
|
||||
myArgs.setBaseDir(std::filesystem::absolute(script.parent_path()));
|
||||
}
|
||||
auto autoArgs = myArgs.getAutoArgs(*state);
|
||||
|
||||
@@ -374,27 +378,28 @@ static void main_nix_build(int argc, char ** argv)
|
||||
else
|
||||
for (auto i : remainingArgs) {
|
||||
if (fromArgs) {
|
||||
auto shebangBaseDir = absPath(dirOf(script));
|
||||
auto shebangBaseDir = std::filesystem::absolute(script.parent_path());
|
||||
exprs.push_back(state->parseExprFromString(
|
||||
std::move(i),
|
||||
(inShebang && compatibilitySettings.nixShellShebangArgumentsRelativeToScript)
|
||||
? lookupFileArg(*state, shebangBaseDir)
|
||||
? lookupFileArg(*state, shebangBaseDir.string())
|
||||
: state->rootPath(".")));
|
||||
} else {
|
||||
auto absolute = i;
|
||||
std::filesystem::path absolute = i;
|
||||
try {
|
||||
absolute = canonPath(absPath(i), true);
|
||||
} catch (Error & e) {
|
||||
absolute = std::filesystem::weakly_canonical(absolute);
|
||||
} catch (std::filesystem::filesystem_error &) {
|
||||
};
|
||||
auto [path, outputNames] = parsePathWithOutputs(absolute);
|
||||
auto [path, outputNames] = parsePathWithOutputs(absolute.string());
|
||||
if (evalStore->isStorePath(path) && hasSuffix(path, ".drv"))
|
||||
drvs.push_back(PackageInfo(*state, evalStore, absolute));
|
||||
drvs.push_back(PackageInfo(*state, evalStore, absolute.string()));
|
||||
else {
|
||||
/* If we're in a #! script, interpret filenames
|
||||
relative to the script. */
|
||||
auto baseDir = inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i;
|
||||
auto baseDir = inShebang && !packages ? absPath(script.parent_path()) / (std::filesystem::path{i})
|
||||
: (std::filesystem::path{i});
|
||||
|
||||
auto sourcePath = lookupFileArg(*state, baseDir);
|
||||
auto sourcePath = lookupFileArg(*state, baseDir.string());
|
||||
auto resolvedPath = isNixShell ? resolveShellExprPath(sourcePath) : resolveExprPath(sourcePath);
|
||||
|
||||
exprs.push_back(state->parseExprFromFile(resolvedPath));
|
||||
@@ -570,7 +575,7 @@ static void main_nix_build(int argc, char ** argv)
|
||||
for (auto & var : drv.env)
|
||||
if (drvOptions.passAsFile.count(var.first)) {
|
||||
auto fn = ".attr-" + std::to_string(fileNr++);
|
||||
Path p = (tmpDir.path() / fn).string();
|
||||
auto p = (tmpDir.path() / fn).string();
|
||||
writeFile(p, var.second);
|
||||
env[var.first + "Path"] = p;
|
||||
} else
|
||||
@@ -649,7 +654,7 @@ static void main_nix_build(int argc, char ** argv)
|
||||
escapeShellArgAlways(tmpDir.path().string()),
|
||||
(pure ? "" : "p=$PATH; "),
|
||||
(pure ? "" : "PATH=$PATH:$p; unset p; "),
|
||||
escapeShellArgAlways(dirOf(*shell)),
|
||||
escapeShellArgAlways(std::filesystem::path(*shell).parent_path().string()),
|
||||
escapeShellArgAlways(*shell),
|
||||
tzExport,
|
||||
envCommand);
|
||||
|
||||
@@ -69,7 +69,7 @@ static void addChannel(const std::string & url, const std::string & name)
|
||||
writeChannels();
|
||||
}
|
||||
|
||||
static Path profile;
|
||||
static std::filesystem::path profile;
|
||||
|
||||
// Remove a channel.
|
||||
static void removeChannel(const std::string & name)
|
||||
@@ -81,7 +81,7 @@ static void removeChannel(const std::string & name)
|
||||
runProgram(getNixBin("nix-env").string(), true, {"--profile", profile, "--uninstall", name});
|
||||
}
|
||||
|
||||
static Path nixDefExpr;
|
||||
static std::filesystem::path nixDefExpr;
|
||||
|
||||
// Fetch Nix expressions and binary cache URLs from the subscribed channels.
|
||||
static void update(const StringSet & channelNames)
|
||||
@@ -117,12 +117,12 @@ static void update(const StringSet & channelNames)
|
||||
|
||||
if (!(channelNames.empty() || channelNames.count(name))) {
|
||||
// no need to update this channel, reuse the existing store path
|
||||
Path symlink = profile + "/" + name;
|
||||
Path storepath = dirOf(readLink(symlink));
|
||||
std::filesystem::path symlink = profile / name;
|
||||
std::filesystem::path storepath = std::filesystem::read_symlink(symlink).parent_path();
|
||||
exprs.push_back(
|
||||
"f: rec { name = \"" + cname
|
||||
+ "\"; type = \"derivation\"; outputs = [\"out\"]; system = \"builtin\"; outPath = builtins.storePath \""
|
||||
+ storepath + "\"; out = { inherit outPath; };}");
|
||||
+ storepath.string() + "\"; out = { inherit outPath; };}");
|
||||
} else {
|
||||
// We want to download the url to a file to see if it's a tarball while also checking if we
|
||||
// got redirected in the process, so that we can grab the various parts of a nix channel
|
||||
@@ -137,7 +137,7 @@ static void update(const StringSet & channelNames)
|
||||
false,
|
||||
{"--no-out-link",
|
||||
"--expr",
|
||||
"import " + unpackChannelPath + "{ name = \"" + cname + "\"; channelName = \"" + name
|
||||
"import " + unpackChannelPath.string() + "{ name = \"" + cname + "\"; channelName = \"" + name
|
||||
+ "\"; src = builtins.storePath \"" + store->printStorePath(result.storePath) + "\"; }"});
|
||||
unpacked = true;
|
||||
}
|
||||
@@ -174,12 +174,12 @@ static void update(const StringSet & channelNames)
|
||||
if (S_ISLNK(st.st_mode))
|
||||
// old-skool ~/.nix-defexpr
|
||||
if (unlink(nixDefExpr.c_str()) == -1)
|
||||
throw SysError("unlinking %1%", nixDefExpr);
|
||||
throw SysError("unlinking %1%", PathFmt(nixDefExpr));
|
||||
} else if (errno != ENOENT) {
|
||||
throw SysError("getting status of %1%", nixDefExpr);
|
||||
throw SysError("getting status of %1%", PathFmt(nixDefExpr));
|
||||
}
|
||||
createDirs(nixDefExpr);
|
||||
auto channelLink = nixDefExpr + "/channels";
|
||||
std::filesystem::create_directories(nixDefExpr);
|
||||
auto channelLink = nixDefExpr / "channels";
|
||||
replaceSymlink(profile, channelLink);
|
||||
}
|
||||
|
||||
@@ -188,12 +188,13 @@ static int main_nix_channel(int argc, char ** argv)
|
||||
{
|
||||
// Figure out the name of the `.nix-channels' file to use
|
||||
auto home = getHome();
|
||||
channelsList = settings.useXDGBaseDirectories ? createNixStateDir() + "/channels" : home + "/.nix-channels";
|
||||
channelsList =
|
||||
settings.useXDGBaseDirectories ? (createNixStateDir() / "channels").string() : home + "/.nix-channels";
|
||||
nixDefExpr = getNixDefExpr();
|
||||
|
||||
// Figure out the name of the channels profile.
|
||||
profile = profilesDir(settings.getProfileDirsOptions()) + "/channels";
|
||||
createDirs(dirOf(profile));
|
||||
profile = profilesDir(settings.getProfileDirsOptions()) / "channels";
|
||||
createDirs(profile.parent_path());
|
||||
|
||||
enum { cNone, cAdd, cRemove, cList, cUpdate, cListGenerations, cRollback } cmd = cNone;
|
||||
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
std::string deleteOlderThan;
|
||||
|
||||
@@ -74,7 +74,7 @@ struct InstallSourceInfo
|
||||
{
|
||||
InstallSourceType type;
|
||||
std::shared_ptr<SourcePath> nixExprPath; /* for srcNixExprDrvs, srcNixExprs */
|
||||
Path profile; /* for srcProfile */
|
||||
std::filesystem::path profile; /* for srcProfile */
|
||||
std::string systemFilter; /* for srcNixExprDrvs */
|
||||
Bindings * autoArgs;
|
||||
};
|
||||
@@ -82,7 +82,7 @@ struct InstallSourceInfo
|
||||
struct Globals
|
||||
{
|
||||
InstallSourceInfo instSource;
|
||||
Path profile;
|
||||
std::filesystem::path profile;
|
||||
std::shared_ptr<EvalState> state;
|
||||
bool dryRun;
|
||||
bool preserveInstalled;
|
||||
@@ -522,8 +522,8 @@ static void setMetaFlag(EvalState & state, PackageInfo & drv, const std::string
|
||||
drv.setMeta(name, v);
|
||||
}
|
||||
|
||||
static void
|
||||
installDerivations(Globals & globals, const Strings & args, const Path & profile, std::optional<int> priority)
|
||||
static void installDerivations(
|
||||
Globals & globals, const Strings & args, const std::filesystem::path & profile, std::optional<int> priority)
|
||||
{
|
||||
debug("installing derivations");
|
||||
|
||||
@@ -800,7 +800,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||
switchLink(globals.profile, generation);
|
||||
}
|
||||
|
||||
static void uninstallDerivations(Globals & globals, Strings & selectors, Path & profile)
|
||||
static void uninstallDerivations(Globals & globals, Strings & selectors, const std::filesystem::path & profile)
|
||||
{
|
||||
while (true) {
|
||||
auto lockToken = optimisticLockProfile(profile);
|
||||
@@ -1294,7 +1294,7 @@ static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
|
||||
if (opArgs.size() != 1)
|
||||
throw UsageError("exactly one argument expected");
|
||||
|
||||
Path profile = absPath(opArgs.front());
|
||||
auto profile = absPath(std::filesystem::path{opArgs.front()});
|
||||
auto profileLink = settings.useXDGBaseDirectories ? createNixStateDir() / "profile" : getHome() / ".nix-profile";
|
||||
|
||||
switchLink(profileLink, profile);
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
PackageInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||
PackageInfos queryInstalled(EvalState & state, const std::filesystem::path & userEnv)
|
||||
{
|
||||
PackageInfos elems;
|
||||
if (pathExists(userEnv + "/manifest.json"))
|
||||
throw Error("profile '%s' is incompatible with 'nix-env'; please use 'nix profile' instead", userEnv);
|
||||
auto manifestFile = userEnv + "/manifest.nix";
|
||||
if (pathExists(userEnv / "manifest.json"))
|
||||
throw Error("profile %s is incompatible with 'nix-env'; please use 'nix profile' instead", PathFmt(userEnv));
|
||||
auto manifestFile = userEnv / "manifest.nix";
|
||||
if (pathExists(manifestFile)) {
|
||||
Value v;
|
||||
state.evalFile(state.rootPath(CanonPath(manifestFile)).resolveSymlinks(), v);
|
||||
state.evalFile(state.rootPath(CanonPath(std::filesystem::weakly_canonical(manifestFile).string())), v);
|
||||
Bindings & bindings = Bindings::emptyBindings;
|
||||
getDerivations(state, v, "", bindings, elems, false);
|
||||
}
|
||||
@@ -32,7 +32,11 @@ PackageInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||
}
|
||||
|
||||
bool createUserEnv(
|
||||
EvalState & state, PackageInfos & elems, const Path & profile, bool keepDerivations, const std::string & lockToken)
|
||||
EvalState & state,
|
||||
PackageInfos & elems,
|
||||
const std::filesystem::path & profile,
|
||||
bool keepDerivations,
|
||||
const std::string & lockToken)
|
||||
{
|
||||
/* Build the components in the user environment, if they don't
|
||||
exist already. */
|
||||
@@ -163,7 +167,7 @@ bool createUserEnv(
|
||||
|
||||
std::filesystem::path lockTokenCur = optimisticLockProfile(profile);
|
||||
if (lockToken != lockTokenCur) {
|
||||
printInfo("profile '%1%' changed while we were busy; restarting", profile);
|
||||
printInfo("profile %s changed while we were busy; restarting", PathFmt(profile));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
PackageInfos queryInstalled(EvalState & state, const Path & userEnv);
|
||||
PackageInfos queryInstalled(EvalState & state, const std::filesystem::path & userEnv);
|
||||
|
||||
bool createUserEnv(
|
||||
EvalState & state, PackageInfos & elems, const Path & profile, bool keepDerivations, const std::string & lockToken);
|
||||
EvalState & state,
|
||||
PackageInfos & elems,
|
||||
const std::filesystem::path & profile,
|
||||
bool keepDerivations,
|
||||
const std::string & lockToken);
|
||||
|
||||
} // namespace nix
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
using namespace nix;
|
||||
|
||||
static Path gcRoot;
|
||||
std::filesystem::path gcRoot;
|
||||
static int rootNr = 0;
|
||||
|
||||
enum OutputKind { okPlain, okRaw, okXML, okJSON };
|
||||
@@ -83,15 +83,15 @@ void processExpr(
|
||||
if (outputName == "")
|
||||
throw Error("derivation '%1%' lacks an 'outputName' attribute", drvPathS);
|
||||
|
||||
if (gcRoot == "")
|
||||
if (gcRoot.empty())
|
||||
printGCWarning();
|
||||
else {
|
||||
Path rootName = absPath(gcRoot);
|
||||
auto rootName = std::filesystem::absolute(gcRoot);
|
||||
if (++rootNr > 1)
|
||||
rootName += "-" + std::to_string(rootNr);
|
||||
auto store2 = state.store.dynamic_pointer_cast<LocalFSStore>();
|
||||
if (store2)
|
||||
drvPathS = store2->addPermRoot(drvPath, rootName);
|
||||
drvPathS = store2->addPermRoot(drvPath, rootName.string());
|
||||
}
|
||||
std::cout << fmt("%s%s\n", drvPathS, (outputName != "out" ? "!" + outputName : ""));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ using std::cout;
|
||||
|
||||
typedef void (*Operation)(Strings opFlags, Strings opArgs);
|
||||
|
||||
static Path gcRoot;
|
||||
static std::filesystem::path gcRoot;
|
||||
static int rootNr = 0;
|
||||
static bool noOutput = false;
|
||||
static std::shared_ptr<Store> store;
|
||||
@@ -99,12 +99,12 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
|
||||
if (gcRoot == "")
|
||||
printGCWarning();
|
||||
else {
|
||||
Path rootName = gcRoot;
|
||||
std::filesystem::path rootName = gcRoot;
|
||||
if (rootNr > 1)
|
||||
rootName += "-" + std::to_string(rootNr);
|
||||
if (i->first != "out")
|
||||
rootName += "-" + i->first;
|
||||
retPath = store2->addPermRoot(outPath, rootName);
|
||||
retPath = store2->addPermRoot(outPath, rootName.string());
|
||||
}
|
||||
}
|
||||
outputs.insert(retPath);
|
||||
@@ -121,11 +121,11 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
|
||||
if (gcRoot == "")
|
||||
printGCWarning();
|
||||
else {
|
||||
Path rootName = gcRoot;
|
||||
std::filesystem::path rootName = gcRoot;
|
||||
rootNr++;
|
||||
if (rootNr > 1)
|
||||
rootName += "-" + std::to_string(rootNr);
|
||||
return {store2->addPermRoot(path.path, rootName)};
|
||||
return {store2->addPermRoot(path.path, rootName.string())};
|
||||
}
|
||||
}
|
||||
return {store->printStorePath(path.path)};
|
||||
@@ -528,8 +528,8 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
|
||||
if (opArgs.size() != 1)
|
||||
throw UsageError("'--print-env' requires one derivation store path");
|
||||
|
||||
Path drvPath = opArgs.front();
|
||||
Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath));
|
||||
std::filesystem::path drvPath = opArgs.front();
|
||||
Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath.string()));
|
||||
|
||||
/* Print each environment variable in the derivation in a format
|
||||
* that can be sourced by the shell. */
|
||||
@@ -689,7 +689,7 @@ static void opGC(Strings opFlags, Strings opArgs)
|
||||
|
||||
if (printRoots) {
|
||||
Roots roots = gcStore.findRoots(false);
|
||||
std::set<std::pair<Path, StorePath>> roots2;
|
||||
std::set<std::pair<std::filesystem::path, StorePath>> roots2;
|
||||
// Transpose and sort the roots.
|
||||
for (auto & [target, links] : roots)
|
||||
for (auto & link : links)
|
||||
|
||||
+4
-4
@@ -421,10 +421,10 @@ struct CmdProfileAdd : InstallablesCommand, MixDefaultProfile
|
||||
for (auto it = begin; it != end; it++) {
|
||||
auto & [name, profileElement] = *it;
|
||||
for (auto & storePath : profileElement.storePaths) {
|
||||
if (conflictError.fileA.starts_with(store->printStorePath(storePath))) {
|
||||
if (conflictError.fileA.string().starts_with(store->printStorePath(storePath))) {
|
||||
return std::tuple(conflictError.fileA, name, profileElement.toInstallables(*store));
|
||||
}
|
||||
if (conflictError.fileB.starts_with(store->printStorePath(storePath))) {
|
||||
if (conflictError.fileB.string().starts_with(store->printStorePath(storePath))) {
|
||||
return std::tuple(conflictError.fileB, name, profileElement.toInstallables(*store));
|
||||
}
|
||||
}
|
||||
@@ -462,8 +462,8 @@ struct CmdProfileAdd : InstallablesCommand, MixDefaultProfile
|
||||
"To prioritise the existing package:\n"
|
||||
"\n"
|
||||
" nix profile add %4% --priority %7%\n",
|
||||
originalConflictingFilePath,
|
||||
newConflictingFilePath,
|
||||
PathFmt(originalConflictingFilePath),
|
||||
PathFmt(newConflictingFilePath),
|
||||
originalEntryName,
|
||||
concatStringsSep(" ", newConflictingRefs),
|
||||
conflictError.priority,
|
||||
|
||||
+4
-4
@@ -40,7 +40,7 @@ public:
|
||||
return registry;
|
||||
}
|
||||
|
||||
Path getRegistryPath()
|
||||
std::filesystem::path getRegistryPath()
|
||||
{
|
||||
if (registry_path.empty()) {
|
||||
return fetchers::getUserRegistryPath().string();
|
||||
@@ -118,7 +118,7 @@ struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand
|
||||
extraAttrs["dir"] = toRef.subdir;
|
||||
registry->remove(fromRef.input);
|
||||
registry->add(fromRef.input, toRef.input, extraAttrs);
|
||||
registry->write(getRegistryPath());
|
||||
registry->write(getRegistryPath().string());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ struct CmdRegistryRemove : RegistryCommand, Command
|
||||
{
|
||||
auto registry = getRegistry();
|
||||
registry->remove(parseFlakeRef(fetchSettings, url).input);
|
||||
registry->write(getRegistryPath());
|
||||
registry->write(getRegistryPath().string());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -198,7 +198,7 @@ struct CmdRegistryPin : RegistryCommand, EvalCommand
|
||||
extraAttrs["dir"] = ref.subdir;
|
||||
registry->remove(ref.input);
|
||||
registry->add(ref.input, resolved, extraAttrs);
|
||||
registry->write(getRegistryPath());
|
||||
registry->write(getRegistryPath().string());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
|
||||
extern char ** environ __attribute__((weak));
|
||||
|
||||
namespace nix::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
|
||||
using namespace nix;
|
||||
|
||||
std::string chrootHelperName = "__run_in_chroot";
|
||||
|
||||
+3
-3
@@ -52,12 +52,12 @@ struct CmdCopySigs : StorePathsCommand
|
||||
|
||||
// logger->setExpected(doneLabel, storePaths.size());
|
||||
|
||||
auto doPath = [&](const Path & storePathS) {
|
||||
auto doPath = [&](const std::filesystem::path & storePathS) {
|
||||
// Activity act(*logger, lvlInfo, "getting signatures for '%s'", storePath);
|
||||
|
||||
checkInterrupt();
|
||||
|
||||
auto storePath = store->parseStorePath(storePathS);
|
||||
auto storePath = store->parseStorePath(storePathS.string());
|
||||
|
||||
auto info = store->queryPathInfo(storePath);
|
||||
|
||||
@@ -101,7 +101,7 @@ static auto rCmdCopySigs = registerCommand2<CmdCopySigs>({"store", "copy-sigs"})
|
||||
|
||||
struct CmdSign : StorePathsCommand
|
||||
{
|
||||
Path secretKeyFile;
|
||||
std::filesystem::path secretKeyFile;
|
||||
|
||||
CmdSign()
|
||||
{
|
||||
|
||||
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user