Use std::filesystem in eval and flake ...

... executables
This commit is contained in:
siddhantCodes 2024-08-11 19:19:46 +05:30
parent 2c12a6962e
commit 0abc664a78
2 changed files with 17 additions and 16 deletions

View File

@ -78,14 +78,14 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
if (pathExists(*writeTo)) if (pathExists(*writeTo))
throw Error("path '%s' already exists", *writeTo); throw Error("path '%s' already exists", *writeTo);
std::function<void(Value & v, const PosIdx pos, const Path & path)> recurse; std::function<void(Value & v, const PosIdx pos, const std::filesystem::path & path)> recurse;
recurse = [&](Value & v, const PosIdx pos, const Path & path) recurse = [&](Value & v, const PosIdx pos, const std::filesystem::path & path)
{ {
state->forceValue(v, pos); state->forceValue(v, pos);
if (v.type() == nString) if (v.type() == nString)
// FIXME: disallow strings with contexts? // FIXME: disallow strings with contexts?
writeFile(path, v.string_view()); writeFile(path.string(), v.string_view());
else if (v.type() == nAttrs) { else if (v.type() == nAttrs) {
if (mkdir(path.c_str() if (mkdir(path.c_str()
#ifndef _WIN32 // TODO abstract mkdir perms for Windows #ifndef _WIN32 // TODO abstract mkdir perms for Windows
@ -98,7 +98,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
try { try {
if (name == "." || name == "..") if (name == "." || name == "..")
throw Error("invalid file name '%s'", name); throw Error("invalid file name '%s'", name);
recurse(*attr.value, attr.pos, concatStrings(path, "/", name)); recurse(*attr.value, attr.pos, path / name);
} catch (Error & e) { } catch (Error & e) {
e.addTrace( e.addTrace(
state->positions[attr.pos], state->positions[attr.pos],

View File

@ -18,6 +18,7 @@
#include "markdown.hh" #include "markdown.hh"
#include "users.hh" #include "users.hh"
#include <filesystem>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <iomanip> #include <iomanip>
@ -870,27 +871,27 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
"If you've set '%s' to a string, try using a path instead.", "If you've set '%s' to a string, try using a path instead.",
templateDir, templateDirAttr->getAttrPathStr()).debugThrow(); templateDir, templateDirAttr->getAttrPathStr()).debugThrow();
std::vector<Path> changedFiles; std::vector<std::filesystem::path> changedFiles;
std::vector<Path> conflictedFiles; std::vector<std::filesystem::path> conflictedFiles;
std::function<void(const Path & from, const Path & to)> copyDir; std::function<void(const std::filesystem::path & from, const std::filesystem::path & to)> copyDir;
copyDir = [&](const Path & from, const Path & to) copyDir = [&](const std::filesystem::path & from, const std::filesystem::path & to)
{ {
createDirs(to); createDirs(to);
for (auto & entry : std::filesystem::directory_iterator{from}) { for (auto & entry : std::filesystem::directory_iterator{from}) {
checkInterrupt(); checkInterrupt();
auto from2 = entry.path().string(); auto from2 = entry.path();
auto to2 = to + "/" + entry.path().filename().string(); auto to2 = to / entry.path().filename();
auto st = lstat(from2); auto st = entry.symlink_status();
if (S_ISDIR(st.st_mode)) if (std::filesystem::is_directory(st))
copyDir(from2, to2); copyDir(from2, to2);
else if (S_ISREG(st.st_mode)) { else if (std::filesystem::is_regular_file(st)) {
auto contents = readFile(from2); auto contents = readFile(from2);
if (pathExists(to2)) { if (pathExists(to2)) {
auto contents2 = readFile(to2); auto contents2 = readFile(to2);
if (contents != contents2) { if (contents != contents2) {
printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2, from2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2.string());
conflictedFiles.push_back(to2); conflictedFiles.push_back(to2);
} else { } else {
notice("skipping identical file: %s", from2); notice("skipping identical file: %s", from2);
@ -899,11 +900,11 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
} else } else
writeFile(to2, contents); writeFile(to2, contents);
} }
else if (S_ISLNK(st.st_mode)) { else if (std::filesystem::is_symlink(st)) {
auto target = readLink(from2); auto target = readLink(from2);
if (pathExists(to2)) { if (pathExists(to2)) {
if (readLink(to2) != target) { if (readLink(to2) != target) {
printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2, from2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2.string());
conflictedFiles.push_back(to2); conflictedFiles.push_back(to2);
} else { } else {
notice("skipping identical file: %s", from2); notice("skipping identical file: %s", from2);