diff --git a/doc/manual/rl-next/assess-profile-generations.md b/doc/manual/rl-next/assess-profile-generations.md new file mode 100644 index 000000000..ef25cc4ce --- /dev/null +++ b/doc/manual/rl-next/assess-profile-generations.md @@ -0,0 +1,12 @@ +--- +synopsis: Assess current profile generations pointers in `nix doctor` +cls: [3108] +category: Improvements +credits: [raito] +--- + +Added a new check to `nix doctor` that verifies whether the current generation of +a Nix profile can be resolved. This helps users diagnose issues with broken or +misconfigured profile symlinks. + +This helps determining if you have broken symlinks or misconfigured packaging. diff --git a/lix/nix/doctor.cc b/lix/nix/doctor.cc index 05b5d5203..594a46bde 100644 --- a/lix/nix/doctor.cc +++ b/lix/nix/doctor.cc @@ -8,6 +8,7 @@ #include "lix/libstore/local-fs-store.hh" #include "lix/libstore/worker-protocol.hh" #include "lix/libutil/exit.hh" +#include "lix/libstore/profiles.hh" #include "doctor.hh" namespace nix { @@ -69,6 +70,10 @@ struct CmdDoctor : StoreCommand } success &= checkStoreProtocol(aio().blockOn(store->getProtocol())); checkTrustedUser(store); + { + Path profile = getEnv("NIX_PROFILE").value_or(getDefaultProfile()); + checkValidCurrentProfileGeneration(profile); + } if (!success) throw Exit(2); @@ -152,6 +157,31 @@ struct CmdDoctor : StoreCommand std::string_view trustedness = trustedMay ? (*trustedMay ? "trusted" : "not trusted") : "unknown trust"; checkInfo(fmt("You are %s by store uri: %s", trustedness, store->getUri())); } + + void checkValidCurrentProfileGeneration(const Path & profile) + { + Generations generations; + std::optional currentGeneration; + std::string errStr; + + try { + std::tie(generations, currentGeneration) = findGenerations(profile); + } catch (SysError const & e) { + errStr = fmt(": %s", e.msg()); + } + + if (!currentGeneration) { + std::stringstream ss; + ss << "Error: current generation cannot be discovered for profile: '" << profile << "'"; + ss << errStr << "\n"; + checkFail(ss.str()); + } else { + std::stringstream ss; + ss << "You have " << generations.size() << " generations for profile '" << profile << "'\n"; + ss << "The current generation number is '" << *currentGeneration << "'\n"; + checkPass(ss.str()); + } + } }; void registerNixDoctor()