diff --git a/Makefile.config.in b/Makefile.config.in
index b632444e8..5c245b8e9 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -19,6 +19,7 @@ LIBLZMA_LIBS = @LIBLZMA_LIBS@
OPENSSL_LIBS = @OPENSSL_LIBS@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
+SHELL = @bash@
SODIUM_LIBS = @SODIUM_LIBS@
SQLITE3_LIBS = @SQLITE3_LIBS@
bash = @bash@
diff --git a/README.md b/README.md
index a1588284d..e5f7a694f 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ for more details.
On Linux and macOS the easiest way to Install Nix is to run the following shell command
(as a user other than root):
-```
+```console
$ curl -L https://nixos.org/nix/install | sh
```
@@ -20,27 +20,8 @@ Information on additional installation methods is available on the [Nix download
## Building And Developing
-### Building Nix
-
-You can build Nix using one of the targets provided by [release.nix](./release.nix):
-
-```
-$ nix-build ./release.nix -A build.aarch64-linux
-$ nix-build ./release.nix -A build.x86_64-darwin
-$ nix-build ./release.nix -A build.i686-linux
-$ nix-build ./release.nix -A build.x86_64-linux
-```
-
-### Development Environment
-
-You can use the provided `shell.nix` to get a working development environment:
-
-```
-$ nix-shell
-$ ./bootstrap.sh
-$ ./configure
-$ make
-```
+See our [Hacking guide](hydra.nixos.org/job/nix/master/build.x86_64-linux/latest/download-by-type/doc/manual#chap-hacking) in our manual for instruction on how to
+build nix from source with nix-build or how to get a development environment.
## Additional Resources
diff --git a/doc/manual/hacking.xml b/doc/manual/hacking.xml
index b671811d3..d25d4b84a 100644
--- a/doc/manual/hacking.xml
+++ b/doc/manual/hacking.xml
@@ -4,18 +4,37 @@
Hacking
-This section provides some notes on how to hack on Nix. To get
+This section provides some notes on how to hack on Nix. To get
the latest version of Nix from GitHub:
-$ git clone git://github.com/NixOS/nix.git
+$ git clone https://github.com/NixOS/nix.git
$ cd nix
-To build it and its dependencies:
+To build Nix for the current operating system/architecture use
+
-$ nix-build release.nix -A build.x86_64-linux
+$ nix-build
+
+or if you have a flakes-enabled nix:
+
+
+$ nix build
+
+
+This will build defaultPackage attribute defined in the flake.nix file.
+
+To build for other platforms add one of the following suffixes to it: aarch64-linux,
+i686-linux, x86_64-darwin, x86_64-linux.
+
+i.e.
+
+
+nix-build -A defaultPackage.x86_64-linux
+
+
To build all dependencies and start a shell in which all
@@ -27,13 +46,27 @@ $ nix-shell
To build Nix itself in this shell:
[nix-shell]$ ./bootstrap.sh
-[nix-shell]$ configurePhase
-[nix-shell]$ make
+[nix-shell]$ ./configure $configureFlags
+[nix-shell]$ make -j $NIX_BUILD_CORES
To install it in $(pwd)/inst and test it:
[nix-shell]$ make install
[nix-shell]$ make installcheck
+[nix-shell]$ ./inst/bin/nix --version
+nix (Nix) 2.4
+
+
+If you have a flakes-enabled nix you can replace:
+
+
+$ nix-shell
+
+
+by:
+
+
+$ nix develop
diff --git a/scripts/install-nix-from-closure.sh b/scripts/install-nix-from-closure.sh
index 5824c2217..6fb0beb2b 100644
--- a/scripts/install-nix-from-closure.sh
+++ b/scripts/install-nix-from-closure.sh
@@ -207,7 +207,7 @@ if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
if [ -w "$fn" ]; then
if ! grep -q "$p" "$fn"; then
echo "modifying $fn..." >&2
- echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
+ echo -e "\nif [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
fi
added=1
break
@@ -218,7 +218,7 @@ if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
if [ -w "$fn" ]; then
if ! grep -q "$p" "$fn"; then
echo "modifying $fn..." >&2
- echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
+ echo -e "\nif [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
fi
added=1
break
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 000000000..330df0ab6
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,3 @@
+(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) {
+ src = ./.;
+}).shellNix
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index 701546671..6363446f6 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -102,56 +102,61 @@ std::pair parseFlakeRefWithFragment(
percentDecode(std::string(match[6])));
}
- /* Check if 'url' is a path (either absolute or relative to
- 'baseDir'). If so, search upward to the root of the repo
- (i.e. the directory containing .git). */
-
else if (std::regex_match(url, match, pathUrlRegex)) {
std::string path = match[1];
- if (!baseDir && !hasPrefix(path, "/"))
- throw BadURL("flake reference '%s' is not an absolute path", url);
- path = absPath(path, baseDir, true);
+ std::string fragment = percentDecode(std::string(match[3]));
- if (!S_ISDIR(lstat(path).st_mode))
- throw BadURL("path '%s' is not a flake (because it's not a directory)", path);
+ if (baseDir) {
+ /* Check if 'url' is a path (either absolute or relative
+ to 'baseDir'). If so, search upward to the root of the
+ repo (i.e. the directory containing .git). */
- if (!allowMissing && !pathExists(path + "/flake.nix"))
- throw BadURL("path '%s' is not a flake (because it doesn't contain a 'flake.nix' file)", path);
+ path = absPath(path, baseDir, true);
- auto fragment = percentDecode(std::string(match[3]));
+ if (!S_ISDIR(lstat(path).st_mode))
+ throw BadURL("path '%s' is not a flake (because it's not a directory)", path);
- auto flakeRoot = path;
- std::string subdir;
+ if (!allowMissing && !pathExists(path + "/flake.nix"))
+ throw BadURL("path '%s' is not a flake (because it doesn't contain a 'flake.nix' file)", path);
- while (flakeRoot != "/") {
- if (pathExists(flakeRoot + "/.git")) {
- auto base = std::string("git+file://") + flakeRoot;
+ auto flakeRoot = path;
+ std::string subdir;
- auto parsedURL = ParsedURL{
- .url = base, // FIXME
- .base = base,
- .scheme = "git+file",
- .authority = "",
- .path = flakeRoot,
- .query = decodeQuery(match[2]),
- };
+ while (flakeRoot != "/") {
+ if (pathExists(flakeRoot + "/.git")) {
+ auto base = std::string("git+file://") + flakeRoot;
- if (subdir != "") {
- if (parsedURL.query.count("dir"))
- throw Error("flake URL '%s' has an inconsistent 'dir' parameter", url);
- parsedURL.query.insert_or_assign("dir", subdir);
+ auto parsedURL = ParsedURL{
+ .url = base, // FIXME
+ .base = base,
+ .scheme = "git+file",
+ .authority = "",
+ .path = flakeRoot,
+ .query = decodeQuery(match[2]),
+ };
+
+ if (subdir != "") {
+ if (parsedURL.query.count("dir"))
+ throw Error("flake URL '%s' has an inconsistent 'dir' parameter", url);
+ parsedURL.query.insert_or_assign("dir", subdir);
+ }
+
+ if (pathExists(flakeRoot + "/.git/shallow"))
+ parsedURL.query.insert_or_assign("shallow", "1");
+
+ return std::make_pair(
+ FlakeRef(Input::fromURL(parsedURL), get(parsedURL.query, "dir").value_or("")),
+ fragment);
}
- if (pathExists(flakeRoot + "/.git/shallow"))
- parsedURL.query.insert_or_assign("shallow", "1");
-
- return std::make_pair(
- FlakeRef(Input::fromURL(parsedURL), get(parsedURL.query, "dir").value_or("")),
- fragment);
+ subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir);
+ flakeRoot = dirOf(flakeRoot);
}
- subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir);
- flakeRoot = dirOf(flakeRoot);
+ } else {
+ if (!hasPrefix(path, "/"))
+ throw BadURL("flake reference '%s' is not an absolute path", url);
+ path = canonPath(path);
}
fetchers::Attrs attrs;
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 0c128d757..7d82ef09b 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -2774,7 +2774,7 @@ struct RestrictedStore : public LocalFSStore
goal.addDependency(info.path);
}
- StorePath addToStoreFromDump(const string & dump, const string & name,
+ StorePath addToStoreFromDump(Source & dump, const string & name,
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair) override
{
auto path = next->addToStoreFromDump(dump, name, method, hashAlgo, repair);
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 33b6ab9b1..9e138e8d9 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -173,31 +173,6 @@ struct TunnelSource : BufferedSource
}
};
-/* If the NAR archive contains a single file at top-level, then save
- the contents of the file to `s'. Otherwise barf. */
-struct RetrieveRegularNARSink : ParseSink
-{
- bool regular;
- string s;
-
- RetrieveRegularNARSink() : regular(true) { }
-
- void createDirectory(const Path & path)
- {
- regular = false;
- }
-
- void receiveContents(unsigned char * data, unsigned int len)
- {
- s.append((const char *) data, len);
- }
-
- void createSymlink(const Path & path, const string & target)
- {
- regular = false;
- }
-};
-
struct ClientSettings
{
bool keepFailed;
@@ -375,25 +350,28 @@ static void performOp(TunnelLogger * logger, ref store,
}
case wopAddToStore: {
- std::string s, baseName;
+ HashType hashAlgo;
+ std::string baseName;
FileIngestionMethod method;
{
- bool fixed; uint8_t recursive;
- from >> baseName >> fixed /* obsolete */ >> recursive >> s;
+ bool fixed;
+ uint8_t recursive;
+ std::string hashAlgoRaw;
+ from >> baseName >> fixed /* obsolete */ >> recursive >> hashAlgoRaw;
if (recursive > (uint8_t) FileIngestionMethod::Recursive)
throw Error("unsupported FileIngestionMethod with value of %i; you may need to upgrade nix-daemon", recursive);
method = FileIngestionMethod { recursive };
/* Compatibility hack. */
if (!fixed) {
- s = "sha256";
+ hashAlgoRaw = "sha256";
method = FileIngestionMethod::Recursive;
}
+ hashAlgo = parseHashType(hashAlgoRaw);
}
- HashType hashAlgo = parseHashType(s);
- StringSink savedNAR;
- TeeSource savedNARSource(from, savedNAR);
- RetrieveRegularNARSink savedRegular;
+ StringSink saved;
+ TeeSource savedNARSource(from, saved);
+ RetrieveRegularNARSink savedRegular { saved };
if (method == FileIngestionMethod::Recursive) {
/* Get the entire NAR dump from the client and save it to
@@ -407,11 +385,9 @@ static void performOp(TunnelLogger * logger, ref store,
logger->startWork();
if (!savedRegular.regular) throw Error("regular file expected");
- auto path = store->addToStoreFromDump(
- method == FileIngestionMethod::Recursive ? *savedNAR.s : savedRegular.s,
- baseName,
- method,
- hashAlgo);
+ // FIXME: try to stream directly from `from`.
+ StringSource dumpSource { *saved.s };
+ auto path = store->addToStoreFromDump(dumpSource, baseName, method, hashAlgo);
logger->stopWork();
to << store->printStorePath(path);
@@ -727,15 +703,15 @@ static void performOp(TunnelLogger * logger, ref store,
if (!trusted)
info.ultimate = false;
- std::string saved;
std::unique_ptr