aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile1
-rw-r--r--Makefile.config.in1
-rw-r--r--doc/manual/generate-builtins.nix10
-rw-r--r--doc/manual/local.mk1
-rw-r--r--doc/manual/src/expressions/builtins-prefix.md9
-rw-r--r--doc/manual/src/expressions/builtins-suffix.md1
-rw-r--r--misc/fish/completion.fish37
-rw-r--r--misc/fish/local.mk1
-rw-r--r--misc/launchd/local.mk2
-rw-r--r--misc/systemd/local.mk2
-rw-r--r--misc/upstart/local.mk2
-rw-r--r--mk/lib.mk27
-rw-r--r--mk/libraries.mk18
-rw-r--r--nix-rust/local.mk8
-rw-r--r--perl/Makefile.config.in1
-rw-r--r--perl/configure.ac2
-rw-r--r--perl/local.mk2
-rwxr-xr-xscripts/install.in2
-rw-r--r--src/libcmd/installables.cc56
-rw-r--r--src/libexpr/eval.cc4
-rw-r--r--src/libexpr/flake/flake.cc5
-rw-r--r--src/libexpr/flake/flake.hh4
-rw-r--r--src/libexpr/local.mk2
-rw-r--r--src/libexpr/primops/fetchTree.cc20
-rw-r--r--src/libfetchers/registry.cc7
-rw-r--r--src/libfetchers/registry.hh3
-rw-r--r--src/libstore/local.mk6
-rw-r--r--src/libstore/machines.cc17
-rw-r--r--src/nix/develop.cc2
-rw-r--r--src/nix/flake.cc4
-rw-r--r--src/nix/registry-add.md7
-rw-r--r--src/nix/registry-pin.md7
-rw-r--r--src/nix/registry-remove.md6
-rw-r--r--src/nix/registry.cc87
-rw-r--r--src/resolve-system-dependencies/local.mk2
-rw-r--r--tests/add.sh2
-rw-r--r--tests/check.nix2
-rw-r--r--tests/check.sh5
-rw-r--r--tests/dummy1
-rw-r--r--tests/flakes.sh80
-rw-r--r--tests/init.sh2
-rw-r--r--tests/shell.nix2
43 files changed, 310 insertions, 151 deletions
diff --git a/.gitignore b/.gitignore
index 2e14561fe..5f402dbc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,7 +76,6 @@ perl/Makefile.config
# /tests/
/tests/test-tmp
/tests/common.sh
-/tests/dummy
/tests/result*
/tests/restricted-innocent
/tests/shell
diff --git a/Makefile b/Makefile
index b7f0e79db..dd259e5cd 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ makefiles = \
src/resolve-system-dependencies/local.mk \
scripts/local.mk \
misc/bash/local.mk \
+ misc/fish/local.mk \
misc/zsh/local.mk \
misc/systemd/local.mk \
misc/launchd/local.mk \
diff --git a/Makefile.config.in b/Makefile.config.in
index fd92365eb..c8c4446b4 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -1,3 +1,4 @@
+HOST_OS = @host_os@
AR = @AR@
BDW_GC_LIBS = @BDW_GC_LIBS@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
diff --git a/doc/manual/generate-builtins.nix b/doc/manual/generate-builtins.nix
index 416a7fdba..92c7b1a31 100644
--- a/doc/manual/generate-builtins.nix
+++ b/doc/manual/generate-builtins.nix
@@ -6,9 +6,11 @@ builtins:
concatStrings (map
(name:
let builtin = builtins.${name}; in
- " - `builtins.${name}` " + concatStringsSep " " (map (s: "*${s}*") builtin.args)
- + " \n\n"
- + concatStrings (map (s: " ${s}\n") (splitLines builtin.doc)) + "\n\n"
+ "<dt><code>${name} "
+ + concatStringsSep " " (map (s: "<var>${s}</var>") builtin.args)
+ + "</code></dt>"
+ + "<dd>\n\n"
+ + builtin.doc
+ + "\n\n</dd>"
)
(attrNames builtins))
-
diff --git a/doc/manual/local.mk b/doc/manual/local.mk
index 271529b38..e25157af8 100644
--- a/doc/manual/local.mk
+++ b/doc/manual/local.mk
@@ -64,6 +64,7 @@ $(d)/conf-file.json: $(bindir)/nix
$(d)/src/expressions/builtins.md: $(d)/builtins.json $(d)/generate-builtins.nix $(d)/src/expressions/builtins-prefix.md $(bindir)/nix
@cat doc/manual/src/expressions/builtins-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtins.nix (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp
+ @cat doc/manual/src/expressions/builtins-suffix.md >> $@.tmp
@mv $@.tmp $@
$(d)/builtins.json: $(bindir)/nix
diff --git a/doc/manual/src/expressions/builtins-prefix.md b/doc/manual/src/expressions/builtins-prefix.md
index c16b2805f..87127de2a 100644
--- a/doc/manual/src/expressions/builtins-prefix.md
+++ b/doc/manual/src/expressions/builtins-prefix.md
@@ -9,7 +9,8 @@ scope. Instead, you can access them through the `builtins` built-in
value, which is a set that contains all built-in functions and values.
For instance, `derivation` is also available as `builtins.derivation`.
- - `derivation` *attrs*; `builtins.derivation` *attrs*\
-
- `derivation` is described in [its own section](derivations.md).
-
+<dl>
+ <dt><code>derivation <var>attrs</var></code>;
+ <code>builtins.derivation <var>attrs</var></code></dt>
+ <dd><p><var>derivation</var> in described in
+ <a href="derivations.md">its own section</a>.</p></dd>
diff --git a/doc/manual/src/expressions/builtins-suffix.md b/doc/manual/src/expressions/builtins-suffix.md
new file mode 100644
index 000000000..a74db2857
--- /dev/null
+++ b/doc/manual/src/expressions/builtins-suffix.md
@@ -0,0 +1 @@
+</dl>
diff --git a/misc/fish/completion.fish b/misc/fish/completion.fish
new file mode 100644
index 000000000..bedbefaf8
--- /dev/null
+++ b/misc/fish/completion.fish
@@ -0,0 +1,37 @@
+function _nix_complete
+ # Get the current command up to a cursor.
+ # - Behaves correctly even with pipes and nested in commands like env.
+ # - TODO: Returns the command verbatim (does not interpolate variables).
+ # That might not be optimal for arguments like -f.
+ set -l nix_args (commandline --current-process --tokenize --cut-at-cursor)
+ # --cut-at-cursor with --tokenize removes the current token so we need to add it separately.
+ # https://github.com/fish-shell/fish-shell/issues/7375
+ # Can be an empty string.
+ set -l current_token (commandline --current-token --cut-at-cursor)
+
+ # Nix wants the index of the argv item to complete but the $nix_args variable
+ # also contains the program name (argv[0]) so we would need to subtract 1.
+ # But the variable also misses the current token so it cancels out.
+ set -l nix_arg_to_complete (count $nix_args)
+
+ env NIX_GET_COMPLETIONS=$nix_arg_to_complete $nix_args $current_token
+end
+
+function _nix_accepts_files
+ set -l response (_nix_complete)
+ # First line is either filenames or no-filenames.
+ test $response[1] = 'filenames'
+end
+
+function _nix
+ set -l response (_nix_complete)
+ # Skip the first line since it handled by _nix_accepts_files.
+ # Tail lines each contain a command followed by a tab character and, optionally, a description.
+ # This is also the format fish expects.
+ string collect -- $response[2..-1]
+end
+
+# Disable file path completion if paths do not belong in the current context.
+complete --command nix --condition 'not _nix_accepts_files' --no-files
+
+complete --command nix --arguments '(_nix)'
diff --git a/misc/fish/local.mk b/misc/fish/local.mk
new file mode 100644
index 000000000..ece899fc3
--- /dev/null
+++ b/misc/fish/local.mk
@@ -0,0 +1 @@
+$(eval $(call install-file-as, $(d)/completion.fish, $(datarootdir)/fish/vendor_completions.d/nix.fish, 0644))
diff --git a/misc/launchd/local.mk b/misc/launchd/local.mk
index 0ba722efb..a39188fe6 100644
--- a/misc/launchd/local.mk
+++ b/misc/launchd/local.mk
@@ -1,4 +1,4 @@
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
$(eval $(call install-data-in, $(d)/org.nixos.nix-daemon.plist, $(prefix)/Library/LaunchDaemons))
diff --git a/misc/systemd/local.mk b/misc/systemd/local.mk
index 785db52a4..1fa037485 100644
--- a/misc/systemd/local.mk
+++ b/misc/systemd/local.mk
@@ -1,4 +1,4 @@
-ifeq ($(OS), Linux)
+ifdef HOST_LINUX
$(foreach n, nix-daemon.socket nix-daemon.service, $(eval $(call install-file-in, $(d)/$(n), $(prefix)/lib/systemd/system, 0644)))
diff --git a/misc/upstart/local.mk b/misc/upstart/local.mk
index 5071676dc..2fbfb29b9 100644
--- a/misc/upstart/local.mk
+++ b/misc/upstart/local.mk
@@ -1,4 +1,4 @@
-ifeq ($(OS), Linux)
+ifdef HOST_LINUX
$(foreach n, nix-daemon.conf, $(eval $(call install-file-in, $(d)/$(n), $(sysconfdir)/init, 0644)))
diff --git a/mk/lib.mk b/mk/lib.mk
index 975102531..92f0983d5 100644
--- a/mk/lib.mk
+++ b/mk/lib.mk
@@ -10,8 +10,25 @@ bin-scripts :=
noinst-scripts :=
man-pages :=
install-tests :=
-OS = $(shell uname -s)
+ifdef HOST_OS
+ HOST_KERNEL = $(firstword $(subst -, ,$(HOST_OS)))
+ ifeq ($(HOST_KERNEL), cygwin)
+ HOST_CYGWIN = 1
+ endif
+ ifeq ($(patsubst darwin%,,$(HOST_KERNEL)),)
+ HOST_DARWIN = 1
+ endif
+ ifeq ($(patsubst freebsd%,,$(HOST_KERNEL)),)
+ HOST_FREEBSD = 1
+ endif
+ ifeq ($(HOST_KERNEL), linux)
+ HOST_LINUX = 1
+ endif
+ ifeq ($(patsubst solaris%,,$(HOST_KERNEL)),)
+ HOST_SOLARIS = 1
+ endif
+endif
# Hack to define a literal space.
space :=
@@ -50,16 +67,16 @@ endif
BUILD_SHARED_LIBS ?= 1
ifeq ($(BUILD_SHARED_LIBS), 1)
- ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
+ ifdef HOST_CYGWIN
GLOBAL_CFLAGS += -U__STRICT_ANSI__ -D_GNU_SOURCE
GLOBAL_CXXFLAGS += -U__STRICT_ANSI__ -D_GNU_SOURCE
else
GLOBAL_CFLAGS += -fPIC
GLOBAL_CXXFLAGS += -fPIC
endif
- ifneq ($(OS), Darwin)
- ifneq ($(OS), SunOS)
- ifneq ($(OS), FreeBSD)
+ ifndef HOST_DARWIN
+ ifndef HOST_SOLARIS
+ ifndef HOST_FREEBSD
GLOBAL_LDFLAGS += -Wl,--no-copy-dt-needed-entries
endif
endif
diff --git a/mk/libraries.mk b/mk/libraries.mk
index 7c0e4f100..07bd54dab 100644
--- a/mk/libraries.mk
+++ b/mk/libraries.mk
@@ -1,9 +1,9 @@
libs-list :=
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
SO_EXT = dylib
else
- ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
+ ifdef HOST_CYGWIN
SO_EXT = dll
else
SO_EXT = so
@@ -59,7 +59,7 @@ define build-library
$(1)_OBJS := $$(addprefix $(buildprefix), $$(addsuffix .o, $$(basename $$(_srcs))))
_libs := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_PATH))
- ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
+ ifdef HOST_CYGWIN
$(1)_INSTALL_DIR ?= $$(bindir)
else
$(1)_INSTALL_DIR ?= $$(libdir)
@@ -73,18 +73,18 @@ define build-library
ifeq ($(BUILD_SHARED_LIBS), 1)
ifdef $(1)_ALLOW_UNDEFINED
- ifeq ($(OS), Darwin)
+ ifdef HOST_DARWIN
$(1)_LDFLAGS += -undefined suppress -flat_namespace
endif
else
- ifneq ($(OS), Darwin)
- ifneq (CYGWIN,$(findstring CYGWIN,$(OS)))
+ ifndef HOST_DARWIN
+ ifndef HOST_CYGWIN
$(1)_LDFLAGS += -Wl,-z,defs
endif
endif
endif
- ifneq ($(OS), Darwin)
+ ifndef HOST_DARWIN
$(1)_LDFLAGS += -Wl,-soname=$$($(1)_NAME).$(SO_EXT)
endif
@@ -93,7 +93,7 @@ define build-library
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
$$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED)
- ifneq ($(OS), Darwin)
+ ifndef HOST_DARWIN
$(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d))
endif
$(1)_LDFLAGS_USE += -L$$(_d) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME)))
@@ -108,7 +108,7 @@ define build-library
$$(trace-ld) $(CXX) -o $$@ -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
$(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME)))
- ifneq ($(OS), Darwin)
+ ifndef HOST_DARWIN
ifeq ($(SET_RPATH_TO_LIBS), 1)
$(1)_LDFLAGS_USE_INSTALLED += -Wl,-rpath,$$($(1)_INSTALL_DIR)
else
diff --git a/nix-rust/local.mk b/nix-rust/local.mk
index 9650cdf93..538244594 100644
--- a/nix-rust/local.mk
+++ b/nix-rust/local.mk
@@ -11,12 +11,12 @@ libnixrust_INSTALL_PATH := $(libdir)/libnixrust.$(SO_EXT)
libnixrust_LDFLAGS_USE := -L$(d)/target/$(RUST_DIR) -lnixrust
libnixrust_LDFLAGS_USE_INSTALLED := -L$(libdir) -lnixrust
-ifeq ($(OS), Linux)
+ifdef HOST_LINUX
libnixrust_LDFLAGS_USE += -ldl
libnixrust_LDFLAGS_USE_INSTALLED += -ldl
endif
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
libnixrust_BUILD_FLAGS = NIX_LDFLAGS="-undefined dynamic_lookup"
else
libnixrust_LDFLAGS_USE += -Wl,-rpath,$(abspath $(d)/target/$(RUST_DIR))
@@ -31,7 +31,7 @@ $(libnixrust_PATH): $(call rwildcard, $(d)/src, *.rs) $(d)/Cargo.toml
$(libnixrust_INSTALL_PATH): $(libnixrust_PATH)
$(target-gen) cp $^ $@
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
install_name_tool -id $@ $@
endif
@@ -40,7 +40,7 @@ clean: clean-rust
clean-rust:
$(suppress) rm -rfv nix-rust/target
-ifneq ($(OS), Darwin)
+ifndef HOST_DARWIN
check: rust-tests
rust-tests:
diff --git a/perl/Makefile.config.in b/perl/Makefile.config.in
index eccfbd9f6..d856de3ad 100644
--- a/perl/Makefile.config.in
+++ b/perl/Makefile.config.in
@@ -1,3 +1,4 @@
+HOST_OS = @host_os@
CC = @CC@
CFLAGS = @CFLAGS@
CXX = @CXX@
diff --git a/perl/configure.ac b/perl/configure.ac
index 85183c005..eb65ac17b 100644
--- a/perl/configure.ac
+++ b/perl/configure.ac
@@ -7,6 +7,8 @@ CXXFLAGS=
AC_PROG_CC
AC_PROG_CXX
+AC_CANONICAL_HOST
+
# Use 64-bit file system calls so that we can support files > 2 GiB.
AC_SYS_LARGEFILE
diff --git a/perl/local.mk b/perl/local.mk
index b13d4c0d6..0eae651d8 100644
--- a/perl/local.mk
+++ b/perl/local.mk
@@ -28,7 +28,7 @@ Store_CXXFLAGS = \
Store_LDFLAGS := $(SODIUM_LIBS) $(NIX_LIBS)
-ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
+ifdef HOST_CYGWIN
archlib = $(shell perl -E 'use Config; print $$Config{archlib};')
libperl = $(shell perl -E 'use Config; print $$Config{libperl};')
Store_LDFLAGS += $(shell find ${archlib} -name ${libperl})
diff --git a/scripts/install.in b/scripts/install.in
index e801d4268..ffc1f2785 100755
--- a/scripts/install.in
+++ b/scripts/install.in
@@ -56,7 +56,7 @@ case "$(uname -s).$(uname -m)" in
system=x86_64-darwin
;;
Darwin.arm64|Darwin.aarch64)
- hash=@binaryTarball_aarch64-darwin@
+ hash=@tarballHash_aarch64-darwin@
path=@tarballPath_aarch64-darwin@
system=aarch64-darwin
;;
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index fe52912cf..658b415f3 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -171,14 +171,50 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
void SourceExprCommand::completeInstallable(std::string_view prefix)
{
- if (file) return; // FIXME
+ if (file) {
+ evalSettings.pureEval = false;
+ auto state = getEvalState();
+ Expr *e = state->parseExprFromFile(
+ resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file)))
+ );
+
+ Value root;
+ state->eval(e, root);
+
+ auto autoArgs = getAutoArgs(*state);
+
+ std::string prefix_ = std::string(prefix);
+ auto sep = prefix_.rfind('.');
+ std::string searchWord;
+ if (sep != std::string::npos) {
+ searchWord = prefix_.substr(sep, std::string::npos);
+ prefix_ = prefix_.substr(0, sep);
+ } else {
+ searchWord = prefix_;
+ prefix_ = "";
+ }
- completeFlakeRefWithFragment(
- getEvalState(),
- lockFlags,
- getDefaultFlakeAttrPathPrefixes(),
- getDefaultFlakeAttrPaths(),
- prefix);
+ Value &v1(*findAlongAttrPath(*state, prefix_, *autoArgs, root).first);
+ state->forceValue(v1);
+ Value v2;
+ state->autoCallFunction(*autoArgs, v1, v2);
+
+ if (v2.type() == nAttrs) {
+ for (auto & i : *v2.attrs) {
+ std::string name = i.name;
+ if (name.find(searchWord) == 0) {
+ completions->add(i.name);
+ }
+ }
+ }
+ } else {
+ completeFlakeRefWithFragment(
+ getEvalState(),
+ lockFlags,
+ getDefaultFlakeAttrPathPrefixes(),
+ getDefaultFlakeAttrPaths(),
+ prefix);
+ }
}
void completeFlakeRefWithFragment(
@@ -573,10 +609,10 @@ InstallableFlake::getCursors(EvalState & state)
std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
{
+ flake::LockFlags lockFlagsApplyConfig = lockFlags;
+ lockFlagsApplyConfig.applyNixConfig = true;
if (!_lockedFlake) {
- _lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlags));
- _lockedFlake->flake.config.apply();
- // FIXME: send new config to the daemon.
+ _lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlagsApplyConfig));
}
return _lockedFlake;
}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index fe25d894a..c3206a577 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -64,7 +64,11 @@ static char * dupStringWithLen(const char * s, size_t size)
RootValue allocRootValue(Value * v)
{
+#if HAVE_BOEHMGC
return std::allocate_shared<Value *>(traceable_allocator<Value *>(), v);
+#else
+ return std::make_shared<Value *>(v);
+#endif
}
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 8e6f06949..e266bc36d 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -298,6 +298,11 @@ LockedFlake lockFlake(
auto flake = getFlake(state, topRef, lockFlags.useRegistries, flakeCache);
+ if (lockFlags.applyNixConfig) {
+ flake.config.apply();
+ // FIXME: send new config to the daemon.
+ }
+
try {
// FIXME: symlink attack
diff --git a/src/libexpr/flake/flake.hh b/src/libexpr/flake/flake.hh
index d17d5e183..4479e95db 100644
--- a/src/libexpr/flake/flake.hh
+++ b/src/libexpr/flake/flake.hh
@@ -104,6 +104,10 @@ struct LockFlags
references like 'nixpkgs'. */
bool useRegistries = true;
+ /* Whether to apply flake's nixConfig attribute to the configuration */
+
+ bool applyNixConfig = false;
+
/* Whether mutable flake references (i.e. those without a Git
revision or similar) without a corresponding lock are
allowed. Mutable flake references with a lock are always
diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk
index c40abfb78..1aed8e152 100644
--- a/src/libexpr/local.mk
+++ b/src/libexpr/local.mk
@@ -16,7 +16,7 @@ libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/lib
libexpr_LIBS = libutil libstore libfetchers
libexpr_LDFLAGS = -lboost_context
-ifeq ($(OS), Linux)
+ifdef HOST_LINUX
libexpr_LDFLAGS += -ldl
endif
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index a57bda04e..730db84ed 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -7,6 +7,7 @@
#include <ctime>
#include <iomanip>
+#include <regex>
namespace nix {
@@ -60,10 +61,19 @@ void emitTreeAttrs(
v.attrs->sort();
}
-std::string fixURI(std::string uri, EvalState &state)
+std::string fixURI(std::string uri, EvalState &state, const std::string & defaultScheme = "file")
{
state.checkURI(uri);
- return uri.find("://") != std::string::npos ? uri : "file://" + uri;
+ return uri.find("://") != std::string::npos ? uri : defaultScheme + "://" + uri;
+}
+
+std::string fixURIForGit(std::string uri, EvalState & state)
+{
+ static std::regex scp_uri("([^/].*)@(.*):(.*)");
+ if (uri[0] != '/' && std::regex_match(uri, scp_uri))
+ return fixURI(std::regex_replace(uri, scp_uri, "$1@$2/$3"), state, "ssh");
+ else
+ return fixURI(uri, state);
}
void addURI(EvalState &state, fetchers::Attrs &attrs, Symbol name, std::string v)
@@ -134,15 +144,15 @@ static void fetchTree(
input = fetchers::Input::fromAttrs(std::move(attrs));
} else {
- auto url = fixURI(state.coerceToString(pos, *args[0], context, false, false), state);
+ auto url = state.coerceToString(pos, *args[0], context, false, false);
if (type == "git") {
fetchers::Attrs attrs;
attrs.emplace("type", "git");
- attrs.emplace("url", url);
+ attrs.emplace("url", fixURIForGit(url, state));
input = fetchers::Input::fromAttrs(std::move(attrs));
} else {
- input = fetchers::Input::fromURL(url);
+ input = fetchers::Input::fromURL(fixURI(url, state));
}
}
diff --git a/src/libfetchers/registry.cc b/src/libfetchers/registry.cc
index 74376adc0..f35359d4b 100644
--- a/src/libfetchers/registry.cc
+++ b/src/libfetchers/registry.cc
@@ -124,6 +124,13 @@ std::shared_ptr<Registry> getUserRegistry()
return userRegistry;
}
+std::shared_ptr<Registry> getCustomRegistry(const Path & p)
+{
+ static auto customRegistry =
+ Registry::read(p, Registry::Custom);
+ return customRegistry;
+}
+
static std::shared_ptr<Registry> flagRegistry =
std::make_shared<Registry>(Registry::Flag);
diff --git a/src/libfetchers/registry.hh b/src/libfetchers/registry.hh
index 1077af020..260a2c460 100644
--- a/src/libfetchers/registry.hh
+++ b/src/libfetchers/registry.hh
@@ -14,6 +14,7 @@ struct Registry
User = 1,
System = 2,
Global = 3,
+ Custom = 4,
};
RegistryType type;
@@ -48,6 +49,8 @@ typedef std::vector<std::shared_ptr<Registry>> Registries;
std::shared_ptr<Registry> getUserRegistry();
+std::shared_ptr<Registry> getCustomRegistry(const Path & p);
+
Path getUserRegistryPath();
Registries getRegistries(ref<Store> store);
diff --git a/src/libstore/local.mk b/src/libstore/local.mk
index b6652984c..2fc334a82 100644
--- a/src/libstore/local.mk
+++ b/src/libstore/local.mk
@@ -9,11 +9,11 @@ libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc $(d)/build/*.cc)
libstore_LIBS = libutil
libstore_LDFLAGS = $(SQLITE3_LIBS) -lbz2 $(LIBCURL_LIBS) $(SODIUM_LIBS) -pthread
-ifeq ($(OS), Linux)
+ifdef HOST_LINUX
libstore_LDFLAGS += -ldl
endif
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
libstore_FILES = sandbox-defaults.sb sandbox-minimal.sb sandbox-network.sb
endif
@@ -23,7 +23,7 @@ ifeq ($(ENABLE_S3), 1)
libstore_LDFLAGS += -laws-cpp-sdk-transfer -laws-cpp-sdk-s3 -laws-cpp-sdk-core
endif
-ifeq ($(OS), SunOS)
+ifdef HOST_SOLARIS
libstore_LDFLAGS += -lsocket
endif
diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc
index b42e5e434..9843ccf04 100644
--- a/src/libstore/machines.cc
+++ b/src/libstore/machines.cc
@@ -16,13 +16,18 @@ Machine::Machine(decltype(storeUri) storeUri,
decltype(mandatoryFeatures) mandatoryFeatures,
decltype(sshPublicHostKey) sshPublicHostKey) :
storeUri(
- // Backwards compatibility: if the URI is a hostname,
- // prepend ssh://.
+ // Backwards compatibility: if the URI is schemeless, is not a path,
+ // and is not one of the special store connection words, prepend
+ // ssh://.
storeUri.find("://") != std::string::npos
- || hasPrefix(storeUri, "local")
- || hasPrefix(storeUri, "remote")
- || hasPrefix(storeUri, "auto")
- || hasPrefix(storeUri, "/")
+ || storeUri.find("/") != std::string::npos
+ || storeUri == "auto"
+ || storeUri == "daemon"
+ || storeUri == "local"
+ || hasPrefix(storeUri, "auto?")
+ || hasPrefix(storeUri, "daemon?")
+ || hasPrefix(storeUri, "local?")
+ || hasPrefix(storeUri, "?")
? storeUri
: "ssh://" + storeUri),
systemTypes(systemTypes),
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 6c089469d..699ec0b99 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -54,7 +54,7 @@ BuildEnvironment readEnvironment(const Path & path)
R"re((?:[a-zA-Z_][a-zA-Z0-9_]*))re";
static std::string simpleStringRegex =
- R"re((?:[a-zA-Z0-9_/:\.\-\+=]*))re";
+ R"re((?:[a-zA-Z0-9_/:\.\-\+=@%]*))re";
static std::string dquotedStringRegex =
R"re((?:\$?"(?:[^"\\]|\\[$`"\\\n])*"))re";
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 64fcfc000..9055b07eb 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -84,6 +84,7 @@ struct CmdFlakeUpdate : FlakeCommand
lockFlags.recreateLockFile = true;
lockFlags.writeLockFile = true;
+ lockFlags.applyNixConfig = true;
lockFlake();
}
@@ -114,6 +115,7 @@ struct CmdFlakeLock : FlakeCommand
settings.tarballTtl = 0;
lockFlags.writeLockFile = true;
+ lockFlags.applyNixConfig = true;
lockFlake();
}
@@ -270,6 +272,8 @@ struct CmdFlakeCheck : FlakeCommand
settings.readOnlyMode = !build;
auto state = getEvalState();
+
+ lockFlags.applyNixConfig = true;
auto flake = lockFlake();
bool hasErrors = false;
diff --git a/src/nix/registry-add.md b/src/nix/registry-add.md
index 80a31996a..a947fa0b3 100644
--- a/src/nix/registry-add.md
+++ b/src/nix/registry-add.md
@@ -21,6 +21,13 @@ R""(
# nix registry add nixpkgs/nixos-20.03 ~/Dev/nixpkgs
```
+* Add `nixpkgs` pointing to `github:nixos/nixpkgs` to your custom flake
+ registry:
+
+ ```console
+ nix registry add --registry ./custom-flake-registry.json nixpkgs github:nixos/nixpkgs
+ ```
+
# Description
This command adds an entry to the user registry that maps flake
diff --git a/src/nix/registry-pin.md b/src/nix/registry-pin.md
index 6e97e003e..ebc0e3eff 100644
--- a/src/nix/registry-pin.md
+++ b/src/nix/registry-pin.md
@@ -24,6 +24,13 @@ R""(
```
+* Pin `nixpkgs` in a custom registry to its most recent Git revision:
+
+ ```console
+ # nix registry pin --registry ./custom-flake-registry.json nixpkgs
+ ```
+
+
# Description
This command adds an entry to the user registry that maps flake
diff --git a/src/nix/registry-remove.md b/src/nix/registry-remove.md
index 4c0eb4947..eecd4c6e7 100644
--- a/src/nix/registry-remove.md
+++ b/src/nix/registry-remove.md
@@ -8,6 +8,12 @@ R""(
# nix registry remove nixpkgs
```
+* Remove the entry `nixpkgs` from a custom registry:
+
+ ```console
+ # nix registry remove --registry ./custom-flake-registry.json nixpkgs
+ ```
+
# Description
This command removes from the user registry any entry for flake
diff --git a/src/nix/registry.cc b/src/nix/registry.cc
index f9719600f..6a92576c7 100644
--- a/src/nix/registry.cc
+++ b/src/nix/registry.cc
@@ -10,6 +10,46 @@
using namespace nix;
using namespace nix::flake;
+
+class RegistryCommand : virtual Args
+{
+ std::string registry_path;
+
+ std::shared_ptr<fetchers::Registry> registry;
+
+public:
+
+ RegistryCommand()
+ {
+ addFlag({
+ .longName = "registry",
+ .description = "The registry to operate on.",
+ .labels = {"registry"},
+ .handler = {&registry_path},
+ });
+ }
+
+ std::shared_ptr<fetchers::Registry> getRegistry()
+ {
+ if (registry) return registry;
+ if (registry_path.empty()) {
+ registry = fetchers::getUserRegistry();
+ } else {
+ registry = fetchers::getCustomRegistry(registry_path);
+ }
+ return registry;
+ }
+
+ Path getRegistryPath()
+ {
+ if (registry_path.empty()) {
+ return fetchers::getUserRegistryPath();
+ } else {
+ return registry_path;
+ }
+ }
+};
+
struct CmdRegistryList : StoreCommand
{
std::string description() override
@@ -45,7 +85,7 @@ struct CmdRegistryList : StoreCommand
}
};
-struct CmdRegistryAdd : MixEvalArgs, Command
+struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand
{
std::string fromUrl, toUrl;
@@ -71,16 +111,16 @@ struct CmdRegistryAdd : MixEvalArgs, Command
{
auto fromRef = parseFlakeRef(fromUrl);
auto toRef = parseFlakeRef(toUrl);
+ auto registry = getRegistry();
fetchers::Attrs extraAttrs;
if (toRef.subdir != "") extraAttrs["dir"] = toRef.subdir;
- auto userRegistry = fetchers::getUserRegistry();
- userRegistry->remove(fromRef.input);
- userRegistry->add(fromRef.input, toRef.input, extraAttrs);
- userRegistry->write(fetchers::getUserRegistryPath());
+ registry->remove(fromRef.input);
+ registry->add(fromRef.input, toRef.input, extraAttrs);
+ registry->write(getRegistryPath());
}
};
-struct CmdRegistryRemove : virtual Args, MixEvalArgs, Command
+struct CmdRegistryRemove : RegistryCommand, Command
{
std::string url;
@@ -103,19 +143,21 @@ struct CmdRegistryRemove : virtual Args, MixEvalArgs, Command
void run() override
{
- auto userRegistry = fetchers::getUserRegistry();
- userRegistry->remove(parseFlakeRef(url).input);
- userRegistry->write(fetchers::getUserRegistryPath());
+ auto registry = getRegistry();
+ registry->remove(parseFlakeRef(url).input);
+ registry->write(getRegistryPath());
}
};
-struct CmdRegistryPin : virtual Args, EvalCommand
+struct CmdRegistryPin : RegistryCommand, EvalCommand
{
std::string url;
+ std::string locked;
+
std::string description() override
{
- return "pin a flake to its current version in user flake registry";
+ return "pin a flake to its current version or to the current version of a flake URL";
}
std::string doc() override
@@ -128,18 +170,31 @@ struct CmdRegistryPin : virtual Args, EvalCommand
CmdRegistryPin()
{
expectArg("url", &url);
+
+ expectArgs({
+ .label = "locked",
+ .optional = true,
+ .handler = {&locked},
+ .completer = {[&](size_t, std::string_view prefix) {
+ completeFlakeRef(getStore(), prefix);
+ }}
+ });
}
void run(nix::ref<nix::Store> store) override
{
+ if (locked.empty()) {
+ locked = url;
+ }
+ auto registry = getRegistry();
auto ref = parseFlakeRef(url);
- auto userRegistry = fetchers::getUserRegistry();
- userRegistry->remove(ref.input);
- auto [tree, resolved] = ref.resolve(store).input.fetch(store);
+ auto locked_ref = parseFlakeRef(locked);
+ registry->remove(ref.input);
+ auto [tree, resolved] = locked_ref.resolve(store).input.fetch(store);
fetchers::Attrs extraAttrs;
if (ref.subdir != "") extraAttrs["dir"] = ref.subdir;
- userRegistry->add(ref.input, resolved, extraAttrs);
- userRegistry->write(fetchers::getUserRegistryPath());
+ registry->add(ref.input, resolved, extraAttrs);
+ registry->write(getRegistryPath());
}
};
diff --git a/src/resolve-system-dependencies/local.mk b/src/resolve-system-dependencies/local.mk
index 054ae01cb..fc48a8417 100644
--- a/src/resolve-system-dependencies/local.mk
+++ b/src/resolve-system-dependencies/local.mk
@@ -1,4 +1,4 @@
-ifeq ($(OS), Darwin)
+ifdef HOST_DARWIN
programs += resolve-system-dependencies
endif
diff --git a/tests/add.sh b/tests/add.sh
index e26e05843..5c3eed793 100644
--- a/tests/add.sh
+++ b/tests/add.sh
@@ -9,7 +9,7 @@ echo $path2
if test "$path1" != "$path2"; then
echo "nix-store --add and --add-fixed mismatch"
exit 1
-fi
+fi
path3=$(nix-store --add-fixed sha256 ./dummy)
echo $path3
diff --git a/tests/check.nix b/tests/check.nix
index bca04fdaf..ec455ae2d 100644
--- a/tests/check.nix
+++ b/tests/check.nix
@@ -44,7 +44,7 @@ with import ./config.nix;
};
hashmismatch = import <nix/fetchurl.nix> {
- url = "file://" + toString ./dummy;
+ url = "file://" + builtins.getEnv "TMPDIR" + "/dummy";
sha256 = "0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73";
};
diff --git a/tests/check.sh b/tests/check.sh
index 5f4997e28..d26d4d8fc 100644
--- a/tests/check.sh
+++ b/tests/check.sh
@@ -74,12 +74,13 @@ nix-build check.nix -A fetchurl --no-out-link --check
nix-build check.nix -A fetchurl --no-out-link --repair
[[ $(cat $path) != foo ]]
+echo 'Hello World' > $TMPDIR/dummy
nix-build check.nix -A hashmismatch --no-out-link || status=$?
[ "$status" = "102" ]
-echo -n > ./dummy
+echo -n > $TMPDIR/dummy
nix-build check.nix -A hashmismatch --no-out-link
-echo 'Hello World' > ./dummy
+echo 'Hello World' > $TMPDIR/dummy
nix-build check.nix -A hashmismatch --no-out-link --check || status=$?
[ "$status" = "102" ]
diff --git a/tests/dummy b/tests/dummy
new file mode 100644
index 000000000..557db03de
--- /dev/null
+++ b/tests/dummy
@@ -0,0 +1 @@
+Hello World
diff --git a/tests/flakes.sh b/tests/flakes.sh
index 9764e1a6c..a4e657980 100644
--- a/tests/flakes.sh
+++ b/tests/flakes.sh
@@ -90,76 +90,14 @@ EOF
git -C $nonFlakeDir add README.md
git -C $nonFlakeDir commit -m 'Initial'
-cat > $registry <<EOF
-{
- "version": 2,
- "flakes": [
- { "from": {
- "type": "indirect",
- "id": "flake1"
- },
- "to": {
- "type": "git",
- "url": "file://$flake1Dir"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "flake2"
- },
- "to": {
- "type": "git",
- "url": "file://$flake2Dir"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "flake3"
- },
- "to": {
- "type": "git",
- "url": "file://$flake3Dir"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "flake4"
- },
- "to": {
- "type": "indirect",
- "id": "flake3"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "flake5"
- },
- "to": {
- "type": "hg",
- "url": "file://$flake5Dir"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "nixpkgs"
- },
- "to": {
- "type": "indirect",
- "id": "flake1"
- }
- },
- { "from": {
- "type": "indirect",
- "id": "templates"
- },
- "to": {
- "type": "git",
- "url": "file://$templatesDir"
- }
- }
- ]
-}
-EOF
+# Construct a custom registry, additionally test the --registry flag
+nix registry add --registry $registry flake1 git+file://$flake1Dir
+nix registry add --registry $registry flake2 git+file://$flake2Dir
+nix registry add --registry $registry flake3 git+file://$flake3Dir
+nix registry add --registry $registry flake4 flake3
+nix registry add --registry $registry flake5 hg+file://$flake5Dir
+nix registry add --registry $registry nixpkgs flake1
+nix registry add --registry $registry templates git+file://$templatesDir
# Test 'nix flake list'.
[[ $(nix registry list | wc -l) == 7 ]]
@@ -405,6 +343,8 @@ nix registry add flake1 flake3
[[ $(nix registry list | wc -l) == 8 ]]
nix registry pin flake1
[[ $(nix registry list | wc -l) == 8 ]]
+nix registry pin flake1 flake3
+[[ $(nix registry list | wc -l) == 8 ]]
nix registry remove flake1
[[ $(nix registry list | wc -l) == 7 ]]
diff --git a/tests/init.sh b/tests/init.sh
index 1a6ccb6fe..6e45a939f 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -35,5 +35,3 @@ nix-store --init
# Did anything happen?
test -e "$NIX_STATE_DIR"/db/db.sqlite
-
-echo 'Hello World' > ./dummy
diff --git a/tests/shell.nix b/tests/shell.nix
index 53759f99a..f174db583 100644
--- a/tests/shell.nix
+++ b/tests/shell.nix
@@ -34,6 +34,8 @@ let pkgs = rec {
name = "shellDrv";
builder = "/does/not/exist";
VAR_FROM_NIX = "bar";
+ ASCII_PERCENT = "%";
+ ASCII_AT = "@";
TEST_inNixShell = if inNixShell then "true" else "false";
inherit stdenv;
outputs = ["dev" "out"];