Merge remote-tracking branch 'nixos/master'
Some checks failed
CI / tests (macos-latest) (push) Has been cancelled
CI / tests (ubuntu-latest) (push) Has been cancelled
CI / Check Cachix and Docker secrets present for installer tests (push) Has been cancelled
CI / installer (push) Has been cancelled
CI / installer_test (macos-latest) (push) Has been cancelled
CI / installer_test (ubuntu-latest) (push) Has been cancelled
CI / docker_push_image (push) Has been cancelled
CI / vm_tests (push) Has been cancelled
CI / flake_regressions (push) Has been cancelled

This commit is contained in:
Max Headroom 2024-08-17 01:53:36 +02:00
commit 7bf3b90d4d
339 changed files with 6393 additions and 2986 deletions

View file

@ -31,3 +31,4 @@ AlwaysBreakBeforeMultilineStrings: true
IndentPPDirectives: AfterHash IndentPPDirectives: AfterHash
PPIndentWidth: 2 PPIndentWidth: 2
BinPackArguments: false BinPackArguments: false
BreakBeforeTernaryOperators: true

View file

@ -49,6 +49,7 @@ jobs:
done done
) & ) &
- run: nix --experimental-features 'nix-command flakes' flake check -L - run: nix --experimental-features 'nix-command flakes' flake check -L
- run: nix --experimental-features 'nix-command flakes' flake show --all-systems --json
# Steps to test CI automation in your own fork. # Steps to test CI automation in your own fork.
# Cachix: # Cachix:
@ -195,20 +196,6 @@ jobs:
- uses: DeterminateSystems/magic-nix-cache-action@main - uses: DeterminateSystems/magic-nix-cache-action@main
- run: nix build -L .#hydraJobs.tests.githubFlakes .#hydraJobs.tests.tarballFlakes .#hydraJobs.tests.functional_user - run: nix build -L .#hydraJobs.tests.githubFlakes .#hydraJobs.tests.tarballFlakes .#hydraJobs.tests.functional_user
meson_build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
# Only meson packages that don't have a tests.run derivation.
# Those that have it are already built and tested as part of nix flake check.
- run: nix build -L .#hydraJobs.build.{nix-cmd,nix-main}.$(nix-instantiate --eval --expr builtins.currentSystem | sed -e 's/"//g')
flake_regressions: flake_regressions:
needs: vm_tests needs: vm_tests
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04

View file

@ -1 +1 @@
2.24.0 2.25.0

View file

@ -41,9 +41,9 @@ Check out the [security policy](https://github.com/NixOS/nix/security/policy).
There are many open pull requests that might already do what you intend to work on. There are many open pull requests that might already do what you intend to work on.
You can use [labels](https://github.com/NixOS/nix/labels) to filter for relevant topics. You can use [labels](https://github.com/NixOS/nix/labels) to filter for relevant topics.
3. Check the [Nix reference manual](https://nixos.org/manual/nix/unstable/contributing/hacking.html) for information on building Nix and running its tests. 3. Check the [Nix reference manual](https://nix.dev/manual/nix/development/development/building.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). For contributions to the command line interface, please check the [CLI guidelines](https://nix.dev/manual/nix/development/development/cli-guideline.html).
4. Make your change! 4. Make your change!
@ -52,6 +52,20 @@ Check out the [security policy](https://github.com/NixOS/nix/security/policy).
Link related issues to inform interested parties and future contributors about your change. Link related issues to inform interested parties and future contributors about your change.
If your pull request closes one or multiple issues, mention that in the description using `Closes: #<number>`, as it will then happen automatically when your change is merged. If your pull request closes one or multiple issues, mention that in the description using `Closes: #<number>`, as it will then happen automatically when your change is merged.
* Credit original authors when you're reusing or building on their work.
* Link to relevant changes in other projects, so that others can understand the full context of the change in the future when you or someone else will change or troubleshoot the code.
This is especially important when your change is based on work done in other repositories.
Example:
```
This is based on the work of @user in <url>.
This solution took inspiration from <url>.
Co-authored-by: User Name <user@example.com>
```
When cherry-picking from a different repository, use the `-x` flag, and then amend the commits to turn the hashes into URLs.
* 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). * 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).
* [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. * [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.
@ -69,7 +83,7 @@ Check out the [security policy](https://github.com/NixOS/nix/security/policy).
- [ ] API documentation in header files - [ ] API documentation in header files
- [ ] Code and comments are self-explanatory - [ ] Code and comments are self-explanatory
- [ ] Commit message explains **why** the change was made - [ ] Commit message explains **why** the change was made
- [ ] New feature or incompatible change: [add a release note](https://nixos.org/manual/nix/stable/contributing/hacking#add-a-release-note) - [ ] New feature or incompatible change: [add a release note](https://nix.dev/manual/nix/development/development/contributing.html#add-a-release-note)
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). 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).
@ -78,7 +92,7 @@ Check out the [security policy](https://github.com/NixOS/nix/security/policy).
The Nix reference manual is hosted on https://nixos.org/manual/nix. 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). 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 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). For larger changes see the [Nix reference manual](https://nix.dev/manual/nix/development/development/contributing.html).
## Getting help ## Getting help

View file

@ -38,22 +38,11 @@ makefiles += \
endif endif
endif endif
ifeq ($(ENABLE_UNIT_TESTS), yes)
makefiles += \
tests/unit/libutil/local.mk \
tests/unit/libutil-support/local.mk \
tests/unit/libstore/local.mk \
tests/unit/libstore-support/local.mk \
tests/unit/libfetchers/local.mk \
tests/unit/libexpr/local.mk \
tests/unit/libexpr-support/local.mk \
tests/unit/libflake/local.mk
endif
ifeq ($(ENABLE_FUNCTIONAL_TESTS), yes) ifeq ($(ENABLE_FUNCTIONAL_TESTS), yes)
ifdef HOST_UNIX ifdef HOST_UNIX
makefiles += \ makefiles += \
tests/functional/local.mk \ tests/functional/local.mk \
tests/functional/flakes/local.mk \
tests/functional/ca/local.mk \ tests/functional/ca/local.mk \
tests/functional/git-hashing/local.mk \ tests/functional/git-hashing/local.mk \
tests/functional/dyn-drv/local.mk \ tests/functional/dyn-drv/local.mk \
@ -92,7 +81,7 @@ ifdef HOST_WINDOWS
GLOBAL_LDFLAGS += -Wl,--export-all-symbols GLOBAL_LDFLAGS += -Wl,--export-all-symbols
endif endif
GLOBAL_CXXFLAGS += -g -Wall -Wdeprecated-copy -Wignored-qualifiers -Wimplicit-fallthrough -Werror=unused-result -include $(buildprefix)config.h -std=c++2a -I src GLOBAL_CXXFLAGS += -g -Wall -Wdeprecated-copy -Wignored-qualifiers -Wimplicit-fallthrough -Werror=unused-result -Werror=suggest-override -include $(buildprefix)config.h -std=c++2a -I src
# Include the main lib, causing rules to be defined # Include the main lib, causing rules to be defined
@ -103,13 +92,6 @@ include mk/lib.mk
# These must be defined after `mk/lib.mk`. Otherwise the first rule # These must be defined after `mk/lib.mk`. Otherwise the first rule
# incorrectly becomes the default target. # incorrectly becomes the default target.
ifneq ($(ENABLE_UNIT_TESTS), yes)
.PHONY: check
check:
@echo "Unit tests are disabled. Configure without '--disable-unit-tests', or avoid calling 'make check'."
@exit 1
endif
ifneq ($(ENABLE_FUNCTIONAL_TESTS), yes) ifneq ($(ENABLE_FUNCTIONAL_TESTS), yes)
.PHONY: installcheck .PHONY: installcheck
installcheck: installcheck:

View file

@ -12,7 +12,6 @@ ENABLE_BUILD = @ENABLE_BUILD@
ENABLE_DOC_GEN = @ENABLE_DOC_GEN@ ENABLE_DOC_GEN = @ENABLE_DOC_GEN@
ENABLE_FUNCTIONAL_TESTS = @ENABLE_FUNCTIONAL_TESTS@ ENABLE_FUNCTIONAL_TESTS = @ENABLE_FUNCTIONAL_TESTS@
ENABLE_S3 = @ENABLE_S3@ ENABLE_S3 = @ENABLE_S3@
ENABLE_UNIT_TESTS = @ENABLE_UNIT_TESTS@
GTEST_LIBS = @GTEST_LIBS@ GTEST_LIBS = @GTEST_LIBS@
HAVE_LIBCPUID = @HAVE_LIBCPUID@ HAVE_LIBCPUID = @HAVE_LIBCPUID@
HAVE_SECCOMP = @HAVE_SECCOMP@ HAVE_SECCOMP = @HAVE_SECCOMP@

View file

@ -1,13 +1,11 @@
add_project_arguments( add_project_arguments(
'-Wno-deprecated-declarations', '-Wdeprecated-copy',
'-Wimplicit-fallthrough', '-Werror=suggest-override',
'-Werror=switch', '-Werror=switch',
'-Werror=switch-enum', '-Werror=switch-enum',
'-Werror=unused-result', '-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers', '-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked '-Wimplicit-fallthrough',
# at ~1% overhead in `nix search`. '-Wno-deprecated-declarations',
#
language : 'cpp', language : 'cpp',
) )

View file

@ -141,18 +141,6 @@ AC_ARG_ENABLE(build, AS_HELP_STRING([--disable-build],[Do not build nix]),
ENABLE_BUILD=$enableval, ENABLE_BUILD=yes) ENABLE_BUILD=$enableval, ENABLE_BUILD=yes)
AC_SUBST(ENABLE_BUILD) AC_SUBST(ENABLE_BUILD)
# Building without unit tests is useful for bootstrapping with a smaller footprint
# or running the tests in a separate derivation. Otherwise, we do compile and
# run them.
AC_ARG_ENABLE(unit-tests, AS_HELP_STRING([--disable-unit-tests],[Do not build the tests]),
ENABLE_UNIT_TESTS=$enableval, ENABLE_UNIT_TESTS=$ENABLE_BUILD)
AC_SUBST(ENABLE_UNIT_TESTS)
AS_IF(
[test "$ENABLE_BUILD" == "no" && test "$ENABLE_UNIT_TESTS" == "yes"],
[AC_MSG_ERROR([Cannot enable unit tests when building overall is disabled. Please do not pass '--enable-unit-tests' or do not pass '--disable-build'.])])
AC_ARG_ENABLE(functional-tests, AS_HELP_STRING([--disable-functional-tests],[Do not build the tests]), AC_ARG_ENABLE(functional-tests, AS_HELP_STRING([--disable-functional-tests],[Do not build the tests]),
ENABLE_FUNCTIONAL_TESTS=$enableval, ENABLE_FUNCTIONAL_TESTS=yes) ENABLE_FUNCTIONAL_TESTS=$enableval, ENABLE_FUNCTIONAL_TESTS=yes)
AC_SUBST(ENABLE_FUNCTIONAL_TESTS) AC_SUBST(ENABLE_FUNCTIONAL_TESTS)
@ -358,16 +346,6 @@ if test "$gc" = yes; then
CFLAGS="$old_CFLAGS" CFLAGS="$old_CFLAGS"
fi fi
AS_IF([test "$ENABLE_UNIT_TESTS" == "yes"],[
# Look for gtest.
PKG_CHECK_MODULES([GTEST], [gtest_main gmock_main])
# Look for rapidcheck.
PKG_CHECK_MODULES([RAPIDCHECK], [rapidcheck rapidcheck_gtest])
])
# Look for nlohmann/json. # Look for nlohmann/json.
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9]) PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])

View file

@ -12,8 +12,8 @@ h1.menu-title::before {
} }
h1.menu-title { .menu-bar {
padding: 0.5em; padding: 0.5em 0em;
} }
.sidebar .sidebar-scrollbox { .sidebar .sidebar-scrollbox {

View file

@ -12,7 +12,7 @@ let
experimentalNotice = optionalString (experimental-feature != null) '' experimentalNotice = optionalString (experimental-feature != null) ''
> **Note** > **Note**
> >
> This function is only available if the [`${experimental-feature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimental-feature}) is enabled. > This function is only available if the [`${experimental-feature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimental-feature}) is enabled.
> >
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md): > For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
> >

View file

@ -38,7 +38,7 @@ let
result = '' result = ''
> **Warning** \ > **Warning** \
> This program is > This program is
> [**experimental**](@docroot@/contributing/experimental-features.md#xp-feature-nix-command) > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
> and its interface is subject to change. > and its interface is subject to change.
# Name # Name

View file

@ -33,10 +33,10 @@ let
> **Warning** > **Warning**
> >
> This setting is part of an > This setting is part of an
> [experimental feature](@docroot@/contributing/experimental-features.md). > [experimental feature](@docroot@/development/experimental-features.md).
> >
> To change this setting, make sure the > To change this setting, make sure the
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}) > [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature})
> is enabled. > is enabled.
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md): > For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
> >

View file

@ -32,10 +32,10 @@ let
> **Warning** > **Warning**
> >
> This store is part of an > This store is part of an
> [experimental feature](@docroot@/contributing/experimental-features.md). > [experimental feature](@docroot@/development/experimental-features.md).
> >
> To use this store, make sure the > To use this store, make sure the
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}) > [`${experimentalFeature}` experimental feature](@docroot@/development/experimental-features.md#xp-feature-${experimentalFeature})
> is enabled. > is enabled.
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md): > For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
> >

View file

@ -4,6 +4,6 @@ with import <nix/utils.nix>;
let let
showExperimentalFeature = name: doc: showExperimentalFeature = name: doc:
'' ''
- [`${name}`](@docroot@/contributing/experimental-features.md#xp-feature-${name}) - [`${name}`](@docroot@/development/experimental-features.md#xp-feature-${name})
''; '';
in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps))) in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))

View file

@ -95,7 +95,7 @@ $(d)/nix-profiles.5: $(d)/src/command-ref/files/profiles.md
$(trace-gen) lowdown -sT man --nroff-nolinks -M section=5 $^.tmp -o $@ $(trace-gen) lowdown -sT man --nroff-nolinks -M section=5 $^.tmp -o $@
@rm $^.tmp @rm $^.tmp
$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/SUMMARY-rl-next.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md $(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/SUMMARY-rl-next.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/development/experimental-feature-descriptions.md
@cp $< $@ @cp $< $@
@$(call process-includes,$@,$@) @$(call process-includes,$@,$@)
@ -124,7 +124,7 @@ $(d)/conf-file.json: $(doc_nix)
$(trace-gen) $(dummy-env) $(doc_nix) config show --json --experimental-features nix-command > $@.tmp $(trace-gen) $(dummy-env) $(doc_nix) config show --json --experimental-features nix-command > $@.tmp
@mv $@.tmp $@ @mv $@.tmp $@
$(d)/src/contributing/experimental-feature-descriptions.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(doc_nix) $(d)/src/development/experimental-feature-descriptions.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(doc_nix)
@rm -rf $@ $@.tmp @rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features.nix (builtins.fromJSON (builtins.readFile $<))' $(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@ @mv $@.tmp $@
@ -207,11 +207,11 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli
done done
@touch $@ @touch $@
# the `! -name 'contributing.md'` filter excludes the one place where # the `! -name 'documentation.md'` filter excludes the one place where
# `@docroot@` is to be preserved for documenting the mechanism # `@docroot@` is to be preserved for documenting the mechanism
# FIXME: maybe contributing guides should live right next to the code # FIXME: maybe contributing guides should live right next to the code
# instead of in the manual # instead of in the manual
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md $(d)/src/command-ref/conf-file.md $(d)/src/language/builtins.md $(d)/src/release-notes/rl-next.md $(d)/src/figures $(d)/src/favicon.png $(d)/src/favicon.svg $(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/development/experimental-feature-descriptions.md $(d)/src/command-ref/conf-file.md $(d)/src/language/builtins.md $(d)/src/release-notes/rl-next.md $(d)/src/figures $(d)/src/favicon.png $(d)/src/favicon.svg
$(trace-gen) \ $(trace-gen) \
tmp="$$(mktemp -d)"; \ tmp="$$(mktemp -d)"; \
cp -r doc/manual "$$tmp"; \ cp -r doc/manual "$$tmp"; \

View file

@ -143,7 +143,7 @@ const redirects = {
"opt-timeout": "command-ref/opt-common.html#opt-timeout", "opt-timeout": "command-ref/opt-common.html#opt-timeout",
"sec-common-options": "command-ref/opt-common.html", "sec-common-options": "command-ref/opt-common.html",
"ch-utilities": "command-ref/utilities.html", "ch-utilities": "command-ref/utilities.html",
"chap-hacking": "contributing/hacking.html", "chap-hacking": "development/building.html",
"adv-attr-allowSubstitutes": "language/advanced-attributes.html#adv-attr-allowSubstitutes", "adv-attr-allowSubstitutes": "language/advanced-attributes.html#adv-attr-allowSubstitutes",
"adv-attr-allowedReferences": "language/advanced-attributes.html#adv-attr-allowedReferences", "adv-attr-allowedReferences": "language/advanced-attributes.html#adv-attr-allowedReferences",
"adv-attr-allowedRequisites": "language/advanced-attributes.html#adv-attr-allowedRequisites", "adv-attr-allowedRequisites": "language/advanced-attributes.html#adv-attr-allowedRequisites",
@ -344,13 +344,14 @@ const redirects = {
}, },
"language/syntax.html": { "language/syntax.html": {
"scoping-rules": "scoping.html", "scoping-rules": "scoping.html",
"string-literal": "string-literals.html",
}, },
"installation/installing-binary.html": { "installation/installing-binary.html": {
"linux": "uninstall.html#linux", "linux": "uninstall.html#linux",
"macos": "uninstall.html#macos", "macos": "uninstall.html#macos",
"uninstalling": "uninstall.html", "uninstalling": "uninstall.html",
}, },
"contributing/hacking.html": { "development/building.html": {
"nix-with-flakes": "#building-nix-with-flakes", "nix-with-flakes": "#building-nix-with-flakes",
"classic-nix": "#building-nix", "classic-nix": "#building-nix",
"running-tests": "testing.html#running-tests", "running-tests": "testing.html#running-tests",
@ -361,7 +362,12 @@ const redirects = {
"installer-tests": "testing.html#installer-tests", "installer-tests": "testing.html#installer-tests",
"one-time-setup": "testing.html#one-time-setup", "one-time-setup": "testing.html#one-time-setup",
"using-the-ci-generated-installer-for-manual-testing": "testing.html#using-the-ci-generated-installer-for-manual-testing", "using-the-ci-generated-installer-for-manual-testing": "testing.html#using-the-ci-generated-installer-for-manual-testing",
"characterization-testing": "#characterisation-testing-unit", "characterization-testing": "testing.html#characterisation-testing-unit",
"add-a-release-note": "contributing.html#add-a-release-note",
"add-an-entry": "contributing.html#add-an-entry",
"build-process": "contributing.html#build-process",
"reverting": "contributing.html#reverting",
"branches": "contributing.html#branches",
}, },
"glossary.html": { "glossary.html": {
"gloss-local-store": "store/types/local-store.html", "gloss-local-store": "store/types/local-store.html",

View file

@ -0,0 +1,21 @@
---
synopsis: Define integer overflow in the Nix language as an error
issues: [10968]
prs: [11188]
---
Previously, integer overflow in the Nix language invoked C++ level signed overflow, which was undefined behaviour, but *usually* manifested as wrapping around on overflow.
Since prior to the public release of Lix, Lix had C++ signed overflow defined to crash the process and nobody noticed this having accidentally removed overflow from the Nix language for three months until it was caught by fiddling around.
Given the significant body of actual Nix code that has been evaluated by Lix in that time, it does not appear that nixpkgs or much of importance depends on integer overflow, so it appears safe to turn into an error.
Some other overflows were fixed:
- `builtins.fromJSON` of values greater than the maximum representable value in a signed 64-bit integer will generate an error.
- `nixConfig` in flakes will no longer accept negative values for configuration options.
Integer overflow now looks like the following:
```
$ nix eval --expr '9223372036854775807 + 1'
error: integer overflow in adding 9223372036854775807 + 1
```

View file

@ -0,0 +1,22 @@
---
synopsis: |-
The `build-hook` setting's default is less useful when using `libnixstore` as a library
prs:
- 11178
---
*This is an obscure issue that only affects usage of the `libnixstore` library outside of the Nix executable.*
As part the ongoing [rewrite of the build system](https://github.com/NixOS/nix/issues/2503) to use [Meson](https://mesonbuild.com/), we are also switching to packaging individual Nix components separately (and building them in separate derivations).
This means that when building `libnixstore` we do not know where the Nix binaries will be installed --- `libnixstore` doesn't know about downstream consumers like the Nix binaries at all.
*This is also unrelated to the _`post`_-`build-hook`*, which is often used for pushing to a cache.*
This has a small adverse affect on remote building --- the `build-remote` executable that is specified from the [`build-hook`](@docroot@/command-ref/conf-file.md#conf-build-hook) setting will not be gotten from the (presumed) installation location, but instead looked up on the `PATH`.
This means that other applications linking `libnixstore` that wish to use remote building must arrange for the `nix` command to be on the PATH (or manually overriding `build-hook`) in order for that to work.
Long term we don't envision this being a downside, because we plan to [get rid of `build-remote` and the build hook setting entirely](https://github.com/NixOS/nix/issues/1221).
There is simply no need to add a second layer of remote-procedure-calling when we want to connect to a remote builder.
The build hook protocol did in principle support custom ways of remote building, but that can also be accomplished with a custom service for the ssh or daemon/ssh-ng protocols, or with a custom [store type](@docroot@/store/types/) i.e. `Store` subclass. <!-- we normally don't mention classes, but consider that this release note is about a library use case -->
The Perl bindings no longer expose `getBinDir` either, since they libraries those bindings wrap no longer know the location of installed binaries as described above.

View file

@ -1,6 +0,0 @@
---
synopsis: Stop vendoring toml11
---
We don't apply any patches to it, and vendoring it locks users into
bugs (it hasn't been updated since its introduction in late 2021).

View file

@ -1,7 +0,0 @@
---
synopsis: Harden the user sandboxing
significance: significant
issues:
---
The build directory has been hardened against interference with the outside world by nesting it inside another directory owned by (and only readable by) the daemon user.

View file

@ -1,28 +0,0 @@
---
synopsis: "`nix-shell <directory>` looks for `shell.nix`"
significance: significant
issues:
- 496
- 2279
- 4529
- 5431
- 11053
prs:
- 11057
---
`nix-shell $x` now looks for `$x/shell.nix` when `$x` resolves to a directory.
Although this might be seen as a breaking change, its primarily interactive usage makes it a minor issue.
This adjustment addresses a commonly reported problem.
This also applies to `nix-shell` shebang scripts. Consider the following example:
```shell
#!/usr/bin/env nix-shell
#!nix-shell -i bash
```
This will now load `shell.nix` from the script's directory, if it exists; `default.nix` otherwise.
The old behavior can be opted into by setting the option [`nix-shell-always-looks-for-shell-nix`](@docroot@/command-ref/conf-file.md#conf-nix-shell-always-looks-for-shell-nix) to `false`.

View file

@ -1,53 +0,0 @@
---
synopsis: "`nix-repl`'s `:doc` shows documentation comments"
significance: significant
issues:
- 3904
- 10771
prs:
- 1652
- 9054
- 11072
---
`nix repl` has a `:doc` command that previously only rendered documentation for internally defined functions.
This feature has been extended to also render function documentation comments, in accordance with [RFC 145].
Example:
```
nix-repl> :doc lib.toFunction
Function toFunction
… defined at /home/user/h/nixpkgs/lib/trivial.nix:1072:5
Turns any non-callable values into constant functions. Returns
callable values as is.
Inputs
v
: Any value
Examples
:::{.example}
## lib.trivial.toFunction usage example
| nix-repl> lib.toFunction 1 2
| 1
|
| nix-repl> lib.toFunction (x: x + 1) 2
| 3
:::
```
Known limitations:
- It does not render documentation for "formals", such as `{ /** the value to return */ x, ... }: x`.
- Some extensions to markdown are not yet supported, as you can see in the example above.
We'd like to acknowledge Yingchi Long for proposing a proof of concept for this functionality in [#9054](https://github.com/NixOS/nix/pull/9054), as well as @sternenseemann and Johannes Kirschbauer for their contributions, proposals, and their work on [RFC 145].
[RFC 145]: https://github.com/NixOS/rfcs/pull/145

View file

@ -1,62 +0,0 @@
---
synopsis: "`nix-shell` shebang uses relative path"
prs:
- 5088
- 11058
issues:
- 4232
---
<!-- unfortunately no link target for the specific syntax -->
Relative [path](@docroot@/language/values.md#type-path) literals in `nix-shell` shebang scripts' options are now resolved relative to the [script's location](@docroot@/glossary?highlight=base%20directory#gloss-base-directory).
Previously they were resolved relative to the current working directory.
For example, consider the following script in `~/myproject/say-hi`:
```shell
#!/usr/bin/env nix-shell
#!nix-shell --expr 'import ./shell.nix'
#!nix-shell --arg toolset './greeting-tools.nix'
#!nix-shell -i bash
hello
```
Older versions of `nix-shell` would resolve `shell.nix` relative to the current working directory; home in this example:
```console
[hostname:~]$ ./myproject/say-hi
error:
… while calling the 'import' builtin
at «string»:1:2:
1| (import ./shell.nix)
| ^
error: path '/home/user/shell.nix' does not exist
```
Since this release, `nix-shell` resolves `shell.nix` relative to the script's location, and `~/myproject/shell.nix` is used.
```console
$ ./myproject/say-hi
Hello, world!
```
**Opt-out**
This is technically a breaking change, so we have added an option so you can adapt independently of your Nix update.
The old behavior can be opted into by setting the option [`nix-shell-shebang-arguments-relative-to-script`](@docroot@/command-ref/conf-file.md#conf-nix-shell-shebang-arguments-relative-to-script) to `false`.
This option will be removed in a future release.
**`nix` command shebang**
The experimental [`nix` command shebang](@docroot@/command-ref/new-cli/nix.md?highlight=shebang#shebang-interpreter) already behaves in this script-relative manner.
Example:
```shell
#!/usr/bin/env nix
#!nix develop
#!nix --expr ``import ./shell.nix``
#!nix -c bash
hello
```

View file

@ -28,6 +28,9 @@
- [Data Types](language/types.md) - [Data Types](language/types.md)
- [String context](language/string-context.md) - [String context](language/string-context.md)
- [Syntax and semantics](language/syntax.md) - [Syntax and semantics](language/syntax.md)
- [Variables](language/variables.md)
- [String literals](language/string-literals.md)
- [Identifiers](language/identifiers.md)
- [Scoping rules](language/scope.md) - [Scoping rules](language/scope.md)
- [String interpolation](language/string-interpolation.md) - [String interpolation](language/string-interpolation.md)
- [Lookup path](language/constructs/lookup-path.md) - [Lookup path](language/constructs/lookup-path.md)
@ -115,16 +118,18 @@
- [Derivation "ATerm" file format](protocols/derivation-aterm.md) - [Derivation "ATerm" file format](protocols/derivation-aterm.md)
- [C API](c-api.md) - [C API](c-api.md)
- [Glossary](glossary.md) - [Glossary](glossary.md)
- [Contributing](contributing/index.md) - [Development](development/index.md)
- [Hacking](contributing/hacking.md) - [Building](development/building.md)
- [Testing](contributing/testing.md) - [Testing](development/testing.md)
- [Documentation](contributing/documentation.md) - [Documentation](development/documentation.md)
- [Experimental Features](contributing/experimental-features.md) - [CLI guideline](development/cli-guideline.md)
- [CLI guideline](contributing/cli-guideline.md) - [JSON guideline](development/json-guideline.md)
- [JSON guideline](contributing/json-guideline.md) - [C++ style guide](development/cxx.md)
- [C++ style guide](contributing/cxx.md) - [Experimental Features](development/experimental-features.md)
- [Contributing](development/contributing.md)
- [Releases](release-notes/index.md) - [Releases](release-notes/index.md)
{{#include ./SUMMARY-rl-next.md}} {{#include ./SUMMARY-rl-next.md}}
- [Release 2.24 (2024-07-31)](release-notes/rl-2.24.md)
- [Release 2.23 (2024-06-03)](release-notes/rl-2.23.md) - [Release 2.23 (2024-06-03)](release-notes/rl-2.23.md)
- [Release 2.22 (2024-04-23)](release-notes/rl-2.22.md) - [Release 2.22 (2024-04-23)](release-notes/rl-2.22.md)
- [Release 2.21 (2024-03-11)](release-notes/rl-2.21.md) - [Release 2.21 (2024-03-11)](release-notes/rl-2.21.md)

View file

@ -20,7 +20,15 @@
/command-ref/command-ref /command-ref 301! /command-ref/command-ref /command-ref 301!
/contributing/contributing /contributing 301! /contributing/contributing /development 301!
/contributing /development 301!
/contributing/hacking /development/building 301!
/contributing/testing /development/testing 301!
/contributing/documentation /development/documentation 301!
/contributing/experimental-features /development/experimental-features 301!
/contributing/cli-guideline /development/cli-guideline 301!
/contributing/json-guideline /development/json-guideline 301!
/contributing/cxx /development/cxx 301!
/expressions/expression-language /language/ 301! /expressions/expression-language /language/ 301!
/expressions/language-constructs /language/constructs 301! /expressions/language-constructs /language/constructs 301!

View file

@ -10,7 +10,7 @@ See:
- [Matrix Room *Nix Bindings*](https://matrix.to/#/#nix-bindings:nixos.org) for discussion and questions. - [Matrix Room *Nix Bindings*](https://matrix.to/#/#nix-bindings:nixos.org) for discussion and questions.
- [Stabilisation Milestone](https://github.com/NixOS/nix/milestone/52) - [Stabilisation Milestone](https://github.com/NixOS/nix/milestone/52)
- [Other C API PRs and issues](https://github.com/NixOS/nix/labels/c%20api) - [Other C API PRs and issues](https://github.com/NixOS/nix/labels/c%20api)
- [Contributing C API Documentation](contributing/documentation.md#c-api-documentation), including how to build it locally. - [Contributing C API Documentation](development/documentation.md#c-api-documentation), including how to build it locally.
[Getting Started]: https://hydra.nixos.org/job/nix/master/external-api-docs/latest/download-by-type/doc/external-api-docs [Getting Started]: https://hydra.nixos.org/job/nix/master/external-api-docs/latest/download-by-type/doc/external-api-docs
[Index]: https://hydra.nixos.org/job/nix/master/external-api-docs/latest/download-by-type/doc/external-api-docs/globals.html [Index]: https://hydra.nixos.org/job/nix/master/external-api-docs/latest/download-by-type/doc/external-api-docs/globals.html

View file

@ -9,22 +9,26 @@ Most Nix commands interpret the following environment variables:
- <span id="env-NIX_PATH">[`NIX_PATH`](#env-NIX_PATH)</span> - <span id="env-NIX_PATH">[`NIX_PATH`](#env-NIX_PATH)</span>
A colon-separated list of directories used to look up the location of Nix A colon-separated list of search path entries used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md).
expressions using [paths](@docroot@/language/types.md#type-path)
enclosed in angle brackets (i.e., `<path>`),
e.g. `/home/eelco/Dev:/etc/nixos`. It can be extended using the
[`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
If `NIX_PATH` is not set at all, Nix will fall back to the following list in [impure](@docroot@/command-ref/conf-file.md#conf-pure-eval) and [unrestricted](@docroot@/command-ref/conf-file.md#conf-restrict-eval) evaluation mode: This environment variable overrides the value of the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path).
1. `$HOME/.nix-defexpr/channels` It can be extended using the [`-I` option](@docroot@/command-ref/opt-common.md#opt-I).
2. `nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
3. `/nix/var/nix/profiles/per-user/root/channels` > **Example**
>
> ```bash
> $ export NIX_PATH=`/home/eelco/Dev:nixos-config=/etc/nixos
> ```
If `NIX_PATH` is set to an empty string, resolving search paths will always fail. 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 > **Example**
>
> ```bash
> $ NIX_PATH= nix-instantiate --eval '<nixpkgs>'
> error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
> ```
- <span id="env-NIX_IGNORE_SYMLINK_STORE">[`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)</span> - <span id="env-NIX_IGNORE_SYMLINK_STORE">[`NIX_IGNORE_SYMLINK_STORE`](#env-NIX_IGNORE_SYMLINK_STORE)</span>

View file

@ -1,6 +1,6 @@
# Experimental Commands # Experimental Commands
This section lists [experimental commands](@docroot@/contributing/experimental-features.md#xp-feature-nix-command). This section lists [experimental commands](@docroot@/development/experimental-features.md#xp-feature-nix-command).
> **Warning** > **Warning**
> >

View file

@ -297,3 +297,8 @@ with import <nixpkgs> {};
runCommand "dummy" { buildInputs = [ python pythonPackages.prettytable ]; } "" runCommand "dummy" { buildInputs = [ python pythonPackages.prettytable ]; } ""
``` ```
The script's file name is passed as the first argument to the interpreter specified by the `-i` flag.
Aside from the very first line, which is a directive to the operating system, the additional `#! nix-shell` lines do not need to be at the beginning of the file.
This allows wrapping them in block comments for languages where `#` does not start a comment, such as ECMAScript, Erlang, PHP, or Ruby.

View file

@ -32,7 +32,7 @@ If no substitutes are available and no store derivation is given, realisation fa
[store objects]: @docroot@/store/store-object.md [store objects]: @docroot@/store/store-object.md
[closure]: @docroot@/glossary.md#gloss-closure [closure]: @docroot@/glossary.md#gloss-closure
[substituters]: @docroot@/command-ref/conf-file.md#conf-substituters [substituters]: @docroot@/command-ref/conf-file.md#conf-substituters
[content-addressed derivations]: @docroot@/contributing/experimental-features.md#xp-feature-ca-derivations [content-addressed derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
[Nix database]: @docroot@/glossary.md#gloss-nix-database [Nix database]: @docroot@/glossary.md#gloss-nix-database
The resulting paths are printed on standard output. The resulting paths are printed on standard output.

View file

@ -187,11 +187,12 @@ Most Nix commands accept the following command-line options:
For `nix-shell`, this option is commonly used to give you a shell in which you can build the packages returned by the expression. For `nix-shell`, this option is commonly used to give you a shell in which you can build the packages returned by the expression.
If you want to get a shell which contain the *built* packages ready for use, give your expression to the `nix-shell --packages ` convenience flag instead. If you want to get a shell which contain the *built* packages ready for use, give your expression to the `nix-shell --packages ` convenience flag instead.
- <span id="opt-I">[`-I`](#opt-I)</span> *path* - <span id="opt-I">[`-I` / `--include`](#opt-I)</span> *path*
Add an entry to the [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path). Add an entry to the list of search paths used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md).
This option may be given multiple times. This option may be given multiple times.
Paths added through `-I` take precedence over [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH).
Paths added through `-I` take precedence over the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path) and the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH).
- <span id="opt-option">[`--option`](#opt-option)</span> *name* *value* - <span id="opt-option">[`--option`](#opt-option)</span> *name* *value*

View file

@ -1,24 +1,67 @@
# Hacking # Building Nix
This section provides some notes on how to hack on Nix. To get the This section provides some notes on how to start hacking on Nix.
latest version of Nix from GitHub: To get the latest version of Nix from GitHub:
```console ```console
$ git clone https://github.com/NixOS/nix.git $ git clone https://github.com/NixOS/nix.git
$ cd nix $ cd nix
``` ```
The following instructions assume you already have some version of Nix installed locally, so that you can use it to set up the development environment. If you don't have it installed, follow the [installation instructions]. > **Note**
>
> The following instructions assume you already have some version of Nix installed locally, so that you can use it to set up the development environment.
> If you don't have it installed, follow the [installation instructions](../installation/index.md).
[installation instructions]: ../installation/index.md
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
```console
$ nix-shell
```
To get a shell with one of the other [supported compilation environments](#compilation-environments):
```console
$ nix-shell --attr devShells.x86_64-linux.native-clangStdenvPackages
```
> **Note**
>
> You can use `native-ccacheStdenvPackages` to drastically improve rebuild time.
> By default, [ccache](https://ccache.dev) keeps artifacts in `~/.cache/ccache/`.
To build Nix itself in this shell:
```console
[nix-shell]$ autoreconfPhase
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ make -j $NIX_BUILD_CORES
```
To install it in `$(pwd)/outputs` and test it:
```console
[nix-shell]$ make install
[nix-shell]$ make installcheck -j $NIX_BUILD_CORES
[nix-shell]$ ./outputs/out/bin/nix --version
nix (Nix) 2.12
```
To build a release version of Nix for the current operating system and CPU architecture:
```console
$ nix-build
```
You can also build Nix for one of the [supported platforms](#platforms).
## Building Nix with flakes ## Building Nix with flakes
This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled. This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
See the [Building Nix](#building-nix) section for equivalent instructions using stable Nix interfaces.
[`flakes`]: @docroot@/contributing/experimental-features.md#xp-feature-flakes [`flakes`]: @docroot@/development/experimental-features.md#xp-feature-flakes
[`nix-command`]: @docroot@/contributing/experimental-features.md#xp-nix-command [`nix-command`]: @docroot@/development/experimental-features.md#xp-nix-command
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found: To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
@ -67,50 +110,6 @@ $ nix build
You can also build Nix for one of the [supported platforms](#platforms). You can also build Nix for one of the [supported platforms](#platforms).
## Building Nix
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
```console
$ nix-shell
```
To get a shell with one of the other [supported compilation environments](#compilation-environments):
```console
$ nix-shell --attr devShells.x86_64-linux.native-clangStdenvPackages
```
> **Note**
>
> You can use `native-ccacheStdenvPackages` to drastically improve rebuild time.
> By default, [ccache](https://ccache.dev) keeps artifacts in `~/.cache/ccache/`.
To build Nix itself in this shell:
```console
[nix-shell]$ autoreconfPhase
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ make -j $NIX_BUILD_CORES
```
To install it in `$(pwd)/outputs` and test it:
```console
[nix-shell]$ make install
[nix-shell]$ make installcheck -j $NIX_BUILD_CORES
[nix-shell]$ ./outputs/out/bin/nix --version
nix (Nix) 2.12
```
To build a release version of Nix for the current operating system and CPU architecture:
```console
$ nix-build
```
You can also build Nix for one of the [supported platforms](#platforms).
## Makefile variables ## Makefile variables
You may need `profiledir=$out/etc/profile.d` and `sysconfdir=$out/etc` to run `make install`. You may need `profiledir=$out/etc/profile.d` and `sysconfdir=$out/etc` to run `make install`.
@ -294,81 +293,3 @@ If it fails, run `git add --patch` to approve the suggestions _and commit again_
To refresh pre-commit hook's config file, do the following: To refresh pre-commit hook's config file, do the following:
1. Exit the development shell and start it again by running `nix develop`. 1. Exit the development shell and start it again by running `nix develop`.
2. If you also use the pre-commit hook, also run `pre-commit-hooks-install` again. 2. If you also use the pre-commit hook, also run `pre-commit-hooks-install` again.
## Add a release note
`doc/manual/rl-next` contains release notes entries for all unreleased changes.
User-visible changes should come with a release note.
### Add an entry
Here's what a complete entry looks like. The file name is not incorporated in the document.
```
---
synopsis: Basically a title
issues: 1234
prs: 1238
---
Here's one or more paragraphs that describe the change.
- It's markdown
- Add references to the manual using @docroot@
```
Significant changes should add the following header, which moves them to the top.
```
significance: significant
```
<!-- Keep an eye on https://codeberg.org/fgaz/changelog-d/issues/1 -->
See also the [format documentation](https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#changelog).
### Build process
Releases have a precomputed `rl-MAJOR.MINOR.md`, and no `rl-next.md`.
## Branches
- [`master`](https://github.com/NixOS/nix/commits/master)
The main development branch. All changes are approved and merged here.
When developing a change, create a branch based on the latest `master`.
Maintainers try to [keep it in a release-worthy state](#reverting).
- [`maintenance-*.*`](https://github.com/NixOS/nix/branches/all?query=maintenance)
These branches are the subject of backports only, and are
also [kept](#reverting) in a release-worthy state.
See [`maintainers/backporting.md`](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md)
- [`latest-release`](https://github.com/NixOS/nix/tree/latest-release)
The latest patch release of the latest minor version.
See [`maintainers/release-process.md`](https://github.com/NixOS/nix/blob/master/maintainers/release-process.md)
- [`backport-*-to-*`](https://github.com/NixOS/nix/branches/all?query=backport)
Generally branches created by the backport action.
See [`maintainers/backporting.md`](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md)
- [_other_](https://github.com/NixOS/nix/branches/all)
Branches that do not conform to the above patterns should be feature branches.
## Reverting
If a change turns out to be merged by mistake, or contain a regression, it may be reverted.
A revert is not a rejection of the contribution, but merely part of an effective development process.
It makes sure that development keeps running smoothly, with minimal uncertainty, and less overhead.
If maintainers have to worry too much about avoiding reverts, they would not be able to merge as much.
By embracing reverts as a good part of the development process, everyone wins.
However, taking a step back may be frustrating, so maintainers will be extra supportive on the next try.

View file

@ -0,0 +1,79 @@
# Contributing
## Add a release note
`doc/manual/rl-next` contains release notes entries for all unreleased changes.
User-visible changes should come with a release note.
### Add an entry
Here's what a complete entry looks like. The file name is not incorporated in the document.
```
---
synopsis: Basically a title
issues: 1234
prs: 1238
---
Here's one or more paragraphs that describe the change.
- It's markdown
- Add references to the manual using @docroot@
```
Significant changes should add the following header, which moves them to the top.
```
significance: significant
```
<!-- Keep an eye on https://codeberg.org/fgaz/changelog-d/issues/1 -->
See also the [format documentation](https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#changelog).
### Build process
Releases have a precomputed `rl-MAJOR.MINOR.md`, and no `rl-next.md`.
## Branches
- [`master`](https://github.com/NixOS/nix/commits/master)
The main development branch. All changes are approved and merged here.
When developing a change, create a branch based on the latest `master`.
Maintainers try to [keep it in a release-worthy state](#reverting).
- [`maintenance-*.*`](https://github.com/NixOS/nix/branches/all?query=maintenance)
These branches are the subject of backports only, and are
also [kept](#reverting) in a release-worthy state.
See [`maintainers/backporting.md`](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md)
- [`latest-release`](https://github.com/NixOS/nix/tree/latest-release)
The latest patch release of the latest minor version.
See [`maintainers/release-process.md`](https://github.com/NixOS/nix/blob/master/maintainers/release-process.md)
- [`backport-*-to-*`](https://github.com/NixOS/nix/branches/all?query=backport)
Generally branches created by the backport action.
See [`maintainers/backporting.md`](https://github.com/NixOS/nix/blob/master/maintainers/backporting.md)
- [_other_](https://github.com/NixOS/nix/branches/all)
Branches that do not conform to the above patterns should be feature branches.
## Reverting
If a change turns out to be merged by mistake, or contain a regression, it may be reverted.
A revert is not a rejection of the contribution, but merely part of an effective development process.
It makes sure that development keeps running smoothly, with minimal uncertainty, and less overhead.
If maintainers have to worry too much about avoiding reverts, they would not be able to merge as much.
By embracing reverts as a good part of the development process, everyone wins.
However, taking a step back may be frustrating, so maintainers will be extra supportive on the next try.

View file

@ -24,7 +24,7 @@ nix build .#^doc
and open `./result-doc/share/doc/nix/manual/index.html`. and open `./result-doc/share/doc/nix/manual/index.html`.
To build the manual incrementally, [enter the development shell](./hacking.md) and run: To build the manual incrementally, [enter the development shell](./building.md) and run:
```console ```console
make manual-html-open -j $NIX_BUILD_CORES make manual-html-open -j $NIX_BUILD_CORES

View file

@ -5,4 +5,4 @@ Check the [contributing guide](https://github.com/NixOS/nix/blob/master/CONTRIBU
This chapter is a collection of guides for making changes to the code and documentation. This chapter is a collection of guides for making changes to the code and documentation.
If you're not sure where to start, try to [compile Nix from source](./hacking.md) and consider [making improvements to documentation](./documentation.md). If you're not sure where to start, try to [compile Nix from source](./building.md) and consider [making improvements to documentation](./documentation.md).

View file

@ -168,7 +168,7 @@
- [impure derivation]{#gloss-impure-derivation} - [impure derivation]{#gloss-impure-derivation}
[An experimental feature](#@docroot@/contributing/experimental-features.md#xp-feature-impure-derivations) that allows derivations to be explicitly marked as impure, [An experimental feature](#@docroot@/development/experimental-features.md#xp-feature-impure-derivations) that allows derivations to be explicitly marked as impure,
so that they are always rebuilt, and their outputs not reused by subsequent calls to realise them. so that they are always rebuilt, and their outputs not reused by subsequent calls to realise them.
- [Nix database]{#gloss-nix-database} - [Nix database]{#gloss-nix-database}
@ -353,7 +353,7 @@
Not yet stabilized functionality guarded by named experimental feature flags. Not yet stabilized functionality guarded by named experimental feature flags.
These flags are enabled or disabled with the [`experimental-features`](./command-ref/conf-file.html#conf-experimental-features) setting. These flags are enabled or disabled with the [`experimental-features`](./command-ref/conf-file.html#conf-experimental-features) setting.
See the contribution guide on the [purpose and lifecycle of experimental feaures](@docroot@/contributing/experimental-features.md). See the contribution guide on the [purpose and lifecycle of experimental feaures](@docroot@/development/experimental-features.md).
[Nix language]: ./language/index.md [Nix language]: ./language/index.md

View file

@ -77,7 +77,7 @@ $ su root
# Installing from a binary tarball # Installing from a binary tarball
You can also download a binary tarball that contains Nix and all its dependencies: You can also download a binary tarball that contains Nix and all its dependencies:
- Choose a [version](https://releases.nixos.org/?prefix=nix/) and [system type](../contributing/hacking.md#platforms) - Choose a [version](https://releases.nixos.org/?prefix=nix/) and [system type](../development/building.md#platforms)
- Download and unpack the tarball - Download and unpack the tarball
- Run the installer - Run the installer

View file

@ -113,7 +113,7 @@ Derivations can declare some infrequently used optional attributes.
> `nix-build`. > `nix-build`.
If the [`configurable-impure-env` experimental If the [`configurable-impure-env` experimental
feature](@docroot@/contributing/experimental-features.md#xp-feature-configurable-impure-env) feature](@docroot@/development/experimental-features.md#xp-feature-configurable-impure-env)
is enabled, these environment variables can also be controlled is enabled, these environment variables can also be controlled
through the through the
[`impure-env`](@docroot@/command-ref/conf-file.md#conf-impure-env) [`impure-env`](@docroot@/command-ref/conf-file.md#conf-impure-env)
@ -226,7 +226,7 @@ Derivations can declare some infrequently used optional attributes.
- [`__contentAddressed`]{#adv-attr-__contentAddressed} - [`__contentAddressed`]{#adv-attr-__contentAddressed}
> **Warning** > **Warning**
> This attribute is part of an [experimental feature](@docroot@/contributing/experimental-features.md). > This attribute is part of an [experimental feature](@docroot@/development/experimental-features.md).
> >
> To use this attribute, you must enable the > To use this attribute, you must enable the
> [`ca-derivations`][xp-feature-ca-derivations] experimental feature. > [`ca-derivations`][xp-feature-ca-derivations] experimental feature.
@ -370,6 +370,6 @@ Derivations can declare some infrequently used optional attributes.
ensures that the derivation can only be built on a machine with the `kvm` feature. ensures that the derivation can only be built on a machine with the `kvm` feature.
[xp-feature-ca-derivations]: @docroot@/contributing/experimental-features.md#xp-feature-ca-derivations [xp-feature-ca-derivations]: @docroot@/development/experimental-features.md#xp-feature-ca-derivations
[xp-feature-dynamic-derivations]: @docroot@/contributing/experimental-features.md#xp-feature-dynamic-derivations [xp-feature-dynamic-derivations]: @docroot@/development/experimental-features.md#xp-feature-dynamic-derivations
[xp-feature-git-hashing]: @docroot@/contributing/experimental-features.md#xp-feature-git-hashing [xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing

View file

@ -4,11 +4,8 @@
> >
> *lookup-path* = `<` *identifier* [ `/` *identifier* ]... `>` > *lookup-path* = `<` *identifier* [ `/` *identifier* ]... `>`
A lookup path is an identifier with an optional path suffix that resolves to a [path value](@docroot@/language/types.md#type-path) if the identifier matches a search path entry. A lookup path is an identifier with an optional path suffix that resolves to a [path value](@docroot@/language/types.md#type-path) if the identifier matches a search path entry in [`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath).
The algorithm for lookup path resolution is described in the documentation on [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile).
The value of a lookup path is determined by [`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath).
See [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile) for details on lookup path resolution.
> **Example** > **Example**
> >

View file

@ -0,0 +1,51 @@
# Identifiers
An *identifier* is an [ASCII](https://en.wikipedia.org/wiki/ASCII) character sequence that:
- Starts with a letter (`a-z`, `A-Z`) or underscore (`_`)
- Can contain any number of:
- Letters (`a-z`, `A-Z`)
- Digits (`0-9`)
- Underscores (`_`)
- Apostrophes (`'`)
- Hyphens (`-`)
- Is not one of the [keywords](#keywords)
> **Syntax**
>
> *identifier* ~ `[A-Za-z_][A-Za-z0-9_'-]*`
# Names
A *name* can be written as an [identifier](#identifier) or a [string literal](./string-literals.md).
> **Syntax**
>
> *name**identifier* | *string*
Names are used in [attribute sets](./syntax.md#attrs-literal), [`let` bindings](./syntax.md#let-expressions), and [`inherit`](./syntax.md#inheriting-attributes).
Two names are the same if they represent the same sequence of characters, regardless of whether they are written as identifiers or strings.
# Keywords
These keywords are reserved and cannot be used as [identifiers](#identifiers):
- [`assert`](./syntax.md#assertions)
- [`else`][if]
- [`if`][if]
- [`in`][let]
- [`inherit`](./syntax.md#inheriting-attributes)
- [`let`][let]
- [`or`](./operators.md#attribute-selection) (see note)
- [`rec`](./syntax.md#recursive-sets)
- [`then`][if]
- [`with`](./syntax.md#with-expressions)
[if]: ./syntax.md#conditionals
[let]: ./syntax.md#let-expressions
> **Note**
>
> The Nix language evaluator currently allows `or` to be used as a name in some contexts, for backwards compatibility reasons.
> Users are advised not to rely on this.
>
> There are long-standing issues with how `or` is parsed as a name, which can't be resolved without making a breaking change to the language.

View file

@ -3,7 +3,7 @@
| Name | Syntax | Associativity | Precedence | | Name | Syntax | Associativity | Precedence |
|----------------------------------------|--------------------------------------------|---------------|------------| |----------------------------------------|--------------------------------------------|---------------|------------|
| [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 | | [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 |
| Function application | *func* *expr* | left | 2 | | [Function application] | *func* *expr* | left | 2 |
| [Arithmetic negation][arithmetic] | `-` *number* | none | 3 | | [Arithmetic negation][arithmetic] | `-` *number* | none | 3 |
| [Has attribute] | *attrset* `?` *attrpath* | none | 4 | | [Has attribute] | *attrset* `?` *attrpath* | none | 4 |
| List concatenation | *list* `++` *list* | right | 5 | | List concatenation | *list* `++` *list* | right | 5 |
@ -26,13 +26,17 @@
| Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 | | Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 |
| Logical disjunction (`OR`) | *bool* <code>\|\|</code> *bool* | left | 13 | | Logical disjunction (`OR`) | *bool* <code>\|\|</code> *bool* | left | 13 |
| [Logical implication] | *bool* `->` *bool* | right | 14 | | [Logical implication] | *bool* `->` *bool* | right | 14 |
| [Pipe operator] (experimental) | *expr* `\|>` *func* | left | 15 |
| [Pipe operator] (experimental) | *func* `<\|` *expr* | right | 15 |
[string]: ./types.md#type-string [string]: ./types.md#type-string
[path]: ./types.md#type-path [path]: ./types.md#type-path
[number]: ./types.md#type-float <!-- TODO(@rhendric, #10970): rationalize this --> [number]: ./types.md#type-float
[list]: ./types.md#list [list]: ./types.md#type-list
[attribute set]: ./types.md#attribute-set [attribute set]: ./types.md#attribute-set
<!-- TODO(@rhendric, #10970): ^ rationalize number -> int/float -->
## Attribute selection ## Attribute selection
> **Syntax** > **Syntax**
@ -42,13 +46,23 @@
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*. Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
If the attribute doesnt exist, return the *expr* after `or` if provided, otherwise abort evaluation. If the attribute doesnt exist, return the *expr* after `or` if provided, otherwise abort evaluation.
An attribute path is a dot-separated list of [attribute names](./types.md#attribute-set). [Attribute selection]: #attribute-selection
## Function application
> **Syntax** > **Syntax**
> >
> *attrpath* = *name* [ `.` *name* ]... > *func* *expr*
[Attribute selection]: #attribute-selection Apply the callable value *func* to the argument *expr*. Note the absence of any visible operator symbol.
A callable value is either:
- a [user-defined function][function]
- a [built-in][builtins] function
- an attribute set with a [`__functor` attribute](./syntax.md#attr-__functor)
> **Warning**
>
> [List][list] items are also separated by whitespace, which means that function calls in list items must be enclosed by parentheses.
## Has attribute ## Has attribute
@ -69,8 +83,12 @@ After evaluating *attrset* and *attrpath*, the computational complexity is O(log
## Arithmetic ## Arithmetic
Numbers are type-compatible: Numbers will retain their type unless mixed with other numeric types:
Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number. Pure integer operations will always return integers, whereas any operation involving at least one floating point number returns a floating point number.
Evaluation of the following numeric operations throws an evaluation error:
- Division by zero
- Integer overflow, that is, any operation yielding a result outside of the representable range of [Nix language integers](./syntax.md#number-literal)
See also [Comparison] and [Equality]. See also [Comparison] and [Equality].
@ -182,3 +200,36 @@ Equivalent to `!`*b1* `||` *b2*.
[Logical implication]: #logical-implication [Logical implication]: #logical-implication
## Pipe operators
- *a* `|>` *b* is equivalent to *b* *a*
- *a* `<|` *b* is equivalent to *a* *b*
> **Example**
>
> ```
> nix-repl> 1 |> builtins.add 2 |> builtins.mul 3
> 9
>
> nix-repl> builtins.add 1 <| builtins.mul 2 <| 3
> 7
> ```
> **Warning**
>
> This syntax is part of an
> [experimental feature](@docroot@/development/experimental-features.md)
> and may change in future releases.
>
> To use this syntax, make sure the
> [`pipe-operators` experimental feature](@docroot@/development/experimental-features.md#xp-feature-pipe-operators)
> is enabled.
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
>
> ```
> extra-experimental-features = pipe-operators
> ```
[Pipe operator]: #pipe-operators
[builtins]: ./builtins.md
[Function application]: #function-application

View file

@ -1,14 +1,28 @@
# Scoping rules # Scoping rules
Nix is [statically scoped](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope), but with multiple scopes and shadowing rules. A *scope* in the Nix language is a dictionary keyed by [name](./identifiers.md#names), mapping each name to an expression and a *definition type*.
The definition type is either *explicit* or *implicit*.
Each entry in this dictionary is a *definition*.
* primary scope: explicitly-bound variables Explicit definitions are created by the following expressions:
* [`let`](./syntax.md#let-expressions) - [let-expressions](syntax.md#let-expressions)
* [`inherit`](./syntax.md#inheriting-attributes) - [recursive attribute set literals](syntax.md#recursive-sets) (`rec`)
* [function](./syntax.md#functions) arguments - [function literals](syntax.md#functions)
* secondary scope: implicitly-bound variables Implicit definitions are only created by [with-expressions](./syntax.md#with-expressions).
* [`with`](./syntax.md#with-expressions)
Primary scope takes precedence over secondary scope. Every expression is *enclosed* by a scope.
See [`with`](./syntax.md#with-expressions) for a detailed example. The outermost expression is enclosed by the [built-in, global scope](./builtins.md), which contains only explicit definitions.
The expressions listed above *extend* their enclosing scope by adding new definitions, or replacing existing ones with the same name.
An explicit definition can replace a definition of any type; an implicit definition can only replace another implicit definition.
Each of the above expressions defines which of its subexpressions are enclosed by the extended scope.
In all other cases, the same scope that encloses an expression is the enclosing scope for its subexpressions.
The Nix language is [statically scoped](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope);
the value of a variable is determined only by the variable's enclosing scope, and not by the dynamic context in which the variable is evaluated.
> **Note**
>
> Expressions entered into the [Nix REPL](@docroot@/command-ref/new-cli/nix3-repl.md) are enclosed by a scope that can be extended by command line arguments or previous REPL commands.
> These ways of extending scope are not, strictly speaking, part of the Nix language.

View file

@ -8,6 +8,10 @@ Such a construct is called *interpolated string*, and the expression inside is a
[path]: ./types.md#type-path [path]: ./types.md#type-path
[attribute set]: ./types.md#attribute-set [attribute set]: ./types.md#attribute-set
> **Syntax**
>
> *interpolation_element*`${` *expression* `}`
## Examples ## Examples
### String ### String

View file

@ -0,0 +1,190 @@
# String literals
A *string literal* represents a [string](types.md#type-string) value.
> **Syntax**
>
> *expression* → *string*
>
> *string*`"` ( *string_char*\* [*interpolation_element*][string interpolation] )* *string_char*\* `"`
>
> *string*`''` ( *indented_string_char*\* [*interpolation_element*][string interpolation] )* *indented_string_char*\* `''`
>
> *string* → *uri*
>
> *string_char* ~ `[^"$\\]|\$(?!\{)|\\.`
>
> *indented_string_char* ~ `[^$']|\$\$|\$(?!\{)|''[$']|''\\.|'(?!')`
>
> *uri* ~ `[A-Za-z][+\-.0-9A-Za-z]*:[!$%&'*+,\-./0-9:=?@A-Z_a-z~]+`
Strings can be written in three ways.
The most common way is to enclose the string between double quotes, e.g., `"foo bar"`.
Strings can span multiple lines.
The results of other expressions can be included into a string by enclosing them in `${ }`, a feature known as [string interpolation].
[string interpolation]: ./string-interpolation.md
The following must be escaped to represent them within a string, by prefixing with a backslash (`\`):
- Double quote (`"`)
> **Example**
>
> ```nix
> "\""
> ```
>
> "\""
- Backslash (`\`)
> **Example**
>
> ```nix
> "\\"
> ```
>
> "\\"
- Dollar sign followed by an opening curly bracket (`${`) "dollar-curly"
> **Example**
>
> ```nix
> "\${"
> ```
>
> "\${"
The newline, carriage return, and tab characters can be written as `\n`, `\r` and `\t`, respectively.
A "double-dollar-curly" (`$${`) can be written literally.
> **Example**
>
> ```nix
> "$${"
> ```
>
> "$\${"
String values are output on the terminal with Nix-specific escaping.
Strings written to files will contain the characters encoded by the escaping.
The second way to write string literals is as an *indented string*, which is enclosed between pairs of *double single-quotes* (`''`), like so:
```nix
''
This is the first line.
This is the second line.
This is the third line.
''
```
This kind of string literal intelligently strips indentation from
the start of each line. To be precise, it strips from each line a
number of spaces equal to the minimal indentation of the string as a
whole (disregarding the indentation of empty lines). For instance,
the first and second line are indented two spaces, while the third
line is indented four spaces. Thus, two spaces are stripped from
each line, so the resulting string is
```nix
"This is the first line.\nThis is the second line.\n This is the third line.\n"
```
> **Note**
>
> Whitespace and newline following the opening `''` is ignored if there is no non-whitespace text on the initial line.
> **Warning**
>
> Prefixed tab characters are not stripped.
>
> > **Example**
> >
> > The following indented string is prefixed with tabs:
> >
> > <pre><code class="nohighlight">''
> > all:
> > @echo hello
> > ''
> > </code></pre>
> >
> > "\tall:\n\t\t@echo hello\n"
Indented strings support [string interpolation].
The following must be escaped to represent them in an indented string:
- `$` is escaped by prefixing it with two single quotes (`''`)
> **Example**
>
> ```nix
> ''
> ''$
> ''
> ```
>
> "$\n"
- `''` is escaped by prefixing it with one single quote (`'`)
> **Example**
>
> ```nix
> ''
> '''
> ''
> ```
>
> "''\n"
These special characters are escaped as follows:
- Linefeed (`\n`): `''\n`
- Carriage return (`\r`): `''\r`
- Tab (`\t`): `''\t`
`''\` escapes any other character.
A "double-dollar-curly" (`$${`) can be written literally.
> **Example**
>
> ```nix
> ''
> $${
> ''
> ```
>
> "$\${\n"
Indented strings are primarily useful in that they allow multi-line
string literals to follow the indentation of the enclosing Nix
expression, and that less escaping is typically necessary for
strings representing languages such as shell scripts and
configuration files because `''` is much less common than `"`.
Example:
```nix
stdenv.mkDerivation {
...
postInstall =
''
mkdir $out/bin $out/etc
cp foo $out/bin
echo "Hello World" > $out/etc/foo.conf
${if enableBar then "cp bar $out/bin" else ""}
'';
...
}
```
Finally, as a convenience, *URIs* as defined in appendix B of
[RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
is*, without quotes. For instance, the string
`"http://example.org/foo.tar.bz2"` can also be written as
`http://example.org/foo.tar.bz2`.

View file

@ -6,175 +6,7 @@ This section covers syntax and semantics of the Nix language.
### String {#string-literal} ### String {#string-literal}
*Strings* can be written in three ways. See [String literals](string-literals.md).
The most common way is to enclose the string between double quotes, e.g., `"foo bar"`.
Strings can span multiple lines.
The results of other expressions can be included into a string by enclosing them in `${ }`, a feature known as [string interpolation].
[string interpolation]: ./string-interpolation.md
The following must be escaped to represent them within a string, by prefixing with a backslash (`\`):
- Double quote (`"`)
> **Example**
>
> ```nix
> "\""
> ```
>
> "\""
- Backslash (`\`)
> **Example**
>
> ```nix
> "\\"
> ```
>
> "\\"
- Dollar sign followed by an opening curly bracket (`${`) "dollar-curly"
> **Example**
>
> ```nix
> "\${"
> ```
>
> "\${"
The newline, carriage return, and tab characters can be written as `\n`, `\r` and `\t`, respectively.
A "double-dollar-curly" (`$${`) can be written literally.
> **Example**
>
> ```nix
> "$${"
> ```
>
> "$\${"
String values are output on the terminal with Nix-specific escaping.
Strings written to files will contain the characters encoded by the escaping.
The second way to write string literals is as an *indented string*, which is enclosed between pairs of *double single-quotes* (`''`), like so:
```nix
''
This is the first line.
This is the second line.
This is the third line.
''
```
This kind of string literal intelligently strips indentation from
the start of each line. To be precise, it strips from each line a
number of spaces equal to the minimal indentation of the string as a
whole (disregarding the indentation of empty lines). For instance,
the first and second line are indented two spaces, while the third
line is indented four spaces. Thus, two spaces are stripped from
each line, so the resulting string is
```nix
"This is the first line.\nThis is the second line.\n This is the third line.\n"
```
> **Note**
>
> Whitespace and newline following the opening `''` is ignored if there is no non-whitespace text on the initial line.
> **Warning**
>
> Prefixed tab characters are not stripped.
>
> > **Example**
> >
> > The following indented string is prefixed with tabs:
> >
> > ''
> > all:
> > @echo hello
> > ''
> >
> > "\tall:\n\t\t@echo hello\n"
Indented strings support [string interpolation].
The following must be escaped to represent them in an indented string:
- `$` is escaped by prefixing it with two single quotes (`''`)
> **Example**
>
> ```nix
> ''
> ''$
> ''
> ```
>
> "$\n"
- `''` is escaped by prefixing it with one single quote (`'`)
> **Example**
>
> ```nix
> ''
> '''
> ''
> ```
>
> "''\n"
These special characters are escaped as follows:
- Linefeed (`\n`): `''\n`
- Carriage return (`\r`): `''\r`
- Tab (`\t`): `''\t`
`''\` escapes any other character.
A "double-dollar-curly" (`$${`) can be written literally.
> **Example**
>
> ```nix
> ''
> $${
> ''
> ```
>
> "$\${\n"
Indented strings are primarily useful in that they allow multi-line
string literals to follow the indentation of the enclosing Nix
expression, and that less escaping is typically necessary for
strings representing languages such as shell scripts and
configuration files because `''` is much less common than `"`.
Example:
```nix
stdenv.mkDerivation {
...
postInstall =
''
mkdir $out/bin $out/etc
cp foo $out/bin
echo "Hello World" > $out/etc/foo.conf
${if enableBar then "cp bar $out/bin" else ""}
'';
...
}
```
Finally, as a convenience, *URIs* as defined in appendix B of
[RFC 2396](http://www.ietf.org/rfc/rfc2396.txt) can be written *as
is*, without quotes. For instance, the string
`"http://example.org/foo.tar.bz2"` can also be written as
`http://example.org/foo.tar.bz2`.
### Number {#number-literal} ### Number {#number-literal}
@ -183,6 +15,13 @@ This section covers syntax and semantics of the Nix language.
Numbers, which can be *integers* (like `123`) or *floating point* Numbers, which can be *integers* (like `123`) or *floating point*
(like `123.43` or `.27e13`). (like `123.43` or `.27e13`).
Integers in the Nix language are 64-bit [two's complement] signed integers, with a range of -9223372036854775808 to 9223372036854775807, inclusive.
[two's complement]: https://en.wikipedia.org/wiki/Two%27s_complement
Note that negative numeric literals are actually parsed as unary negation of positive numeric literals.
This means that the minimum integer `-9223372036854775808` cannot be written as-is as a literal, since the positive number `9223372036854775808` is one past the maximum range.
See [arithmetic] and [comparison] operators for semantics. See [arithmetic] and [comparison] operators for semantics.
[arithmetic]: ./operators.md#arithmetic [arithmetic]: ./operators.md#arithmetic
@ -247,37 +86,76 @@ Elements in a list can be accessed using [`builtins.elemAt`](./builtins.md#built
## Attribute Set {#attrs-literal} ## Attribute Set {#attrs-literal}
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`). An attribute set is a collection of name-value-pairs called *attributes*.
An attribute name can be an identifier or a [string](#string). Attribute sets are written enclosed in curly brackets (`{ }`).
An identifier must start with a letter (`a-z`, `A-Z`) or underscore (`_`), and can otherwise contain letters (`a-z`, `A-Z`), numbers (`0-9`), underscores (`_`), apostrophes (`'`), or dashes (`-`). Attribute names and attribute values are separated by an equal sign (`=`).
Each value can be an arbitrary expression, terminated by a semicolon (`;`)
An attribute name is a string without context, and is denoted by a [name] (an [identifier](./identifiers.md#identifiers) or [string literal](string-literals.md)).
[name]: ./identifiers.md#names
> **Syntax** > **Syntax**
> >
> *name* = *identifier* | *string* \ > *attrset*`{` { *name* `=` *expr* `;` } `}`
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
Names and values are separated by an equal sign (`=`).
Each value is an arbitrary expression terminated by a semicolon (`;`).
> **Syntax**
>
> *attrset* = `{` [ *name* `=` *expr* `;` ]... `}`
Attributes can appear in any order. Attributes can appear in any order.
An attribute name may only occur once. An attribute name may only occur once in each attribute set.
Example: > **Example**
>
> This defines an attribute set with attributes named:
> - `x` with the value `123`, an integer
> - `text` with the value `"Hello"`, a string
> - `y` where the value is the result of applying the function `f` to the attribute set `{ bla = 456; }`
>
> ```nix
> {
> x = 123;
> text = "Hello";
> y = f { bla = 456; };
> }
> ```
```nix Attributes in nested attribute sets can be written using *attribute paths*.
{
x = 123;
text = "Hello";
y = f { bla = 456; };
}
```
This defines a set with attributes named `x`, `text`, `y`. > **Syntax**
>
> *attrset*`{` { *attrpath* `=` *expr* `;` } `}`
An attribute path is a dot-separated list of [names][name].
> **Syntax**
>
> *attrpath* = *name* { `.` *name* }
<!-- -->
> **Example**
>
> ```nix
> { a.b.c = 1; a.b.d = 2; }
> ```
>
> {
> a = {
> b = {
> c = 1;
> d = 2;
> };
> };
> }
Attribute names can also be set implicitly by using the [`inherit` keyword](#inheriting-attributes).
> **Example**
>
> ```nix
> { inherit (builtins) true; }
> ```
>
> { true = true; }
Attributes can be accessed with the [`.` operator](./operators.md#attribute-selection). Attributes can be accessed with the [`.` operator](./operators.md#attribute-selection).
@ -340,7 +218,7 @@ a string), that attribute is simply not added to the set:
This will evaluate to `{}` if `foo` evaluates to `false`. This will evaluate to `{}` if `foo` evaluates to `false`.
A set that has a `__functor` attribute whose value is callable (i.e. is A set that has a [`__functor`]{#attr-__functor} attribute whose value is callable (i.e. is
itself a function or a set with a `__functor` attribute whose value is itself a function or a set with a `__functor` attribute whose value is
callable) can be applied as if it were a function, with the set itself callable) can be applied as if it were a function, with the set itself
passed in first , e.g., passed in first , e.g.,

View file

@ -45,7 +45,7 @@ The function [`builtins.isBool`](builtins.md#builtins-isBool) can be used to det
A _string_ in the Nix language is an immutable, finite-length sequence of bytes, along with a [string context](string-context.md). A _string_ in the Nix language is an immutable, finite-length sequence of bytes, along with a [string context](string-context.md).
Nix does not assume or support working natively with character encodings. Nix does not assume or support working natively with character encodings.
String values without string context can be expressed as [string literals](syntax.md#string-literal). String values without string context can be expressed as [string literals](string-literals.md).
The function [`builtins.isString`](builtins.md#builtins-isString) can be used to determine if a value is a string. The function [`builtins.isString`](builtins.md#builtins-isString) can be used to determine if a value is a string.
### Path {#type-path} ### Path {#type-path}

View file

@ -0,0 +1,10 @@
# Variables
A *variable* is an [identifier](identifiers.md) used as an expression.
> **Syntax**
>
> *expression* → *identifier*
A variable must have the same name as a definition in the [scope](./scope.md) that encloses it.
The value of a variable is the value of the corresponding expression in the enclosing scope.

View file

@ -14,6 +14,6 @@ Derivations are serialised in one of the following formats:
DrvWithVersion(<version-string>, ...) DrvWithVersion(<version-string>, ...)
``` ```
The only `version-string`s that are in use today are for [experimental features](@docroot@/contributing/experimental-features.md): The only `version-string`s that are in use today are for [experimental features](@docroot@/development/experimental-features.md):
- `"xp-dyn-drv"` for the [`dynamic-derivations`](@docroot@/contributing/experimental-features.md#xp-feature-dynamic-derivations) experimental feature. - `"xp-dyn-drv"` for the [`dynamic-derivations`](@docroot@/development/experimental-features.md#xp-feature-dynamic-derivations) experimental feature.

View file

@ -3,7 +3,7 @@
> **Warning** > **Warning**
> >
> This JSON format is currently > This JSON format is currently
> [**experimental**](@docroot@/contributing/experimental-features.md#xp-feature-nix-command) > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
> and subject to change. > and subject to change.
The JSON serialization of a The JSON serialization of a

View file

@ -3,7 +3,7 @@
> **Warning** > **Warning**
> >
> This JSON format is currently > This JSON format is currently
> [**experimental**](@docroot@/contributing/experimental-features.md#xp-feature-nix-command) > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
> and subject to change. > and subject to change.
Info about a [store object]. Info about a [store object].

View file

@ -13,7 +13,7 @@
- The `discard-references` feature has been stabilized. - The `discard-references` feature has been stabilized.
This means that the This means that the
[unsafeDiscardReferences](@docroot@/contributing/experimental-features.md#xp-feature-discard-references) [unsafeDiscardReferences](@docroot@/development/experimental-features.md#xp-feature-discard-references)
attribute is no longer guarded by an experimental flag and can be used attribute is no longer guarded by an experimental flag and can be used
freely. freely.
@ -21,7 +21,7 @@
This only affects `nix-build --json` when "building" non-derivation things like fetched sources, which is a no-op. This only affects `nix-build --json` when "building" non-derivation things like fetched sources, which is a no-op.
- A new builtin [`outputOf`](@docroot@/language/builtins.md#builtins-outputOf) has been added. - A new builtin [`outputOf`](@docroot@/language/builtins.md#builtins-outputOf) has been added.
It is part of the [`dynamic-derivations`](@docroot@/contributing/experimental-features.md#xp-feature-dynamic-derivations) experimental feature. It is part of the [`dynamic-derivations`](@docroot@/development/experimental-features.md#xp-feature-dynamic-derivations) experimental feature.
- Flake follow paths at depths greater than 2 are now handled correctly, preventing "follows a non-existent input" errors. - Flake follow paths at depths greater than 2 are now handled correctly, preventing "follows a non-existent input" errors.

View file

@ -17,8 +17,8 @@
- `nix-shell` shebang lines now support single-quoted arguments. - `nix-shell` shebang lines now support single-quoted arguments.
- `builtins.fetchTree` is now its own experimental feature, [`fetch-tree`](@docroot@/contributing/experimental-features.md#xp-fetch-tree). - `builtins.fetchTree` is now its own experimental feature, [`fetch-tree`](@docroot@/development/experimental-features.md#xp-fetch-tree).
This allows stabilising it independently of the rest of what is encompassed by [`flakes`](@docroot@/contributing/experimental-features.md#xp-fetch-tree). This allows stabilising it independently of the rest of what is encompassed by [`flakes`](@docroot@/development/experimental-features.md#xp-fetch-tree).
- The interface for creating and updating lock files has been overhauled: - The interface for creating and updating lock files has been overhauled:
@ -33,7 +33,7 @@
- The flake-specific flags `--recreate-lock-file` and `--update-input` have been removed from all commands operating on installables. - The flake-specific flags `--recreate-lock-file` and `--update-input` have been removed from all commands operating on installables.
They are superceded by `nix flake update`. They are superceded by `nix flake update`.
- Commit signature verification for the [`builtins.fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) is added as the new [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches). - Commit signature verification for the [`builtins.fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) is added as the new [`verified-fetches` experimental feature](@docroot@/development/experimental-features.md#xp-feature-verified-fetches).
- [`nix path-info --json`](@docroot@/command-ref/new-cli/nix3-path-info.md) - [`nix path-info --json`](@docroot@/command-ref/new-cli/nix3-path-info.md)
(experimental) now returns a JSON map rather than JSON list. (experimental) now returns a JSON map rather than JSON list.

View file

@ -14,7 +14,7 @@
- Modify `nix derivation {add,show}` JSON format [#9866](https://github.com/NixOS/nix/issues/9866) [#10722](https://github.com/NixOS/nix/pull/10722) - Modify `nix derivation {add,show}` JSON format [#9866](https://github.com/NixOS/nix/issues/9866) [#10722](https://github.com/NixOS/nix/pull/10722)
The JSON format for derivations has been slightly revised to better conform to our [JSON guidelines](@docroot@/contributing/cli-guideline.md#returning-future-proof-json). The JSON format for derivations has been slightly revised to better conform to our [JSON guidelines](@docroot@/development/cli-guideline.md#returning-future-proof-json).
In particular, the hash algorithm and content addressing method of content-addresed derivation outputs are now separated into two fields `hashAlgo` and `method`, In particular, the hash algorithm and content addressing method of content-addresed derivation outputs are now separated into two fields `hashAlgo` and `method`,
rather than one field with an arcane `:`-separated format. rather than one field with an arcane `:`-separated format.
@ -89,7 +89,7 @@
This makes records of this sort more self-describing, and easier to consume programmatically. This makes records of this sort more self-describing, and easier to consume programmatically.
We will follow this design principle going forward; We will follow this design principle going forward;
the [JSON guidelines](@docroot@/contributing/json-guideline.md) in the contributing section have been updated accordingly. the [JSON guidelines](@docroot@/development/json-guideline.md) in the contributing section have been updated accordingly.
- Large path warnings [#10661](https://github.com/NixOS/nix/pull/10661) - Large path warnings [#10661](https://github.com/NixOS/nix/pull/10661)

View file

@ -0,0 +1,324 @@
# Release 2.24.0 (2024-07-31)
### Significant changes
- Harden user sandboxing
The build directory has been hardened against interference with the outside world by nesting it inside another directory owned by (and only readable by) the daemon user.
This is a low severity security fix, [CVE-2024-38531](https://www.cve.org/CVERecord?id=CVE-2024-38531).
Credit: [**@alois31**](https://github.com/alois31), [**Linus Heckemann (@lheckemann)**](https://github.com/lheckemann)
Co-authors: [**@edolstra**](https://github.com/edolstra)
- `nix-shell <directory>` looks for `shell.nix` [#496](https://github.com/NixOS/nix/issues/496) [#2279](https://github.com/NixOS/nix/issues/2279) [#4529](https://github.com/NixOS/nix/issues/4529) [#5431](https://github.com/NixOS/nix/issues/5431) [#11053](https://github.com/NixOS/nix/issues/11053) [#11057](https://github.com/NixOS/nix/pull/11057)
`nix-shell $x` now looks for `$x/shell.nix` when `$x` resolves to a directory.
Although this might be seen as a breaking change, its primarily interactive usage makes it a minor issue.
This adjustment addresses a commonly reported problem.
This also applies to `nix-shell` shebang scripts. Consider the following example:
```shell
#!/usr/bin/env nix-shell
#!nix-shell -i bash
```
This will now load `shell.nix` from the script's directory, if it exists; `default.nix` otherwise.
The old behavior can be opted into by setting the option [`nix-shell-always-looks-for-shell-nix`](@docroot@/command-ref/conf-file.md#conf-nix-shell-always-looks-for-shell-nix) to `false`.
Author: [**Robert Hensing (@roberth)**](https://github.com/roberth)
- `nix-repl`'s `:doc` shows documentation comments [#3904](https://github.com/NixOS/nix/issues/3904) [#10771](https://github.com/NixOS/nix/issues/10771) [#1652](https://github.com/NixOS/nix/pull/1652) [#9054](https://github.com/NixOS/nix/pull/9054) [#11072](https://github.com/NixOS/nix/pull/11072)
`nix repl` has a `:doc` command that previously only rendered documentation for internally defined functions.
This feature has been extended to also render function documentation comments, in accordance with [RFC 145].
Example:
```
nix-repl> :doc lib.toFunction
Function toFunction
… defined at /home/user/h/nixpkgs/lib/trivial.nix:1072:5
Turns any non-callable values into constant functions. Returns
callable values as is.
Inputs
v
: Any value
Examples
:::{.example}
## lib.trivial.toFunction usage example
| nix-repl> lib.toFunction 1 2
| 1
|
| nix-repl> lib.toFunction (x: x + 1) 2
| 3
:::
```
Known limitations:
- It does not render documentation for "formals", such as `{ /** the value to return */ x, ... }: x`.
- Some extensions to markdown are not yet supported, as you can see in the example above.
We'd like to acknowledge [Yingchi Long (@inclyc)](https://github.com/inclyc) for proposing a proof of concept for this functionality in [#9054](https://github.com/NixOS/nix/pull/9054), as well as [@sternenseemann](https://github.com/sternenseemann) and [Johannes Kirschbauer (@hsjobeki)](https://github.com/hsjobeki) for their contributions, proposals, and their work on [RFC 145].
Author: [**Robert Hensing (@roberth)**](https://github.com/roberth)
[RFC 145]: https://github.com/NixOS/rfcs/pull/145
### Other changes
- Solve `cached failure of attribute X` [#9165](https://github.com/NixOS/nix/issues/9165) [#10513](https://github.com/NixOS/nix/issues/10513) [#10564](https://github.com/NixOS/nix/pull/10564)
This eliminates all "cached failure of attribute X" messages by forcing evaluation of the original value when needed to show the exception to the user. This enhancement improves error reporting by providing the underlying message and stack trace.
Author: [**Eelco Dolstra (@edolstra)**](https://github.com/edolstra)
- Run the flake regressions test suite [#10603](https://github.com/NixOS/nix/pull/10603)
This update introduces a GitHub action to run a subset of the [flake regressions test suite](https://github.com/NixOS/flake-regressions), which includes 259 flakes with their expected evaluation results. Currently, the action runs the first 25 flakes due to the full test suite's extensive runtime. A manually triggered action may be implemented later to run the entire test suite.
Author: [**Eelco Dolstra (@edolstra)**](https://github.com/edolstra)
- Support unit prefixes in configuration settings [#10668](https://github.com/NixOS/nix/pull/10668)
Configuration settings in Nix now support unit prefixes, allowing for more intuitive and readable configurations. For example, you can now specify [`--min-free 1G`](@docroot@/command-ref/opt-common.md#opt-min-free) to set the minimum free space to 1 gigabyte.
This enhancement was extracted from [#7851](https://github.com/NixOS/nix/pull/7851) and is also useful for PR [#10661](https://github.com/NixOS/nix/pull/10661).
Author: [**Eelco Dolstra (@edolstra)**](https://github.com/edolstra)
- `nix build`: show all FOD errors with `--keep-going` [#10734](https://github.com/NixOS/nix/pull/10734)
The [`nix build`](@docroot@/command-ref/new-cli/nix3-build.md) command has been updated to improve the behavior of the [`--keep-going`] flag. Now, when `--keep-going` is used, all hash-mismatch errors of failing fixed-output derivations (FODs) are displayed, similar to the behavior for other build failures. This enhancement ensures that all relevant build errors are shown, making it easier for users to update multiple derivations at once or to diagnose and fix issues.
Author: [**Jörg Thalheim (@Mic92)**](https://github.com/Mic92), [**Maximilian Bosch (@Ma27)**](https://github.com/Ma27)
[`--keep-going`](@docroot@/command-ref/opt-common.md#opt-keep-going)
- Build with Meson [#2503](https://github.com/NixOS/nix/issues/2503) [#10378](https://github.com/NixOS/nix/pull/10378) [#10855](https://github.com/NixOS/nix/pull/10855) [#10904](https://github.com/NixOS/nix/pull/10904) [#10908](https://github.com/NixOS/nix/pull/10908) [#10914](https://github.com/NixOS/nix/pull/10914) [#10933](https://github.com/NixOS/nix/pull/10933) [#10936](https://github.com/NixOS/nix/pull/10936) [#10954](https://github.com/NixOS/nix/pull/10954) [#10955](https://github.com/NixOS/nix/pull/10955) [#10963](https://github.com/NixOS/nix/pull/10963) [#10967](https://github.com/NixOS/nix/pull/10967) [#10973](https://github.com/NixOS/nix/pull/10973) [#11034](https://github.com/NixOS/nix/pull/11034) [#11054](https://github.com/NixOS/nix/pull/11054) [#11055](https://github.com/NixOS/nix/pull/11055) [#11060](https://github.com/NixOS/nix/pull/11060) [#11064](https://github.com/NixOS/nix/pull/11064) [#11155](https://github.com/NixOS/nix/pull/11155)
These changes aim to replace the use of autotools and `make` with Meson for building various components of Nix. Additionally, each library is built in its own derivation, leveraging Meson's "subprojects" feature to allow a single development shell for building all libraries while also supporting separate builds. This approach aims to improve productivity and build modularity, compared to both make and a monolithic Meson-based derivation.
Special thanks to everyone who has contributed to the Meson port, particularly [**@p01arst0rm**](https://github.com/p01arst0rm) and [**@Qyriad**](https://github.com/Qyriad).
Authors: [**John Ericson (@Ericson2314)**](https://github.com/Ericson2314), [**Tom Bereknyei**](https://github.com/tomberek), [**Théophane Hufschmitt (@thufschmitt)**](https://github.com/thufschmitt), [**Valentin Gagarin (@fricklerhandwerk)**](https://github.com/fricklerhandwerk), [**Robert Hensing (@roberth)**](https://github.com/roberth)
Co-authors: [**@p01arst0rm**](https://github.com/p01arst0rm), [**@Qyriad**](https://github.com/Qyriad)
- Evaluation cache: fix cache regressions [#10570](https://github.com/NixOS/nix/issues/10570) [#11086](https://github.com/NixOS/nix/pull/11086)
This update addresses two bugs in the evaluation cache system:
1. Regression in #10570: The evaluation cache was not being persisted in `nix develop`.
2. Nix could sometimes try to commit the evaluation cache SQLite transaction without there being an active transaction, resulting in non-error errors being printed.
Author: [**Lexi Mattick (@kognise)**](https://github.com/kognise)
- Introduce `libnixflake` [#9063](https://github.com/NixOS/nix/pull/9063)
A new library, `libnixflake`, has been introduced to better separate the Flakes layer within Nix. This change refactors the codebase to encapsulate Flakes-specific functionality within its own library.
See the commits in the pull request for detailed changes, with the only significant code modifications happening in the initial commit.
This change was alluded to in [RFC 134](https://github.com/nixos/rfcs/blob/master/rfcs/0134-nix-store-layer.md) and is a step towards a more modular and maintainable codebase.
Author: [**John Ericson (@Ericson2314)**](https://github.com/Ericson2314)
- CLI options `--arg-from-file` and `--arg-from-stdin` [#9913](https://github.com/NixOS/nix/pull/9913)
- The `--debugger` now prints source location information, instead of the
pointers of source location information. Before:
```
nix-repl> :bt
0: while evaluating the attribute 'python311.pythonForBuild.pkgs'
0x600001522598
```
After:
```
0: while evaluating the attribute 'python311.pythonForBuild.pkgs'
/nix/store/hg65h51xnp74ikahns9hyf3py5mlbbqq-source/overrides/default.nix:132:27
131|
132| bootstrappingBase = pkgs.${self.python.pythonAttr}.pythonForBuild.pkgs;
| ^
133| in
```
- Stop vendoring `toml11`
We don't apply any patches to it, and vendoring it locks users into
bugs (it hasn't been updated since its introduction in late 2021).
Author: [**Winter (@winterqt)**](https://github.com/winterqt)
- Rename hash format `base32` to `nix32` [#8678](https://github.com/NixOS/nix/pull/8678)
Hash format `base32` was renamed to `nix32` since it used a special nix-specific character set for
[Base32](https://en.wikipedia.org/wiki/Base32).
**Deprecation**: Use `nix32` instead of `base32` as `toHashFormat`
For the builtin `convertHash`, the `toHashFormat` parameter now accepts the same hash formats as the `--to`/`--from`
parameters of the `nix hash conert` command: `"base16"`, `"nix32"`, `"base64"`, and `"sri"`. The former `"base32"` value
remains as a deprecated alias for `"nix32"`. Please convert your code from:
```nix
builtins.convertHash { inherit hash hashAlgo; toHashFormat = "base32";}
```
to
```nix
builtins.convertHash { inherit hash hashAlgo; toHashFormat = "nix32";}
```
- Add `pipe-operators` experimental feature [#11131](https://github.com/NixOS/nix/pull/11131)
This is a draft implementation of [RFC 0148](https://github.com/NixOS/rfcs/pull/148).
The `pipe-operators` experimental feature adds [`<|` and `|>` operators][pipe operators] to the Nix language.
*a* `|>` *b* is equivalent to the function application *b* *a*, and
*a* `<|` *b* is equivalent to the function application *a* *b*.
For example:
```
nix-repl> 1 |> builtins.add 2 |> builtins.mul 3
9
nix-repl> builtins.add 1 <| builtins.mul 2 <| 3
7
```
`<|` and `|>` are right and left associative, respectively, and have lower precedence than any other operator.
These properties may change in future releases.
See [the RFC](https://github.com/NixOS/rfcs/pull/148) for more examples and rationale.
[pipe operators]: @docroot@/language/operators.md#pipe-operators
- `nix-shell` shebang uses relative path [#4232](https://github.com/NixOS/nix/issues/4232) [#5088](https://github.com/NixOS/nix/pull/5088) [#11058](https://github.com/NixOS/nix/pull/11058)
<!-- unfortunately no link target for the specific syntax -->
Relative [path](@docroot@/language/types.md#type-path) literals in `nix-shell` shebang scripts' options are now resolved relative to the [script's location](@docroot@/glossary.md?highlight=base%20directory#gloss-base-directory).
Previously they were resolved relative to the current working directory.
For example, consider the following script in `~/myproject/say-hi`:
```shell
#!/usr/bin/env nix-shell
#!nix-shell --expr 'import ./shell.nix'
#!nix-shell --arg toolset './greeting-tools.nix'
#!nix-shell -i bash
hello
```
Older versions of `nix-shell` would resolve `shell.nix` relative to the current working directory, such as the user's home directory in this example:
```console
[hostname:~]$ ./myproject/say-hi
error:
… while calling the 'import' builtin
at «string»:1:2:
1| (import ./shell.nix)
| ^
error: path '/home/user/shell.nix' does not exist
```
Since this release, `nix-shell` resolves `shell.nix` relative to the script's location, and `~/myproject/shell.nix` is used.
```console
$ ./myproject/say-hi
Hello, world!
```
**Opt-out**
This is technically a breaking change, so we have added an option so you can adapt independently of your Nix update.
The old behavior can be opted into by setting the option [`nix-shell-shebang-arguments-relative-to-script`](@docroot@/command-ref/conf-file.md#conf-nix-shell-shebang-arguments-relative-to-script) to `false`.
This option will be removed in a future release.
Author: [**Robert Hensing (@roberth)**](https://github.com/roberth)
- Improve handling of tarballs that don't consist of a single top-level directory [#11195](https://github.com/NixOS/nix/pull/11195)
In previous Nix releases, the tarball fetcher (used by `builtins.fetchTarball`) erroneously merged top-level directories into a single directory, and silently discarded top-level files that are not directories. This is no longer the case. The new behaviour is that *only* if the tarball consists of a single directory, the top-level path component of the files in the tarball is removed (similar to `tar`'s `--strip-components=1`).
Author: [**Eelco Dolstra (@edolstra)**](https://github.com/edolstra)
- Improve handling of tarballs that don't consist of a single top-level directory [#11195](https://github.com/NixOS/nix/pull/11195)
In previous Nix releases, the tarball fetcher (used by `builtins.fetchTarball`) erroneously merged top-level directories into a single directory, and silently discarded top-level files that are not directories. This is no longer the case.
Author: [**Eelco Dolstra (@edolstra)**](https://github.com/edolstra)
- Setting to warn about large paths [#10778](https://github.com/NixOS/nix/pull/10778)
Nix can now warn when evaluation of a Nix expression causes a large
path to be copied to the Nix store. The threshold for this warning can
be configured using the `warn-large-path-threshold` setting,
e.g. `--warn-large-path-threshold 100M`.
# Contributors
This release was made possible by the following 43 contributors:
- Andreas Rammhold [**(@andir)**](https://github.com/andir)
- Andrew Marshall [**(@amarshall)**](https://github.com/amarshall)
- Brian McKenna [**(@puffnfresh)**](https://github.com/puffnfresh)
- Cameron [**(@SkamDart)**](https://github.com/SkamDart)
- Cole Helbling [**(@cole-h)**](https://github.com/cole-h)
- Corbin Simpson [**(@MostAwesomeDude)**](https://github.com/MostAwesomeDude)
- Eelco Dolstra [**(@edolstra)**](https://github.com/edolstra)
- Emily [**(@emilazy)**](https://github.com/emilazy)
- Enno Richter [**(@elohmeier)**](https://github.com/elohmeier)
- Farid Zakaria [**(@fzakaria)**](https://github.com/fzakaria)
- HaeNoe [**(@haenoe)**](https://github.com/haenoe)
- Hamir Mahal [**(@hamirmahal)**](https://github.com/hamirmahal)
- Harmen [**(@alicebob)**](https://github.com/alicebob)
- Ivan Trubach [**(@tie)**](https://github.com/tie)
- Jared Baur [**(@jmbaur)**](https://github.com/jmbaur)
- John Ericson [**(@Ericson2314)**](https://github.com/Ericson2314)
- Jonathan De Troye [**(@detroyejr)**](https://github.com/detroyejr)
- Jörg Thalheim [**(@Mic92)**](https://github.com/Mic92)
- Klemens Nanni [**(@klemensn)**](https://github.com/klemensn)
- Las Safin [**(@L-as)**](https://github.com/L-as)
- Lexi Mattick [**(@kognise)**](https://github.com/kognise)
- Matthew Bauer [**(@matthewbauer)**](https://github.com/matthewbauer)
- Max “Goldstein” Siling [**(@GoldsteinE)**](https://github.com/GoldsteinE)
- Mingye Wang [**(@Artoria2e5)**](https://github.com/Artoria2e5)
- Philip Taron [**(@philiptaron)**](https://github.com/philiptaron)
- Pierre Bourdon [**(@delroth)**](https://github.com/delroth)
- Pino Toscano [**(@pinotree)**](https://github.com/pinotree)
- RTUnreal [**(@RTUnreal)**](https://github.com/RTUnreal)
- Robert Hensing [**(@roberth)**](https://github.com/roberth)
- Romain Neil [**(@romain-neil)**](https://github.com/romain-neil)
- Ryan Hendrickson [**(@rhendric)**](https://github.com/rhendric)
- Sergei Trofimovich [**(@trofi)**](https://github.com/trofi)
- Shogo Takata [**(@pineapplehunter)**](https://github.com/pineapplehunter)
- Siddhant Kumar [**(@siddhantk232)**](https://github.com/siddhantk232)
- Silvan Mosberger [**(@infinisil)**](https://github.com/infinisil)
- Théophane Hufschmitt [**(@thufschmitt)**](https://github.com/thufschmitt)
- Valentin Gagarin [**(@fricklerhandwerk)**](https://github.com/fricklerhandwerk)
- Winter [**(@winterqt)**](https://github.com/winterqt)
- jade [**(@lf-)**](https://github.com/lf-)
- kirillrdy [**(@kirillrdy)**](https://github.com/kirillrdy)
- pennae [**(@pennae)**](https://github.com/pennae)
- poweredbypie [**(@poweredbypie)**](https://github.com/poweredbypie)
- tomberek [**(@tomberek)**](https://github.com/tomberek)

View file

@ -23,7 +23,7 @@ more than 2800 commits from 195 contributors since release 2.3.
* The **`nix` command** has seen a lot of work and is now almost at * The **`nix` command** has seen a lot of work and is now almost at
feature parity with the old command-line interface (the `nix-*` feature parity with the old command-line interface (the `nix-*`
commands). It aims to be [more modern, consistent and pleasant to commands). It aims to be [more modern, consistent and pleasant to
use](../contributing/cli-guideline.md) than the old CLI. It is still use](../development/cli-guideline.md) than the old CLI. It is still
marked as experimental but its interface should not change much marked as experimental but its interface should not change much
anymore in future releases. anymore in future releases.

View file

@ -82,4 +82,4 @@ In the future, we may support a Git-like hash for such file system objects, or w
[file system object]: ../file-system-object.md [file system object]: ../file-system-object.md
[store object]: ../store-object.md [store object]: ../store-object.md
[xp-feature-git-hashing]: @docroot@/contributing/experimental-features.md#xp-feature-git-hashing [xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing

View file

@ -92,4 +92,4 @@ becomes more widespread, this restriction will be revisited.
[fso-ca]: ../file-system-object/content-address.md [fso-ca]: ../file-system-object/content-address.md
[sp-spec]: @docroot@/protocols/store-path.md [sp-spec]: @docroot@/protocols/store-path.md
[xp-feature-git-hashing]: @docroot@/contributing/experimental-features.md#xp-feature-git-hashing [xp-feature-git-hashing]: @docroot@/development/experimental-features.md#xp-feature-git-hashing

View file

@ -3,11 +3,11 @@
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1673956053, "lastModified": 1696426674,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -23,11 +23,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1712014858, "lastModified": 1719994518,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -36,49 +36,60 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils": { "git-hooks-nix": {
"inputs": {
"flake-compat": [],
"gitignore": [],
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1721042469,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=",
"owner": "numtide", "owner": "cachix",
"repo": "flake-utils", "repo": "git-hooks.nix",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "rev": "f451c19376071a90d8c58ab1a953c6e9840527fd",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "numtide", "owner": "cachix",
"repo": "flake-utils", "repo": "git-hooks.nix",
"type": "github" "type": "github"
} }
}, },
"libgit2": { "libgit2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1697646580, "lastModified": 1715853528,
"narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", "narHash": "sha256-J2rCxTecyLbbDdsyBWn9w7r3pbKRMkI9E7RvRgAqBdY=",
"owner": "libgit2", "owner": "libgit2",
"repo": "libgit2", "repo": "libgit2",
"rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", "rev": "36f7e21ad757a3dacc58cf7944329da6bc1d6e96",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "libgit2", "owner": "libgit2",
"ref": "v1.8.1",
"repo": "libgit2", "repo": "libgit2",
"type": "github" "type": "github"
} }
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1721560568, "lastModified": 1723688146,
"narHash": "sha256-L61BXz7n/yNzOeZ3FqlnUmxj4145JOVeq9fvQTQzbNM=", "narHash": "sha256-sqLwJcHYeWLOeP/XoLwAtYjr01TISlkOfz+NG82pbdg=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "be3ca229c85e978880babdeda9748b14e6aa008f", "rev": "c3d4ac725177c030b1e289015989da2ad9d56af0",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-24.05", "ref": "nixos-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -115,41 +126,15 @@
"type": "github" "type": "github"
} }
}, },
"pre-commit-hooks": {
"inputs": {
"flake-compat": [],
"flake-utils": "flake-utils",
"gitignore": [],
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1712897695,
"narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"git-hooks-nix": "git-hooks-nix",
"libgit2": "libgit2", "libgit2": "libgit2",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-23-11": "nixpkgs-23-11", "nixpkgs-23-11": "nixpkgs-23-11",
"nixpkgs-regression": "nixpkgs-regression", "nixpkgs-regression": "nixpkgs-regression"
"pre-commit-hooks": "pre-commit-hooks"
} }
} }
}, },

View file

@ -6,24 +6,22 @@
description = "The purely functional package manager - but super!"; description = "The purely functional package manager - but super!";
# TODO switch to nixos-23.11-small inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
# https://nixpk.gs/pr-tracker.html?pr=291954
inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.05";
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446"; inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; }; inputs.libgit2 = { url = "github:libgit2/libgit2/v1.8.1"; flake = false; };
# dev tooling # dev tooling
inputs.flake-parts.url = "github:hercules-ci/flake-parts"; inputs.flake-parts.url = "github:hercules-ci/flake-parts";
inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; inputs.git-hooks-nix.url = "github:cachix/git-hooks.nix";
# work around https://github.com/NixOS/nix/issues/7730 # work around https://github.com/NixOS/nix/issues/7730
inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
inputs.pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; inputs.git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs";
inputs.pre-commit-hooks.inputs.nixpkgs-stable.follows = "nixpkgs"; inputs.git-hooks-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
# work around 7730 and https://github.com/NixOS/nix/issues/7807 # work around 7730 and https://github.com/NixOS/nix/issues/7807
inputs.pre-commit-hooks.inputs.flake-compat.follows = ""; inputs.git-hooks-nix.inputs.flake-compat.follows = "";
inputs.pre-commit-hooks.inputs.gitignore.follows = ""; inputs.git-hooks-nix.inputs.gitignore.follows = "";
outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }: outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }:
@ -33,12 +31,6 @@
officialRelease = false; officialRelease = false;
version = lib.fileContents ./.version + versionSuffix;
versionSuffix =
if officialRelease
then ""
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}_${self.shortRev or "dirty"}";
linux32BitSystems = [ "i686-linux" ]; linux32BitSystems = [ "i686-linux" ];
linux64BitSystems = [ "x86_64-linux" "aarch64-linux" ]; linux64BitSystems = [ "x86_64-linux" "aarch64-linux" ];
linuxSystems = linux32BitSystems ++ linux64BitSystems; linuxSystems = linux32BitSystems ++ linux64BitSystems;
@ -137,21 +129,21 @@
# without "polluting" the top level "`pkgs`" attrset. # without "polluting" the top level "`pkgs`" attrset.
# This also has the benefit of providing us with a distinct set of packages # This also has the benefit of providing us with a distinct set of packages
# we can iterate over. # we can iterate over.
nixComponents = lib.makeScope final.nixDependencies.newScope (import ./packaging/components.nix); nixComponents = lib.makeScope final.nixDependencies.newScope (import ./packaging/components.nix {
inherit (final) lib;
inherit officialRelease;
src = self;
});
# The dependencies are in their own scope, so that they don't have to be # The dependencies are in their own scope, so that they don't have to be
# in Nixpkgs top level `pkgs` or `nixComponents`. # in Nixpkgs top level `pkgs` or `nixComponents`.
nixDependencies = lib.makeScope final.newScope (import ./packaging/dependencies.nix { nixDependencies = lib.makeScope final.newScope (import ./packaging/dependencies.nix {
inherit inputs stdenv versionSuffix; inherit inputs stdenv;
pkgs = final; pkgs = final;
}); });
nix = final.nixComponents.nix; nix = final.nixComponents.nix;
nix_noTests = final.nix.override {
doInstallCheck = false;
};
# See https://github.com/NixOS/nixpkgs/pull/214409 # See https://github.com/NixOS/nixpkgs/pull/214409
# Remove when fixed in this flake's nixpkgs # Remove when fixed in this flake's nixpkgs
pre-commit = pre-commit =
@ -176,6 +168,7 @@
linux64BitSystems linux64BitSystems
nixpkgsFor nixpkgsFor
self self
officialRelease
; ;
}; };
@ -217,6 +210,9 @@
"${nixpkgsPrefix}${pkgName}-${testName}" = test; "${nixpkgsPrefix}${pkgName}-${testName}" = test;
}) })
) )
// lib.optionalAttrs (nixpkgs.stdenv.hostPlatform == nixpkgs.stdenv.buildPlatform) {
"${nixpkgsPrefix}nix-functional-tests" = nixpkgs.nixComponents.nix-functional-tests;
}
) )
// devFlake.checks.${system} or {} // devFlake.checks.${system} or {}
); );
@ -226,7 +222,7 @@
# for which we don't apply the full build matrix such as cross or static. # for which we don't apply the full build matrix such as cross or static.
inherit (nixpkgsFor.${system}.native) inherit (nixpkgsFor.${system}.native)
changelog-d; changelog-d;
default = self.packages.${system}.nix; default = self.packages.${system}.nix-ng;
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-internal-api-docs; nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-internal-api-docs;
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs; nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents.nix-external-api-docs;
} }
@ -234,22 +230,48 @@
// flatMapAttrs // flatMapAttrs
{ # Components we'll iterate over in the upcoming lambda { # Components we'll iterate over in the upcoming lambda
"nix" = { }; "nix" = { };
# Temporarily disabled because GitHub Actions OOM issues. Once "nix-util" = { };
# the old build system is gone and we are back to one build "nix-util-c" = { };
# system, we should reenable these. "nix-util-test-support" = { };
#"nix-util" = { }; "nix-util-tests" = { };
#"nix-store" = { };
#"nix-fetchers" = { }; "nix-store" = { };
"nix-store-c" = { };
"nix-store-test-support" = { };
"nix-store-tests" = { };
"nix-fetchers" = { };
"nix-fetchers-tests" = { };
"nix-expr" = { };
"nix-expr-c" = { };
"nix-expr-test-support" = { };
"nix-expr-tests" = { };
"nix-flake" = { };
"nix-flake-tests" = { };
"nix-main" = { };
"nix-main-c" = { };
"nix-cmd" = { };
"nix-cli" = { };
"nix-functional-tests" = { supportsCross = false; };
"nix-perl-bindings" = { supportsCross = false; };
"nix-ng" = { };
} }
(pkgName: {}: { (pkgName: { supportsCross ? true }: {
# These attributes go right into `packages.<system>`. # These attributes go right into `packages.<system>`.
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName}; "${pkgName}" = nixpkgsFor.${system}.native.nixComponents.${pkgName};
"${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName}; "${pkgName}-static" = nixpkgsFor.${system}.static.nixComponents.${pkgName};
} }
// flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: { // lib.optionalAttrs supportsCross (flatMapAttrs (lib.genAttrs crossSystems (_: { })) (crossSystem: {}: {
# These attributes go right into `packages.<system>`. # These attributes go right into `packages.<system>`.
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}; "${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName};
}) }))
// flatMapAttrs (lib.genAttrs stdenvs (_: { })) (stdenvName: {}: { // flatMapAttrs (lib.genAttrs stdenvs (_: { })) (stdenvName: {}: {
# These attributes go right into `packages.<system>`. # These attributes go right into `packages.<system>`.
"${pkgName}-${stdenvName}" = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nixComponents.${pkgName}; "${pkgName}-${stdenvName}" = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nixComponents.${pkgName};
@ -259,10 +281,10 @@
dockerImage = dockerImage =
let let
pkgs = nixpkgsFor.${system}.native; pkgs = nixpkgsFor.${system}.native;
image = import ./docker.nix { inherit pkgs; tag = version; }; image = import ./docker.nix { inherit pkgs; tag = pkgs.nix.version; };
in in
pkgs.runCommand pkgs.runCommand
"docker-image-tarball-${version}" "docker-image-tarball-${pkgs.nix.version}"
{ meta.description = "Docker image with Nix for ${system}"; } { meta.description = "Docker image with Nix for ${system}"; }
'' ''
mkdir -p $out/nix-support mkdir -p $out/nix-support
@ -330,6 +352,7 @@
++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs ++ lib.optionals havePerl pkgs.nixComponents.nix-perl-bindings.nativeBuildInputs
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs ++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs ++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
++ pkgs.nixComponents.nix-functional-tests.baseNativeBuildInputs
++ lib.optional ++ lib.optional
(!stdenv.buildPlatform.canExecute stdenv.hostPlatform (!stdenv.buildPlatform.canExecute stdenv.hostPlatform
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479 # Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
@ -340,6 +363,7 @@
++ [ ++ [
pkgs.buildPackages.cmake pkgs.buildPackages.cmake
pkgs.buildPackages.shellcheck pkgs.buildPackages.shellcheck
pkgs.buildPackages.changelog-d
modular.pre-commit.settings.package modular.pre-commit.settings.package
(pkgs.writeScriptBin "pre-commit-hooks-install" (pkgs.writeScriptBin "pre-commit-hooks-install"
modular.pre-commit.settings.installationScript) modular.pre-commit.settings.installationScript)

View file

@ -0,0 +1,52 @@
{
"bogus": "bogus",
"edolstra@gmail.com": "edolstra",
"roberth@users.noreply.github.com": "roberth",
"toscano.pino@tiscali.it": "pinotree",
"valentin@gagarin.work": "fricklerhandwerk",
"mr.trubach@icloud.com": "tie",
"robert@roberthensing.nl": "roberth",
"lix@jade.fyi": "lf-",
"cole.e.helbling@outlook.com": "cole-h",
"joerg@thalheim.io": "Mic92",
"John.Ericson@Obsidian.Systems": "Ericson2314",
"ryan.hendrickson@alum.mit.edu": "rhendric",
"67135060+poweredbypie@users.noreply.github.com": "poweredbypie",
"detroyejr@outlook.com": "detroyejr",
"silvan.mosberger@tweag.io": "infinisil",
"vcs@emily.moe": "emilazy",
"farid.m.zakaria@gmail.com": "fzakaria",
"22859658+RTUnreal@users.noreply.github.com": "RTUnreal",
"me@las.rs": "L-as",
"philip.taron@gmail.com": "philiptaron",
"root@goldstein.rs": "GoldsteinE",
"tomberek@users.noreply.github.com": "tomberek",
"lexi.mattick@neuralink.com": "kognise",
"andrew@johnandrewmarshall.com": "amarshall",
"contact@romain-neil.fr": "romain-neil",
"Mic92@users.noreply.github.com": "Mic92",
"valentin.gagarin@tweag.io": "fricklerhandwerk",
"siddhantk232@gmail.com": "siddhantk232",
"kn@openbsd.org": "klemensn",
"slyich@gmail.com": "trofi",
"theophane.hufschmitt@tweag.io": "thufschmitt",
"alicebob@lijzij.de": "alicebob",
"winter@winter.cafe": "winterqt",
"brian@brianmckenna.org": "puffnfresh",
"git@haenoe.party": "haenoe",
"peshogo@gmail.com": "pineapplehunter",
"poweredbypie@users.noreply.github.com": "poweredbypie",
"arthur200126@gmail.com": "Artoria2e5",
"tomberek@gmail.com": "tomberek",
"jaredbaur@fastmail.com": "jmbaur",
"andreas@rammhold.de": "andir",
"hamirmahal@gmail.com": "hamirmahal",
"git@JohnEricson.me": "Ericson2314",
"8763518+SkamDart@users.noreply.github.com": "SkamDart",
"kirillrdy@gmail.com": "kirillrdy",
"pennae@lix.systems": "pennae",
"delroth@gmail.com": "delroth",
"enno@nerdworks.de": "elohmeier",
"mjbauer95@gmail.com": "matthewbauer",
"MostAwesomeDude@gmail.com": "MostAwesomeDude"
}

View file

@ -0,0 +1,45 @@
{
"fzakaria": "Farid Zakaria",
"kognise": "Lexi Mattick",
"L-as": "Las Safin",
"haenoe": "HaeNoe",
"andir": "Andreas Rammhold",
"matthewbauer": "Matthew Bauer",
"emilazy": "Emily",
"pineapplehunter": "Shogo Takata",
"RTUnreal": null,
"jmbaur": "Jared Baur",
"Ericson2314": "John Ericson",
"pinotree": "Pino Toscano",
"tie": "Ivan Trubach",
"poweredbypie": null,
"fricklerhandwerk": "Valentin Gagarin",
"Mic92": "J\u00f6rg Thalheim",
"alicebob": "Harmen",
"elohmeier": "Enno Richter",
"delroth": "Pierre Bourdon",
"kirillrdy": null,
"thufschmitt": "Th\u00e9ophane Hufschmitt",
"detroyejr": "Jonathan De Troye",
"klemensn": "Klemens Nanni",
"tomberek": null,
"rhendric": "Ryan Hendrickson",
"philiptaron": "Philip Taron",
"puffnfresh": "Brian McKenna",
"lf-": "jade",
"romain-neil": "Romain Neil",
"hamirmahal": "Hamir Mahal",
"edolstra": "Eelco Dolstra",
"Artoria2e5": "Mingye Wang",
"SkamDart": "Cameron",
"roberth": "Robert Hensing",
"amarshall": "Andrew Marshall",
"trofi": "Sergei Trofimovich",
"cole-h": "Cole Helbling",
"infinisil": "Silvan Mosberger",
"siddhantk232": "Siddhant Kumar",
"winterqt": "Winter",
"GoldsteinE": "Max \u201cGoldstein\u201d Siling",
"pennae": null,
"MostAwesomeDude": "Corbin Simpson"
}

View file

@ -2,7 +2,7 @@
{ {
imports = [ imports = [
inputs.pre-commit-hooks.flakeModule inputs.git-hooks-nix.flakeModule
]; ];
perSystem = { config, pkgs, ... }: { perSystem = { config, pkgs, ... }: {
@ -275,7 +275,6 @@
''^src/libutil/current-process\.hh$'' ''^src/libutil/current-process\.hh$''
''^src/libutil/english\.cc$'' ''^src/libutil/english\.cc$''
''^src/libutil/english\.hh$'' ''^src/libutil/english\.hh$''
''^src/libutil/environment-variables\.cc$''
''^src/libutil/error\.cc$'' ''^src/libutil/error\.cc$''
''^src/libutil/error\.hh$'' ''^src/libutil/error\.hh$''
''^src/libutil/exit\.hh$'' ''^src/libutil/exit\.hh$''
@ -357,7 +356,6 @@
''^src/libutil/util\.cc$'' ''^src/libutil/util\.cc$''
''^src/libutil/util\.hh$'' ''^src/libutil/util\.hh$''
''^src/libutil/variant-wrapper\.hh$'' ''^src/libutil/variant-wrapper\.hh$''
''^src/libutil/windows/environment-variables\.cc$''
''^src/libutil/windows/file-descriptor\.cc$'' ''^src/libutil/windows/file-descriptor\.cc$''
''^src/libutil/windows/file-path\.cc$'' ''^src/libutil/windows/file-path\.cc$''
''^src/libutil/windows/processes\.cc$'' ''^src/libutil/windows/processes\.cc$''
@ -485,7 +483,6 @@
''^tests/unit/libutil/pool\.cc'' ''^tests/unit/libutil/pool\.cc''
''^tests/unit/libutil/references\.cc'' ''^tests/unit/libutil/references\.cc''
''^tests/unit/libutil/suggestions\.cc'' ''^tests/unit/libutil/suggestions\.cc''
''^tests/unit/libutil/tests\.cc''
''^tests/unit/libutil/url\.cc'' ''^tests/unit/libutil/url\.cc''
''^tests/unit/libutil/xml-writer\.cc'' ''^tests/unit/libutil/xml-writer\.cc''
]; ];
@ -644,19 +641,8 @@
''^tests/functional/selfref-gc\.sh$'' ''^tests/functional/selfref-gc\.sh$''
''^tests/functional/shell\.sh$'' ''^tests/functional/shell\.sh$''
''^tests/functional/shell\.shebang\.sh$'' ''^tests/functional/shell\.shebang\.sh$''
''^tests/functional/signing\.sh$''
''^tests/functional/simple\.builder\.sh$'' ''^tests/functional/simple\.builder\.sh$''
''^tests/functional/simple\.sh$''
''^tests/functional/ssh-relay\.sh$''
''^tests/functional/store-info\.sh$''
''^tests/functional/structured-attrs\.sh$''
''^tests/functional/substitute-with-invalid-ca\.sh$''
''^tests/functional/suggestions\.sh$''
''^tests/functional/supplementary-groups\.sh$'' ''^tests/functional/supplementary-groups\.sh$''
''^tests/functional/tarball\.sh$''
''^tests/functional/test-infra\.sh$''
''^tests/functional/test-libstoreconsumer\.sh$''
''^tests/functional/timeout\.sh$''
''^tests/functional/toString-path\.sh$'' ''^tests/functional/toString-path\.sh$''
''^tests/functional/user-envs-migration\.sh$'' ''^tests/functional/user-envs-migration\.sh$''
''^tests/functional/user-envs-test-case\.sh$'' ''^tests/functional/user-envs-test-case\.sh$''

184
maintainers/release-credits Executable file
View file

@ -0,0 +1,184 @@
#!/usr/bin/env nix
# vim: set filetype=python:
#!nix develop --impure --expr
#!nix ``
#!nix let flake = builtins.getFlake ("git+file://" + toString ../.);
#!nix pkgs = flake.inputs.nixpkgs.legacyPackages.${builtins.currentSystem};
#!nix in pkgs.mkShell { nativeBuildInputs = [
#!nix (pkgs.python3.withPackages (ps: with ps; [ requests ]))
#!nix ]; }
#!nix `` --command python3
# This script lists out the contributors for a given release.
# It must be run from the root of the Nix repository.
import os
import sys
import json
import requests
github_token = os.environ.get("GITHUB_TOKEN")
if not github_token:
print("GITHUB_TOKEN is not set. If you hit the rate limit, set it", file=sys.stderr)
# Might be ok, as we have a cache.
# raise ValueError("GITHUB_TOKEN must be set")
# 1. Read the current version in .version
version = os.environ.get("VERSION")
if not version:
version = open(".version").read().strip()
print(f"Generating release credits for Nix {version}", file=sys.stderr)
# 2. Compute previous version
vcomponents = version.split(".")
if len(vcomponents) >= 2:
prev_version = f"{vcomponents[0]}.{int(vcomponents[1])-1}.0"
else:
raise ValueError(".version must have at least two components")
# For unreleased versions
endref = "HEAD"
# For older releases
# endref = version
# 2. Find the merge base between the current version and the previous version
mergeBase = os.popen(f"git merge-base {prev_version} {endref}").read().strip()
print(f"Merge base between {prev_version} and {endref} is {mergeBase}", file=sys.stderr)
# 3. Find the date of the merge base
mergeBaseDate = os.popen(f"git show -s --format=%ci {mergeBase}").read().strip()[0:10]
print(f"Merge base date is {mergeBaseDate}", file=sys.stderr)
# 4. Get the commits between the merge base and the current version
def get_commits():
raw = os.popen(f"git log --pretty=format:'%H\t%an\t%ae' {mergeBase}..{endref}").read().strip()
lines = raw.split("\n")
return [ { "hash": items[0], "author": items[1], "email": items[2] }
for line in lines
for items in (line.split("\t"),)
]
def commits_to_first_commit_by_email(commits):
by_email = dict()
for commit in commits:
email = commit["email"]
if email not in by_email:
by_email[email] = commit
return by_email
samples = commits_to_first_commit_by_email(get_commits())
# For quick testing, only pick two samples from the dict
# samples = dict(list(samples.items())[:2])
# Query the GitHub API to get handle
def get_github_commit(commit):
url = f"https://api.github.com/repos/NixOS/nix/commits/{commit['hash']}"
headers = {'Authorization': f'token {github_token}'}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
class Cache:
def __init__(self, filename, require = True):
self.filename = filename
try:
with open(filename, "r") as f:
self.values = json.load(f)
except FileNotFoundError:
if require:
raise
self.values = dict()
def save(self):
with open(self.filename, "w") as f:
json.dump(self.values, f, indent=4)
print(f"Saved cache to {self.filename}", file=sys.stderr)
# The email to handle cache maps email addresses to either
# - a handle (string)
# - None (if no handle was found)
email_to_handle_cache = Cache("maintainers/data/release-credits-email-to-handle.json")
handles = set()
emails = dict()
for sample in samples:
s = samples[sample]
email = s["email"]
if not email in email_to_handle_cache.values:
print(f"Querying GitHub API for {s['hash']}, to get handle for {s['email']}")
ghc = get_github_commit(samples[sample])
gha = ghc["author"]
if gha and gha["login"]:
handle = gha["login"]
print(f"Handle: {handle}")
email_to_handle_cache.values[email] = handle
else:
print(f"Found no handle for {s['email']}")
email_to_handle_cache.values[email] = None
handle = email_to_handle_cache.values[email]
if handle is not None:
handles.add(handle)
else:
emails[email] = s["author"]
# print(email_to_handle_cache.values)
email_to_handle_cache.save()
handle_to_name_cache = Cache("maintainers/data/release-credits-handle-to-name.json")
print(f"Found {len(handles)} handles", file=sys.stderr)
for handle in handles:
if not handle in handle_to_name_cache.values:
print(f"Querying GitHub API for {handle}, to get name", file=sys.stderr)
url = f"https://api.github.com/users/{handle}"
headers = {'Authorization': f'token {github_token}'}
response = requests.get(url, headers=headers)
response.raise_for_status()
user = response.json()
name = user["name"]
print(f"Name: {name}", file=sys.stderr)
handle_to_name_cache.values[handle] = name
handle_to_name_cache.save()
entries = list()
def is_bot(handle):
return handle.endswith("[bot]")
for handle in handles:
name = handle_to_name_cache.values[handle]
if name is None:
# This way it looks more regular
name = handle
# Note to bots: I'm only doing this because it would distract humans, and
# therefore delay your creation. I'm sorry; it's for your benefit.
if not is_bot(handle):
entries += [ f"- {name} [**(@{handle})**](https://github.com/{handle})" ]
def shuffle(entries):
salt = os.urandom(16)
return sorted(entries, key=lambda x: hash((x, salt)))
# Fair ordering is undecidable
entries = shuffle(entries)
# For a sanity check, we could sort the entries by handle instead.
# entries = sorted(entries)
print("")
print(f"This release was made possible by the following {len(entries)} contributors:")
print("")
for entry in entries:
print(entry)
for email in emails:
print(f"- {emails[email]}")

View file

@ -1,4 +1,5 @@
#!/usr/bin/env nix #!/usr/bin/env nix
# vim: set filetype=bash:
#!nix shell .#changelog-d --command bash #!nix shell .#changelog-d --command bash
# --- CONFIGURATION --- # --- CONFIGURATION ---
@ -151,6 +152,13 @@ section_title="Release $version_full ($DATE)"
echo "# $section_title" echo "# $section_title"
echo echo
changelog-d doc/manual/rl-next | sed -e 's/ *$//' changelog-d doc/manual/rl-next | sed -e 's/ *$//'
if ! $IS_PATCH; then
echo
echo "# Contributors"
echo
VERSION=$version_full ./maintainers/release-credits
fi
) | tee -a $file ) | tee -a $file
log "Wrote $file" log "Wrote $file"

View file

@ -39,6 +39,10 @@ release:
* Proof-read / edit / rearrange the release notes if needed. Breaking changes * Proof-read / edit / rearrange the release notes if needed. Breaking changes
and highlights should go to the top. and highlights should go to the top.
* Run `maintainers/release-credits` to make sure the credits script works
and produces a sensible output. Some emails might not automatically map to
a GitHub handle.
* Push. * Push.
```console ```console

View file

@ -42,7 +42,7 @@ my $flakeUrl = $evalInfo->{flake};
my $flakeInfo = decode_json(`nix flake metadata --json "$flakeUrl"` or die) if $flakeUrl; my $flakeInfo = decode_json(`nix flake metadata --json "$flakeUrl"` or die) if $flakeUrl;
my $nixRev = ($flakeInfo ? $flakeInfo->{revision} : $evalInfo->{jobsetevalinputs}->{nix}->{revision}) or die; my $nixRev = ($flakeInfo ? $flakeInfo->{revision} : $evalInfo->{jobsetevalinputs}->{nix}->{revision}) or die;
my $buildInfo = decode_json(fetch("$evalUrl/job/build.x86_64-linux", 'application/json')); my $buildInfo = decode_json(fetch("$evalUrl/job/build.nix.x86_64-linux", 'application/json'));
#print Dumper($buildInfo); #print Dumper($buildInfo);
my $releaseName = $buildInfo->{nixname}; my $releaseName = $buildInfo->{nixname};
@ -91,7 +91,7 @@ sub getStorePath {
sub copyManual { sub copyManual {
my $manual; my $manual;
eval { eval {
$manual = getStorePath("build.x86_64-linux", "doc"); $manual = getStorePath("build.nix.x86_64-linux", "doc");
}; };
if ($@) { if ($@) {
warn "$@"; warn "$@";
@ -240,12 +240,12 @@ if ($haveDocker) {
# Upload nix-fallback-paths.nix. # Upload nix-fallback-paths.nix.
write_file("$tmpDir/fallback-paths.nix", write_file("$tmpDir/fallback-paths.nix",
"{\n" . "{\n" .
" x86_64-linux = \"" . getStorePath("build.x86_64-linux") . "\";\n" . " x86_64-linux = \"" . getStorePath("build.nix.x86_64-linux") . "\";\n" .
" i686-linux = \"" . getStorePath("build.i686-linux") . "\";\n" . " i686-linux = \"" . getStorePath("build.nix.i686-linux") . "\";\n" .
" aarch64-linux = \"" . getStorePath("build.aarch64-linux") . "\";\n" . " aarch64-linux = \"" . getStorePath("build.nix.aarch64-linux") . "\";\n" .
" riscv64-linux = \"" . getStorePath("buildCross.riscv64-unknown-linux-gnu.x86_64-linux") . "\";\n" . " riscv64-linux = \"" . getStorePath("buildCross.nix.riscv64-unknown-linux-gnu.x86_64-linux") . "\";\n" .
" x86_64-darwin = \"" . getStorePath("build.x86_64-darwin") . "\";\n" . " x86_64-darwin = \"" . getStorePath("build.nix.x86_64-darwin") . "\";\n" .
" aarch64-darwin = \"" . getStorePath("build.aarch64-darwin") . "\";\n" . " aarch64-darwin = \"" . getStorePath("build.nix.aarch64-darwin") . "\";\n" .
"}\n"); "}\n");
# Upload release files to S3. # Upload release files to S3.

View file

@ -42,3 +42,4 @@ subproject('nix-fetchers-tests')
subproject('nix-expr-test-support') subproject('nix-expr-test-support')
subproject('nix-expr-tests') subproject('nix-expr-tests')
subproject('nix-flake-tests') subproject('nix-flake-tests')
subproject('nix-functional-tests')

View file

@ -29,4 +29,8 @@ ifdef HOST_OS
HOST_SOLARIS = 1 HOST_SOLARIS = 1
HOST_UNIX = 1 HOST_UNIX = 1
endif endif
ifeq ($(HOST_KERNEL), gnu)
HOST_HURD = 1
HOST_UNIX = 1
endif
endif endif

View file

@ -28,7 +28,7 @@ run_test
if [[ "$status" = 0 ]]; then if [[ "$status" = 0 ]]; then
echo "$post_run_msg [${green}PASS$normal]" echo "$post_run_msg [${green}PASS$normal]"
elif [[ "$status" = 99 ]]; then elif [[ "$status" = 77 ]]; then
echo "$post_run_msg [${yellow}SKIP$normal]" echo "$post_run_msg [${yellow}SKIP$normal]"
else else
echo "$post_run_msg [${red}FAIL$normal]" echo "$post_run_msg [${red}FAIL$normal]"

View file

@ -47,15 +47,12 @@
, pname ? "nix-super" , pname ? "nix-super"
, versionSuffix ? "" , version
, versionSuffix
# Whether to build Nix. Useful to skip for tasks like testing existing pre-built versions of Nix # Whether to build Nix. Useful to skip for tasks like testing existing pre-built versions of Nix
, doBuild ? true , doBuild ? true
# Run the unit tests as part of the build. See `installUnitTests` for an
# alternative to this.
, doCheck ? __forDefaults.canRunInstalled
# Run the functional tests as part of the build. # Run the functional tests as part of the build.
, doInstallCheck ? test-client != null || __forDefaults.canRunInstalled , doInstallCheck ? test-client != null || __forDefaults.canRunInstalled
@ -88,11 +85,6 @@
# - readline # - readline
, readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline" , readlineFlavor ? if stdenv.hostPlatform.isWindows then "readline" else "editline"
# Whether to install unit tests. This is useful when cross compiling
# since we cannot run them natively during the build, but can do so
# later.
, installUnitTests ? doBuild && !__forDefaults.canExecuteHost
# For running the functional tests against a pre-built Nix. Probably # For running the functional tests against a pre-built Nix. Probably
# want to use in conjunction with `doBuild = false;`. # want to use in conjunction with `doBuild = false;`.
, test-daemon ? null , test-daemon ? null
@ -112,13 +104,11 @@
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
# selected attributes with defaults, will be used to define some # selected attributes with defaults, will be used to define some
# things which should instead be gotten via `finalAttrs` in order to # things which should instead be gotten via `finalAttrs` in order to
# work with overriding. # work with overriding.
attrs = { attrs = {
inherit doBuild doCheck doInstallCheck; inherit doBuild doInstallCheck;
}; };
mkDerivation = mkDerivation =
@ -134,16 +124,11 @@ in
mkDerivation (finalAttrs: let mkDerivation (finalAttrs: let
inherit (finalAttrs) inherit (finalAttrs)
doCheck
doInstallCheck doInstallCheck
; ;
doBuild = !finalAttrs.dontBuild; doBuild = !finalAttrs.dontBuild;
# Either running the unit tests during the build, or installing them
# to be run later, requiresthe unit tests to be built.
buildUnitTests = doCheck || installUnitTests;
in { in {
inherit pname version; inherit pname version;
@ -177,8 +162,6 @@ in {
./scripts/local.mk ./scripts/local.mk
] ++ lib.optionals enableManual [ ] ++ lib.optionals enableManual [
./doc/manual ./doc/manual
] ++ lib.optionals buildUnitTests [
./tests/unit
] ++ lib.optionals doInstallCheck [ ] ++ lib.optionals doInstallCheck [
./tests/functional ./tests/functional
])); ]));
@ -191,8 +174,6 @@ in {
# If we are doing just build or just docs, the one thing will use # If we are doing just build or just docs, the one thing will use
# "out". We only need additional outputs if we are doing both. # "out". We only need additional outputs if we are doing both.
++ lib.optional (doBuild && enableManual) "doc" ++ lib.optional (doBuild && enableManual) "doc"
++ lib.optional installUnitTests "check"
++ lib.optional doCheck "testresults"
; ;
nativeBuildInputs = [ nativeBuildInputs = [
@ -216,7 +197,8 @@ in {
] ++ lib.optional stdenv.hostPlatform.isStatic unixtools.hexdump ] ++ lib.optional stdenv.hostPlatform.isStatic unixtools.hexdump
; ;
buildInputs = lib.optionals doBuild [ buildInputs = lib.optionals doBuild (
[
brotli brotli
bzip2 bzip2
curl curl
@ -230,41 +212,30 @@ in {
({ inherit readline editline; }.${readlineFlavor}) ({ inherit readline editline; }.${readlineFlavor})
] ++ lib.optionals enableMarkdown [ ] ++ lib.optionals enableMarkdown [
lowdown lowdown
] ++ lib.optionals buildUnitTests [
gtest
rapidcheck
] ++ lib.optional stdenv.isLinux libseccomp ] ++ lib.optional stdenv.isLinux libseccomp
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
# There have been issues building these dependencies # There have been issues building these dependencies
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin)) ++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
(aws-sdk-cpp.override { aws-sdk-cpp
apis = ["s3" "transfer"]; );
customMemoryManagement = false;
})
;
propagatedBuildInputs = [ propagatedBuildInputs = lib.optionals doBuild ([
boost boost
nlohmann_json nlohmann_json
] ++ lib.optional enableGC boehmgc; ] ++ lib.optional enableGC boehmgc
);
dontBuild = !attrs.doBuild; dontBuild = !attrs.doBuild;
doCheck = attrs.doCheck;
configureFlags = [ configureFlags = [
(lib.enableFeature doBuild "build") (lib.enableFeature doBuild "build")
(lib.enableFeature buildUnitTests "unit-tests")
(lib.enableFeature doInstallCheck "functional-tests") (lib.enableFeature doInstallCheck "functional-tests")
(lib.enableFeature enableManual "doc-gen") (lib.enableFeature enableManual "doc-gen")
(lib.enableFeature enableGC "gc") (lib.enableFeature enableGC "gc")
(lib.enableFeature enableMarkdown "markdown") (lib.enableFeature enableMarkdown "markdown")
(lib.enableFeature installUnitTests "install-unit-tests")
(lib.withFeatureAs true "readline-flavor" readlineFlavor) (lib.withFeatureAs true "readline-flavor" readlineFlavor)
] ++ lib.optionals (!forDevShell) [ ] ++ lib.optionals (!forDevShell) [
"--sysconfdir=/etc" "--sysconfdir=/etc"
] ++ lib.optionals installUnitTests [
"--with-check-bin-dir=${builtins.placeholder "check"}/bin"
"--with-check-lib-dir=${builtins.placeholder "check"}/lib"
] ++ lib.optionals (doBuild) [ ] ++ lib.optionals (doBuild) [
"--with-boost=${boost}/lib" "--with-boost=${boost}/lib"
] ++ lib.optionals (doBuild && stdenv.isLinux) [ ] ++ lib.optionals (doBuild && stdenv.isLinux) [
@ -345,10 +316,6 @@ in {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
mainProgram = "nix"; mainProgram = "nix";
broken = !(lib.all (a: a) [ broken = !(lib.all (a: a) [
# We cannot run or install unit tests if we don't build them or
# Nix proper (which they depend on).
(installUnitTests -> doBuild)
(doCheck -> doBuild)
# The build process for the manual currently requires extracting # The build process for the manual currently requires extracting
# data from the Nix executable we are trying to document. # data from the Nix executable we are trying to document.
(enableManual -> doBuild) (enableManual -> doBuild)

View file

@ -1,11 +1,34 @@
{
lib,
src,
officialRelease,
}:
scope: scope:
let let
inherit (scope) callPackage; inherit (scope) callPackage;
baseVersion = lib.fileContents ../.version;
versionSuffix = lib.optionalString (!officialRelease) "pre";
fineVersionSuffix = lib.optionalString
(!officialRelease)
"pre${builtins.substring 0 8 (src.lastModifiedDate or src.lastModified or "19700101")}_${src.shortRev or "dirty"}";
fineVersion = baseVersion + fineVersionSuffix;
in in
# This becomes the pkgs.nixComponents attribute set # This becomes the pkgs.nixComponents attribute set
{ {
nix = callPackage ../package.nix { }; version = baseVersion + versionSuffix;
inherit versionSuffix;
nix = callPackage ../package.nix {
version = fineVersion;
versionSuffix = fineVersionSuffix;
};
nix-util = callPackage ../src/libutil/package.nix { }; nix-util = callPackage ../src/libutil/package.nix { };
nix-util-c = callPackage ../src/libutil-c/package.nix { }; nix-util-c = callPackage ../src/libutil-c/package.nix { };
@ -33,11 +56,15 @@ in
nix-cmd = callPackage ../src/libcmd/package.nix { }; nix-cmd = callPackage ../src/libcmd/package.nix { };
# Will replace `nix` once the old build system is gone. nix-cli = callPackage ../src/nix/package.nix { version = fineVersion; };
nix-ng = callPackage ../src/nix/package.nix { };
nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { }; nix-functional-tests = callPackage ../src/nix-functional-tests/package.nix { version = fineVersion; };
nix-external-api-docs = callPackage ../src/external-api-docs/package.nix { };
nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { version = fineVersion; };
nix-external-api-docs = callPackage ../src/external-api-docs/package.nix { version = fineVersion; };
nix-perl-bindings = callPackage ../src/perl/package.nix { }; nix-perl-bindings = callPackage ../src/perl/package.nix { };
# Will replace `nix` once the old build system is gone.
nix-ng = callPackage ../packaging/everything.nix { };
} }

View file

@ -8,7 +8,6 @@
pkgs, pkgs,
stdenv, stdenv,
versionSuffix,
}: }:
let let
@ -63,14 +62,28 @@ let
# Work around weird `--as-needed` linker behavior with BSD, see # Work around weird `--as-needed` linker behavior with BSD, see
# https://github.com/mesonbuild/meson/issues/3593 # https://github.com/mesonbuild/meson/issues/3593
bsdNoLinkAsNeeded = finalAttrs: prevAttrs: lib.optionalAttrs stdenv.hostPlatform.isBSD { bsdNoLinkAsNeeded = finalAttrs: prevAttrs:
lib.optionalAttrs stdenv.hostPlatform.isBSD {
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or []; mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [];
}; };
miscGoodPractice = finalAttrs: prevAttrs:
{
strictDeps = prevAttrs.strictDeps or true;
enableParallelBuilding = true;
};
in in
scope: { scope: {
inherit stdenv versionSuffix; inherit stdenv;
version = lib.fileContents ../.version + versionSuffix;
aws-sdk-cpp = (pkgs.aws-sdk-cpp.override {
apis = [ "s3" "transfer" ];
customMemoryManagement = false;
}).overrideAttrs {
# only a stripped down version is built, which takes a lot less resources
# to build, so we don't need a "big-parallel" machine.
requiredSystemFeatures = [ ];
};
libseccomp = pkgs.libseccomp.overrideAttrs (_: rec { libseccomp = pkgs.libseccomp.overrideAttrs (_: rec {
version = "2.5.5"; version = "2.5.5";
@ -136,8 +149,14 @@ scope: {
inherit resolvePath filesetToSource; inherit resolvePath filesetToSource;
mkMesonDerivation = f: stdenv.mkDerivation mkMesonDerivation = f: let
exts = [
miscGoodPractice
bsdNoLinkAsNeeded
localSourceLayer
];
in stdenv.mkDerivation
(lib.extends (lib.extends
(lib.composeExtensions bsdNoLinkAsNeeded localSourceLayer) (lib.foldr lib.composeExtensions (_: _: {}) exts)
f); f);
} }

93
packaging/everything.nix Normal file
View file

@ -0,0 +1,93 @@
{
lib,
stdenv,
buildEnv,
nix-util,
nix-util-c,
nix-util-test-support,
nix-util-tests,
nix-store,
nix-store-c,
nix-store-test-support,
nix-store-tests,
nix-fetchers,
nix-fetchers-tests,
nix-expr,
nix-expr-c,
nix-expr-test-support,
nix-expr-tests,
nix-flake,
nix-flake-tests,
nix-main,
nix-main-c,
nix-cmd,
nix-cli,
nix-functional-tests,
nix-internal-api-docs,
nix-external-api-docs,
nix-perl-bindings,
}:
(buildEnv rec {
name = "nix-${nix-cli.version}";
paths = [
nix-util
nix-util-c
nix-util-test-support
nix-util-tests
nix-store
nix-store-c
nix-store-test-support
nix-store-tests
nix-fetchers
nix-fetchers-tests
nix-expr
nix-expr-c
nix-expr-test-support
nix-expr-tests
nix-flake
nix-flake-tests
nix-main
nix-main-c
nix-cmd
nix-cli
nix-internal-api-docs
nix-external-api-docs
] ++ lib.optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
nix-perl-bindings
];
}).overrideAttrs (_: {
doCheck = true;
doInstallCheck = true;
checkInputs = [
# Actually run the unit tests too
nix-util-tests.tests.run
nix-store-tests.tests.run
nix-expr-tests.tests.run
nix-flake-tests.tests.run
];
installCheckInputs = [
nix-functional-tests
];
})

View file

@ -6,6 +6,7 @@
, linux64BitSystems , linux64BitSystems
, nixpkgsFor , nixpkgsFor
, self , self
, officialRelease
}: }:
let let
inherit (inputs) nixpkgs nixpkgs-regression; inherit (inputs) nixpkgs nixpkgs-regression;
@ -16,7 +17,7 @@ let
}; };
testNixVersions = pkgs: client: daemon: testNixVersions = pkgs: client: daemon:
pkgs.callPackage ../package.nix { pkgs.nixComponents.callPackage ../package.nix {
pname = pname =
"nix-tests" "nix-tests"
+ lib.optionalString + lib.optionalString
@ -28,6 +29,12 @@ let
test-daemon = daemon; test-daemon = daemon;
doBuild = false; doBuild = false;
# This could be more accurate, but a shorter version will match the
# fine version with rev. This functionality is already covered in
# the normal test, so it's fine.
version = pkgs.nixComponents.version;
versionSuffix = pkgs.nixComponents.versionSuffix;
}; };
# Technically we could just return `pkgs.nixComponents`, but for Hydra it's # Technically we could just return `pkgs.nixComponents`, but for Hydra it's
@ -54,6 +61,8 @@ let
"nix-main" "nix-main"
"nix-main-c" "nix-main-c"
"nix-cmd" "nix-cmd"
"nix-cli"
"nix-functional-tests"
"nix-ng" "nix-ng"
]; ];
in in
@ -68,14 +77,16 @@ in
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName})); lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.nixComponents.${pkgName}));
buildCross = forAllPackages (pkgName: buildCross = forAllPackages (pkgName:
forAllCrossSystems (crossSystem: # Hack to avoid non-evaling package
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}))); (if pkgName == "nix-functional-tests" then lib.flip builtins.removeAttrs ["x86_64-w64-mingw32"] else lib.id)
(forAllCrossSystems (crossSystem:
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents.${pkgName}))));
buildNoGc = forAllSystems (system: buildNoGc = forAllSystems (system:
self.packages.${system}.nix.override { enableGC = false; } self.packages.${system}.nix.override { enableGC = false; }
); );
buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nix_noTests); buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents.nix-cli);
# Toggles some settings for better coverage. Windows needs these # Toggles some settings for better coverage. Windows needs these
# library combinations, and Debian build Nix with GNU readline too. # library combinations, and Debian build Nix with GNU readline too.

View file

@ -101,7 +101,7 @@ static int main_build_remote(int argc, char * * argv)
} }
std::optional<StorePath> drvPath; std::optional<StorePath> drvPath;
StoreReference storeUri; std::string storeUri;
while (true) { while (true) {
@ -234,17 +234,16 @@ static int main_build_remote(int argc, char * * argv)
lock = -1; lock = -1;
try { try {
storeUri = bestMachine->storeUri.render();
Activity act(*logger, lvlTalkative, actUnknown, fmt("connecting to '%s'", bestMachine->storeUri.render())); Activity act(*logger, lvlTalkative, actUnknown, fmt("connecting to '%s'", storeUri));
sshStore = bestMachine->openStore(); sshStore = bestMachine->openStore();
sshStore->connect(); sshStore->connect();
storeUri = bestMachine->storeUri;
} catch (std::exception & e) { } catch (std::exception & e) {
auto msg = chomp(drainFD(5, false)); auto msg = chomp(drainFD(5, false));
printError("cannot build on '%s': %s%s", printError("cannot build on '%s': %s%s",
bestMachine->storeUri.render(), e.what(), storeUri, e.what(),
msg.empty() ? "" : ": " + msg); msg.empty() ? "" : ": " + msg);
bestMachine->enabled = false; bestMachine->enabled = false;
continue; continue;
@ -259,15 +258,28 @@ connected:
assert(sshStore); assert(sshStore);
std::cerr << "# accept\n" << storeUri.render() << "\n"; std::cerr << "# accept\n" << storeUri << "\n";
auto inputs = readStrings<PathSet>(source); auto inputs = readStrings<PathSet>(source);
auto wantedOutputs = readStrings<StringSet>(source); auto wantedOutputs = readStrings<StringSet>(source);
AutoCloseFD uploadLock = openLockFile(currentLoad + "/" + escapeUri(storeUri.render()) + ".upload-lock", true); AutoCloseFD uploadLock;
{
auto setUpdateLock = [&](auto && fileName){
uploadLock = openLockFile(currentLoad + "/" + escapeUri(fileName) + ".upload-lock", true);
};
try {
setUpdateLock(storeUri);
} catch (SysError & e) {
if (e.errNo != ENAMETOOLONG) throw;
// Try again hashing the store URL so we have a shorter path
auto h = hashString(HashAlgorithm::MD5, storeUri);
setUpdateLock(h.to_string(HashFormat::Base64, false));
}
}
{ {
Activity act(*logger, lvlTalkative, actUnknown, fmt("waiting for the upload lock to '%s'", storeUri.render())); Activity act(*logger, lvlTalkative, actUnknown, fmt("waiting for the upload lock to '%s'", storeUri));
auto old = signal(SIGALRM, handleAlarm); auto old = signal(SIGALRM, handleAlarm);
alarm(15 * 60); alarm(15 * 60);
@ -280,7 +292,7 @@ connected:
auto substitute = settings.buildersUseSubstitutes ? Substitute : NoSubstitute; auto substitute = settings.buildersUseSubstitutes ? Substitute : NoSubstitute;
{ {
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying dependencies to '%s'", storeUri.render())); Activity act(*logger, lvlTalkative, actUnknown, fmt("copying dependencies to '%s'", storeUri));
copyPaths(*store, *sshStore, store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute); copyPaths(*store, *sshStore, store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute);
} }
@ -318,7 +330,7 @@ connected:
optResult = sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv); optResult = sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv);
auto & result = *optResult; auto & result = *optResult;
if (!result.success()) if (!result.success())
throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri.render(), result.errorMsg); throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
} else { } else {
copyClosure(*store, *sshStore, StorePathSet {*drvPath}, NoRepair, NoCheckSigs, substitute); copyClosure(*store, *sshStore, StorePathSet {*drvPath}, NoRepair, NoCheckSigs, substitute);
auto res = sshStore->buildPathsWithResults({ auto res = sshStore->buildPathsWithResults({
@ -361,7 +373,7 @@ connected:
} }
if (!missingPaths.empty()) { if (!missingPaths.empty()) {
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying outputs from '%s'", storeUri.render())); Activity act(*logger, lvlTalkative, actUnknown, fmt("copying outputs from '%s'", storeUri));
if (auto localStore = store.dynamic_pointer_cast<LocalStore>()) if (auto localStore = store.dynamic_pointer_cast<LocalStore>())
for (auto & path : missingPaths) for (auto & path : missingPaths)
localStore->locksHeld.insert(store->printStorePath(path)); /* FIXME: ugly */ localStore->locksHeld.insert(store->printStorePath(path)); /* FIXME: ugly */

View file

@ -53,10 +53,6 @@ mkMesonDerivation (finalAttrs: {
echo "doc external-api-docs $out/share/doc/nix/external-api/html" >> ''${!outputDoc}/nix-support/hydra-build-products echo "doc external-api-docs $out/share/doc/nix/external-api/html" >> ''${!outputDoc}/nix-support/hydra-build-products
''; '';
enableParallelBuilding = true;
strictDeps = true;
meta = { meta = {
platforms = lib.platforms.all; platforms = lib.platforms.all;
}; };

View file

@ -48,10 +48,6 @@ mkMesonDerivation (finalAttrs: {
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> ''${!outputDoc}/nix-support/hydra-build-products echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> ''${!outputDoc}/nix-support/hydra-build-products
''; '';
enableParallelBuilding = true;
strictDeps = true;
meta = { meta = {
platforms = lib.platforms.all; platforms = lib.platforms.all;
}; };

View file

@ -91,75 +91,11 @@ MixEvalArgs::MixEvalArgs()
.longName = "include", .longName = "include",
.shortName = 'I', .shortName = 'I',
.description = R"( .description = R"(
Add *path* to the Nix search path. The Nix search path is Add *path* to search path entries used to resolve [lookup paths](@docroot@/language/constructs/lookup-path.md)
initialized from the colon-separated [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH) environment
variable, and is used to look up the location of Nix expressions using [paths](@docroot@/language/types.md#type-path) enclosed in angle
brackets (i.e., `<nixpkgs>`).
For instance, passing This option may be given multiple times.
``` Paths added through `-I` take precedence over the [`nix-path` configuration setting](@docroot@/command-ref/conf-file.md#conf-nix-path) and the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH).
-I /home/eelco/Dev
-I /etc/nixos
```
will cause Nix to look for paths relative to `/home/eelco/Dev` and
`/etc/nixos`, in that order. This is equivalent to setting the
`NIX_PATH` environment variable to
```
/home/eelco/Dev:/etc/nixos
```
It is also possible to match paths against a prefix. For example,
passing
```
-I nixpkgs=/home/eelco/Dev/nixpkgs-branch
-I /etc/nixos
```
will cause Nix to search for `<nixpkgs/path>` in
`/home/eelco/Dev/nixpkgs-branch/path` and `/etc/nixos/nixpkgs/path`.
If a path in the Nix search path starts with `http://` or `https://`,
it is interpreted as the URL of a tarball that will be downloaded and
unpacked to a temporary location. The tarball must consist of a single
top-level directory. For example, passing
```
-I nixpkgs=https://github.com/NixOS/nixpkgs/archive/master.tar.gz
```
tells Nix to download and use the current contents of the `master`
branch in the `nixpkgs` repository.
The URLs of the tarballs from the official `nixos.org` channels
(see [the manual page for `nix-channel`](../nix-channel.md)) can be
abbreviated as `channel:<channel-name>`. For instance, the
following two flags are equivalent:
```
-I nixpkgs=channel:nixos-21.05
-I nixpkgs=https://nixos.org/channels/nixos-21.05/nixexprs.tar.xz
```
You can also fetch source trees using [flake URLs](./nix3-flake.md#url-like-syntax) and add them to the
search path. For instance,
```
-I nixpkgs=flake:nixpkgs
```
specifies that the prefix `nixpkgs` shall refer to the source tree
downloaded from the `nixpkgs` entry in the flake registry. Similarly,
```
-I nixpkgs=flake:github:NixOS/nixpkgs/nixos-22.05
```
makes `<nixpkgs>` refer to a particular branch of the
`NixOS/nixpkgs` repository on GitHub.
)", )",
.category = category, .category = category,
.labels = {"path"}, .labels = {"path"},

View file

@ -104,12 +104,12 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
auto drvPath = attr->forceDerivation(); auto drvPath = attr->forceDerivation();
std::optional<NixInt> priority; std::optional<NixInt::Inner> priority;
if (attr->maybeGetAttr(state->sOutputSpecified)) { if (attr->maybeGetAttr(state->sOutputSpecified)) {
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) { } else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
if (auto aPriority = aMeta->maybeGetAttr("priority")) if (auto aPriority = aMeta->maybeGetAttr("priority"))
priority = aPriority->getInt(); priority = aPriority->getInt().value;
} }
return {{ return {{

View file

@ -40,7 +40,7 @@ struct ExtraPathInfoValue : ExtraPathInfo
/** /**
* An optional priority for use with "build envs". See Package * An optional priority for use with "build envs". See Package
*/ */
std::optional<NixInt> priority; std::optional<NixInt::Inner> priority;
/** /**
* The attribute path associated with this value. The idea is * The attribute path associated with this value. The idea is

View file

@ -1,5 +1,6 @@
#include "markdown.hh" #include "markdown.hh"
#include "util.hh" #include "environment-variables.hh"
#include "error.hh"
#include "finally.hh" #include "finally.hh"
#include "terminal.hh" #include "terminal.hh"
@ -10,12 +11,13 @@
namespace nix { namespace nix {
std::string renderMarkdownToTerminal(std::string_view markdown)
{
#if HAVE_LOWDOWN #if HAVE_LOWDOWN
static std::string doRenderMarkdownToTerminal(std::string_view markdown)
{
int windowWidth = getWindowSize().second; int windowWidth = getWindowSize().second;
struct lowdown_opts opts { struct lowdown_opts opts
{
.type = LOWDOWN_TERM, .type = LOWDOWN_TERM,
.maxdepth = 20, .maxdepth = 20,
.cols = (size_t) std::max(windowWidth - 5, 60), .cols = (size_t) std::max(windowWidth - 5, 60),
@ -51,9 +53,21 @@ std::string renderMarkdownToTerminal(std::string_view markdown)
throw Error("allocation error while rendering Markdown"); throw Error("allocation error while rendering Markdown");
return filterANSIEscapes(std::string(buf->data, buf->size), !isTTY()); return filterANSIEscapes(std::string(buf->data, buf->size), !isTTY());
#else
return std::string(markdown);
#endif
} }
std::string renderMarkdownToTerminal(std::string_view markdown)
{
if (auto e = getEnv("_NIX_TEST_RAW_MARKDOWN"); e && *e == "1")
return std::string(markdown);
else
return doRenderMarkdownToTerminal(markdown);
} }
#else
std::string renderMarkdownToTerminal(std::string_view markdown)
{
return std::string(markdown);
}
#endif
} // namespace nix

View file

@ -1,10 +1,17 @@
#pragma once #pragma once
///@file ///@file
#include "types.hh" #include <string_view>
namespace nix { namespace nix {
/**
* Render the given Markdown text to the terminal.
*
* If Nix is compiled without Markdown support, this function will return the input text as-is.
*
* The renderer takes into account the terminal width, and wraps text accordingly.
*/
std::string renderMarkdownToTerminal(std::string_view markdown); std::string renderMarkdownToTerminal(std::string_view markdown);
} }

View file

@ -93,14 +93,8 @@ mkMesonDerivation (finalAttrs: {
LDFLAGS = "-fuse-ld=gold"; LDFLAGS = "-fuse-ld=gold";
}; };
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO `releaseTools.coverageAnalysis` in Nixpkgs needs to be updated
# to work with `strictDeps`.
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = { meta = {

View file

@ -19,6 +19,7 @@ extern "C" {
#include "repl-interacter.hh" #include "repl-interacter.hh"
#include "file-system.hh" #include "file-system.hh"
#include "repl.hh" #include "repl.hh"
#include "environment-variables.hh"
namespace nix { namespace nix {
@ -34,6 +35,7 @@ void sigintHandler(int signo)
static detail::ReplCompleterMixin * curRepl; // ugly static detail::ReplCompleterMixin * curRepl; // ugly
#ifndef USE_READLINE
static char * completionCallback(char * s, int * match) static char * completionCallback(char * s, int * match)
{ {
auto possible = curRepl->completePrefix(s); auto possible = curRepl->completePrefix(s);
@ -100,6 +102,7 @@ static int listPossibleCallback(char * s, char *** avp)
return ac; return ac;
} }
#endif
ReadlineLikeInteracter::Guard ReadlineLikeInteracter::init(detail::ReplCompleterMixin * repl) ReadlineLikeInteracter::Guard ReadlineLikeInteracter::init(detail::ReplCompleterMixin * repl)
{ {
@ -175,10 +178,23 @@ bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptT
return true; return true;
} }
// editline doesn't echo the input to the output when non-interactive, unlike readline
// this results in a different behavior when running tests. The echoing is
// quite useful for reading the test output, so we add it here.
if (auto e = getEnv("_NIX_TEST_REPL_ECHO"); s && e && *e == "1")
{
#ifndef USE_READLINE
// This is probably not right for multi-line input, but we don't use that
// in the characterisation tests, so it's fine.
std::cout << promptForType(promptType) << s << std::endl;
#endif
}
if (!s) if (!s)
return false; return false;
input += s; input += s;
input += '\n'; input += '\n';
return true; return true;
} }

View file

@ -7,7 +7,6 @@
#include "ansicolor.hh" #include "ansicolor.hh"
#include "shared.hh" #include "shared.hh"
#include "config-global.hh"
#include "eval.hh" #include "eval.hh"
#include "eval-settings.hh" #include "eval-settings.hh"
#include "attr-path.hh" #include "attr-path.hh"
@ -77,10 +76,14 @@ struct NixRepl
int displ; int displ;
StringSet varNames; StringSet varNames;
RunNix * runNixPtr;
void runNix(Path program, const Strings & args, const std::optional<std::string> & input = {});
std::unique_ptr<ReplInteracter> interacter; std::unique_ptr<ReplInteracter> interacter;
NixRepl(const LookupPath & lookupPath, nix::ref<Store> store,ref<EvalState> state, NixRepl(const LookupPath & lookupPath, nix::ref<Store> store,ref<EvalState> state,
std::function<AnnotatedValues()> getValues); std::function<AnnotatedValues()> getValues, RunNix * runNix);
virtual ~NixRepl() = default; virtual ~NixRepl() = default;
ReplExitStatus mainLoop() override; ReplExitStatus mainLoop() override;
@ -125,32 +128,16 @@ std::string removeWhitespace(std::string s)
NixRepl::NixRepl(const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state, NixRepl::NixRepl(const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
std::function<NixRepl::AnnotatedValues()> getValues) std::function<NixRepl::AnnotatedValues()> getValues, RunNix * runNix = nullptr)
: AbstractNixRepl(state) : AbstractNixRepl(state)
, debugTraceIndex(0) , debugTraceIndex(0)
, getValues(getValues) , getValues(getValues)
, staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get())) , staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get()))
, runNixPtr{runNix}
, interacter(make_unique<ReadlineLikeInteracter>(getDataDir() + "/nix/repl-history")) , interacter(make_unique<ReadlineLikeInteracter>(getDataDir() + "/nix/repl-history"))
{ {
} }
void runNix(Path program, const Strings & args,
const std::optional<std::string> & input = {})
{
auto subprocessEnv = getEnv();
subprocessEnv["NIX_CONFIG"] = globalConfig.toKeyValue();
//isInteractive avoid grabling interactive commands
runProgram2(RunOptions {
.program = settings.nixBinDir+ "/" + program,
.args = args,
.environment = subprocessEnv,
.input = input,
.isInteractive = true,
});
return;
}
static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positions, const DebugTrace & dt) static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positions, const DebugTrace & dt)
{ {
if (dt.isError) if (dt.isError)
@ -217,7 +204,7 @@ ReplExitStatus NixRepl::mainLoop()
case ProcessLineResult::PromptAgain: case ProcessLineResult::PromptAgain:
break; break;
default: default:
abort(); unreachable();
} }
} catch (ParseError & e) { } catch (ParseError & e) {
if (e.msg().find("unexpected end of file") != std::string::npos) { if (e.msg().find("unexpected end of file") != std::string::npos) {
@ -644,9 +631,6 @@ ProcessLineResult NixRepl::processLine(std::string line)
fallbackPos = attr->pos; fallbackPos = attr->pos;
fallbackDoc = state->getDocCommentForPos(fallbackPos); fallbackDoc = state->getDocCommentForPos(fallbackPos);
} }
} else {
evalString(arg, v);
} }
evalString(arg, v); evalString(arg, v);
@ -836,9 +820,18 @@ void NixRepl::evalString(std::string s, Value & v)
} }
void NixRepl::runNix(Path program, const Strings & args, const std::optional<std::string> & input)
{
if (runNixPtr)
(*runNixPtr)(program, args, input);
else
throw Error("Cannot run '%s', no method of calling the Nix CLI provided", program);
}
std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create( std::unique_ptr<AbstractNixRepl> AbstractNixRepl::create(
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state, const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state,
std::function<AnnotatedValues()> getValues) std::function<AnnotatedValues()> getValues, RunNix * runNix)
{ {
return std::make_unique<NixRepl>( return std::make_unique<NixRepl>(
lookupPath, lookupPath,

View file

@ -19,9 +19,19 @@ struct AbstractNixRepl
typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues; typedef std::vector<std::pair<Value*,std::string>> AnnotatedValues;
using RunNix = void(Path program, const Strings & args, const std::optional<std::string> & input);
/**
* @param runNix Function to run the nix CLI to support various
* `:<something>` commands. Optional; if not provided,
* everything else will still work fine, but those commands won't.
*/
static std::unique_ptr<AbstractNixRepl> create( static std::unique_ptr<AbstractNixRepl> create(
const LookupPath & lookupPath, nix::ref<Store> store, ref<EvalState> state, const LookupPath & lookupPath,
std::function<AnnotatedValues()> getValues); nix::ref<Store> store,
ref<EvalState> state,
std::function<AnnotatedValues()> getValues,
RunNix * runNix = nullptr);
static ReplExitStatus runSimple( static ReplExitStatus runSimple(
ref<EvalState> evalState, ref<EvalState> evalState,

View file

@ -14,6 +14,16 @@
#include "nix_api_util.h" #include "nix_api_util.h"
#include <stddef.h> #include <stddef.h>
#ifndef __has_c_attribute
# define __has_c_attribute(x) 0
#endif
#if __has_c_attribute(deprecated)
# define NIX_DEPRECATED(msg) [[deprecated(msg)]]
#else
# define NIX_DEPRECATED(msg)
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -45,7 +55,7 @@ typedef struct EvalState EvalState; // nix::EvalState
* @see nix_value_incref, nix_value_decref * @see nix_value_incref, nix_value_decref
*/ */
typedef struct nix_value nix_value; typedef struct nix_value nix_value;
[[deprecated("use nix_value instead")]] typedef nix_value Value; NIX_DEPRECATED("use nix_value instead") typedef nix_value Value;
// Function prototypes // Function prototypes
/** /**

View file

@ -306,7 +306,7 @@ int64_t nix_get_int(nix_c_context * context, const nix_value * value)
try { try {
auto & v = check_value_in(value); auto & v = check_value_in(value);
assert(v.type() == nix::nInt); assert(v.type() == nix::nInt);
return v.integer(); return v.integer().value;
} }
NIXC_CATCH_ERRS_RES(0); NIXC_CATCH_ERRS_RES(0);
} }

View file

@ -63,12 +63,8 @@ mkMesonDerivation (finalAttrs: {
LDFLAGS = "-fuse-ld=gold"; LDFLAGS = "-fuse-ld=gold";
}; };
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = { meta = {

View file

@ -134,7 +134,7 @@ std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v
return {SourcePath{path.accessor, CanonPath(fn.substr(0, colon))}, lineno}; return {SourcePath{path.accessor, CanonPath(fn.substr(0, colon))}, lineno};
} catch (std::invalid_argument & e) { } catch (std::invalid_argument & e) {
fail(); fail();
abort(); unreachable();
} }
} }

View file

@ -4,6 +4,8 @@
#include "eval.hh" #include "eval.hh"
#include "eval-inline.hh" #include "eval-inline.hh"
#include "store-api.hh" #include "store-api.hh"
// Need specialization involving `SymbolStr` just in this one module.
#include "strings-inline.hh"
namespace nix::eval_cache { namespace nix::eval_cache {
@ -326,7 +328,7 @@ struct AttrDb
case AttrType::Bool: case AttrType::Bool:
return {{rowId, queryAttribute.getInt(2) != 0}}; return {{rowId, queryAttribute.getInt(2) != 0}};
case AttrType::Int: case AttrType::Int:
return {{rowId, int_t{queryAttribute.getInt(2)}}}; return {{rowId, int_t{NixInt{queryAttribute.getInt(2)}}}};
case AttrType::ListOfStrings: case AttrType::ListOfStrings:
return {{rowId, tokenizeString<std::vector<std::string>>(queryAttribute.getStr(2), "\t")}}; return {{rowId, tokenizeString<std::vector<std::string>>(queryAttribute.getStr(2), "\t")}};
case AttrType::Missing: case AttrType::Missing:
@ -469,7 +471,7 @@ Value & AttrCursor::forceValue()
else if (v.type() == nBool) else if (v.type() == nBool)
cachedValue = {root->db->setBool(getKey(), v.boolean()), v.boolean()}; cachedValue = {root->db->setBool(getKey(), v.boolean()), v.boolean()};
else if (v.type() == nInt) else if (v.type() == nInt)
cachedValue = {root->db->setInt(getKey(), v.integer()), int_t{v.integer()}}; cachedValue = {root->db->setInt(getKey(), v.integer().value), int_t{v.integer()}};
else if (v.type() == nAttrs) else if (v.type() == nAttrs)
; // FIXME: do something? ; // FIXME: do something?
else else

View file

@ -1,5 +1,7 @@
#include "error.hh" #include "error.hh"
#include "environment-variables.hh" #include "environment-variables.hh"
#include "eval-settings.hh"
#include "config-global.hh"
#include "serialise.hh" #include "serialise.hh"
#include "eval-gc.hh" #include "eval-gc.hh"
@ -84,14 +86,17 @@ void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
{ {
void *& sp = *sp_ptr; void *& sp = *sp_ptr;
auto pthread_id = reinterpret_cast<pthread_t>(_pthread_id); auto pthread_id = reinterpret_cast<pthread_t>(_pthread_id);
# ifndef __APPLE__
pthread_attr_t pattr; pthread_attr_t pattr;
# endif
size_t osStackSize; size_t osStackSize;
void * osStackLow; // The low address of the stack, which grows down.
void * osStackLimit;
void * osStackBase; void * osStackBase;
# ifdef __APPLE__ # ifdef __APPLE__
osStackSize = pthread_get_stacksize_np(pthread_id); osStackSize = pthread_get_stacksize_np(pthread_id);
osStackLow = pthread_get_stackaddr_np(pthread_id); osStackLimit = pthread_get_stackaddr_np(pthread_id);
# else # else
if (pthread_attr_init(&pattr)) { if (pthread_attr_init(&pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_init failed"); throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
@ -110,18 +115,18 @@ void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
# else # else
# error "Need one of `pthread_attr_get_np` or `pthread_getattr_np`" # error "Need one of `pthread_attr_get_np` or `pthread_getattr_np`"
# endif # endif
if (pthread_attr_getstack(&pattr, &osStackLow, &osStackSize)) { if (pthread_attr_getstack(&pattr, &osStackLimit, &osStackSize)) {
throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed"); throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed");
} }
if (pthread_attr_destroy(&pattr)) { if (pthread_attr_destroy(&pattr)) {
throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed"); throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed");
} }
# endif # endif
osStackBase = (char *) osStackLow + osStackSize; osStackBase = (char *) osStackLimit + osStackSize;
// NOTE: We assume the stack grows down, as it does on all architectures we support. // NOTE: We assume the stack grows down, as it does on all architectures we support.
// Architectures that grow the stack up are rare. // Architectures that grow the stack up are rare.
if (sp >= osStackBase || sp < osStackLow) { // lo is outside the os stack if (sp >= osStackBase || sp < osStackLimit) { // sp is outside the os stack
sp = osStackLow; sp = osStackLimit;
} }
} }
@ -206,10 +211,17 @@ static inline void initGCReal()
} }
} }
static size_t gcCyclesAfterInit = 0;
size_t getGCCycles()
{
assertGCInitialized();
return static_cast<size_t>(GC_get_gc_no()) - gcCyclesAfterInit;
}
#endif #endif
static bool gcInitialised = false; static bool gcInitialised = false;
static GC_word gcCyclesAfterInit = 0;
void initGC() void initGC()
{ {
@ -218,10 +230,17 @@ void initGC()
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
initGCReal(); initGCReal();
gcCyclesAfterInit = GC_get_gc_no();
#endif #endif
// NIX_PATH must override the regular setting
// See the comment in applyConfig
if (auto nixPathEnv = getEnv("NIX_PATH")) {
globalConfig.set("nix-path", concatStringsSep(" ", EvalSettings::parseNixPath(nixPathEnv.value())));
}
gcInitialised = true; gcInitialised = true;
gcCyclesAfterInit = GC_get_gc_no();
} }
void assertGCInitialized() void assertGCInitialized()
@ -229,10 +248,4 @@ void assertGCInitialized()
assert(gcInitialised); assert(gcInitialised);
} }
size_t getGCCycles()
{
assertGCInitialized();
return GC_get_gc_no() - gcCyclesAfterInit;
}
} // namespace nix } // namespace nix

View file

@ -15,9 +15,11 @@ void initGC();
*/ */
void assertGCInitialized(); void assertGCInitialized();
#ifdef HAVE_BOEHMGC
/** /**
* The number of GC cycles since initGC(). * The number of GC cycles since initGC().
*/ */
size_t getGCCycles(); size_t getGCCycles();
#endif
} } // namespace nix

View file

@ -8,7 +8,7 @@ namespace nix {
/* Very hacky way to parse $NIX_PATH, which is colon-separated, but /* Very hacky way to parse $NIX_PATH, which is colon-separated, but
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */ can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
static Strings parseNixPath(const std::string & s) Strings EvalSettings::parseNixPath(const std::string & s)
{ {
Strings res; Strings res;
@ -48,10 +48,7 @@ EvalSettings::EvalSettings(bool & readOnlyMode, EvalSettings::LookupPathHooks lo
: readOnlyMode{readOnlyMode} : readOnlyMode{readOnlyMode}
, lookupPathHooks{lookupPathHooks} , lookupPathHooks{lookupPathHooks}
{ {
auto var = getEnv("NIX_PATH"); auto var = getEnv("NIX_ABORT_ON_WARN");
if (var) nixPath = parseNixPath(*var);
var = getEnv("NIX_ABORT_ON_WARN");
if (var && (var == "1" || var == "yes" || var == "true")) if (var && (var == "1" || var == "yes" || var == "true"))
builtinsAbortOnWarn = true; builtinsAbortOnWarn = true;
} }

View file

@ -47,6 +47,8 @@ struct EvalSettings : Config
static bool isPseudoUrl(std::string_view s); static bool isPseudoUrl(std::string_view s);
static Strings parseNixPath(const std::string & s);
static std::string resolvePseudoUrl(std::string_view url); static std::string resolvePseudoUrl(std::string_view url);
LookupPathHooks lookupPathHooks; LookupPathHooks lookupPathHooks;
@ -63,7 +65,7 @@ struct EvalSettings : Config
extern "C" typedef void (*ValueInitialiser) (EvalState & state, Value & v); extern "C" typedef void (*ValueInitialiser) (EvalState & state, Value & v);
``` ```
The [Nix C++ API documentation](@docroot@/contributing/documentation.md#api-documentation) has more details on evaluator internals. The [Nix C++ API documentation](@docroot@/development/documentation.md#api-documentation) has more details on evaluator internals.
- `builtins.exec` *arguments* - `builtins.exec` *arguments*
@ -71,25 +73,30 @@ struct EvalSettings : Config
)"}; )"};
Setting<Strings> nixPath{ Setting<Strings> nixPath{
this, getDefaultNixPath(), "nix-path", this, {}, "nix-path",
R"( R"(
List of search paths to use for [lookup path](@docroot@/language/constructs/lookup-path.md) resolution. List of search paths to use for [lookup path](@docroot@/language/constructs/lookup-path.md) resolution.
This setting determines the value of This setting determines the value of
[`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath) and can be used with [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile). [`builtins.nixPath`](@docroot@/language/builtins.md#builtins-nixPath) and can be used with [`builtins.findFile`](@docroot@/language/builtins.md#builtins-findFile).
The default value is - The configuration setting is overridden by the [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH)
environment variable.
- `NIX_PATH` is overridden by [specifying the setting as the command line flag](@docroot@/command-ref/conf-file.md#command-line-flags) `--nix-path`.
- Any current value is extended by the [`-I` option](@docroot@/command-ref/opt-common.md#opt-I) or `--extra-nix-path`.
``` If the respective paths are accessible, the default values are:
$HOME/.nix-defexpr/channels
nixpkgs=$NIX_STATE_DIR/profiles/per-user/root/channels/nixpkgs
$NIX_STATE_DIR/profiles/per-user/root/channels
```
It can be overridden with the [`NIX_PATH` environment variable](@docroot@/command-ref/env-common.md#env-NIX_PATH) or the [`-I` command line option](@docroot@/command-ref/opt-common.md#opt-I). - `$HOME/.nix-defexpr/channels`
- `nixpkgs=$NIX_STATE_DIR/profiles/per-user/root/channels/nixpkgs`
- `$NIX_STATE_DIR/profiles/per-user/root/channels`
See [`NIX_STATE_DIR`](@docroot@/command-ref/env-common.md#env-NIX_STATE_DIR) for details.
> **Note** > **Note**
> >
> If [pure evaluation](#conf-pure-eval) is enabled, `nixPath` evaluates to the empty list `[ ]`. > If [restricted evaluation](@docroot@/command-ref/conf-file.md#conf-restrict-eval) is enabled, the default value is empty.
>
> If [pure evaluation](#conf-pure-eval) is enabled, `builtins.nixPath` *always* evaluates to the empty list `[ ]`.
)", {}, false}; )", {}, false};
Setting<std::string> currentSystem{ Setting<std::string> currentSystem{

Some files were not shown because too many files have changed in this diff Show more