Merge pull request #6699 from tennox/better-flake-new-error-message

flakes: apply templates partially on conflicts
This commit is contained in:
Théophane Hufschmitt 2022-06-29 18:21:07 +02:00 committed by GitHub
commit b7eb4ac169
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 9 deletions

View file

@ -740,7 +740,8 @@ 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()); templateDir, templateDirAttr->getAttrPathStr());
std::vector<Path> files; std::vector<Path> changedFiles;
std::vector<Path> conflictedFiles;
std::function<void(const Path & from, const Path & to)> copyDir; std::function<void(const Path & from, const Path & to)> copyDir;
copyDir = [&](const Path & from, const Path & to) copyDir = [&](const Path & from, const Path & to)
@ -757,31 +758,41 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
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) {
throw Error("refusing to overwrite existing file '%s'", to2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2, from2);
conflictedFiles.push_back(to2);
} else {
notice("skipping identical file: %s", from2);
}
continue;
} else } else
writeFile(to2, contents); writeFile(to2, contents);
} }
else if (S_ISLNK(st.st_mode)) { else if (S_ISLNK(st.st_mode)) {
auto target = readLink(from2); auto target = readLink(from2);
if (pathExists(to2)) { if (pathExists(to2)) {
if (readLink(to2) != target) if (readLink(to2) != target) {
throw Error("refusing to overwrite existing symlink '%s'", to2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2, from2);
conflictedFiles.push_back(to2);
} else {
notice("skipping identical file: %s", from2);
}
continue;
} else } else
createSymlink(target, to2); createSymlink(target, to2);
} }
else else
throw Error("file '%s' has unsupported type", from2); throw Error("file '%s' has unsupported type", from2);
files.push_back(to2); changedFiles.push_back(to2);
notice("wrote: %s", to2); notice("wrote: %s", to2);
} }
}; };
copyDir(templateDir, flakeDir); copyDir(templateDir, flakeDir);
if (pathExists(flakeDir + "/.git")) { if (!changedFiles.empty() && 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 : changedFiles) args.push_back(s);
runProgram("git", true, args); runProgram("git", true, args);
} }
auto welcomeText = cursor->maybeGetAttr("welcomeText"); auto welcomeText = cursor->maybeGetAttr("welcomeText");
@ -789,6 +800,9 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
notice("\n"); notice("\n");
notice(renderMarkdownToTerminal(welcomeText->getString())); notice(renderMarkdownToTerminal(welcomeText->getString()));
} }
if (!conflictedFiles.empty())
throw Error("Encountered %d conflicts - see above", conflictedFiles.size());
} }
}; };

View file

@ -408,8 +408,10 @@ cat > $templatesDir/trivial/flake.nix <<EOF
}; };
} }
EOF EOF
echo a > $templatesDir/trivial/a
echo b > $templatesDir/trivial/b
git -C $templatesDir add flake.nix trivial/flake.nix git -C $templatesDir add flake.nix trivial/
git -C $templatesDir commit -m 'Initial' git -C $templatesDir commit -m 'Initial'
nix flake check templates nix flake check templates
@ -424,6 +426,18 @@ nix flake show $flake7Dir
nix flake show $flake7Dir --json | jq nix flake show $flake7Dir --json | jq
git -C $flake7Dir commit -a -m 'Initial' git -C $flake7Dir commit -a -m 'Initial'
# Test 'nix flake init' with benign conflicts
rm -rf $flake7Dir && mkdir $flake7Dir && git -C $flake7Dir init
echo a > $flake7Dir/a
(cd $flake7Dir && nix flake init) # check idempotence
# Test 'nix flake init' with conflicts
rm -rf $flake7Dir && mkdir $flake7Dir && git -C $flake7Dir init
echo b > $flake7Dir/a
pushd $flake7Dir
(! nix flake init) |& grep "refusing to overwrite existing file '$flake7Dir/a'"
popd
# Test 'nix flake new'. # Test 'nix flake new'.
rm -rf $flake6Dir rm -rf $flake6Dir
nix flake new -t templates#trivial $flake6Dir nix flake new -t templates#trivial $flake6Dir