nix flake init: Fix

This commit is contained in:
Eelco Dolstra 2022-06-01 13:54:34 +02:00
parent da553de7b1
commit b01ee2a93d
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
2 changed files with 32 additions and 34 deletions

View file

@ -106,13 +106,16 @@ struct SourcePath
{ return accessor.pathExists(path); } { return accessor.pathExists(path); }
InputAccessor::Stat lstat() const InputAccessor::Stat lstat() const
{ return accessor.lstat(path); } { return accessor.lstat(path); }
std::optional<InputAccessor::Stat> maybeLstat() const std::optional<InputAccessor::Stat> maybeLstat() const
{ return accessor.maybeLstat(path); } { return accessor.maybeLstat(path); }
InputAccessor::DirEntries readDirectory() const InputAccessor::DirEntries readDirectory() const
{ return accessor.readDirectory(path); } { return accessor.readDirectory(path); }
std::string readLink() const
{ return accessor.readLink(path); }
void dumpPath( void dumpPath(
Sink & sink, Sink & sink,

View file

@ -727,44 +727,39 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
auto cursor = installable.getCursor(*evalState); auto cursor = installable.getCursor(*evalState);
auto templateDirAttr = cursor->getAttr("path"); auto templateDirAttr = cursor->getAttr("path")->forceValue();
auto templateDir = templateDirAttr->getString(); PathSet context;
auto templateDir = evalState->coerceToPath(noPos, templateDirAttr, context);
if (!store->isInStore(templateDir)) std::vector<CanonPath> files;
throw TypeError(
"'%s' was not found in the Nix store\n"
"If you've set '%s' to a string, try using a path instead.",
templateDir, templateDirAttr->getAttrPathStr());
std::vector<Path> files; std::function<void(const SourcePath & from, const CanonPath & to)> copyDir;
copyDir = [&](const SourcePath & from, const CanonPath & to)
std::function<void(const Path & from, const Path & to)> copyDir;
copyDir = [&](const Path & from, const Path & to)
{ {
createDirs(to); createDirs(to.abs());
for (auto & entry : readDirectory(from)) { for (auto & [name, entry] : from.readDirectory()) {
auto from2 = from + "/" + entry.name; auto from2 = from + name;
auto to2 = to + "/" + entry.name; auto to2 = to + name;
auto st = lstat(from2); auto st = from2.lstat();
if (S_ISDIR(st.st_mode)) if (st.type == InputAccessor::tDirectory)
copyDir(from2, to2); copyDir(from2, to2);
else if (S_ISREG(st.st_mode)) { else if (st.type == InputAccessor::tRegular) {
auto contents = readFile(from2); auto contents = from2.readFile();
if (pathExists(to2)) { if (pathExists(to2.abs())) {
auto contents2 = readFile(to2); auto contents2 = readFile(to2.abs());
if (contents != contents2) if (contents != contents2)
throw Error("refusing to overwrite existing file '%s'", to2); throw Error("refusing to overwrite existing file '%s'", to2);
} else } else
writeFile(to2, contents); writeFile(to2.abs(), contents);
} }
else if (S_ISLNK(st.st_mode)) { else if (st.type == InputAccessor::tSymlink) {
auto target = readLink(from2); auto target = from2.readLink();
if (pathExists(to2)) { if (pathExists(to2.abs())) {
if (readLink(to2) != target) if (readLink(to2.abs()) != target)
throw Error("refusing to overwrite existing symlink '%s'", to2); throw Error("refusing to overwrite existing symlink '%s'", to2);
} else } else
createSymlink(target, to2); createSymlink(target, to2.abs());
} }
else else
throw Error("file '%s' has unsupported type", from2); throw Error("file '%s' has unsupported type", from2);
@ -773,15 +768,15 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
} }
}; };
copyDir(templateDir, flakeDir); copyDir(templateDir, CanonPath(flakeDir));
if (pathExists(flakeDir + "/.git")) { if (pathExists(flakeDir + "/.git")) {
Strings args = { "-C", flakeDir, "add", "--intent-to-add", "--force", "--" }; Strings args = { "-C", flakeDir, "add", "--intent-to-add", "--force", "--" };
for (auto & s : files) args.push_back(s); for (auto & s : files) args.push_back(s.abs());
runProgram("git", true, args); runProgram("git", true, args);
} }
auto welcomeText = cursor->maybeGetAttr("welcomeText");
if (welcomeText) { if (auto welcomeText = cursor->maybeGetAttr("welcomeText")) {
notice("\n"); notice("\n");
notice(renderMarkdownToTerminal(welcomeText->getString())); notice(renderMarkdownToTerminal(welcomeText->getString()));
} }