aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/builtins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/builtins')
-rw-r--r--src/libstore/builtins/buildenv.cc140
-rw-r--r--src/libstore/builtins/buildenv.hh21
-rw-r--r--src/libstore/builtins/fetchurl.cc14
3 files changed, 96 insertions, 79 deletions
diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc
index 096593886..802fb87bc 100644
--- a/src/libstore/builtins/buildenv.cc
+++ b/src/libstore/builtins/buildenv.cc
@@ -1,4 +1,4 @@
-#include "builtins.hh"
+#include "buildenv.hh"
#include <sys/stat.h>
#include <sys/types.h>
@@ -7,16 +7,14 @@
namespace nix {
-typedef std::map<Path,int> Priorities;
-
-// FIXME: change into local variables.
-
-static Priorities priorities;
-
-static unsigned long symlinks;
+struct State
+{
+ std::map<Path, int> priorities;
+ unsigned long symlinks = 0;
+};
/* For each activated package, create symlinks */
-static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
+static void createLinks(State & state, const Path & srcDir, const Path & dstDir, int priority)
{
DirEntries srcFiles;
@@ -24,7 +22,10 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
srcFiles = readDirectory(srcDir);
} catch (SysError & e) {
if (e.errNo == ENOTDIR) {
- printError("warning: not including '%s' in the user environment because it's not a directory", srcDir);
+ logWarning({
+ .name = "Create links - directory",
+ .hint = hintfmt("not including '%s' in the user environment because it's not a directory", srcDir)
+ });
return;
}
throw;
@@ -43,7 +44,10 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
throw SysError("getting status of '%1%'", srcFile);
} catch (SysError & e) {
if (e.errNo == ENOENT || e.errNo == ENOTDIR) {
- printError("warning: skipping dangling symlink '%s'", dstFile);
+ logWarning({
+ .name = "Create links - skipping symlink",
+ .hint = hintfmt("skipping dangling symlink '%s'", dstFile)
+ });
continue;
}
throw;
@@ -67,22 +71,22 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
auto res = lstat(dstFile.c_str(), &dstSt);
if (res == 0) {
if (S_ISDIR(dstSt.st_mode)) {
- createLinks(srcFile, dstFile, priority);
+ createLinks(state, srcFile, dstFile, priority);
continue;
} else if (S_ISLNK(dstSt.st_mode)) {
auto target = canonPath(dstFile, true);
if (!S_ISDIR(lstat(target).st_mode))
throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target);
if (unlink(dstFile.c_str()) == -1)
- throw SysError(format("unlinking '%1%'") % dstFile);
+ throw SysError("unlinking '%1%'", dstFile);
if (mkdir(dstFile.c_str(), 0755) == -1)
- throw SysError(format("creating directory '%1%'"));
- createLinks(target, dstFile, priorities[dstFile]);
- createLinks(srcFile, dstFile, priority);
+ throw SysError("creating directory '%1%'", dstFile);
+ createLinks(state, target, dstFile, state.priorities[dstFile]);
+ createLinks(state, srcFile, dstFile, priority);
continue;
}
} else if (errno != ENOENT)
- throw SysError(format("getting status of '%1%'") % dstFile);
+ throw SysError("getting status of '%1%'", dstFile);
}
else {
@@ -90,7 +94,7 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
auto res = lstat(dstFile.c_str(), &dstSt);
if (res == 0) {
if (S_ISLNK(dstSt.st_mode)) {
- auto prevPriority = priorities[dstFile];
+ auto prevPriority = state.priorities[dstFile];
if (prevPriority == priority)
throw Error(
"packages '%1%' and '%2%' have the same priority %3%; "
@@ -101,49 +105,65 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
if (prevPriority < priority)
continue;
if (unlink(dstFile.c_str()) == -1)
- throw SysError(format("unlinking '%1%'") % dstFile);
+ throw SysError("unlinking '%1%'", dstFile);
} else if (S_ISDIR(dstSt.st_mode))
throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile);
} else if (errno != ENOENT)
- throw SysError(format("getting status of '%1%'") % dstFile);
+ throw SysError("getting status of '%1%'", dstFile);
}
createSymlink(srcFile, dstFile);
- priorities[dstFile] = priority;
- symlinks++;
+ state.priorities[dstFile] = priority;
+ state.symlinks++;
}
}
-typedef std::set<Path> FileProp;
+void buildProfile(const Path & out, Packages && pkgs)
+{
+ State state;
-static FileProp done;
-static FileProp postponed = FileProp{};
+ std::set<Path> done, postponed;
-static Path out;
+ auto addPkg = [&](const Path & pkgDir, int priority) {
+ if (!done.insert(pkgDir).second) return;
+ createLinks(state, pkgDir, out, priority);
-static void addPkg(const Path & pkgDir, int priority)
-{
- if (!done.insert(pkgDir).second) return;
- createLinks(pkgDir, out, priority);
+ try {
+ for (const auto & p : tokenizeString<std::vector<string>>(
+ readFile(pkgDir + "/nix-support/propagated-user-env-packages"), " \n"))
+ if (!done.count(p))
+ postponed.insert(p);
+ } catch (SysError & e) {
+ if (e.errNo != ENOENT && e.errNo != ENOTDIR) throw;
+ }
+ };
- try {
- for (const auto & p : tokenizeString<std::vector<string>>(
- readFile(pkgDir + "/nix-support/propagated-user-env-packages"), " \n"))
- if (!done.count(p))
- postponed.insert(p);
- } catch (SysError & e) {
- if (e.errNo != ENOENT && e.errNo != ENOTDIR) throw;
- }
-}
+ /* Symlink to the packages that have been installed explicitly by the
+ * user. Process in priority order to reduce unnecessary
+ * symlink/unlink steps.
+ */
+ std::sort(pkgs.begin(), pkgs.end(), [](const Package & a, const Package & b) {
+ return a.priority < b.priority || (a.priority == b.priority && a.path < b.path);
+ });
+ for (const auto & pkg : pkgs)
+ if (pkg.active)
+ addPkg(pkg.path, pkg.priority);
-struct Package {
- Path path;
- bool active;
- int priority;
- Package(Path path, bool active, int priority) : path{path}, active{active}, priority{priority} {}
-};
+ /* Symlink to the packages that have been "propagated" by packages
+ * installed by the user (i.e., package X declares that it wants Y
+ * installed as well). We do these later because they have a lower
+ * priority in case of collisions.
+ */
+ auto priorityCounter = 1000;
+ while (!postponed.empty()) {
+ std::set<Path> pkgDirs;
+ postponed.swap(pkgDirs);
+ for (const auto & pkgDir : pkgDirs)
+ addPkg(pkgDir, priorityCounter++);
+ }
-typedef std::vector<Package> Packages;
+ debug("created %d symlinks in user environment", state.symlinks);
+}
void builtinBuildenv(const BasicDerivation & drv)
{
@@ -153,7 +173,7 @@ void builtinBuildenv(const BasicDerivation & drv)
return i->second;
};
- out = getAttr("out");
+ Path out = getAttr("out");
createDirs(out);
/* Convert the stuff we get from the environment back into a
@@ -171,31 +191,7 @@ void builtinBuildenv(const BasicDerivation & drv)
}
}
- /* Symlink to the packages that have been installed explicitly by the
- * user. Process in priority order to reduce unnecessary
- * symlink/unlink steps.
- */
- std::sort(pkgs.begin(), pkgs.end(), [](const Package & a, const Package & b) {
- return a.priority < b.priority || (a.priority == b.priority && a.path < b.path);
- });
- for (const auto & pkg : pkgs)
- if (pkg.active)
- addPkg(pkg.path, pkg.priority);
-
- /* Symlink to the packages that have been "propagated" by packages
- * installed by the user (i.e., package X declares that it wants Y
- * installed as well). We do these later because they have a lower
- * priority in case of collisions.
- */
- auto priorityCounter = 1000;
- while (!postponed.empty()) {
- auto pkgDirs = postponed;
- postponed = FileProp{};
- for (const auto & pkgDir : pkgDirs)
- addPkg(pkgDir, priorityCounter++);
- }
-
- printError("created %d symlinks in user environment", symlinks);
+ buildProfile(out, std::move(pkgs));
createSymlink(getAttr("manifest"), out + "/manifest.nix");
}
diff --git a/src/libstore/builtins/buildenv.hh b/src/libstore/builtins/buildenv.hh
new file mode 100644
index 000000000..0a37459b0
--- /dev/null
+++ b/src/libstore/builtins/buildenv.hh
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "derivations.hh"
+#include "store-api.hh"
+
+namespace nix {
+
+struct Package {
+ Path path;
+ bool active;
+ int priority;
+ Package(Path path, bool active, int priority) : path{path}, active{active}, priority{priority} {}
+};
+
+typedef std::vector<Package> Packages;
+
+void buildProfile(const Path & out, Packages && pkgs);
+
+void builtinBuildenv(const BasicDerivation & drv);
+
+}
diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc
index f6ae5d2e6..2048f8f87 100644
--- a/src/libstore/builtins/fetchurl.cc
+++ b/src/libstore/builtins/fetchurl.cc
@@ -1,5 +1,5 @@
#include "builtins.hh"
-#include "download.hh"
+#include "filetransfer.hh"
#include "store-api.hh"
#include "archive.hh"
#include "compression.hh"
@@ -18,7 +18,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
auto getAttr = [&](const string & name) {
auto i = drv.env.find(name);
- if (i == drv.env.end()) throw Error(format("attribute '%s' missing") % name);
+ if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
return i->second;
};
@@ -26,9 +26,9 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
auto mainUrl = getAttr("url");
bool unpack = get(drv.env, "unpack").value_or("") == "1";
- /* Note: have to use a fresh downloader here because we're in
+ /* Note: have to use a fresh fileTransfer here because we're in
a forked process. */
- auto downloader = makeDownloader();
+ auto fileTransfer = makeFileTransfer();
auto fetch = [&](const std::string & url) {
@@ -36,13 +36,13 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
/* No need to do TLS verification, because we check the hash of
the result anyway. */
- DownloadRequest request(url);
+ FileTransferRequest request(url);
request.verifyTLS = false;
request.decompress = false;
auto decompressor = makeDecompressionSink(
unpack && hasSuffix(mainUrl, ".xz") ? "xz" : "none", sink);
- downloader->download(std::move(request), *decompressor);
+ fileTransfer->download(std::move(request), *decompressor);
decompressor->finish();
});
@@ -54,7 +54,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
auto executable = drv.env.find("executable");
if (executable != drv.env.end() && executable->second == "1") {
if (chmod(storePath.c_str(), 0755) == -1)
- throw SysError(format("making '%1%' executable") % storePath);
+ throw SysError("making '%1%' executable", storePath);
}
};