mirror of
https://github.com/NixOS/nix.git
synced 2025-12-14 04:51:05 +01:00
Convert profiles to use std::filesystem::path
Co-authored-by: Vinayak Goyal <vinayakankugoyal@gmail.com> Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
This commit is contained in:
parent
c7b61f3d13
commit
504c5e7cf9
20 changed files with 154 additions and 103 deletions
|
|
@ -31,12 +31,12 @@ static std::optional<GenerationNumber> parseName(const std::string & profileName
|
|||
return {};
|
||||
}
|
||||
|
||||
std::pair<Generations, std::optional<GenerationNumber>> findGenerations(Path profile)
|
||||
std::pair<Generations, std::optional<GenerationNumber>> findGenerations(std::filesystem::path profile)
|
||||
{
|
||||
Generations gens;
|
||||
|
||||
std::filesystem::path profileDir = dirOf(profile);
|
||||
auto profileName = std::string(baseNameOf(profile));
|
||||
std::filesystem::path profileDir = profile.parent_path();
|
||||
auto profileName = profile.filename().string();
|
||||
|
||||
for (auto & i : DirectoryIterator{profileDir}) {
|
||||
checkInterrupt();
|
||||
|
|
@ -48,18 +48,20 @@ std::pair<Generations, std::optional<GenerationNumber>> findGenerations(Path pro
|
|||
|
||||
gens.sort([](const Generation & a, const Generation & b) { return a.number < b.number; });
|
||||
|
||||
return {gens, pathExists(profile) ? parseName(profileName, readLink(profile)) : std::nullopt};
|
||||
return {gens, pathExists(profile) ? parseName(profileName, readLink(profile).string()) : std::nullopt};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a generation name that can be parsed by `parseName()`.
|
||||
*/
|
||||
static Path makeName(const Path & profile, GenerationNumber num)
|
||||
static std::filesystem::path makeName(const std::filesystem::path & profile, GenerationNumber num)
|
||||
{
|
||||
return fmt("%s-%s-link", profile, num);
|
||||
/* NB std::filesystem::path when put in format strings is
|
||||
quoted automatically. */
|
||||
return fmt("%s-%s-link", profile.string(), num);
|
||||
}
|
||||
|
||||
Path createGeneration(LocalFSStore & store, Path profile, StorePath outPath)
|
||||
std::filesystem::path createGeneration(LocalFSStore & store, std::filesystem::path profile, StorePath outPath)
|
||||
{
|
||||
/* The new generation number should be higher than old the
|
||||
previous ones. */
|
||||
|
|
@ -90,21 +92,24 @@ Path createGeneration(LocalFSStore & store, Path profile, StorePath outPath)
|
|||
to the permanent roots (of which the GC would have a stale
|
||||
view). If we didn't do it this way, the GC might remove the
|
||||
user environment etc. we've just built. */
|
||||
Path generation = makeName(profile, num + 1);
|
||||
store.addPermRoot(outPath, generation);
|
||||
auto generation = makeName(profile, num + 1);
|
||||
store.addPermRoot(outPath, generation.string());
|
||||
|
||||
return generation;
|
||||
}
|
||||
|
||||
static void removeFile(const Path & path)
|
||||
static void removeFile(const std::filesystem::path & path)
|
||||
{
|
||||
if (remove(path.c_str()) == -1)
|
||||
throw SysError("cannot unlink '%1%'", path);
|
||||
try {
|
||||
std::filesystem::remove(path);
|
||||
} catch (std::filesystem::filesystem_error & e) {
|
||||
throw SysError("removing file '%1%'", path);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteGeneration(const Path & profile, GenerationNumber gen)
|
||||
void deleteGeneration(const std::filesystem::path & profile, GenerationNumber gen)
|
||||
{
|
||||
Path generation = makeName(profile, gen);
|
||||
std::filesystem::path generation = makeName(profile, gen);
|
||||
removeFile(generation);
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +122,7 @@ void deleteGeneration(const Path & profile, GenerationNumber gen)
|
|||
*
|
||||
* - We only actually delete if `dryRun` is false.
|
||||
*/
|
||||
static void deleteGeneration2(const Path & profile, GenerationNumber gen, bool dryRun)
|
||||
static void deleteGeneration2(const std::filesystem::path & profile, GenerationNumber gen, bool dryRun)
|
||||
{
|
||||
if (dryRun)
|
||||
notice("would remove profile version %1%", gen);
|
||||
|
|
@ -127,7 +132,8 @@ static void deleteGeneration2(const Path & profile, GenerationNumber gen, bool d
|
|||
}
|
||||
}
|
||||
|
||||
void deleteGenerations(const Path & profile, const std::set<GenerationNumber> & gensToDelete, bool dryRun)
|
||||
void deleteGenerations(
|
||||
const std::filesystem::path & profile, const std::set<GenerationNumber> & gensToDelete, bool dryRun)
|
||||
{
|
||||
PathLocks lock;
|
||||
lockProfile(lock, profile);
|
||||
|
|
@ -153,7 +159,7 @@ static inline void iterDropUntil(Generations & gens, auto && i, auto && cond)
|
|||
;
|
||||
}
|
||||
|
||||
void deleteGenerationsGreaterThan(const Path & profile, GenerationNumber max, bool dryRun)
|
||||
void deleteGenerationsGreaterThan(const std::filesystem::path & profile, GenerationNumber max, bool dryRun)
|
||||
{
|
||||
if (max == 0)
|
||||
throw Error("Must keep at least one generation, otherwise the current one would be deleted");
|
||||
|
|
@ -178,7 +184,7 @@ void deleteGenerationsGreaterThan(const Path & profile, GenerationNumber max, bo
|
|||
deleteGeneration2(profile, i->number, dryRun);
|
||||
}
|
||||
|
||||
void deleteOldGenerations(const Path & profile, bool dryRun)
|
||||
void deleteOldGenerations(const std::filesystem::path & profile, bool dryRun)
|
||||
{
|
||||
PathLocks lock;
|
||||
lockProfile(lock, profile);
|
||||
|
|
@ -190,7 +196,7 @@ void deleteOldGenerations(const Path & profile, bool dryRun)
|
|||
deleteGeneration2(profile, i.number, dryRun);
|
||||
}
|
||||
|
||||
void deleteGenerationsOlderThan(const Path & profile, time_t t, bool dryRun)
|
||||
void deleteGenerationsOlderThan(const std::filesystem::path & profile, time_t t, bool dryRun)
|
||||
{
|
||||
PathLocks lock;
|
||||
lockProfile(lock, profile);
|
||||
|
|
@ -238,16 +244,16 @@ time_t parseOlderThanTimeSpec(std::string_view timeSpec)
|
|||
return curTime - *days * 24 * 3600;
|
||||
}
|
||||
|
||||
void switchLink(Path link, Path target)
|
||||
void switchLink(std::filesystem::path link, std::filesystem::path target)
|
||||
{
|
||||
/* Hacky. */
|
||||
if (dirOf(target) == dirOf(link))
|
||||
target = baseNameOf(target);
|
||||
if (target.parent_path() == link.parent_path())
|
||||
target = target.filename();
|
||||
|
||||
replaceSymlink(target, link);
|
||||
}
|
||||
|
||||
void switchGeneration(const Path & profile, std::optional<GenerationNumber> dstGen, bool dryRun)
|
||||
void switchGeneration(const std::filesystem::path & profile, std::optional<GenerationNumber> dstGen, bool dryRun)
|
||||
{
|
||||
PathLocks lock;
|
||||
lockProfile(lock, profile);
|
||||
|
|
@ -274,44 +280,47 @@ void switchGeneration(const Path & profile, std::optional<GenerationNumber> dstG
|
|||
switchLink(profile, dst->path);
|
||||
}
|
||||
|
||||
void lockProfile(PathLocks & lock, const Path & profile)
|
||||
void lockProfile(PathLocks & lock, const std::filesystem::path & profile)
|
||||
{
|
||||
lock.lockPaths({profile}, fmt("waiting for lock on profile '%1%'", profile));
|
||||
lock.setDeletion(true);
|
||||
}
|
||||
|
||||
std::string optimisticLockProfile(const Path & profile)
|
||||
std::string optimisticLockProfile(const std::filesystem::path & profile)
|
||||
{
|
||||
return pathExists(profile) ? readLink(profile) : "";
|
||||
return pathExists(profile) ? readLink(profile).string() : "";
|
||||
}
|
||||
|
||||
Path profilesDir()
|
||||
std::filesystem::path profilesDir()
|
||||
{
|
||||
auto profileRoot = isRootUser() ? rootProfilesDir() : createNixStateDir() + "/profiles";
|
||||
auto profileRoot = isRootUser() ? rootProfilesDir() : std::filesystem::path{createNixStateDir()} / "profiles";
|
||||
createDirs(profileRoot);
|
||||
return profileRoot;
|
||||
}
|
||||
|
||||
Path rootProfilesDir()
|
||||
std::filesystem::path rootProfilesDir()
|
||||
{
|
||||
return settings.nixStateDir + "/profiles/per-user/root";
|
||||
return std::filesystem::path{settings.nixStateDir} / "profiles/per-user/root";
|
||||
}
|
||||
|
||||
Path getDefaultProfile()
|
||||
std::filesystem::path getDefaultProfile()
|
||||
{
|
||||
Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile";
|
||||
std::filesystem::path profileLink = settings.useXDGBaseDirectories
|
||||
? std::filesystem::path{createNixStateDir()} / "profile"
|
||||
: std::filesystem::path{getHome()} / ".nix-profile";
|
||||
try {
|
||||
auto profile = profilesDir() + "/profile";
|
||||
auto profile = profilesDir() / "profile";
|
||||
if (!pathExists(profileLink)) {
|
||||
replaceSymlink(profile, profileLink);
|
||||
}
|
||||
// Backwards compatibility 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";
|
||||
auto globalProfileLink = std::filesystem::path{settings.nixStateDir} / "profiles" / "default";
|
||||
if (isRootUser() && !pathExists(globalProfileLink)) {
|
||||
replaceSymlink(profile, globalProfileLink);
|
||||
}
|
||||
return absPath(readLink(profileLink), dirOf(profileLink));
|
||||
auto linkDir = profileLink.parent_path();
|
||||
return absPath(readLink(profileLink), &linkDir);
|
||||
} catch (Error &) {
|
||||
return profileLink;
|
||||
} catch (std::filesystem::filesystem_error &) {
|
||||
|
|
@ -319,14 +328,14 @@ Path getDefaultProfile()
|
|||
}
|
||||
}
|
||||
|
||||
Path defaultChannelsDir()
|
||||
std::filesystem::path defaultChannelsDir()
|
||||
{
|
||||
return profilesDir() + "/channels";
|
||||
return profilesDir() / "channels";
|
||||
}
|
||||
|
||||
Path rootChannelsDir()
|
||||
std::filesystem::path rootChannelsDir()
|
||||
{
|
||||
return rootProfilesDir() + "/channels";
|
||||
return rootProfilesDir() / "channels";
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue