diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 18eee830b9e0..baad3bc7317d 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -81,11 +81,11 @@ static int main_build_remote(int argc, char * * argv) /* It would be more appropriate to use $XDG_RUNTIME_DIR, since that gets cleared on reboot, but it wouldn't work on macOS. */ - auto currentLoadName = "/current-load"; + PathView currentLoadName = "current-load"; if (auto localStore = store.dynamic_pointer_cast()) - currentLoad = std::string { localStore->stateDir } + currentLoadName; + currentLoad = localStore->stateDir / currentLoadName; else - currentLoad = settings.nixStateDir + currentLoadName; + currentLoad = settings.nixStateDir / currentLoadName.native(); std::shared_ptr sshStore; AutoCloseFD bestSlotLock; diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 155b43b700b2..071fecefd90d 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -192,7 +192,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) return res.finish(); } -SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir) +SourcePath lookupFileArg(EvalState & state, PathView s, const Path * baseDir) { if (EvalSettings::isPseudoUrl(s)) { auto accessor = fetchers::downloadTarball( diff --git a/src/libcmd/common-eval-args.hh b/src/libcmd/common-eval-args.hh index 75cb19334fe8..11d081728df2 100644 --- a/src/libcmd/common-eval-args.hh +++ b/src/libcmd/common-eval-args.hh @@ -41,6 +41,6 @@ private: /** * @param baseDir Optional [base directory](https://nixos.org/manual/nix/unstable/glossary#gloss-base-directory) */ -SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr); +SourcePath lookupFileArg(EvalState & state, PathView s, const Path * baseDir = nullptr); } diff --git a/src/libexpr/eval-settings.cc b/src/libexpr/eval-settings.cc index 2ccbe327fad1..e7e92c1a2379 100644 --- a/src/libexpr/eval-settings.cc +++ b/src/libexpr/eval-settings.cc @@ -58,7 +58,7 @@ Strings EvalSettings::getDefaultNixPath() if (s.empty()) { res.push_back(p); } else { - res.push_back(s + "=" + p); + res.push_back(s + "=" + p.native()); } } }; diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index dfe3044ea348..d4455a96f8de 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -84,7 +84,9 @@ Settings::Settings() } #if defined(__linux__) && defined(SANDBOX_SHELL) - sandboxPaths = tokenizeString("/bin/sh=" SANDBOX_SHELL); + sandboxPaths = std::set { + Path { "/bin/sh=" SANDBOX_SHELL } + }; #endif /* chroot-like behavior from Apple's sandbox */ @@ -154,7 +156,7 @@ std::vector getUserConfigFiles() // Use the paths specified in NIX_USER_CONF_FILES if it has been defined auto nixConfFiles = getEnv("NIX_USER_CONF_FILES"); if (nixConfFiles.has_value()) { - return tokenizeString>(nixConfFiles.value(), ":"); + return tokenizeString>(nixConfFiles.value(), ":"); } // Use the paths specified by the XDG spec diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 0c71a7515536..4b9d6a26e1ea 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -276,7 +276,7 @@ public: )"}; Setting builders{ - this, "@" + nixConfDir + "/machines", "builders", + this, "@" + (nixConfDir / "machines").native(), "builders", R"( A semicolon- or newline-separated list of build machines. diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 5da87e935db6..eebe6344fd46 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -26,7 +26,7 @@ class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public v { private: - Path cacheUri; + std::string cacheUri; struct State { @@ -40,7 +40,7 @@ class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public v HttpBinaryCacheStore( const std::string & scheme, - const Path & _cacheUri, + const std::string & _cacheUri, const Params & params) : StoreConfig(params) , BinaryCacheStoreConfig(params) diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 5481dd762e27..5e8684548034 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -45,7 +45,7 @@ class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public std::string getUri() override { - return "file://" + binaryCacheDir; + return "file://" + binaryCacheDir.native(); } static std::set uriSchemes(); diff --git a/src/libstore/local-fs-store.hh b/src/libstore/local-fs-store.hh index 8fb08120012d..2ce59618bea6 100644 --- a/src/libstore/local-fs-store.hh +++ b/src/libstore/local-fs-store.hh @@ -16,17 +16,17 @@ struct LocalFSStoreConfig : virtual StoreConfig "Directory prefixed to all other paths."}; const PathSetting stateDir{this, - rootDir.get() ? *rootDir.get() + "/nix/var/nix" : settings.nixStateDir, + rootDir.get() ? *rootDir.get() / "nix/var/nix" : settings.nixStateDir, "state", "Directory where Nix will store state."}; const PathSetting logDir{this, - rootDir.get() ? *rootDir.get() + "/nix/var/log/nix" : settings.nixLogDir, + rootDir.get() ? *rootDir.get() / "nix/var/log/nix" : settings.nixLogDir, "log", "directory where Nix will store log files."}; const PathSetting realStoreDir{this, - rootDir.get() ? *rootDir.get() + "/nix/store" : storeDir, "real", + rootDir.get() ? *rootDir.get() / "nix/store" : storeDir, "real", "Physical path of the Nix store."}; }; @@ -66,7 +66,7 @@ public: Path toRealPath(const Path & storePath) override { assert(isInStore(storePath)); - return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1); + return getRealStoreDir() / Path::string_type { storePath, storeDir.native().size() + 1 }; } std::optional getBuildLogExact(const StorePath & path) override; diff --git a/src/libstore/nar-accessor.cc b/src/libstore/nar-accessor.cc index cecf8148f455..b8e061a8f6d6 100644 --- a/src/libstore/nar-accessor.cc +++ b/src/libstore/nar-accessor.cc @@ -15,7 +15,9 @@ struct NarMember std::string target; - /* If this is a directory, all the children of the directory. */ + /** + * If this is a directory, all the children of the directory. + */ std::map children; }; diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index 07beb8acb0b3..3d6c11f383dd 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -208,7 +208,10 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache }; { - auto r(state->insertCache.use()(uri)(time(0))(storeDir)(wantMassQuery)(priority)); + auto r { + state->insertCache.use() + (uri)(time(0))(storeDir.native())(wantMassQuery)(priority) + }; if (!r.next()) { abort(); } ret.id = (int) r.getInt(0); } diff --git a/src/libstore/pathlocks.hh b/src/libstore/pathlocks.hh index 42a84a1a37bb..09ad123bf30a 100644 --- a/src/libstore/pathlocks.hh +++ b/src/libstore/pathlocks.hh @@ -2,6 +2,7 @@ ///@file #include "file-descriptor.hh" +#include "file-path.hh" namespace nix { diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 73d3976f43ae..17579d892dc3 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -39,7 +39,7 @@ std::pair> findGenerations(Path pro for (auto & i : readDirectory(profileDir)) { if (auto n = parseName(profileName, i.name)) { - auto path = profileDir + "/" + i.name; + auto path = profileDir / i.name; gens.push_back({ .number = *n, .path = path, @@ -255,7 +255,7 @@ time_t parseOlderThanTimeSpec(std::string_view timeSpec) void switchLink(Path link, Path target) { /* Hacky. */ - if (dirOf(target) == dirOf(link)) target = baseNameOf(target); + if (dirOf(target) == dirOf(link)) target = baseNameOf(target).native(); replaceSymlink(target, link); } @@ -310,28 +310,30 @@ Path profilesDir() auto profileRoot = isRootUser() ? rootProfilesDir() - : createNixStateDir() + "/profiles"; + : createNixStateDir() / "profiles"; createDirs(profileRoot); return profileRoot; } Path rootProfilesDir() { - return settings.nixStateDir + "/profiles/per-user/root"; + return settings.nixStateDir / "profiles/per-user/root"; } Path getDefaultProfile() { - Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile"; + Path profileLink = settings.useXDGBaseDirectories + ? createNixStateDir() / "profile" + : getHome() / ".nix-profile"; try { - auto profile = profilesDir() + "/profile"; + auto profile = profilesDir() / "profile"; if (!pathExists(profileLink)) { replaceSymlink(profile, profileLink); } // Backwards compatibiliy measure: Make root's profile available as // `.../default` as it's what NixOS and most of the init scripts expect - Path globalProfileLink = settings.nixStateDir + "/profiles/default"; + Path globalProfileLink = settings.nixStateDir / "profiles/default"; if (isRootUser() && !pathExists(globalProfileLink)) { replaceSymlink(profile, globalProfileLink); } @@ -343,12 +345,12 @@ Path getDefaultProfile() Path defaultChannelsDir() { - return profilesDir() + "/channels"; + return profilesDir() / "channels"; } Path rootChannelsDir() { - return rootProfilesDir() + "/channels"; + return rootProfilesDir() / "channels"; } } diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 3175c197870a..d281d481cc97 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -62,7 +62,7 @@ SQLite::SQLite(const Path & path, SQLiteOpenMode mode) bool immutable = mode == SQLiteOpenMode::Immutable; int flags = immutable ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE; if (mode == SQLiteOpenMode::Normal) flags |= SQLITE_OPEN_CREATE; - auto uri = "file:" + percentEncode(path) + "?immutable=" + (immutable ? "1" : "0"); + auto uri = "file:" + percentEncode(path.native()) + "?immutable=" + (immutable ? "1" : "0"); int ret = sqlite3_open_v2(uri.c_str(), &db, SQLITE_OPEN_URI | flags, vfs); if (ret != SQLITE_OK) { const char * err = sqlite3_errstr(ret); diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index 003e4d1013dc..a9a0055ecf23 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -5,6 +5,7 @@ #include #include "error.hh" +#include "file-path.hh" struct sqlite3; struct sqlite3_stmt; diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc index 04f45827943c..e634841ff354 100644 --- a/src/libstore/ssh.cc +++ b/src/libstore/ssh.cc @@ -35,7 +35,7 @@ void SSHMaster::addCommonSSHOpts(Strings & args) auto p = host.rfind("@"); std::string thost = p != std::string::npos ? std::string(host, p + 1) : host; writeFile(fileName, thost + " " + base64Decode(sshPublicHostKey) + "\n"); - args.insert(args.end(), {"-oUserKnownHostsFile=" + fileName}); + args.insert(args.end(), {"-oUserKnownHostsFile=" + fileName.native()}); } if (compress) args.push_back("-C"); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index ae8c224374fa..8d2e2c5e61c5 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -224,13 +224,13 @@ public: /** * Follow symlinks until we end up with a path in the Nix store. */ - Path followLinksToStore(std::string_view path) const; + Path followLinksToStore(PathView path) const; /** * Same as followLinksToStore(), but apply toStorePath() to the * result. */ - StorePath followLinksToStorePath(std::string_view path) const; + StorePath followLinksToStorePath(PathView path) const; /** * Check whether a path is valid. diff --git a/src/libstore/store-dir-config.hh b/src/libstore/store-dir-config.hh index 643f8854dd03..d2b63c57bdf5 100644 --- a/src/libstore/store-dir-config.hh +++ b/src/libstore/store-dir-config.hh @@ -67,7 +67,7 @@ struct StoreDirConfig : public Config * @return true if ‘path’ is a store path, i.e. a direct child of the * Nix store. */ - bool isStorePath(std::string_view path) const; + bool isStorePath(PathView path) const; /** * Split a path like /nix/store/-/ into diff --git a/src/libstore/uds-remote-store.cc b/src/libstore/uds-remote-store.cc index 649644146bf0..e8da5af38d14 100644 --- a/src/libstore/uds-remote-store.cc +++ b/src/libstore/uds-remote-store.cc @@ -52,7 +52,7 @@ UDSRemoteStore::UDSRemoteStore( std::string UDSRemoteStore::getUri() { if (path) { - return std::string("unix://") + *path; + return std::string { "unix://" } + path->native(); } else { return "daemon"; } diff --git a/src/libstore/uds-remote-store.hh b/src/libstore/uds-remote-store.hh index 8bce8994a3a4..988a6404ad94 100644 --- a/src/libstore/uds-remote-store.hh +++ b/src/libstore/uds-remote-store.hh @@ -60,7 +60,7 @@ private: }; ref openConnection() override; - std::optional path; + std::optional path; }; } diff --git a/src/libstore/unix/lock.cc b/src/libstore/unix/lock.cc index 023c74e349bf..bc1881d87a00 100644 --- a/src/libstore/unix/lock.cc +++ b/src/libstore/unix/lock.cc @@ -50,7 +50,7 @@ struct SimpleUserLock : UserLock static std::unique_ptr acquire() { assert(settings.buildUsersGroup != ""); - createDirs(settings.nixStateDir + "/userpool"); + createDirs(settings.nixStateDir / "userpool"); /* Get the members of the build-users-group. */ struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); @@ -139,14 +139,14 @@ struct AutoUserLock : UserLock assert((uint64_t) settings.startId + (uint64_t) settings.uidCount <= std::numeric_limits::max()); assert(nrIds <= maxIdsPerBuild); - createDirs(settings.nixStateDir + "/userpool2"); + createDirs(settings.nixStateDir / "userpool2"); size_t nrSlots = settings.uidCount / maxIdsPerBuild; for (size_t i = 0; i < nrSlots; i++) { debug("trying user slot '%d'", i); - createDirs(settings.nixStateDir + "/userpool2"); + createDirs(settings.nixStateDir / "userpool2"); auto fnUserLock = fmt("%s/userpool2/slot-%d", settings.nixStateDir, i); diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 04f777d00f1e..d007a8607eb0 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -30,7 +30,7 @@ static ArchiveSettings archiveSettings; static GlobalConfig::Register rArchiveSettings(&archiveSettings); -PathFilter defaultPathFilter = [](const Path &) { return true; }; +PathFilter defaultPathFilter = [](PathView) { return true; }; void SourceAccessor::dumpPath( @@ -97,7 +97,7 @@ void SourceAccessor::dumpPath( } else if (st.type == tSymlink) - sink << "type" << "symlink" << "target" << readLink(path); + sink << "type" << "symlink" << "target" << readLink(path).string(); else throw Error("file '%s' has an unsupported type", path); diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh index 28c63bb85506..c4ff8a866ca5 100644 --- a/src/libutil/archive.hh +++ b/src/libutil/archive.hh @@ -8,7 +8,6 @@ namespace nix { - /** * dumpPath creates a Nix archive of the specified path. * diff --git a/src/libutil/args.hh b/src/libutil/args.hh index 7759b74a93cc..89a5a61bbdcf 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -113,6 +113,11 @@ protected: , arity(1) { } + Handler(Path * dest) + : fun([=](std::vector ss) { *dest = ss[0]; }) + , arity(1) + { } + template Handler(T * dest, const T & val) : fun([dest, val](std::vector ss) { *dest = val; }) @@ -283,6 +288,18 @@ public: }); } + /** + * Expect a path argument. + */ + void expectArg(const std::string & label, Path * dest, bool optional = false) + { + expectArgs({ + .label = label, + .optional = optional, + .handler = {dest} + }); + } + /** * Expect 0 or more arguments. */ diff --git a/src/libutil/config-impl.hh b/src/libutil/config-impl.hh index 1da0cb6389ed..3ab645694f58 100644 --- a/src/libutil/config-impl.hh +++ b/src/libutil/config-impl.hh @@ -28,6 +28,14 @@ template<> struct BaseSetting::trait { static constexpr bool appendable = true; }; +template<> struct BaseSetting::trait +{ + static constexpr bool appendable = true; +}; +template<> struct BaseSetting::trait +{ + static constexpr bool appendable = true; +}; template<> struct BaseSetting>::trait { static constexpr bool appendable = true; @@ -48,6 +56,8 @@ bool BaseSetting::isAppendable() template<> void BaseSetting::appendOrSet(Strings newValue, bool append); template<> void BaseSetting::appendOrSet(StringSet newValue, bool append); template<> void BaseSetting::appendOrSet(StringMap newValue, bool append); +template<> void BaseSetting::appendOrSet(Paths newValue, bool append); +template<> void BaseSetting::appendOrSet(PathSet newValue, bool append); template<> void BaseSetting>::appendOrSet(std::set newValue, bool append); template @@ -109,6 +119,10 @@ DECLARE_CONFIG_SERIALISER(bool) DECLARE_CONFIG_SERIALISER(Strings) DECLARE_CONFIG_SERIALISER(StringSet) DECLARE_CONFIG_SERIALISER(StringMap) +DECLARE_CONFIG_SERIALISER(Path) +DECLARE_CONFIG_SERIALISER(std::optional) +DECLARE_CONFIG_SERIALISER(Paths) +DECLARE_CONFIG_SERIALISER(PathSet) DECLARE_CONFIG_SERIALISER(std::set) template diff --git a/src/libutil/config.hh b/src/libutil/config.hh index 07322b60d7a0..76b40887adc5 100644 --- a/src/libutil/config.hh +++ b/src/libutil/config.hh @@ -8,6 +8,7 @@ #include #include "types.hh" +#include "file-path.hh" #include "experimental-features.hh" namespace nix { @@ -350,7 +351,7 @@ public: Path parse(const std::string & str) const override; - Path operator +(const char * p) const { return value + p; } + Path operator /(PathView p) const { return value / p.native(); } void operator =(const Path & v) { this->assign(v); } }; diff --git a/src/libutil/current-process.hh b/src/libutil/current-process.hh index a5adb70cfd5b..a8423095e4b6 100644 --- a/src/libutil/current-process.hh +++ b/src/libutil/current-process.hh @@ -7,7 +7,7 @@ # include #endif -#include "types.hh" +#include "file-path.hh" namespace nix { diff --git a/src/libutil/file-path.hh b/src/libutil/file-path.hh index 6fb1001250b2..5c614596467a 100644 --- a/src/libutil/file-path.hh +++ b/src/libutil/file-path.hh @@ -10,43 +10,41 @@ namespace nix { /** * Paths are just `std::filesystem::path`s. - * - * @todo drop `NG` suffix and replace the ones in `types.hh`. */ -typedef std::filesystem::path PathNG; -typedef std::list PathsNG; -typedef std::set PathSetNG; +typedef std::filesystem::path Path; +typedef std::list Paths; +typedef std::set PathSet; /** * Stop gap until `std::filesystem::path_view` from P1030R6 exists in a * future C++ standard. * - * @todo drop `NG` suffix and replace the one in `types.hh`. + * @todo drop `` suffix and replace the one in `types.hh`. */ -struct PathViewNG : std::basic_string_view +struct PathView : std::basic_string_view { - using string_view = std::basic_string_view; + using string_view = std::basic_string_view; using string_view::string_view; - PathViewNG(const PathNG & path) - : std::basic_string_view(path.native()) + PathView(const Path & path) + : std::basic_string_view(path.native()) { } - PathViewNG(const PathNG::string_type & path) - : std::basic_string_view(path) + PathView(const Path::string_type & path) + : std::basic_string_view(path) { } const string_view & native() const { return *this; } string_view & native() { return *this; } }; -std::string os_string_to_string(PathViewNG::string_view path); +std::string os_string_to_string(PathView::string_view path); -PathNG::string_type string_to_os_string(std::string_view s); +Path::string_type string_to_os_string(std::string_view s); -std::optional maybePathNG(PathView path); +std::optional maybePath(PathView path); -PathNG pathNG(PathView path); +Path path(PathView path); } diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index b03bb767b6f1..95a8b008bc52 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -59,13 +59,12 @@ Path absPath(PathView path, std::optional dir, bool resolveSymlinks) if (!getcwd(buf, sizeof(buf))) #endif throw SysError("cannot get cwd"); - scratch = concatStrings(buf, "/", path); + scratch = Path { buf } / path; #ifdef __GNU__ free(buf); #endif } else - scratch = concatStrings(*dir, "/", path); - path = scratch; + scratch = Path { Path::string_type { *dir } } / path; } return canonPath(path, resolveSymlinks); } @@ -120,14 +119,14 @@ Path canonPath(PathView path, bool resolveSymlinks) Path dirOf(const PathView path) { - Path::size_type pos = path.rfind('/'); + PathView::size_type pos = path.rfind('/'); if (pos == path.npos) return "."; - return pos == 0 ? "/" : Path(path, 0, pos); + return pos == 0 ? "/" : Path { path.substr(0,pos) }; } -std::string_view baseNameOf(std::string_view path) +PathView baseNameOf(PathView path) { if (path.empty()) return ""; @@ -142,11 +141,11 @@ std::string_view baseNameOf(std::string_view path) else pos += 1; - return path.substr(pos, last - pos + 1); + return PathView { path.substr(pos, last - pos + 1) }; } -bool isInDir(std::string_view path, std::string_view dir) +bool isInDir(PathView path, PathView dir) { return path.substr(0, 1) == "/" && path.substr(0, dir.size()) == dir @@ -155,7 +154,7 @@ bool isInDir(std::string_view path, std::string_view dir) } -bool isDirOrInDir(std::string_view path, std::string_view dir) +bool isDirOrInDir(PathView path, PathView dir) { return path == dir || isInDir(path, dir); } @@ -314,7 +313,7 @@ void readFile(const Path & path, Sink & sink) } -void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync) +void writeFile(const Path & path, PathView s, mode_t mode, bool sync) { AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT // TODO @@ -470,25 +469,26 @@ void deletePath(const Path & path) } -Paths createDirs(const Path & path) +Paths createDirs(PathView path) { Paths created; if (path == "/") return created; struct stat st; - if (STAT(path.c_str(), &st) == -1) { + auto path2 = Path { path.native() }; + if (STAT(path2.c_str(), &st) == -1) { created = createDirs(dirOf(path)); - if (mkdir(path.c_str() + if (mkdir(path2.c_str() #ifndef _WIN32 // TODO abstract mkdir perms for Windows , 0777 #endif ) == -1 && errno != EEXIST) throw SysError("creating directory '%1%'", path); st = STAT(path); - created.push_back(path); + created.push_back(path2); } - if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1) + if (S_ISLNK(st.st_mode) && stat(path2.c_str(), &st) == -1) throw SysError("statting symlink '%1%'", path); if (!S_ISDIR(st.st_mode)) throw Error("'%1%' is not a directory", path); @@ -509,7 +509,7 @@ void deletePath(const Path & path, uint64_t & bytesFreed) AutoDelete::AutoDelete() : del{false} {} -AutoDelete::AutoDelete(const std::string & p, bool recursive) : path(p) +AutoDelete::AutoDelete(PathView p, bool recursive) : path(Path { p.native() }) { del = true; this->recursive = recursive; @@ -536,8 +536,8 @@ void AutoDelete::cancel() del = false; } -void AutoDelete::reset(const Path & p, bool recursive) { - path = p; +void AutoDelete::reset(PathView p, bool recursive) { + path = Path { p.native() }; this->recursive = recursive; del = true; } @@ -597,7 +597,7 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix, std::pair createTempFile(const Path & prefix) { - Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX"); + Path tmpl(defaultTempDir() / prefix + ".XXXXXX"); // Strictly speaking, this is UB, but who cares... // FIXME: use O_TMPFILE. AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str())); @@ -659,7 +659,7 @@ void copy(const fs::directory_entry & from, const fs::path & to, bool andDelete) { #ifndef _WIN32 // TODO: Rewrite the `is_*` to use `symlink_status()` - auto statOfFrom = lstat(from.path().c_str()); + auto statOfFrom = lstat(from.path()); #endif auto fromStatus = from.symlink_status(); diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh index 0c4e7cfdd489..8f94ae81ba67 100644 --- a/src/libutil/file-system.hh +++ b/src/libutil/file-system.hh @@ -73,25 +73,25 @@ Path canonPath(PathView path, bool resolveSymlinks = false); * immediate child thereof (e.g., `/foo`), this means `/` * is returned. */ -Path dirOf(const PathView path); +Path dirOf(PathView path); /** * @return the base name of the given canonical path, i.e., everything * following the final `/` (trailing slashes are removed). */ -std::string_view baseNameOf(std::string_view path); +PathView baseNameOf(PathView path); /** * Check whether 'path' is a descendant of 'dir'. Both paths must be * canonicalized. */ -bool isInDir(std::string_view path, std::string_view dir); +bool isInDir(PathView path, PathView dir); /** * Check whether 'path' is equal to 'dir' or a descendant of * 'dir'. Both paths must be canonicalized. */ -bool isDirOrInDir(std::string_view path, std::string_view dir); +bool isDirOrInDir(PathView path, PathView dir); /** * Get status of `path`. @@ -156,7 +156,7 @@ void readFile(const Path & path, Sink & sink); /** * Write a string to a file. */ -void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false); +void writeFile(const Path & path, PathView s, mode_t mode = 0666, bool sync = false); void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false); @@ -223,10 +223,10 @@ class AutoDelete bool recursive; public: AutoDelete(); - AutoDelete(const Path & p, bool recursive = true); + AutoDelete(PathView p, bool recursive = true); ~AutoDelete(); void cancel(); - void reset(const Path & p, bool recursive = true); + void reset(PathView p, bool recursive = true); operator Path() const { return path; } operator PathView() const { return path; } }; @@ -245,13 +245,13 @@ typedef std::unique_ptr AutoCloseDir; /** * Create a temporary directory. */ -Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", +Path createTempDir(PathView tmpRoot = "", PathView prefix = "nix", bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); /** * Create a temporary file, returning a file handle and its path. */ -std::pair createTempFile(const Path & prefix = "nix"); +std::pair createTempFile(PathView prefix = "nix"); /** * Return `TMPDIR`, or the default temporary directory if unset or empty. @@ -261,7 +261,7 @@ Path defaultTempDir(); /** * Used in various places. */ -typedef std::function PathFilter; +typedef std::function PathFilter; extern PathFilter defaultPathFilter; diff --git a/src/libutil/fs-sink.cc b/src/libutil/fs-sink.cc index 91070ea89a9a..710241ef8ae0 100644 --- a/src/libutil/fs-sink.cc +++ b/src/libutil/fs-sink.cc @@ -71,6 +71,7 @@ static GlobalConfig::Register r1(&restoreSinkSettings); void RestoreSink::createDirectory(const Path & path) { +<<<<<<< HEAD Path p = dstPath + path; if ( #ifndef _WIN32 // TODO abstract mkdir perms for Windows @@ -80,6 +81,15 @@ void RestoreSink::createDirectory(const Path & path) #endif ) throw NativeSysError("creating directory '%1%'", p); +||||||| parent of 25ef34583 (Make `Path` `std::filesystem::path` not `std::string`) + Path p = dstPath + path; + if (mkdir(p.c_str(), 0777) == -1) + throw SysError("creating directory '%1%'", p); +======= + Path p = dstPath / path; + if (mkdir(p.c_str(), 0777) == -1) + throw SysError("creating directory '%1%'", p); +>>>>>>> 25ef34583 (Make `Path` `std::filesystem::path` not `std::string`) }; struct RestoreRegularFile : CreateRegularFileSink { @@ -92,7 +102,7 @@ struct RestoreRegularFile : CreateRegularFileSink { void RestoreSink::createRegularFile(const Path & path, std::function func) { - Path p = dstPath + path; + Path p = dstPath / path; RestoreRegularFile crf; crf.fd = #ifdef _WIN32 @@ -143,7 +153,7 @@ void RestoreRegularFile::operator () (std::string_view data) void RestoreSink::createSymlink(const Path & path, const std::string & target) { - Path p = dstPath + path; + Path p = dstPath / path; nix::createSymlink(target, p); } diff --git a/src/libutil/json-utils.hh b/src/libutil/json-utils.hh index 08c98cc8c0d4..302db5ce4036 100644 --- a/src/libutil/json-utils.hh +++ b/src/libutil/json-utils.hh @@ -7,6 +7,8 @@ #include "types.hh" +#include "file-path.hh" + namespace nix { const nlohmann::json * get(const nlohmann::json & map, const std::string & key); @@ -62,6 +64,9 @@ struct json_avoids_null : std::true_type {}; template<> struct json_avoids_null : std::true_type {}; +template<> +struct json_avoids_null : std::true_type {}; + template struct json_avoids_null> : std::true_type {}; diff --git a/src/libutil/linux/cgroup.hh b/src/libutil/linux/cgroup.hh index 783a0ab87422..4124b098188f 100644 --- a/src/libutil/linux/cgroup.hh +++ b/src/libutil/linux/cgroup.hh @@ -4,7 +4,7 @@ #include #include -#include "types.hh" +#include "file-path.hh" namespace nix { diff --git a/src/libutil/types.hh b/src/libutil/types.hh index c86f52175d52..c6f821024125 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -18,14 +18,6 @@ typedef std::set StringSet; typedef std::map StringMap; typedef std::map StringPairs; -/** - * Paths are just strings. - */ -typedef std::string Path; -typedef std::string_view PathView; -typedef std::list Paths; -typedef std::set PathSet; - typedef std::vector> Headers; /** diff --git a/src/libutil/users.cc b/src/libutil/users.cc index d546e364f508..c6b93eb88c09 100644 --- a/src/libutil/users.cc +++ b/src/libutil/users.cc @@ -22,7 +22,7 @@ std::vector getConfigDirs() { Path configHome = getConfigDir(); auto configDirs = getEnv("XDG_CONFIG_DIRS").value_or("/etc/xdg"); - std::vector result = tokenizeString>(configDirs, ":"); + std::vector result = tokenizeString>(configDirs, ":"); result.insert(result.begin(), configHome); return result; } diff --git a/src/libutil/users.hh b/src/libutil/users.hh index 153cc73fdae4..f778167dce24 100644 --- a/src/libutil/users.hh +++ b/src/libutil/users.hh @@ -1,7 +1,7 @@ #pragma once ///@file -#include "types.hh" +#include "file-path.hh" #ifndef _WIN32 # include diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 46533b34bd05..460c54ddca8a 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -308,7 +308,8 @@ static void main_nix_build(int argc, char * * argv) absolute = canonPath(absPath(i), true); } catch (Error & e) {}; auto [path, outputNames] = parsePathWithOutputs(absolute); - if (evalStore->isStorePath(path) && hasSuffix(path, ".drv")) + if (evalStore->isStorePath(PathView { path }) + && hasSuffix(path, ".drv")) drvs.push_back(PackageInfo(*state, evalStore, absolute)); else /* If we're in a #! script, interpret filenames @@ -317,7 +318,7 @@ static void main_nix_build(int argc, char * * argv) state->parseExprFromFile( resolveExprPath( lookupFileArg(*state, - inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i)))); + inShebang && !packages ? absPath(i, absPath(dirOf(script))) : Path { i })))); } } diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index 9f7f557b59db..6c1c49f85490 100644 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -107,7 +107,7 @@ static void update(const StringSet & channelNames) // no need to update this channel, reuse the existing store path Path symlink = profile + "/" + name; Path storepath = dirOf(readLink(symlink)); - exprs.push_back("f: rec { name = \"" + cname + "\"; type = \"derivation\"; outputs = [\"out\"]; system = \"builtin\"; outPath = builtins.storePath \"" + storepath + "\"; out = { inherit outPath; };}"); + exprs.push_back("f: rec { name = \"" + cname + "\"; type = \"derivation\"; outputs = [\"out\"]; system = \"builtin\"; outPath = builtins.storePath \"" + storepath.native() + "\"; 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 diff --git a/tests/unit/libstore/machines.cc b/tests/unit/libstore/machines.cc index 9fd7fda54cc3..d984b5fa6761 100644 --- a/tests/unit/libstore/machines.cc +++ b/tests/unit/libstore/machines.cc @@ -143,7 +143,7 @@ TEST(machines, getMachinesWithCorrectFileReference) { auto path = absPath("tests/unit/libstore/test-data/machines.valid"); ASSERT_TRUE(pathExists(path)); - settings.builders = std::string("@") + path; + settings.builders = std::string("@") + path.native(); Machines actual = getMachines(); ASSERT_THAT(actual, SizeIs(3)); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl"))));