aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md61
-rw-r--r--doc/manual/generate-manpage.nix14
-rw-r--r--doc/manual/src/command-ref/env-common.md11
-rw-r--r--doc/manual/src/contributing/hacking.md32
-rw-r--r--doc/manual/src/language/operators.md4
-rw-r--r--docker.nix12
-rw-r--r--flake.nix12
-rw-r--r--mk/libraries.mk2
-rw-r--r--src/libexpr/primops/fetchTree.cc8
-rw-r--r--src/libstore/build/hook-instance.cc5
-rw-r--r--src/libstore/build/local-derivation-goal.cc50
-rw-r--r--src/libstore/build/local-derivation-goal.hh2
-rw-r--r--src/libutil/error.cc6
-rw-r--r--src/libutil/util.cc6
-rw-r--r--src/libutil/util.hh2
-rw-r--r--src/nix/build.cc42
-rw-r--r--src/nix/flake.md6
-rw-r--r--src/nix/profile.md20
-rw-r--r--src/nix/store-copy-log.cc2
-rw-r--r--tests/flakes/flake-in-submodule.sh52
-rw-r--r--tests/local.mk1
21 files changed, 275 insertions, 75 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..1b0ecaf36
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,61 @@
+# Contributing to Nix
+
+Welcome and thank you for your interest in contributing to Nix!
+We appreciate your support.
+
+Reading and following these guidelines will help us make the contribution process easy and effective for everyone involved.
+
+
+## Report a bug
+
+1. Check on the [GitHub issue tracker](https://github.com/NixOS/nix/issues) if your bug was already reported.
+
+2. If you were not able to find the bug or feature [open a new issue](https://github.com/NixOS/nix/issues/new/choose)
+
+3. The issue templates will guide you in specifying your issue.
+ The more complete the information you provide, the more likely it can be found by others and the more useful it is in the future.
+ Make sure reported bugs can be reproduced easily.
+
+4. Once submitted, do not expect issues to be picked up or solved right away.
+ The only way to ensure this, is to [work on the issue yourself](#making-changes-to-nix).
+
+## Report a security vulnerability
+
+Check out the [security policy](https://github.com/NixOS/nix/security/policy).
+
+## Making changes to Nix
+
+1. Check for [pull requests](https://github.com/NixOS/nix/pulls) that might already cover the contribution you are about to make.
+ There are many open pull requests that might already do what you intent to work on.
+ You can use [labels](https://github.com/NixOS/nix/labels) to filter for relevant topics.
+
+2. Search for related issues that cover what you're going to work on. It could help to mention there that you will work on the issue.
+
+3. Check the [Nix reference manual](https://nixos.org/manual/nix/unstable/contributing/hacking.html) for information on building Nix and running its tests.
+
+ For contributions to the command line interface, please check the [CLI guidelines](https://nixos.org/manual/nix/unstable/contributing/cli-guideline.html).
+
+4. Make your changes!
+
+5. [Create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) for your changes.
+ * [Mark the pull request as draft](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request) if you're not done with the changes.
+ * Make sure to have [a clean history of commits on your branch by using rebase](https://www.digitalocean.com/community/tutorials/how-to-rebase-and-update-a-pull-request).
+ * Link related issues in your pull request to inform interested parties and future contributors about your change.
+ If your pull request closes one or multiple issues, note that in the description using `Closes: #<number>`, as it will then happen automatically when your change is merged.
+
+6. Do not expect your pull request to be reviewed immediately.
+ Nix maintainers follow a [structured process for reviews and design decisions](https://github.com/NixOS/nix/tree/master/maintainers#project-board-protocol), which may or may not prioritise your work.
+
+7. If you need additional feedback or help to getting pull request into shape, ask other contributors using [@mentions](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#mentioning-people-and-teams).
+
+## Making changes to the Nix manual
+
+The Nix reference manual is hosted on https://nixos.org/manual/nix.
+The underlying source files are located in [`doc/manual/src`](./doc/manual/src).
+For small changes you can [use GitHub to edit these files](https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files)
+For larger changes see the [Nix reference manual](https://nixos.org/manual/nix/unstable/contributing/hacking.html).
+
+## Getting help
+
+Whenever you're stuck or do not know how to proceed, you can always ask for help.
+The appropriate channels to do so can be found on the [NixOS Community](https://nixos.org/community/) page.
diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix
index 8c7c4d358..bc19d0303 100644
--- a/doc/manual/generate-manpage.nix
+++ b/doc/manual/generate-manpage.nix
@@ -7,6 +7,7 @@ let
showCommand = { command, details, filename, toplevel }:
let
+
result = ''
> **Warning** \
> This program is **experimental** and its interface is subject to change.
@@ -25,6 +26,7 @@ let
${maybeOptions}
'';
+
showSynopsis = command: args:
let
showArgument = arg: "*${arg.label}*" + (if arg ? arity then "" else "...");
@@ -32,6 +34,7 @@ let
in ''
`${command}` [*option*...] ${arguments}
'';
+
maybeSubcommands = if details ? commands && details.commands != {}
then ''
where *subcommand* is one of the following:
@@ -39,26 +42,35 @@ let
${subcommands}
''
else "";
+
subcommands = if length categories > 1
then listCategories
else listSubcommands details.commands;
+
categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands)));
+
listCategories = concatStrings (map showCategory categories);
+
showCategory = cat: ''
**${toString cat.description}:**
${listSubcommands (filterAttrs (n: v: v.category == cat) details.commands)}
'';
+
listSubcommands = cmds: concatStrings (attrValues (mapAttrs showSubcommand cmds));
+
showSubcommand = name: subcmd: ''
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
'';
+
maybeDocumentation = if details ? doc then details.doc else "";
+
maybeOptions = if details.flags == {} then "" else ''
# Options
${showOptions details.flags toplevel.flags}
'';
+
showOptions = options: commonOptions:
let
allOptions = options // commonOptions;
@@ -99,7 +111,7 @@ let
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
parsedToplevel = builtins.fromJSON toplevel;
-
+
manpages = processCommand {
command = "nix";
details = parsedToplevel;
diff --git a/doc/manual/src/command-ref/env-common.md b/doc/manual/src/command-ref/env-common.md
index c5d38db47..2be55be52 100644
--- a/doc/manual/src/command-ref/env-common.md
+++ b/doc/manual/src/command-ref/env-common.md
@@ -13,6 +13,17 @@ Most Nix commands interpret the following environment variables:
e.g. `/home/eelco/Dev:/etc/nixos`. It can be extended using the
[`-I` option](./opt-common.md#opt-I).
+ If `NIX_PATH` is not set at all, Nix will fall back to the following list in [impure](./conf-file.md#conf-pure-eval) and [unrestricted](./conf-file.md#conf-restrict-eval) evaluation mode:
+
+ 1. `$HOME/.nix-defexpr/channels`
+ 2. `nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
+ 3. `/nix/var/nix/profiles/per-user/root/channels`
+
+ If `NIX_PATH` is set to an empty string, resolving search paths will always fail.
+ For example, attempting to use `<nixpkgs>` will produce:
+
+ error: file 'nixpkgs' was not found in the Nix search path
+
- [`NIX_IGNORE_SYMLINK_STORE`]{#env-NIX_IGNORE_SYMLINK_STORE}\
Normally, the Nix store directory (typically `/nix/store`) is not
allowed to contain any symlink components. This is to prevent
diff --git a/doc/manual/src/contributing/hacking.md b/doc/manual/src/contributing/hacking.md
index 3869c37a4..ca69f076a 100644
--- a/doc/manual/src/contributing/hacking.md
+++ b/doc/manual/src/contributing/hacking.md
@@ -389,3 +389,35 @@ If a broken link occurs in a snippet that was inserted into multiple generated f
If the `@docroot@` literal appears in an error message from the `mdbook-linkcheck` tool, the `@docroot@` replacement needs to be applied to the generated source file that mentions it.
See existing `@docroot@` logic in the [Makefile].
Regular markdown files used for the manual have a base path of their own and they can use relative paths instead of `@docroot@`.
+
+## API documentation
+
+Doxygen API documentation is [available
+online](https://hydra.nixos.org/job/nix/master/internal-api-docs/latest/download-by-type/doc/internal-api-docs). You
+can also build and view it yourself:
+
+```console
+# nix build .#hydraJobs.internal-api-docs
+# xdg-open ./result/share/doc/nix/internal-api/html/index.html
+```
+
+or inside a `nix develop` shell by running:
+
+```
+# make internal-api-html
+# xdg-open ./outputs/doc/share/doc/nix/internal-api/html/index.html
+```
+
+## Coverage analysis
+
+A coverage analysis report is [available
+online](https://hydra.nixos.org/job/nix/master/coverage/latest/download-by-type/report/coverage). You
+can build it yourself:
+
+```
+# nix build .#hydraJobs.coverage
+# xdg-open ./result/coverage/index.html
+```
+
+Metrics about the change in line/function coverage over time are also
+[available](https://hydra.nixos.org/job/nix/master/coverage#tabs-charts).
diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md
index 90b325597..a07d976ad 100644
--- a/doc/manual/src/language/operators.md
+++ b/doc/manual/src/language/operators.md
@@ -43,8 +43,8 @@ If the attribute doesn’t exist, return *value* if provided, otherwise abort ev
An attribute path is a dot-separated list of attribute names.
An attribute name can be an identifier or a string.
-> *attrpath* = *name* [ `.` *name* ]...
-> *name* = *identifier* | *string*
+> *attrpath* = *name* [ `.` *name* ]... \
+> *name* = *identifier* | *string* \
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
[Attribute selection]: #attribute-selection
diff --git a/docker.nix b/docker.nix
index 203a06b53..52199af66 100644
--- a/docker.nix
+++ b/docker.nix
@@ -8,6 +8,7 @@
, extraPkgs ? []
, maxLayers ? 100
, nixConf ? {}
+, flake-registry ? null
}:
let
defaultPkgs = with pkgs; [
@@ -247,7 +248,16 @@ let
mkdir -p $out/bin $out/usr/bin
ln -s ${pkgs.coreutils}/bin/env $out/usr/bin/env
ln -s ${pkgs.bashInteractive}/bin/bash $out/bin/sh
- '';
+
+ '' + (lib.optionalString (flake-registry != null) ''
+ nixCacheDir="/root/.cache/nix"
+ mkdir -p $out$nixCacheDir
+ globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
+ ln -s ${flake-registry}/flake-registry.json $out$globalFlakeRegistryPath
+ mkdir -p $out/nix/var/nix/gcroots/auto
+ rootName=$(${pkgs.nix}/bin/nix --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
+ ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
+ '');
in
pkgs.dockerTools.buildLayeredImageWithNixDb {
diff --git a/flake.nix b/flake.nix
index ad219877b..2fa16f8e2 100644
--- a/flake.nix
+++ b/flake.nix
@@ -319,12 +319,18 @@
};
let
canRunInstalled = currentStdenv.buildPlatform.canExecute currentStdenv.hostPlatform;
+
+ sourceByRegexInverted = rxs: origSrc: final.lib.cleanSourceWith {
+ filter = (path: type:
+ let relPath = final.lib.removePrefix (toString origSrc + "/") (toString path);
+ in ! lib.any (re: builtins.match re relPath != null) rxs);
+ src = origSrc;
+ };
in currentStdenv.mkDerivation (finalAttrs: {
name = "nix-${version}";
inherit version;
- src = self;
-
+ src = sourceByRegexInverted [ "tests/nixos/.*" "tests/installer/.*" ] self;
VERSION_SUFFIX = versionSuffix;
outputs = [ "out" "dev" "doc" ];
@@ -566,7 +572,7 @@
postInstall = ''
mkdir -p $out/nix-support
- echo "doc internal-api-docs $out/share/doc/nix/internal-api" >> $out/nix-support/hydra-build-products
+ echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> $out/nix-support/hydra-build-products
'';
};
diff --git a/mk/libraries.mk b/mk/libraries.mk
index 02e4d47f9..1bc73d7f7 100644
--- a/mk/libraries.mk
+++ b/mk/libraries.mk
@@ -126,7 +126,7 @@ define build-library
$(1)_PATH := $$(_d)/$$($(1)_NAME).a
$$($(1)_PATH): $$($(1)_OBJS) | $$(_d)/
- +$$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$^
+ $$(trace-ld) $(LD) $$(ifndef $(HOST_DARWIN),-U) -r -o $$(_d)/$$($(1)_NAME).o $$^
$$(trace-ar) $(AR) crs $$@ $$(_d)/$$($(1)_NAME).o
$(1)_LDFLAGS_USE += $$($(1)_PATH) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE))
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index fd51dfb90..0f54fedde 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -481,10 +481,10 @@ static RegisterPrimOp primop_fetchGit({
builtins.fetchGit ./work-dir
```
- If the URL points to a local directory, and no `ref` or `rev` is
- given, `fetchGit` will use the current content of the checked-out
- files, even if they are not committed or added to Git's index. It will
- only consider files added to the Git repository, as listed by `git ls-files`.
+ If the URL points to a local directory, and no `ref` or `rev` is
+ given, `fetchGit` will use the current content of the checked-out
+ files, even if they are not committed or added to Git's index. It will
+ only consider files added to the Git repository, as listed by `git ls-files`.
)",
.fun = prim_fetchGit,
});
diff --git a/src/libstore/build/hook-instance.cc b/src/libstore/build/hook-instance.cc
index ea2ae210e..075ad554f 100644
--- a/src/libstore/build/hook-instance.cc
+++ b/src/libstore/build/hook-instance.cc
@@ -35,7 +35,10 @@ HookInstance::HookInstance()
/* Fork the hook. */
pid = startProcess([&]() {
- commonChildInit(fromHook.writeSide.get());
+ if (dup2(fromHook.writeSide.get(), STDERR_FILENO) == -1)
+ throw SysError("cannot pipe standard error into log file");
+
+ commonChildInit();
if (chdir("/") == -1) throw SysError("changing into /");
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 521117c68..3484d2044 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -827,6 +827,27 @@ void LocalDerivationGoal::startBuilder()
if (unlockpt(builderOut.get()))
throw SysError("unlocking pseudoterminal");
+ /* Open the slave side of the pseudoterminal and use it as stderr. */
+ auto openSlave = [&]()
+ {
+ AutoCloseFD builderOut = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
+ if (!builderOut)
+ throw SysError("opening pseudoterminal slave");
+
+ // Put the pt into raw mode to prevent \n -> \r\n translation.
+ struct termios term;
+ if (tcgetattr(builderOut.get(), &term))
+ throw SysError("getting pseudoterminal attributes");
+
+ cfmakeraw(&term);
+
+ if (tcsetattr(builderOut.get(), TCSANOW, &term))
+ throw SysError("putting pseudoterminal into raw mode");
+
+ if (dup2(builderOut.get(), STDERR_FILENO) == -1)
+ throw SysError("cannot pipe standard error into log file");
+ };
+
buildResult.startTime = time(0);
/* Fork a child to build the package. */
@@ -880,6 +901,11 @@ void LocalDerivationGoal::startBuilder()
Pid helper = startProcess([&]() {
sendPid.readSide.close();
+ /* We need to open the slave early, before
+ CLONE_NEWUSER. Otherwise we get EPERM when running as
+ root. */
+ openSlave();
+
/* Drop additional groups here because we can't do it
after we've created the new user namespace. FIXME:
this means that if we're not root in the parent
@@ -898,7 +924,7 @@ void LocalDerivationGoal::startBuilder()
if (usingUserNamespace)
options.cloneFlags |= CLONE_NEWUSER;
- pid_t child = startProcess([&]() { runChild(slaveName); }, options);
+ pid_t child = startProcess([&]() { runChild(); }, options);
writeFull(sendPid.writeSide.get(), fmt("%d\n", child));
_exit(0);
@@ -974,7 +1000,8 @@ void LocalDerivationGoal::startBuilder()
#endif
{
pid = startProcess([&]() {
- runChild(slaveName);
+ openSlave();
+ runChild();
});
}
@@ -1620,7 +1647,7 @@ void setupSeccomp()
}
-void LocalDerivationGoal::runChild(const Path & slaveName)
+void LocalDerivationGoal::runChild()
{
/* Warning: in the child we should absolutely not make any SQLite
calls! */
@@ -1629,22 +1656,7 @@ void LocalDerivationGoal::runChild(const Path & slaveName)
try { /* child */
- /* Open the slave side of the pseudoterminal. */
- AutoCloseFD builderOut = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
- if (!builderOut)
- throw SysError("opening pseudoterminal slave");
-
- // Put the pt into raw mode to prevent \n -> \r\n translation.
- struct termios term;
- if (tcgetattr(builderOut.get(), &term))
- throw SysError("getting pseudoterminal attributes");
-
- cfmakeraw(&term);
-
- if (tcsetattr(builderOut.get(), TCSANOW, &term))
- throw SysError("putting pseudoterminal into raw mode");
-
- commonChildInit(builderOut.get());
+ commonChildInit();
try {
setupSeccomp();
diff --git a/src/libstore/build/local-derivation-goal.hh b/src/libstore/build/local-derivation-goal.hh
index 4d2f1ac28..c9ecc8828 100644
--- a/src/libstore/build/local-derivation-goal.hh
+++ b/src/libstore/build/local-derivation-goal.hh
@@ -169,7 +169,7 @@ struct LocalDerivationGoal : public DerivationGoal
int getChildStatus() override;
/* Run the builder's process. */
- void runChild(const std::string & slaveName);
+ void runChild();
/* Check that the derivation outputs all exist and register them
as valid. */
diff --git a/src/libutil/error.cc b/src/libutil/error.cc
index e4f0d4677..c9d61942a 100644
--- a/src/libutil/error.cc
+++ b/src/libutil/error.cc
@@ -302,14 +302,14 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
if (!einfo.traces.empty()) {
size_t count = 0;
for (const auto & trace : einfo.traces) {
+ if (trace.hint.str().empty()) continue;
+ if (frameOnly && !trace.frame) continue;
+
if (!showTrace && count > 3) {
oss << "\n" << ANSI_WARNING "(stack trace truncated; use '--show-trace' to show the full trace)" ANSI_NORMAL << "\n";
break;
}
- if (trace.hint.str().empty()) continue;
- if (frameOnly && !trace.frame) continue;
-
count++;
frameOnly = trace.frame;
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index c605a33e6..843a10eab 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1968,7 +1968,7 @@ std::string showBytes(uint64_t bytes)
// FIXME: move to libstore/build
-void commonChildInit(int stderrFd)
+void commonChildInit()
{
logger = makeSimpleLogger();
@@ -1982,10 +1982,6 @@ void commonChildInit(int stderrFd)
if (setsid() == -1)
throw SysError("creating a new session");
- /* Dup the write side of the logger pipe into stderr. */
- if (dup2(stderrFd, STDERR_FILENO) == -1)
- throw SysError("cannot pipe standard error into log file");
-
/* Dup stderr to stdout. */
if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
throw SysError("cannot dup stderr into stdout");
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 52ca36fd1..a8e6f9fbb 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -704,7 +704,7 @@ typedef std::function<bool(const Path & path)> PathFilter;
extern PathFilter defaultPathFilter;
/* Common initialisation performed in child processes. */
-void commonChildInit(int stderrFd);
+void commonChildInit();
/* Create a Unix domain socket. */
AutoCloseFD createUnixDomainSocket();
diff --git a/src/nix/build.cc b/src/nix/build.cc
index f8593135e..bca20e97c 100644
--- a/src/nix/build.cc
+++ b/src/nix/build.cc
@@ -41,6 +41,29 @@ nlohmann::json builtPathsWithResultToJSON(const std::vector<BuiltPathWithResult>
return res;
}
+// TODO deduplicate with other code also setting such out links.
+static void createOutLinks(const Path& outLink, const std::vector<BuiltPathWithResult>& buildables, LocalFSStore& store2)
+{
+ for (const auto & [_i, buildable] : enumerate(buildables)) {
+ auto i = _i;
+ std::visit(overloaded {
+ [&](const BuiltPath::Opaque & bo) {
+ std::string symlink = outLink;
+ if (i) symlink += fmt("-%d", i);
+ store2.addPermRoot(bo.path, absPath(symlink));
+ },
+ [&](const BuiltPath::Built & bfd) {
+ for (auto & output : bfd.outputs) {
+ std::string symlink = outLink;
+ if (i) symlink += fmt("-%d", i);
+ if (output.first != "out") symlink += fmt("-%s", output.first);
+ store2.addPermRoot(output.second, absPath(symlink));
+ }
+ },
+ }, buildable.path.raw());
+ }
+}
+
struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
{
Path outLink = "result";
@@ -115,24 +138,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
if (outLink != "")
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
- for (const auto & [_i, buildable] : enumerate(buildables)) {
- auto i = _i;
- std::visit(overloaded {
- [&](const BuiltPath::Opaque & bo) {
- std::string symlink = outLink;
- if (i) symlink += fmt("-%d", i);
- store2->addPermRoot(bo.path, absPath(symlink));
- },
- [&](const BuiltPath::Built & bfd) {
- for (auto & output : bfd.outputs) {
- std::string symlink = outLink;
- if (i) symlink += fmt("-%d", i);
- if (output.first != "out") symlink += fmt("-%s", output.first);
- store2->addPermRoot(output.second, absPath(symlink));
- }
- },
- }, buildable.path.raw());
- }
+ createOutLinks(outLink, buildables, *store2);
if (printOutputPaths) {
stopProgressBar();
diff --git a/src/nix/flake.md b/src/nix/flake.md
index 9073d0c3b..8eaa41b96 100644
--- a/src/nix/flake.md
+++ b/src/nix/flake.md
@@ -54,7 +54,7 @@ output attribute). They are also allowed in the `inputs` attribute
of a flake, e.g.
```nix
-inputs.nixpkgs.url = github:NixOS/nixpkgs;
+inputs.nixpkgs.url = "github:NixOS/nixpkgs";
```
is equivalent to
@@ -282,7 +282,7 @@ Nixpkgs flake and provides a single package (i.e. an
{
description = "A flake for building Hello World";
- inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-20.03";
outputs = { self, nixpkgs }: {
@@ -374,7 +374,7 @@ inputs.nixpkgs = {
Alternatively, you can use the URL-like syntax:
```nix
-inputs.import-cargo.url = github:edolstra/import-cargo;
+inputs.import-cargo.url = "github:edolstra/import-cargo";
inputs.nixpkgs.url = "nixpkgs";
```
diff --git a/src/nix/profile.md b/src/nix/profile.md
index 273e02280..bf61ef4b9 100644
--- a/src/nix/profile.md
+++ b/src/nix/profile.md
@@ -12,7 +12,7 @@ them to be rolled back easily.
The default profile used by `nix profile` is `$HOME/.nix-profile`,
which, if it does not exist, is created as a symlink to
`/nix/var/nix/profiles/default` if Nix is invoked by the
-`root` user, or `/nix/var/nix/profiles/per-user/`*username* otherwise.
+`root` user, or `${XDG_STATE_HOME-$HOME/.local/state}/nix/profiles/profile` otherwise.
You can specify another profile location using `--profile` *path*.
@@ -24,11 +24,11 @@ the profile. In turn, *path*`-`*N* is a symlink to a path in the Nix
store. For example:
```console
-$ ls -l /nix/var/nix/profiles/per-user/alice/profile*
-lrwxrwxrwx 1 alice users 14 Nov 25 14:35 /nix/var/nix/profiles/per-user/alice/profile -> profile-7-link
-lrwxrwxrwx 1 alice users 51 Oct 28 16:18 /nix/var/nix/profiles/per-user/alice/profile-5-link -> /nix/store/q69xad13ghpf7ir87h0b2gd28lafjj1j-profile
-lrwxrwxrwx 1 alice users 51 Oct 29 13:20 /nix/var/nix/profiles/per-user/alice/profile-6-link -> /nix/store/6bvhpysd7vwz7k3b0pndn7ifi5xr32dg-profile
-lrwxrwxrwx 1 alice users 51 Nov 25 14:35 /nix/var/nix/profiles/per-user/alice/profile-7-link -> /nix/store/mp0x6xnsg0b8qhswy6riqvimai4gm677-profile
+$ ls -l ~alice/.local/state/nix/profiles/profile*
+lrwxrwxrwx 1 alice users 14 Nov 25 14:35 /home/alice/.local/state/nix/profiles/profile -> profile-7-link
+lrwxrwxrwx 1 alice users 51 Oct 28 16:18 /home/alice/.local/state/nix/profiles/profile-5-link -> /nix/store/q69xad13ghpf7ir87h0b2gd28lafjj1j-profile
+lrwxrwxrwx 1 alice users 51 Oct 29 13:20 /home/alice/.local/state/nix/profiles/profile-6-link -> /nix/store/6bvhpysd7vwz7k3b0pndn7ifi5xr32dg-profile
+lrwxrwxrwx 1 alice users 51 Nov 25 14:35 /home/alice/.local/state/nix/profiles/profile-7-link -> /nix/store/mp0x6xnsg0b8qhswy6riqvimai4gm677-profile
```
Each of these symlinks is a root for the Nix garbage collector.
@@ -38,20 +38,20 @@ profile is a tree of symlinks to the files of the installed packages,
e.g.
```console
-$ ll -R /nix/var/nix/profiles/per-user/eelco/profile-7-link/
-/nix/var/nix/profiles/per-user/eelco/profile-7-link/:
+$ ll -R ~eelco/.local/state/nix/profiles/profile-7-link/
+/home/eelco/.local/state/nix/profiles/profile-7-link/:
total 20
dr-xr-xr-x 2 root root 4096 Jan 1 1970 bin
-r--r--r-- 2 root root 1402 Jan 1 1970 manifest.json
dr-xr-xr-x 4 root root 4096 Jan 1 1970 share
-/nix/var/nix/profiles/per-user/eelco/profile-7-link/bin:
+/home/eelco/.local/state/nix/profiles/profile-7-link/bin:
total 20
lrwxrwxrwx 5 root root 79 Jan 1 1970 chromium -> /nix/store/ijm5k0zqisvkdwjkc77mb9qzb35xfi4m-chromium-86.0.4240.111/bin/chromium
lrwxrwxrwx 7 root root 87 Jan 1 1970 spotify -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/bin/spotify
lrwxrwxrwx 3 root root 79 Jan 1 1970 zoom-us -> /nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927/bin/zoom-us
-/nix/var/nix/profiles/per-user/eelco/profile-7-link/share/applications:
+/home/eelco/.local/state/nix/profiles/profile-7-link/share/applications:
total 12
lrwxrwxrwx 4 root root 120 Jan 1 1970 chromium-browser.desktop -> /nix/store/4cf803y4vzfm3gyk3vzhzb2327v0kl8a-chromium-unwrapped-86.0.4240.111/share/applications/chromium-browser.desktop
lrwxrwxrwx 7 root root 110 Jan 1 1970 spotify.desktop -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/share/applications/spotify.desktop
diff --git a/src/nix/store-copy-log.cc b/src/nix/store-copy-log.cc
index 1dda8c0b8..a6e8aeff7 100644
--- a/src/nix/store-copy-log.cc
+++ b/src/nix/store-copy-log.cc
@@ -24,8 +24,6 @@ struct CmdCopyLog : virtual CopyCommand, virtual InstallablesCommand
;
}
- Category category() override { return catUtility; }
-
void run(ref<Store> srcStore, Installables && installables) override
{
auto & srcLogStore = require<LogStore>(*srcStore);
diff --git a/tests/flakes/flake-in-submodule.sh b/tests/flakes/flake-in-submodule.sh
new file mode 100644
index 000000000..21a4b52de
--- /dev/null
+++ b/tests/flakes/flake-in-submodule.sh
@@ -0,0 +1,52 @@
+source common.sh
+
+# Tests that:
+# - flake.nix may reside inside of a git submodule
+# - the flake can access content outside of the submodule
+#
+# rootRepo
+# ├── root.nix
+# └── submodule
+# ├── flake.nix
+# └── sub.nix
+
+
+requireGit
+
+clearStore
+
+# Submodules can't be fetched locally by default.
+# See fetchGitSubmodules.sh
+export XDG_CONFIG_HOME=$TEST_HOME/.config
+git config --global protocol.file.allow always
+
+
+rootRepo=$TEST_ROOT/rootRepo
+subRepo=$TEST_ROOT/submodule
+
+
+createGitRepo $subRepo
+cat > $subRepo/flake.nix <<EOF
+{
+ outputs = { self }: {
+ sub = import ./sub.nix;
+ root = import ../root.nix;
+ };
+}
+EOF
+echo '"expression in submodule"' > $subRepo/sub.nix
+git -C $subRepo add flake.nix sub.nix
+git -C $subRepo commit -m Initial
+
+createGitRepo $rootRepo
+
+git -C $rootRepo submodule init
+git -C $rootRepo submodule add $subRepo submodule
+echo '"expression in root repo"' > $rootRepo/root.nix
+git -C $rootRepo add root.nix
+git -C $rootRepo commit -m "Add root.nix"
+
+# Flake can live inside a submodule and can be accessed via ?dir=submodule
+[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#sub ) = '"expression in submodule"' ]]
+# The flake can access content outside of the submodule
+[[ $(nix eval --json git+file://$rootRepo\?submodules=1\&dir=submodule#root ) = '"expression in root repo"' ]]
diff --git a/tests/local.mk b/tests/local.mk
index 4c4383c38..328f27e90 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -13,6 +13,7 @@ nix_tests = \
flakes/unlocked-override.sh \
flakes/absolute-paths.sh \
flakes/build-paths.sh \
+ flakes/flake-in-submodule.sh \
ca/gc.sh \
gc.sh \
remote-store.sh \