1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-09-19 10:50:24 -04:00

Add the ability to import/export from/to a file

Allow specifying a file in `nix store export` and `nix store import`.

Also refuse to write binary things to the terminal unless explicitly
asked to.
This commit is contained in:
Théophane Hufschmitt 2023-11-27 20:55:38 +01:00
parent 1a3c3224d3
commit 3929d27ea4
2 changed files with 62 additions and 2 deletions

View file

@ -44,6 +44,19 @@ struct CmdStoreExport : StorePathsCommand, MixImportExport
;
}
std::optional<Path> outputFile = std::nullopt;
CmdStoreExport()
{
addFlag({
.longName = "output-file",
.description = "Write the archive to the given file instead of stdout.",
.labels = {"file"},
.handler = {&outputFile},
});
}
void run(ref<Store> store, StorePaths && storePaths) override
{
@ -54,7 +67,22 @@ struct CmdStoreExport : StorePathsCommand, MixImportExport
StorePathSet pathsAsSet;
pathsAsSet.insert(storePaths.begin(), storePaths.end());
FdSink sink(STDOUT_FILENO);
auto sink = [&]() -> FdSink {
if (outputFile) {
if (*outputFile == "-") {
return FdSink(STDOUT_FILENO);
} else {
auto fd = open(outputFile->c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
return FdSink(fd);
}
} else if (isatty(STDOUT_FILENO)) {
throw Error("Refusing to write binary data to a terminal. Use `--output-file` to specify a file to write to.");
} else {
return FdSink(STDOUT_FILENO);
}
}();
store->exportPaths(pathsAsSet, sink);
sink.flush();
}
@ -73,9 +101,27 @@ struct CmdStoreImport : StoreCommand, MixImportExport
;
}
std::optional<Path> inputFile = std::nullopt;
CmdStoreImport() {
addFlag({
.longName = "input-file",
.description = "Read the archive from the given file instead of stdin.",
.labels = {"file"},
.handler = {&inputFile},
});
}
void run(ref<Store> store) override
{
FdSource source(STDIN_FILENO);
FdSource source = [&]() -> FdSource {
if (inputFile && *inputFile != "-") {
auto fd = open(inputFile->c_str(), O_RDONLY);
return FdSource(fd);
} else {
return FdSource(STDIN_FILENO);
}
}();
auto paths = store->importPaths(source, NoCheckSigs);
for (auto & path : paths)

View file

@ -22,3 +22,17 @@ for IMPORTED_STORE_PATH in $IMPORTED_STORE_PATHS; do
nix path-info "$IMPORTED_STORE_PATH" ||
fail "path $BUILT_STORE_PATH should have been imported but isn't valid"
done
faketty () {
# Run a command in a pseudo-terminal.
script -qefc "$(printf "%q " "$@")" /dev/null
}
! faketty nix store export --format binary --recursive $BUILT_STORE_PATHS > /dev/null || \
fail "nix store export should refuse to write in a tty by default"
faketty nix store export --format binary --recursive $BUILT_STORE_PATHS --output-file - > /dev/null || \
fail "nix store export should accept to write in a tty if explicitly asked to"
nix store export --format binary --recursive $BUILT_STORE_PATHS --output-file "$TEST_ROOT/store-export2"
diff "$TEST_ROOT/store-export" "$TEST_ROOT/store-export2" || \
fail '`nix store export --output-file blah` should be equivalent to `nix store export > blah`'