aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmd')
-rw-r--r--src/libcmd/installable-flake.cc9
-rw-r--r--src/libcmd/repl-interacter.cc33
-rw-r--r--src/libcmd/repl-interacter.hh5
-rw-r--r--src/libcmd/repl.cc11
4 files changed, 54 insertions, 4 deletions
diff --git a/src/libcmd/installable-flake.cc b/src/libcmd/installable-flake.cc
index 615f70945..46bdd411b 100644
--- a/src/libcmd/installable-flake.cc
+++ b/src/libcmd/installable-flake.cc
@@ -105,9 +105,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
fmt("while evaluating the flake output attribute '%s'", attrPath)))
{
return { *derivedPathWithInfo };
+ } else {
+ throw Error(
+ "expected flake output attribute '%s' to be a derivation or path but found %s: %s",
+ attrPath,
+ showType(v),
+ ValuePrinter(*this->state, v, errorPrintOptions)
+ );
}
- else
- throw Error("flake output attribute '%s' is not a derivation or path", attrPath);
}
auto drvPath = attr->forceDerivation();
diff --git a/src/libcmd/repl-interacter.cc b/src/libcmd/repl-interacter.cc
index 829383add..41589cda1 100644
--- a/src/libcmd/repl-interacter.cc
+++ b/src/libcmd/repl-interacter.cc
@@ -1,6 +1,8 @@
#include <cstdio>
#include <iostream>
#include <string>
+#include <string_view>
+#include <cerrno>
#ifdef READLINE
#include <readline/history.h>
@@ -175,14 +177,43 @@ bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptT
if (!s)
return false;
+
+ this->writeHistory();
input += s;
input += '\n';
return true;
}
+void ReadlineLikeInteracter::writeHistory()
+{
+ int ret = write_history(historyFile.c_str());
+ int writeHistErr = errno;
+
+ if (ret == 0) {
+ return;
+ }
+
+ // If the open fails, editline returns EOF. If the close fails, editline
+ // forwards the return value of fclose(), which is EOF on error.
+ // readline however, returns the errno.
+ // So if we didn't get exactly EOF, then consider the return value the error
+ // code; otherwise use the errno we saved above.
+ // https://github.com/troglobit/editline/issues/66
+ if (ret != EOF) {
+ writeHistErr = ret;
+ }
+
+ // In any of these cases, we should explicitly ignore the error, but log
+ // them so the user isn't confused why their history is getting eaten.
+
+ std::string_view const errMsg(std::strerror(writeHistErr));
+ warn("ignoring error writing repl history to %s: %s", this->historyFile, errMsg);
+
+}
+
ReadlineLikeInteracter::~ReadlineLikeInteracter()
{
- write_history(historyFile.c_str());
+ this->writeHistory();
}
AutomationInteracter::Guard AutomationInteracter::init(detail::ReplCompleterMixin *)
diff --git a/src/libcmd/repl-interacter.hh b/src/libcmd/repl-interacter.hh
index c31b1a1e6..8f815fceb 100644
--- a/src/libcmd/repl-interacter.hh
+++ b/src/libcmd/repl-interacter.hh
@@ -42,6 +42,11 @@ public:
}
virtual Guard init(detail::ReplCompleterMixin * repl) override;
virtual bool getLine(std::string & input, ReplPromptType promptType) override;
+ /** Writes the current history to the history file.
+ *
+ * This function logs but ignores errors from readline's write_history().
+ */
+ virtual void writeHistory();
virtual ~ReadlineLikeInteracter() override;
};
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 525c25560..46b6d57ed 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -90,7 +90,8 @@ struct NixRepl
Strings loadedFiles;
std::function<AnnotatedValues()> getValues;
- const static int envSize = 32768;
+ // Uses 8MiB of memory. It's fine.
+ const static int envSize = 1 << 20;
std::shared_ptr<StaticEnv> staticEnv;
Env * env;
int displ;
@@ -375,6 +376,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
// Quietly ignore evaluation errors.
} catch (BadURL & e) {
// Quietly ignore BadURL flake-related errors.
+ } catch (SysError & e) {
+ // Quietly ignore system errors which can for example be raised by
+ // a non-existent file being `import`-ed.
}
}
@@ -854,6 +858,11 @@ void NixRepl::loadReplOverlays()
replInitFilesFunction->determinePos(noPos)
);
+ // n.b. this does in fact load the stuff into the environment twice (once
+ // from the superset of the environment returned by repl-overlays and once
+ // from the thing itself), but it's not fixable because clearEnv here could
+ // lead to dangling references to the old environment in thunks.
+ // https://git.lix.systems/lix-project/lix/issues/337#issuecomment-3745
addAttrsToScope(newAttrs);
}