Compare commits

..
Author SHA1 Message Date
e425a1d18d Import C bindings from NixOS/nix#8699
Co-authored-by: Yorick van Pelt <yorick@yorickvanpelt.nl>
Co-authored-by: José Luis Lafuente <jose.lafuente@tweag.io>
Change-Id: I48aa262d880aa75aa5b230553f663c35c283d5f6
2024-03-17 16:38:04 +00:00
Puck Meerburg de17a2f0fa libexpr: Lessen const bound on Value::listElems() const
I do not like this being a requirement, but it is necessary to make the
C api work with the least amount of ABI changes.

listElems() const returns a constant pointer to N constant pointers of
Value. This bound is lessened (within defined behavior) to a constant
pointer to N *mutable* pointers of Value. The upstream reasoning behind
this is reasonable enough, though I strongly distrust it.

It might be better to drop the `const` off of the C ABI instead.

Change-Id: I8e750b086c1b8d13972aa748ce8f6139f6bcbadb
2024-03-17 16:25:12 +00:00
Puck Meerburg 7f9e09a434 libexpr: rename parseSearchPath to SearchPath::parse
This was never called??

Change-Id: I5c1b3ce0d5479a638fda98467efb2f34faaac726
2024-03-17 16:06:00 +00:00
Puck Meerburg 883d2ad4d2 libexpr: use std::function rather than C function pointers for primops
In preparation for the C bindings, which use this.

Change-Id: Ic1c58998951e69e66a794976585a381754dfbbeb
2024-03-17 16:04:36 +00:00
Qyriad 7acdcf5511 meson: better match autotools cxxflags
Change-Id: I667c8685b13b7bab91e281053f807a11616ae3d4
2024-03-16 19:23:19 -06:00
Qyriad f150b3f7f8 meson: migrate generated headers to a generator() object
Change-Id: Ie7b9cab4189825e8f02dfb39d298302bc36fcb61
2024-03-15 18:55:59 -06:00
Qyriad 75f823f2e4 meson: fix libstore on linux
Change-Id: I95fef8e630575c970538d2d8ba4c91d16ae5f8ac
2024-03-15 18:55:28 -06:00
Qyriad 6fb79d08ae meson: getting the nix command building
Change-Id: If2f4a82b0d23a11a828bb4b305fabe4e30e1e91b
2024-03-15 16:44:54 -06:00
Qyriad 557dc678fd meson: we can now build libcmd!
Change-Id: I3506b3d599cd038020d208b899f81b7251932fd8
2024-03-13 21:16:03 -06:00
Qyriad f2113c2416 meson: we can now build libmain!
Change-Id: I2333a18d790df843d07163ff884c80095d89e0cc
2024-03-13 21:08:34 -06:00
Qyriad e30dac46fe meson: we can now build libexpr!
Change-Id: I937a217fdcb5bd33491cc20f04a734e9d732d5e5
2024-03-13 20:53:51 -06:00
Qyriad 1af43a19a2 meson: we can now build libfetchers!
Change-Id: Ic3a64bbc6bb1a77d01652f339f62b7f301e6e7dc
2024-03-12 21:58:53 -06:00
Qyriad e2310d7cb2 meson: we can now build libstore!
Change-Id: I615bba179ce445af42a631f3859ef46308af50e2
2024-03-12 14:05:36 -06:00
Qyriad 8c54e1ac26 meson: can now build libutil!
Change-Id: I6088a5a68637e19f85fcb4660b03ed9d1fc5f3a1
2024-03-12 07:19:52 -06:00
Qyriad bace7379b7 meson: generate a config.h that works with the current build system
Change-Id: I578982fdfc34af1f24ad0c1335dcd7bdef01fd9d
2024-03-09 20:29:51 -07:00
Qyriad a98500320e package: cleanup of all intermediaries
Change-Id: I0da5182de6b01c192cfcba407959d659d70c6dc9
2024-03-09 15:51:31 -07:00
Qyriad 5afa84342c package: migrate devShells
Change-Id: Ic63721667edd4bef79aa699a0de8411639e5159b
2024-03-09 15:51:27 -07:00
Qyriad 2fe0b373e9 package: migrate internal-api-docs
Change-Id: I344d73a412c2c6e4bb2eb14bd4859056324f1ba7
2024-03-09 15:51:24 -07:00
Qyriad e14b56943d package: migrate testNixVersions
Change-Id: I71845f8a6d7b77c3617d055e726ed4a28cd05fa3
2024-03-09 15:51:20 -07:00
Qyriad 1b8f5bb870 package: use pname, version, and doBuild (first change with diff hash)
The src fileset, preConfigure, and separateDebugInfo also respond to doBuild if its overridden

This commit is logically just a continuation of the previous commit's
refactor, but exists separately to delineate when the core Nix
derivation hash changed (this commit).

Change-Id: I67a61bc9608d91b6a833ebc5c3894b2d2e694050
2024-03-09 15:51:16 -07:00
Qyriad f8efdea4a2 package: refactor Nix out of flake.nix and into package.nix
This series takes a somewhat different approach from the flake rework
done in NixOS/nix. The package.nix here does not provide callPackage
options for all the various settings in the build, and instead the other
places Nix derivations are used (like internal-api-docs) will .overrideAttrs
the normal Nix package derivation. This more closely matches how these
things were structured originally, and results in less churn and more
atomicity in these changes.

In the future, package.nix likely will migrate to have more build
options in the callPackage arguments, but we are also planning to
rewrite the build system anyway.

Change-Id: I170c4e5a4184bab62e1fd75e56db876d4ff116cf
2024-03-09 15:48:16 -07:00
eldritch horrors b221a14f0a Merge pull request #9925 from 9999years/fmt-cleanup
Cleanup `fmt.hh`

(cherry picked from commit 47a1dbb4b8e7913cbb9b4d604728b912e76e4ca0)
Change-Id: Id076a45cb39652f437fe3f8bda10c310a9894777
2024-03-09 07:00:13 -07:00
eldritch horrors 3d9c7fc1e7 Add comment
(cherry picked from commit 9723f533d85133fa3c4d9421a58c7765cb61e733)
Change-Id: Idd729febc0bb8c7c8db72a0fae73b680f66767f4
2024-03-09 04:47:05 -07:00
eldritch horrors f536696b73 Add comments
(cherry picked from commit 474fc4078acbe062fcc31ce91c69c8f33bf00d5f)
Change-Id: I9f78f7afd8468d0ab676c0f60c4f7d6140128583
2024-03-09 04:47:05 -07:00
eldritch horrors f27a27f49e Remove EXCEPTION_NEEDS_THROW_SPEC
We're on C++ 20 now, we don't need this

(cherry picked from commit faaccecbc82d98288582bdc8ca96991796561371)
Change-Id: I172fa336107fd18b1aac2262309682e0d7065d07
2024-03-09 04:47:05 -07:00
eldritch horrors 7eb15e13aa Attach positions to errors in derivationStrict
(cherry picked from commit 87dc4bc7d139a7eccb257e71558314a0d99e8d6a)
Change-Id: Ib7509cbb1d246ca5aa3607ff860420fe7a754f6a
2024-03-09 04:47:05 -07:00
eldritch horrors 08252967a8 libexpr: Support structured error classes
While preparing PRs like #9753, I've had to change error messages in
dozens of code paths. It would be nice if instead of

    EvalError("expected 'boolean' but found '%1%'", showType(v))

we could write

    TypeError(v, "boolean")

or similar. Then, changing the error message could be a mechanical
refactor with the compiler pointing out places the constructor needs to
be changed, rather than the error-prone process of grepping through the
codebase. Structured errors would also help prevent the "same" error
from having multiple slightly different messages, and could be a first
step towards error codes / an error index.

This PR reworks the exception infrastructure in `libexpr` to
support exception types with different constructor signatures than
`BaseError`. Actually refactoring the exceptions to use structured data
will come in a future PR (this one is big enough already, as it has to
touch every exception in `libexpr`).

The core design is in `eval-error.hh`. Generally, errors like this:

    state.error("'%s' is not a string", getAttrPathStr())
      .debugThrow<TypeError>()

are transformed like this:

    state.error<TypeError>("'%s' is not a string", getAttrPathStr())
      .debugThrow()

The type annotation has moved from `ErrorBuilder::debugThrow` to
`EvalState::error`.

(cherry picked from commit c6a89c1a1659b31694c0fbcd21d78a6dd521c732)
Change-Id: Iced91ba4e00ca9e801518071fb43798936cbd05a
2024-03-09 04:47:05 -07:00
eldritch horrors d4c738fe4c Move PodIdx to pos-idx.hh and PosTable to pos-table.hh
(cherry picked from commit c62c21e29af20f1c14a59ab37d7a25dd0b70f69e)
Change-Id: Id4ea2fc33b0874b2f1f2a32cabcbeb0afa26808f
2024-03-09 04:47:05 -07:00
eldritch horrors 7673312ccc Merge pull request #9928 from 9999years/error-messages-in-nix-repl
Improve error printing in `nix repl`

(cherry picked from commit a8050d9b83052e4b5c52bf2d116381aedec3a93e)
Change-Id: I588f92d1dd4c546c98788b71403cc034f5e7129a
2024-03-09 03:37:35 -07:00
eldritch horrors c864923928 Merge pull request #9929 from 9999years/dont-print-values-in-magenta
Don't print the first bracket in values in magenta in error messages

(cherry picked from commit 46a0625a40aef6946a35f92fdacf0e6b4a14414f)
Change-Id: I8435565c87db182116140eaeea9df1243e67ea94
2024-03-09 03:37:35 -07:00
eldritch horrors 3e1be9c530 Merge pull request #9917 from 9999years/enter-debugger-more-reliably
Enter debugger more reliably in `let` expressions and function calls

(cherry picked from commit c4ed92fa6f836d3d8eb354a48c37a2f9eeecc3aa)
Change-Id: I16d0cad7e898feecd2399723b92ba8df67222fb4
2024-03-09 03:37:35 -07:00
eldritch horrorsandjade 3796811571 Merge pull request #9927 from 9999years/catch-error-in-value-printer
Catch `Error`, not `BaseError` in `ValuePrinter`

BaseError includes Interrupt. We probably don't want the value printer to tell you Ctrl-C was pressed while it was printing.

(cherry picked from commit c291d2d8dda38aa88b004e2ed05b28653c07e342)
Change-Id: I70b105bfb2f52a8f345ae0281d12f022aa36b14e
2024-03-09 03:37:35 -07:00
eldritch horrors b6b31d255a Merge pull request #9926 from 9999years/fix-cycle-detection-in-nix-repl
Fix cycle detection in `nix repl`

(cherry picked from commit e190c20c3394fd1a5cd9be1afc3f30ab32dcd36b)
Change-Id: Ie385e781b9f0b7171ca653bcd53a990bb41f9e4b
2024-03-09 03:37:35 -07:00
eldritch horrors 1bb8fe48a2 Minor formatting tweaks
(cherry picked from commit 365b831e6f290c733da6879dae871dada343a1eb)
Change-Id: Ife3d269d2f87d6e3fe8a348995019dfc08ac75eb
2024-03-09 00:25:54 -07:00
eldritch horrors 0cf06c5ab5 Update src/libexpr/eval.cc
Co-authored-by: John Ericson <git@JohnEricson.me>
(cherry picked from commit 80b84710b8c676620ed1e8bf8ff3bb1d5bc19b80)
Change-Id: I128555f1ae13cf0e202f565ee439f698efe12431
2024-03-09 00:25:54 -07:00
eldritch horrors f7b2476415 don't repeatedly look up ast internal symbols
these symbols are used a *lot*, so it makes sense to cache them. this
mostly increases clarity of the code (however clear one may wish to call
the parser desugaring here), but it also provides a small performance
benefit.

(cherry picked from commit 09a1128d9e2ff0ae6176784938047350d6f8a782)
Change-Id: I73d9f66be4555168e048cb2d542277251580c2d1
2024-03-09 00:25:54 -07:00
eldritch horrors 92693973b6 decouple parser and EvalState
there's no reason the parser itself should be doing semantic analysis
like bindVars. split this bit apart (retaining the previous name in
EvalState) and have the parser really do *only* parsing, decoupled from
EvalState.

(cherry picked from commit b596cc9e7960b9256bcd557334d81e9d555be5a2)
Change-Id: I481a7623afc783e9d28a6eb4627552cf8a780986
2024-03-09 00:25:54 -07:00
eldritch horrors faaae9d045 slim down parser.y
most EvalState and Expr members defined here could be elsewhere, where
they'd be easier to maintain (not being embedded in a file with arcane
syntax) and *somewhat* more faithfully placed according to the path of
the file they're defined in.

(cherry picked from commit e1aa585964c3d864ebff0030584f3349a539d615)
Change-Id: Ibc704567462bb40f37cda05d8fadd465519db5f5
2024-03-09 00:25:54 -07:00
eldritch horrors f9f8664879 rename ParserState::{makeCurPos -> at}
most instances of this being used do not refer to the "current"
position, sometimes not even to one reasonably close by. it could also
be called `makePos` instead, but `at` seems clear in context.

(cherry picked from commit 835a6c7bcfd0b22acc16f31de5fc7bb650d52017)
Change-Id: I17cab8a6cc14cac5b64624431957bfcf04140809
2024-03-09 00:25:54 -07:00
eldritch horrors e1cd0077f3 move ParseData to own header, rename to ParserState
ParserState better describes what this struct really is. the parser
really does modify its state (most notably position and symbol tables),
so calling it that rather than obliquely "data" (which implies being
input only) makes sense.

(cherry picked from commit 007605616477f4f0d8a0064c375b1d3cf6188ac5)
Change-Id: I92feaec796530e1d4d0f7d4fba924229591cea95
2024-03-09 00:25:54 -07:00
eldritch horrors 60e3a05175 make parser utility functions members of ParseData
all of them need access to parser state in some way. make them members
to allow this without fussing so much.

(cherry picked from commit 1b09b80afac27c67157d4b315c237fa7bb9b8d08)
Change-Id: I3145c95666a5617b735eff7cb403c54c0fe86347
2024-03-09 00:25:54 -07:00
eldritch horrors ba16d99124 simplify parse error reporting
since nix doesn't use the bison `error` terminal anywhere any invocation
of yyerror will immediately cause a failure. since we're *already*
leaking tons of memory whatever little bit bison allocates internally
doesn't much matter any more, and we'll be replacing the parser soon anyway.

coincidentally this now also matches the error behavior of URIs when
they are disabled or ~/ paths in pure eval mode, duplicate attr
detection etc.

(cherry picked from commit e8d9de967fe47a7f9324b0022a2ef50df59f419d)
Change-Id: I560c50d11dceddc2d7cf9ed2c6c631a309ce574e
2024-03-09 00:25:54 -07:00
eldritch horrors 2cea973e29 remove ParserFormals
this is a proper subset of Formals anyway, so let's just use those and
avoid the extra allocations and moves.

(cherry picked from commit f07388bf985c2440413f398cf93d5f5840d1ec8c)
Change-Id: I4508c9c9c918cbaaed649dc753eb86f5cafc7ab6
2024-03-09 00:25:54 -07:00
eldritch horrors 609a8e0d94 Merge pull request #9754 from 9999years/print-value-when-coercion-fails
Print the value in `error: cannot coerce` messages

(cherry picked from commit 5b7bfd2d6b89d7dd5f54c1ca6c8072358d31a84e)

===

test taken from 6e8d5983143ae576e3f4b1d2954a5267f2943a49; it was added
previously (and not backported because its pr was a mostly-revert), but
it's useful to have around.

Change-Id: Icbd14b55e3610ce7b774667bf14b82e6dc717982
2024-03-09 00:05:41 -07:00
eldritch horrors 2f7c3fa251 Merge pull request #9818 from Ma27/print-value-on-function-call-type-error
libexpr: print value of what is attempted to be called as function
(cherry picked from commit 50e5d7b883042852538371237e32a66bb22f0485)
Change-Id: I7cb6290bd8f244e83bfce3b2eed2a4c8b4f16a83
2024-03-09 00:05:41 -07:00
eldritch horrors 87e6ac5eb7 Merge pull request #9753 from 9999years/print-value-on-type-error
Print the value in `value is X while a Y is expected` error

(cherry picked from commit 5f72a97092da6af28a7d2b2a50d74e9d34fae7e1)
Change-Id: Idb4bc903ae59a0f5b6fb3b1da4d47970fe0a6efe
2024-03-09 00:05:41 -07:00
eldritch horrors 896e525681 Disable bear on all the things with darwin as hostPlatform
Just `stdenv.isDarwin` isn't enough because it doesn't apply to the
build platform, which mean that cross packages building from darwin to
another platform will have `isDarwin` set to false.
Replace it by `stdenv.buildPlatform.isDarwin`.

(cherry picked from commit a0cb75d96f76a3be48b9319e26d8ad78ef4e4525)

(h/t jade for finding this one)
Change-Id: If3cb74e6feaa5d51de550d9a140c71683c2214cd
2024-03-09 00:03:50 -07:00
eldritch horrors 7e1f8b09a4 Merge pull request #9755 from 9999years/printer-followup
Printer followup

(cherry picked from commit 51f524c629b778b75cb62a9e0c85bae655984abc)
Change-Id: I29214cc86c5e846cbcfec382022293a70011b316
2024-03-09 04:04:46 +01:00
eldritch horrors 512c1f05c3 Unify and refactor value printing
Previously, there were two mostly-identical value printers -- one in
`libexpr/eval.cc` (which didn't force values) and one in
`libcmd/repl.cc` (which did force values and also printed ANSI color
codes).

This PR unifies both of these printers into `print.cc` and provides a
`PrintOptions` struct for controlling the output, which allows for
toggling whether values are forced, whether repeated values are tracked,
and whether ANSI color codes are displayed.

Additionally, `PrintOptions` allows tuning the maximum number of
attributes, list items, and bytes in a string that will be displayed;
this makes it ideal for contexts where printing too much output (e.g.
all of Nixpkgs) is distracting. (As requested by @roberth in
https://github.com/NixOS/nix/pull/9554#issuecomment-1845095735)

Please read the tests for example output.

Future work:
- It would be nice to provide this function as a builtin, perhaps
  `builtins.toStringDebug` -- a printing function that never fails would
  be useful when debugging Nix code.
- It would be nice to support customizing `PrintOptions` members on the
  command line, e.g. `--option to-string-max-attrs 1000`.

(cherry picked from commit 0fa08b451682fb3311fe58112ff05c4fe5bee3a4, )

===

Restore ambiguous value printer for `nix-instantiate`

The Nix team has requested that this output format remain unchanged.
I've added a warning to the man page explaining that `nix-instantiate
--eval` output will not parse correctly in many situations.

(cherry picked from commit df84dd4d8dd3fd6381ac2ca3064432ab31a16b79)

Change-Id: I7cca6b4b53cd0642f2d49af657d5676a8554c9f8
2024-03-09 03:50:06 +01:00
eldritch horrors 0e8f505f66 Unindent print.hh declarations
(cherry picked from commit c9125603a535f82cc9a53f47533f0a3d174e7008)
Change-Id: I137a272feee7eb42a017f373cbe4705b0e79b7c1
2024-03-08 18:54:10 -07:00
Puck Meerburg 80b79d0137 flake.nix: upgrade to nixos-23.11
This also bypasses the Objective-C fork safety during tests.

Change-Id: I92bf9f911e8a1fbd32eae13255f9a9dabde40b21
2024-03-08 23:59:01 +00:00
Puck Meerburg a3eba9d717 flake.nix: remove unused hydraJobs
This is in preparation for setting buildbot up to use hydraJobs instead
of checks.

Change-Id: Ie971e7db3940d9fbb7ed2f53d6429f607e00051f
2024-03-08 17:48:35 +00:00
jadeandGerrit Code Review eac76dbe90 Merge "Update version to 2.90.0" into main 2024-03-07 20:26:26 -07:00
Jade Lovelaceandeldritch horrors b5f7b1c83b Update version to 2.90.0
Change-Id: Idc844d86a7392790cd86dddd78a38dca036554d4
2024-03-07 19:57:39 -07:00
eldritch horrorsandGerrit Code Review d76125747f Merge changes I03bbff94,I778edad1,Iaa80073b,Ib1d58fe4 into main
* changes:
  Add release notes
  Print how many checks are run
  Print derivation paths
  Log what `nix flake check` does
2024-03-07 18:48:17 -07:00
eldritch horrorsandJade Lovelace bb7e7711b4 Add release notes
(cherry picked from commit 561a56cd13b4f12e3dfb6c5e3f42e5d8add04ecc)

===

Modified the release notes' synopsis to make it match its contents,
probably a copy-paste.
Co-authored-by: Raito Bezarius <raito@lix.systems>

Change-Id: I03bbff940b93e7df4b6c2fe9159c49a59ed47b55
2024-03-07 12:29:57 -08:00
eldritch horrors 232f4feace Merge pull request #9324 from 9999years/fix-8854-take-2
Don't attempt to `git add` ignored files

(cherry picked from commit 359990dfdc713c80aabd7ea6f7e4528628fbe108)

===

also added a regression test that isn't upstream to be sure we're
actually fixing the bug.

Change-Id: I8267a3d0ece9909d8008b7435b90e7b3eee366f6
2024-03-07 14:50:43 +01:00
eldritch horrors 852bc55c87 Merge pull request #9890 from obsidiansystems/remove-unneeded-toRealPath
Change an `allowPath` call to take a store path again

(cherry picked from commit 7c9ed1b1a325fe64a186e9d454607eaa0a7e8951)
Change-Id: Ia5ec924315a1f2640a0438cfb4b1ee0689cd3558
2024-03-07 13:04:25 +01:00
eldritch horrors 8a268359b0 Merge pull request #9560 from obsidiansystems/serve-proto-unkeyed-valid-path-info-serializer
Factor out `ServeProto::Serialiser<UnkeyedValidPathInfo>` and test

(cherry picked from commit 139982997eec493a0f74105c427953f6be77da6d)
Change-Id: I28e4ba5a681a90d81915a56e6dbaa5456d64f96d
2024-03-07 12:37:33 +01:00
eldritch horrors 9eb58f5209 Merge pull request #9032 from Ma27/structured-attrs-env-vars
structured attrs: improve support / usage of NIX_ATTRS_{SH,JSON}_FILE

(cherry picked from commit 3c042f3b0b0a7ef9c47bf049f5410dbd4aac9e90)
Change-Id: I7e41838338ee1edf31fff6f9e354c3db2bba6c0e
2024-03-07 10:46:47 +01:00
eldritch horrors ca03f7cc28 Merge pull request #9676 from DavHau/git-testsuite
initialize test suite for git fetchers

(cherry picked from commit 0bd9e10aea747df51c8a5af124864c722cbeafde)
Change-Id: Idf94a47794190c3e1de07fc4e7848741c4e9ffed
2024-03-07 10:25:03 +01:00
eldritch horrors b87f059ed4 Merge pull request #9631 from cole-h/fixup-check-warnings
Fix warnings when running checks

(cherry picked from commit 75e10e42f3c63fd9b9c8cf222b992ab77e497854)
Change-Id: Id955008fe045f23f72fae2a2cdf8f7ccddd1e6b9
2024-03-07 09:58:15 +01:00
eldritch horrors 689a5f22f1 Print how many checks are run
(cherry picked from commit d75a5f427a385e56c821fdf49a70a150fe7fe6fd)
Change-Id: I778edad1928adf90a69d0bbe8dd36623181b20d4
2024-03-07 01:22:25 -07:00
eldritch horrorsandjade f2c32738ad Print derivation paths
Also be more consistent with quotes around attribute paths

(cherry picked from commit 9404ce36e4edd1df12892089bdab1ceb7d4d7a97)
Change-Id: Iaa80073b4a07a6ffef106a3c12ecd02b4f6f67aa
2024-03-07 01:22:25 -07:00
eldritch horrors 2020998cfd Log what nix flake check does
There's still room for improvement, but this produces much more
informative output with `-v`:

```
$ nix flake check -v
evaluating flake...
checking flake output 'checks'...
checking derivation checks.aarch64-darwin.ghcid-ng-tests...
checking derivation checks.aarch64-darwin.ghcid-ng-clippy...
checking derivation checks.aarch64-darwin.ghcid-ng-doc...
checking derivation checks.aarch64-darwin.ghcid-ng-fmt...
checking derivation checks.aarch64-darwin.ghcid-ng-audit...
checking flake output 'packages'...
checking derivation packages.aarch64-darwin.ghcid-ng...
checking derivation packages.aarch64-darwin.ghcid-ng-tests...
checking derivation packages.aarch64-darwin.default...
checking flake output 'apps'...
checking flake output 'devShells'...
checking derivation devShells.aarch64-darwin.default...
running flake checks...
warning: The check omitted these incompatible systems: aarch64-linux, x86_64-darwin, x86_64-linux
Use '--all-systems' to check all.
```

(cherry picked from commit 49221493e243c4d10e69e7465a21be53902e16a8)
Change-Id: Ib1d58fe48cc82f4801a2ee5f91ba0d5a74907c0b
2024-03-07 01:22:25 -07:00
eldritch horrors bac3c5ad97 Merge pull request #9787 from obsidiansystems/bind-proc-syserror
`bind`: give same treatment as `connect` in #8544, dedup

(cherry picked from commit 28674247ec792a981741198abc190a71bb254b82)
Change-Id: I1ac5fc43fa10ec5f37a226730c3d84033fdbfd52
2024-03-07 00:43:51 -07:00
eldritch horrors 06e92450bd Merge pull request #8544 from edolstra/handle-missing-gc-socket
LocalStore: :addTempRoot(): Handle ENOENT
(cherry picked from commit 7115edc85af060ef235ac0270245ab46cc828f7c)
Change-Id: Ie6b1596049c3fde09b98f2f0727899f98e48e6b1
2024-03-07 00:43:51 -07:00
eldritch horrors b14f88e0d4 Merge pull request #9985 from alois31/symlink-resolution
Restore `builtins.pathExists` behavior on broken symlinks

(cherry picked from commit d53c8901ef7f2033855dd99063522e3d56a19dab)

===

note that this variant differs markedly from the source commit because
we haven't endured quite as much lazy trees.

Change-Id: I0facf282f21fe0db4134be5c65a8368c1b3a06fc
2024-03-07 00:43:51 -07:00
eldritch horrors 1342c8f18e Merge pull request #10074 from lf-/jade/ban-implicit-fallthrough
Warn on implicit switch case fallthrough

(cherry picked from commit 21282c3c204597641402c6bcff8fc9ee7bc31fa1)
Change-Id: I5ebbdfb6c037d2c55254f37dd391c07c2ce7443e
2024-03-07 00:11:12 -07:00
jadeandGerrit Code Review 0d9a043f43 Merge "fix: bounds check result in getMaxCPU" into main 2024-03-06 22:24:51 -07:00
Jade Lovelace 6122bed3af fix: bounds check result in getMaxCPU
Upstream-Bug: https://github.com/NixOS/nix/issues/9725
Upstream-PR: https://github.com/NixOS/nix/pull/10172
Change-Id: I2b8e8b15ee28951be98e5cbe3ccea5b9c8de5994
2024-03-06 21:00:33 -08:00
eldritch horrors f10e673272 tests/nixos/remote-builds*: Inline module + format
(cherry picked from commit 5167351efbee5c5a7390510eb720c31c6976f4d9)
Change-Id: I0caba23b589ed428d08895d7b8f0c22532bd259e
2024-03-06 21:32:47 -07:00
eldritch horrors 097acae35b tests/nixos: Test remote build against older versions
(cherry picked from commit e502d1cf945fb3cdd0ca1e1c16ec330ccab51c7b)
Change-Id: If6a1758b6457c5dae9305829c4d71d1905cfca22
2024-03-06 21:32:47 -07:00
eldritch horrors 65f1b15c95 Merge pull request #9934 from nmeum/absPath-out-of-bounds
absPath: Explicitly check if path is empty before accessing it
(cherry picked from commit 6ec08b85f607852eb6f976c1392c4917d0a53787)
Change-Id: Ieeb53fb65d0e334e6017ceb3a48b3b6ae1047843
2024-03-07 03:35:47 +01:00
eldritch horrors 25cae6d377 Merge pull request #9604 from obsidiansystems/test-substitute-on-destination
Test `nix copy --substitute-on-destination`

(cherry picked from commit ed93e51f4b0a8149521e3cf5b4f3ff4eabf5b060)
Change-Id: I33f8b591f42acf96fd18f27758dd1141b4bbbb5f
2024-03-07 03:34:00 +01:00
eldritch horrors 706f0df55b Merge pull request #9280 from R-VdP/rvdp/fix_remote_logging_phase_reporting
Include phase reporting in log file for ssh-ng builds

(cherry picked from commit b1e7d7cad625095656fff05ac4aedeb12135110a)
Change-Id: I4076669b0ba160412f7c628ca9113f9abbc8c303
2024-03-06 19:11:12 -07:00
Puck Meerburg 6f36a8834c Copy the output of fixed-output derivations before registering them
It is possible to exfiltrate a file descriptor out of the build sandbox
of FODs, and use it to modify the store path after it has been
registered. To avoid that issue, don't register the output of the build,
but a copy of it (that will be free of any leaked file descriptor).

Test that we can't leverage abstract unix domain sockets to leak file
descriptors out of the sandbox and modify the path after it has been
registered.

(cherry picked from commit 2dadfeb690e7f4b8f97298e29791d202fdba5ca6)
(tests cherry picked from commit c854ae5b3078ac5d99fa75fe148005044809e18c)

Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
Co-authored-by: Theophane Hufschmitt <theophane.hufschmitt@tweag.io>
Co-authored-by: Tom Bereknyei <tomberek@gmail.com>

Change-Id: I87cd58f1c0a4f7b7a610d354206b33301e47b1a4
2024-03-07 01:44:58 +00:00
eldritch horrors 89e99d94e4 Merge pull request #9634 from 9999years/combine-abstract-pos-and-pos
Combine `AbstractPos`, `PosAdapter`, and `Pos`

(cherry picked from commit 113499d16fc87d53b73fb62fe6242154909756ed)

===

this is a bit cursed because originally it was based on InputAccessor
code that we don't have and moved/patched features we likewise don't
have (fetchToStore caching, all the individual accessors,
ContentAddressMethod). the commit is adjusted accordingly to
match (remove caching, ignore accessors, use FileIngestionMethod).

note that `state.rootPath . CanonPath == abs` and
computeStorePathForPath works relative to cwd, so the slight rewrite in
the moved fetchToStore is legal.

Change-Id: I05fd340c273f0bcc8ffabfebdc4a88b98083bce5
2024-03-05 23:46:18 -07:00
eldritch horrors e9b5929b22 Merge pull request #9860 from 9999years/set-stack-darwin
Increase stack size on macOS as well as Linux

(cherry picked from commit efb91d5979a625d5c50558aeabfd24e802ed9173,
4a2444b3f32a2f5d42c4d65302793b987d1ac667)
Change-Id: Ieb72283c61bb9e360683f531d6635697b293c313
2024-03-05 23:36:42 -07:00
eldritch horrors a499383187 Merge pull request #10085 from ShamrockLee/ignore-obsolete-testdir
.gitignore: ignore historical test binaries

(cherry picked from commit cd2d8b6d4c3f8cec1a21a4d0a7d1ea626aa2a78e)
Change-Id: Ieb01910ab7722df78d8570ca6e408f1de5839fb8
2024-03-05 23:36:31 -07:00
eldritch horrors c67b392385 Merge pull request #9608 from NixOS/default-lowdown
Remove custom lowdown

(cherry picked from commit 790cf13c268c7197c276cc02efda4cfe64a3a688)
Change-Id: Ie01f9a69e81e793fc7ac869de943da370dc75e36
2024-03-05 23:36:11 -07:00
eldritch horrors bfe2facede Merge pull request #9443 from ivan770/reproducibility
doc: fix machine-specific capabilities leaking
(cherry picked from commit dda0e34ecf16bb1c736d585414122a7e3587db70)
Change-Id: I3d07cc5039ee954b215a7a27caa3bf7359d92c26
2024-03-05 23:35:22 -07:00
eldritch horrors e8f1acfb18 Merge pull request #5145 from fedepell/local_doc_build_5140
Docs build: depend on locally built nix executable and not installed one

(cherry picked from commit ca72e3e7e8f69526f028475a7a9b40812da1acdd)

===

includes changes from (because not doing so removes manpages):

Merge pull request #9976 from alois31/restore-manual-pages

Restore manual pages

(cherry picked from commit d3c1997127e0fc08576e842b2bfe046d8a28d2f4)

Change-Id: I685ff16163ac552a1754570c03c992c63a461d50
2024-03-05 23:01:05 +01:00
eldritch horrors 13d2f96257 Merge pull request #9541 from obsidiansystems/config-buildprefix-fix
Including `config.h` also needs `$(buildprefix)`

(cherry picked from commit 96fdea3394ff61e24c53358644a5064218218d13)
Change-Id: I8b5c0b1826aa007aa681c8b199f9b1489cac6784
2024-03-05 21:16:55 +01:00
eldritch horrors 2e1f5e2666 Merge pull request #9105 from Ericson2314/split-out-nixos-tests
Define NixOS tests in `tests/nixos/default.nix` rather than `flake.nix`

(cherry picked from commit c29b8ba142a0650d1182ca838ddc1b2d273dcd2a)
Change-Id: Ieae1b6476d95024485df7067e008013bc5542039
2024-03-05 21:11:59 +01:00
eldritch horrors 5bda6d9dc8 Merge pull request #9915 from 9999years/evaluating-attribute-position
Add position information to `while evaluating the attribute` errors in the debugger

(cherry picked from commit ffe67c86a8ef3695e5c8b9c9800c192ac633dded)
Change-Id: I177ea5ec60898abe09fb9d80d9602b2a32ff8f44
2024-03-04 09:25:17 +01:00
eldritch horrors 4551dd0f2c Merge pull request #10010 from 9999years/fix-9941
Fix "Failed tcsetattr(TCSADRAIN)" when `nix repl` is not a TTY

(cherry picked from commit 864fc85fc88ff092725ba99907611b2b8d2205fb)
Change-Id: I8198674b935fabd741a349cc74544e61c53ea7b3
2024-03-04 09:25:17 +01:00
eldritch horrors 41b7876b32 Merge pull request #10067 from ramboman/fix-proxy-nix
`nix`: Fix `haveInternet` to check for proxy

(cherry picked from commit accae60e7710a18f6f2bd7d2f4cd836bcd76b684)
Change-Id: I996dafdcd266f4bc5806386c86b19040120842bf
2024-03-04 09:25:17 +01:00
eldritch horrors 82075c8ebd Merge pull request #10054 from syvb/channel-unpack-count
Say how many channels were unpacked in nix-channel

(cherry picked from commit 9ae665b9e1dc64c507ab6002fc5d7824208f3777)
Change-Id: Ie0950cf32123b550c5b83981a020e513f72a9b7c
2024-03-04 09:25:17 +01:00
eldritch horrors 523250d18b Merge pull request #10055 from GrahamDennis/gdennis/faster-flake-lock-parsing
Faster flake.lock parsing

(cherry picked from commit ff4fa4dbd307fb155155421a7ec0625383dcedeb)
Change-Id: I34325834770db66fa56f0d8d02d3d2322dea3c65
2024-03-04 09:25:17 +01:00
eldritch horrors edb8e24ee0 Merge pull request #10001 from abathur/fix_macos_daemon_perms
install-darwin: fix symbolic perms for install cmd
(cherry picked from commit ee9f6d022f33663501503cf7d2b3d0cf605ac268)
Change-Id: I83240e1e93aa9a2ba34d5ac3abd8ef4f7ec54ac3
2024-03-04 09:25:17 +01:00
eldritch horrors 96a3683308 Ban building Nix with NDEBUG
When reviewing old PRs, I found that #9997 adds some code to ensure one
particular assert is always present. But, removing asserts isn't
something we do in our own release builds either in the flake here or in
nixpkgs, and is plainly a bad idea that increases support burden,
especially if other distros make bad choices of build flags in their Nix
packaging.

For context, the assert macro in the C standard is defined to do nothing
if NDEBUG is set.

There is no way in our build system to set -DNDEBUG without manually
adding it to CFLAGS, so this is simply a configuration we do not use.
Let's ban it at compile time.

I put this preprocessor directive in src/libutil.cc because it is not
obvious where else to put it, and it seems like the most logical file
since you are not getting a usable nix without it.

Upstream-PR: https://github.com/NixOS/nix/pull/10126
Original-Change-Id: I513cceaac1371decb3d96231e6ef9181c910c218
Change-Id: I531a51f6348a746e8e41d88203b08f614898356c
2024-03-04 09:24:58 +01:00
eldritch horrors c6064390e8 Merge pull request #9992 from edolstra/fix-warning
Fix "may be used uninitialized" warning

(cherry picked from commit c4ebb82da4eade975e874da600dc50e9dec610cb)
Change-Id: I0ce99bf102ad12902f7055c29a56e665b8320ca8
2024-03-04 08:59:58 +01:00
eldritch horrors bbf69a4898 Merge pull request #9974 from edolstra/less-chatty-post-build-hook
runPostBuildHook(): Be less chatty

(cherry picked from commit 28a988bdde7b20abff9000162015500c44a5812b)
Change-Id: Ibb49b71bf631d04d08970d719f091221b15c5036
2024-03-04 08:59:18 +01:00
eldritch horrors 647d762ab5 Merge pull request #9933 from pennae/debugger-fix
fix debugger crashing while printing envs

(cherry picked from commit 9b8b4860913afdb7f9cb1e1e81f9a9dd192cd1c1)
Change-Id: Ica6a17e4b3e3b8b8093719f442c28be7f13be09d
2024-03-04 08:57:44 +01:00
eldritch horrors 542a19104e Merge pull request #9918 from 9999years/debugger-locals-for-let-expressions
Expose locals from `let` expressions to the debugger

(cherry picked from commit acef4f17a2daab4ccdf656bdf229792db2f779e4)
Change-Id: Ib3623254f67ac762f4e7230d625e9f87dff38a84
2024-03-04 08:54:52 +01:00
eldritch horrors cd654451c9 Merge pull request #9924 from 9999years/rename-yellowtxt
Rename `yellowtxt` -> `magentatxt`

(cherry picked from commit fb78a99e04206e7b1df84a362bb87d3300b41855)
Change-Id: I9ade553d9f499e6713aeff3463c9a653a880a051
2024-03-04 08:53:10 +01:00
eldritch horrors 43cedec6c5 Merge pull request #9919 from 9999years/reduce-debugger-clutter
Reduce visual clutter in the debugger

(cherry picked from commit f388a6148dae0fc999f1a67d0b96d76788f9b97f)
Change-Id: I21bfe3e9f75816484b0f46dbe09e0ff40b22c6d9
2024-03-04 08:52:57 +01:00
eldritch horrors 9ef32cf3b8 Merge pull request #9930 from rvl/print-dev-env-unbound-variables
print-dev-env: Avoid using unbound shellHook variable
(cherry picked from commit 25385a408ef7281d966c8732608833e224b32586)
Change-Id: Id1aca13942adfa628f7bdcfc0b6fc03bb3bab9ea
2024-03-04 08:51:49 +01:00
eldritch horrors 625df32afc Merge pull request #9913 from 9999years/debugger-positions
Print positions in `--debugger`, instead of pointers

(cherry picked from commit 49cf090cb2f51d6935756a6cf94d568cab063f81)
Change-Id: Ic27917b2aab3657c28d599898377bf0c14753f8a
2024-03-04 08:51:02 +01:00
eldritch horrors 74272a9bc4 Merge pull request #9861 from 9999years/colored-diff-in-lang-tests
Color `diff` output in `tests/functional/lang` tests

(cherry picked from commit 1dc55c0f2f034bce6e3de4a5cda96d686b10a7f8)
Change-Id: Ie9b3fc3446bd3caa0fd8885de88639516a2ff862
2024-03-04 08:50:00 +01:00
eldritch horrors 78422bdbab Merge pull request #9848 from obsidiansystems/default-system-features-static
Make `StoreConfig::getDefaultSystemFeatures` a static method

(cherry picked from commit 5a9513cdbae31ea5e6f6e7afa7b3c2e3a9a26474)
Change-Id: Ia9c0ae2b7de419bd60aea8bf905154b96c428276
2024-03-04 08:47:55 +01:00
eldritch horrors 50ef364dbe Merge pull request #9844 from NixOS/pkg-config-gmock
Link both gmock and gtest, not just gtest

(cherry picked from commit 979b00bce9efa9560a58a10661865f4e896d0903)
Change-Id: Ic12d596e635057d67de277fbeb1602017e7623d0
2024-03-04 08:47:39 +01:00
eldritch horrors 2bb0a06346 Merge pull request #9841 from obsidiansystems/float-speed-factor
Convert `Machine::speedFactor` from a non-neg int to a non-neg float

(cherry picked from commit 69d0ae27e376e7c7c4f237716b0149223b8a805a)
Change-Id: I2afb5cf9e4fe1384985c58353946135c3d102b42
2024-03-04 08:40:38 +01:00
eldritch horrors 044c117a9f Merge pull request #9481 from iFreilicht/disallow-nix-search-without-search-terms
nix search: Disallow empty regex

(cherry picked from commit 1c260fa6d1f47d83954792771d0614db163cc3bc)
Change-Id: Iaaf3605c24a342fcb05d0b534a9f305533d3b5fa
2024-03-04 08:40:12 +01:00
eldritch horrors 20d7b93b0c Merge pull request #9838 from obsidiansystems/systemTypes-set
Make `Machine::systemTypes` a set not vector

(cherry picked from commit f1b030415376e81c5804647c055d71eaba4aa725)
Change-Id: I6d4f5c0bfc226e9bd66c58c360cd99e3fac9a129
2024-03-04 08:39:24 +01:00
eldritch horrors fad1a25e17 Merge pull request #9805 from yshui/prefetch-unpack
Add --unpack to nix store prefetch-file

(cherry picked from commit f51409cf98e9b18f27a6d0240a0aa0c3f37c2fd0)
Change-Id: I974b04f3efc8b210a9399a71d3704490cfc2c80c
2024-03-04 08:24:18 +01:00
eldritch horrors b6bb869e52 Merge pull request #9632 from cole-h/nix-daemon-testing
Use `nix daemon` in the test suite

(cherry picked from commit e6e160a0758c0354ed810b0ec9846ed885adcc11)
Change-Id: I537a25d3d48f609cd77b2c3a8ad68e87aebabfe8
2024-03-04 08:17:32 +01:00
eldritch horrors 298db5d1cd Merge pull request #9804 from edolstra/missing-nar-crash
Fix crash when NAR is missing from binary cache

(cherry picked from commit 3b20cca9625a1701a10a883735e7315185629563)
Change-Id: I50ff18f4a6de69c323473b4a8e3e098d1f365145
2024-03-04 08:16:28 +01:00
eldritch horrors 68f148ed45 Merge pull request #9798 from edolstra/remote-store-eof
Print a more helpful message if the daemon crashes

(cherry picked from commit 32706b14a7531c2c21b9f96da083a540a0031ec4)
Change-Id: Ief7c465bca7666e2b7e7c9d1dd0c01c5f9014146
2024-03-04 08:12:15 +01:00
eldritch horrors 5dd872363a Merge pull request #9797 from edolstra/fix-error-message
Store: :buildPaths(): Fix display of store paths
(cherry picked from commit b5ed36e6633cac844fe4388dcc0cc8055a18ef9e)
Change-Id: Ic6008491088dc6febd4a1e44dc2dbb96c47661f4
2024-03-04 08:11:46 +01:00
eldritch horrors e81ee8b337 Merge pull request #9785 from hercules-ci/test-substring-negative
tests/functional/lang: Test substring with negative length

(cherry picked from commit 86156d05dd33f856d8804f89669a7fe9b81f1a0d)
Change-Id: I2e2086027a43f8111ba5068ac16590eaa0b798d4
2024-03-04 08:07:16 +01:00
eldritch horrors 2c85fcce87 Merge pull request #9747 from awakesecurity/mz/fix-quadratic-splitString
Fix performance of builtins.substring for empty substrings

(cherry picked from commit b2deff1947c2fe57fdbf1a472eb9003eb407f8d3)
Change-Id: I4ddfc8d26a4781c9520fff9807849a073ee7bed8
2024-03-04 08:06:36 +01:00
eldritch horrors 64b077cdaa Merge pull request #9763 from L-as/avoid-unnecessary-copy
Avoid unnecessary copy of goal log

(cherry picked from commit 268c49264ae2657c602f84f9bff3eb31306253ea)
Change-Id: I5d9de9e43a7ddcb09d25bbc7367c9d83f58c7a75
2024-03-04 08:01:03 +01:00
eldritch horrors e310bbf913 Merge pull request #8043 from bobvanderlinden/pr-shell-env
nix: develop: use SHELL from rc script
(cherry picked from commit 0d55d660d5ea081630aa9606b047eb755cff1528)
Change-Id: I83be6c63b282d7f01a0defa78d9e787c77f1f02d
2024-03-04 07:59:32 +01:00
eldritch horrors 180984178d Merge pull request #9648 from cole-h/nix-shell-ordering
nix shell: reflect command line order in PATH order

(cherry picked from commit b91c935c2faf08ced2c763dcd2a831f26d84fa86)
Change-Id: If16c120bb74857c2817366e74e5b0877eb997260
2024-03-04 07:50:55 +01:00
eldritch horrors aaf1ed1a4c Merge pull request #9726 from DavHau/gitignore
gitignore: add result-*
(cherry picked from commit 47633ceec3b228490a7bcab06c679d9a3de9d9ff)
Change-Id: I4480d7dd8146600d1334c75b39ff3b3b2f9496eb
2024-03-04 07:50:42 +01:00
eldritch horrors 5f2eaa1b35 Merge pull request #9662 from shlevy/flat-fixed-references-assert
Improve error message for fixed-outputs with references.

(cherry picked from commit ff6de4a9ee6c3862db9ee5f09ff9c3f43ae7a088)
Change-Id: I733c49760b9a3f1b76a6bece3b250b8579cd6cac
2024-03-04 07:50:02 +01:00
eldritch horrors aac8416eac Merge pull request #9670 from DavHau/log-lines
saner default for log-lines: change to 25

(cherry picked from commit dedbbbb451bb8f2bd0925e59a8b3d127157015f8)
Change-Id: I8847df4aeb6e5c2d2be0e04f2a0a1aa595cb3b2f
2024-03-04 07:48:57 +01:00
eldritch horrors 4c56629a52 Merge pull request #9692 from 9999years/update-clang-stdenv
Remove `clang11Stdenv`

(cherry picked from commit cbf99c71c6f58579174c1c7649a5421c1d2ba9b0)
Change-Id: I716ce1a54f2006c4a9dc9716e8529fe7858ecebb
2024-03-04 07:48:42 +01:00
eldritch horrors 298be50d7d Merge pull request #9690 from obsidiansystems/nixos-23.05-small-again
flake: Go back to regular `nixos-23.05-small`
(cherry picked from commit 1ed245a60672c123c1348a63061fb4d64fb95212)
Change-Id: I33f5fe20cd6bc658a461f560e458b440b3b7e18e
2024-03-04 07:47:58 +01:00
eldritch horrors 8f5d0d4c05 Merge pull request #9687 from edolstra/withFramedSink-ctrl-c-hang
withFramedSink(): Receive interrupts on the stderr thread

(cherry picked from commit 965cfe96886c988c3aa94bfc7fefdd37325f4536)
Change-Id: I8320a96957c01ec0e3450d1b3ae38a3baff78d49
2024-03-04 07:40:17 +01:00
eldritch horrors 137673de56 Merge pull request #9681 from edolstra/eval-optimisations
Optimize empty list constants

(cherry picked from commit 315aade89d00c692715e5953c36a1b7d6528b703)
Change-Id: I0f28ef8a27ccedc45acf44243eec9dc35b733300
2024-03-04 07:39:12 +01:00
eldritch horrors 6b279cd10e Merge pull request #9658 from pennae/env-diet
reduce the size of Env by one pointer

(cherry picked from commit 83f5622545a2fc31eb7e7d5105f64ed6dd3058b3)
Change-Id: I5636290526d0165cfc61aee1e7a5b94db4a26cef
2024-03-04 07:37:45 +01:00
eldritch horrors cd326a2aa4 Merge pull request #9673 from pennae/drv-parse-opts
optimize derivation parsing

(cherry picked from commit 3511430902941f0f26dc71313a54bb5096f57305)
Change-Id: I00f76dcd464a5811944613731501af504b6e8c29
2024-03-04 07:36:51 +01:00
eldritch horrors 96f1a404d0 Merge pull request #9617 from 9999years/stack-overflow-segfault
Fix segfault on infinite recursion in some cases

(cherry picked from commit bf1b294bd81ca76c5ec9fe3ecd52196bf52a8300)
Change-Id: Id137541426ec8536567835953fccf986a3aebf16
2024-03-04 07:35:20 +01:00
eldritch horrors e1b1e6f7ab Merge pull request #9666 from unblevable/dervation-typo
Fix "dervation" typo

(cherry picked from commit a21c762dab365049b77af95355ee4236d173e216)
Change-Id: Ib6c0521758eb23115cfa243b9f3a34bb6e249e5f
2024-03-04 07:33:32 +01:00
eldritch horrors dd180911d8 Merge pull request #9582 from pennae/misc-opts
a packet of small optimizations

(cherry picked from commit ee439734e924eb337a869ff2e48aff8b989198bc)
Change-Id: I125d870710750a32a0dece48f39a3e9132b0d023
2024-03-04 07:32:31 +01:00
eldritch horrors 076844e386 Merge pull request #9621 from blaggacao/fix/too-restrictive-branch-regex-master
fix: valid branch name
(cherry picked from commit d2016c6b59f4a5223a18c92c817d61c448ce39ab)
Change-Id: Ic346739b91bf1b10515c9ff3b3e180a64afe6343
2024-03-04 07:27:52 +01:00
eldritch horrors 67de43b1d7 Merge pull request #9645 from tweag/undeprecate-isNull
Undeprecate isNull

(cherry picked from commit 8e64cd59b0fe1a4e1d3ba8d359ea0f9af2936f94)
Change-Id: If36b85a3fc01ee700bcaf4d5d83a5884a4b5de92
2024-03-04 07:27:37 +01:00
eldritch horrors 859da103ae Merge pull request #9637 from 9999years/fix-logging-test-on-macos
Fix `logging.sh` test on macOS

(cherry picked from commit 94a03a810e948f65776c3386d9a5234db551dc9e)
Change-Id: I65dde18ee53ccded31790e0cf1f836c3ad6dc492
2024-03-04 07:26:34 +01:00
eldritch horrors 1d6ae6f9ff Merge pull request #9639 from awakesecurity/mz/darwin-UID-override
installer: allow overriding of NIX_FIRST_BUILD_ID on darwin
(cherry picked from commit e85fd92816571ea00abafa3929298d0e091bcb9b)
Change-Id: Ifffc3fedd740079345c205f54c62c76053e24846
2024-03-04 07:26:19 +01:00
eldritch horrors 6622abb463 Merge pull request #9641 from amarshall/darwin-sandbox-stderr
Allow access to /dev/stderr in Darwin sandbox

(cherry picked from commit c6d7013583c568590aff285fb7414d1675a745f4)
Change-Id: I5657f6f4ee9dad8c978bad0d71f5cac51584e4f2
2024-03-04 07:26:03 +01:00
eldritch horrors 2ddf453e0d Merge pull request #9619 from 9999years/remove-blank-lines-in-errors
Remove some blank lines from stack traces

(cherry picked from commit cea83544362bd6426e9bc0b7dd0d611c19b0e3fd)
Change-Id: Ic1af8b09e9994d3c69fd3b37ae47a4bb786a15a1
2024-03-04 07:23:44 +01:00
eldritch horrors 7614aa9797 Merge pull request #4093 from matthewbauer/eval-system
Add eval-system option

(cherry picked from commit 071dbbee33af9f27338c3e53e4ea067dbfa14010)
Change-Id: Ia81358c8cfb60241da07a4d0e84b9ee62a18a53f
2024-03-04 07:21:01 +01:00
eldritch horrors 64a269ef73 Merge pull request #9600 from SharzyL/fix_nix_copy
fix: nix copy ssh-ng:// not respecting --substitute-on-destination
(cherry picked from commit b1c633c6bb2e2dbc8a2891edf0d0c6f9d31d890b)
Change-Id: I77356d14a9011d6dc4cf64776995f7590d918874
2024-03-04 07:16:31 +01:00
eldritch horrors 13f78c557b Merge pull request #9589 from obsidiansystems/floating-content-addressing-derivations-eval-store
Fix building CA derivations with and eval store

(cherry picked from commit dfc0cee7024a082d90a4f68296f55a82dfd52126)
Change-Id: I28feb5a36d4fe75f0ed3e3e2db6eb56b67d0f371
2024-03-04 07:15:08 +01:00
eldritch horrors bc34274aae Merge pull request #9588 from obsidiansystems/queryDerivationOutputMap-evalStore
Give `Store::queryDerivationOutputMap` and `evalStore` argument

(cherry picked from commit 8cddda4f892cb42be43e9bd87aa0111572617e78)
Change-Id: I394e7e11c3f2e0cd3dbe0f48d757c14c09835e44
2024-03-04 07:13:33 +01:00
eldritch horrors fa03f23923 Merge pull request #9587 from amjoseph-nixpkgs/pr/wopBuildDerivation/explain
libstore/daemon.cc: note trust model difference in readDerivation()s

(cherry picked from commit 5c917c32048ef185ea0eec352c3505485aa3212c)
Change-Id: I9945bc84e9529b005eafdc5c08b5bf1553335340
2024-03-04 07:13:00 +01:00
eldritch horrors 2e2f2579fa Merge pull request #9575 from hercules-ci/shell-on-hydra
flake.nix: Cache shell inputs through hydra

(cherry picked from commit b1842a4f05113967e8c20c9ebfd79edc39da259b)
Change-Id: I9e59b3c7dbf441e74cff3e4f24bbf65170ac505b
2024-03-04 07:12:28 +01:00
eldritch horrors 116e48fad3 Merge pull request #9573 from hercules-ci/rl-next-md-frontmatter
rl-next: Fix and support markdown frontmatter syntax
(cherry picked from commit 69b7876a0810269ad71807594cfd99b26cd8a5ff)
Change-Id: I8bfb8967af0943080fdd70d257c34abaf0a9fedf
2024-03-04 07:12:09 +01:00
eldritch horrors 2ba9788003 Merge pull request #9555 from 9999years/positions-in-errors
Pass positions when evaluating

(cherry picked from commit c8458bd731eb1c74159bebe459ea00165e056b65)
Change-Id: I1b4a5d58973be6264ffdb23b4492da200fdb71be
2024-03-04 07:11:25 +01:00
eldritch horrors d42cd24afe Merge pull request #9563 from obsidiansystems/tryResolve-evalStore
Give `Derivation::tryResolve` an `evalStore` argument

(cherry picked from commit 36ca6adc60511dc822870f2df43c0a578e481925)
Change-Id: If76b185a01ffa982e4c49cf333a9b5fbf9edebfe
2024-03-04 07:11:25 +01:00
eldritch horrors dd2926f7ea Merge pull request #9557 from bryanhonof/bryanhonof.fix-apple-double-shenanigans
Add option to libarchive so it behaves correctly

(cherry picked from commit c3827ff6348a4d5199eaddf8dbc2ca2e2ef46ec5)
Change-Id: Ib0f928851093f4c644bac071d1c8f8aeec803198
2024-03-04 07:11:25 +01:00
eldritch horrors bc32950ac5 Merge pull request #9518 from NixOS/fix-static-build
Update Nixpkgs to fix static build

(cherry picked from commit 9817788f6b25fefa731b838391f859e886ae0d24)
Change-Id: Ibe07a263f4d8f3b230775fb993881e5151a53784
2024-03-04 07:11:25 +01:00
eldritch horrors e9243c849a Merge pull request #9529 from wh0/patch-1
tests: avoid a chroot store without sandbox support
(cherry picked from commit 5910140f252280f6be429d1cb5e91e69999f5b43)
Change-Id: Ic2255261334012f36a465a96073f50669952dc26
2024-03-04 07:11:25 +01:00
eldritch horrors 94bf5a8018 Merge pull request #9494 from sellout/nix-run-execv
Don’t use `execvp` when we know the path

(cherry picked from commit dfa219d03b2277e61dde1c1ddddddff7411ef112)
Change-Id: I2226340cebbe935e1f2fe10207daba69683c8cb3
2024-03-04 07:11:25 +01:00
eldritch horrors 8505f963a1 Merge pull request #9972 from NixOS/allow-unoptimized-builds
Don't hardcode the `-O2` compiler flag

(cherry picked from commit 57ebcadb2f00e69c7548e72cbd63986c4c39bb78)
Change-Id: I49987181b2381627cb1c37b978b94c3163598af2
2024-03-04 07:11:25 +01:00
eldritch horrors 4018fcb9b8 Merge pull request #9233 from bouk/bouk/apply-config-inner
config: add included files into parsedContents before applying
(cherry picked from commit 82359eba6b692691ef08a71196ef25a61bc4d3d3)
Change-Id: Idde3177010fec7b8bafe6088c3c23d5caf491845
2024-03-04 07:11:25 +01:00
eldritch horrors a2d5e803cf Merge pull request #9476 from alois31/restore-progress-bar
nix repl: Only hide the progress bar while waiting for user input

(cherry picked from commit 3bebaefcd0c5d650f7edcd39f397bb45c4382f41)
Change-Id: Ie7c0db46f7c2cf5f938e66bdd3c31f0b62bdb104
2024-03-04 07:11:25 +01:00
eldritch horrors 001be52794 Merge pull request #9430 from hercules-ci/remove-vlas
Fix stack overflow in `filter`

(cherry picked from commit cb7f25869daa2491eeac5fee49ad8f31b2218c15)
Change-Id: Ib90f97a9805bbb4d0e2741551d490f054fc0a675
2024-03-04 07:11:25 +01:00
eldritch horrors a089d8f5f6 Merge pull request #9465 from obsidiansystems/build-dir
Use `buildprefix` in a few more places

(cherry picked from commit b6a3fde6b7a416929553e6be36fc991680ddf9ef)
Change-Id: I2790663fa9f8242ac2db6582b7e421d2fdf42942
2024-03-04 07:11:25 +01:00
eldritch horrors c208e918e5 fix: nlohmann::adl_serializer for std::optional (#9147)
This allows templates such as `NLOHMANN_DEFINE_TYPE_*` templates and other generators with things like `std::vector<std::optional<T>>`.

Co-authored-by: John Ericson <John.Ericson@Obsidian.Systems>
(cherry picked from commit 02bd821f2e71372d31bbe6700bd68086cc2ee70a)
Change-Id: I8b0ebcf2af4226610dadd565962f2d2327415a03
2024-03-04 07:11:25 +01:00
eldritch horrors b7c61d337b Merge pull request #9462 from trofi/eval.o-dependency
libexpr: add missing dependency on 'flake/call-flake.nix.gen.hh'
(cherry picked from commit f0180487a0e4c0091b46cb1469c44144f5400240)
Change-Id: I27211872ad75034ae3f04e18b2987f9968073d00
2024-03-04 07:11:25 +01:00
eldritch horrors e8a488236c Merge pull request #9393 from hercules-ci/changelog-d
Automatically compile hand-written release notes with `changelog-d`

(cherry picked from commit 928f0c13414d20c1af88b30bd6700fd730ee0bab)
Change-Id: Ia0685835c52edf185b64dd696b19305746c077e5
2024-03-04 07:11:19 +01:00
eldritch horrors d8a293d61d Merge pull request #9451 from kolloch/feature/git-ignore-ds-store
gitignore: Also ignore .DS_Store
(cherry picked from commit fdac6e38188affbf73b77d83751d2bf8d88d57d6)
Change-Id: Ib04be12427ab6a6edca5f78ccb377d40aab562fd
2024-03-04 06:04:07 +01:00
eldritch horrors cad1683048 Merge pull request #9398 from Qyriad/fixes/flake-not-found
flakes: bare minimum fix the error message for untracked flake.nix
(cherry picked from commit 7f626dba332f320fafb9f9c749986ea523d20f42)
Change-Id: I470ac56a670a8c11e4164c6b059184a02344d491
2024-03-04 06:03:33 +01:00
eldritch horrors cba87025f8 Merge pull request #9445 from NixOS/allow-input-in-git-commit
Allow user input in `git commit`

(cherry picked from commit 43fb39ca29a0b054a4c18623520c496d27c57192)
Change-Id: I13bd4c007234ee2133289c68ef8ab2eae4def78a
2024-03-04 06:01:09 +01:00
eldritch horrors 9981c714f6 Merge pull request #9425 from iFreilicht/fix-unbound-variable-errors
Fix "unbound variable" errors in bash

(cherry picked from commit 9ad9e988b83a9a9a9748034ac77e743b2cab20e6)
Change-Id: Ib7c8cb303f34104b9785c9376225f93174f3dae7
2024-03-04 05:59:32 +01:00
eldritch horrors 340a6cf977 Merge pull request #9257 from Artturin/nixenvjsondrvpath
`nix-env --query`: fix `--json` ignoring `--drv-path`

(cherry picked from commit 516e7ddc41f39ff939b5d5b5dc71e590f24890d4)
Change-Id: I84b5bccea9d0383e2e74544743b703942e7be547
2024-03-04 05:59:15 +01:00
eldritch horrors 01069d8c46 Merge pull request #9400 from hercules-ci/refactors-from-5e3986f59cb
Refactors from 5e3986f59c

(cherry picked from commit e540d48c4fb460e5e577d8b8b33e8eca9959c49b)
Change-Id: I5b21b770a0c20ec2ec9845d3a97a524f1b0135ee
2024-03-04 05:58:02 +01:00
eldritch horrors 439f88b7d7 Merge pull request #9399 from edolstra/revert-vlas
Revert use of boost::container::small_vector in the evaluator

(cherry picked from commit 6832d18ac734f4b855f97c07b158491dd01cefcd)
Change-Id: I7f10af0c8b8a8beb4b1e36424120995f4ed82738
2024-03-04 05:57:04 +01:00
eldritch horrors 3f3badffc9 Merge pull request #9395 from nbraud/buitlins
builtins.concatMap: Fix typo in error message

(cherry picked from commit 4292d997568eb30503e287f98e24821ff0bc2816)
Change-Id: Ia33d1b02e41f699ef0c8c2d6487c9f70b2cc8cf4
2024-03-04 05:56:04 +01:00
eldritch horrors 2df9c2c00f Merge pull request #9374 from hercules-ci/fix-nogc
Fix buildNoGc

(cherry picked from commit 7762335a9c4d56f7501825345728c3f94e88bc31)
Change-Id: I3ad53c9c1dd9180a2abc3528e9437c28ac95b303
2024-03-04 05:54:10 +01:00
eldritch horrors 5d77afe0a4 Merge pull request #6469 from gbpdt/fix/skipped_build_locking
Unlock output paths when a derivation is already built

(cherry picked from commit 7ba4e073e8622ca86b52e03d68476e80250ab62f)
Change-Id: I9de077679290d5141a610ac43d99d3a43acff87c
2024-03-04 05:53:17 +01:00
eldritch horrors 5e182235cb Merge pull request #7348 from thufschmitt/dont-use-vlas
Remove the usage of VLAs in the code

(cherry picked from commit ac4431e9d016e62fb5dc9ae36833bd0c6cdadeec)
Change-Id: Ifbf5fbfc2e27122362a2aaea4b62c7cf3ca46b1a
2024-03-04 05:51:23 +01:00
eldritch horrors 30f3298e9d Merge pull request #9364 from edolstra/fix-coverage
Fix a broken generated header file dependency

(cherry picked from commit 57de482e00221d781f916d49c315a8fa0816e956)
Change-Id: I0580274bf51132fbeb34e8c0a91a7017071d2bb3
2024-03-04 05:48:04 +01:00
eldritch horrors e3bf288180 Update scripts/nix-profile-daemon.fish.in
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
(cherry picked from commits 867f894289437a96630579592a46a4253151f079,
896013ec0c0d4633349ff0373bdae626667adc77,
150b5aba509d169a50c6ad62100c3ad7bf00242b,
1362a0a55aaddccef5a525e3b1179239d650bb07)

Change-Id: I0ba6a399d22cc5e927d9ef7046cc6f95856c1559
2024-03-04 05:46:35 +01:00
eldritch horrors 1b135e6e7b Fix boost::bad_format_string exception in builtins.addErrorContext (#9291)
* Fix boost::bad_format_string exception in builtins.addErrorContext

The message passed to addTrace was incorrectly being used as a format
string and this this would cause an exception when the string contained
a '%', which can be hit in places where arbitrary file paths are
interpolated.

* add test

(cherry picked from commit 61d6fe059e959455e156c1d57bb91155d363e983)
Change-Id: Idd671127a9c1ccc8b94e58e727632fcc064f3cbe
2024-03-04 05:39:12 +01:00
eldritch horrors 6cb215f63b Merge pull request #9293 from ThinkChaos/ssh-misc-improvments
SSH small improvments

(cherry picked from commit dcc49744ed0c3b91f905b0f3304d3ca700f9f717)
Change-Id: Ie87910df3ab739d0ff983c085190da1d108e96e2
2024-03-04 05:38:09 +01:00
eldritch horrors b7e7949035 Merge pull request #9299 from tfc/config-improvements
Improvements in src/libutil/config.*

(cherry picked from commit dea63bb81078d7290410544285c6df1a8e002952)
Change-Id: I8090eb2ad393dd9964cf2d5254ec8c796b1bd367
2024-03-04 05:36:42 +01:00
eldritch horrors 8ed486ebe6 Merge pull request #9225 from drupol/nixpkgs-pr-107251/make-gnutar-reproducible
fix: make sure `tar` reproducibility flags are set
(cherry picked from commit 28dddde0aca978114eaef00a14a2ab14b2459f4a)
Change-Id: I57c4d4374f5195099e6d763827b6d7d05785b3a8
2024-03-04 05:34:19 +01:00
eldritch horrors 6e0dd9f673 Merge pull request #9289 from edolstra/fix-warnings
Fix gcc warnings

(cherry picked from commit 66cb364f581486e0c426b35149ac13d19f7842bc)
Change-Id: I1474dbc18a4beaaf1bce16d4abbcc99806b79ff1
2024-03-04 05:27:35 +01:00
eldritch horrors 2633ca3f88 Merge pull request #9288 from edolstra/fix-nar-access-test
Fix nar-access test on macOS

(cherry picked from commit e9a857e4189241d23111e18e284ab7ac9d56b798)
Change-Id: I2fd2ec3e6ccb88350bdcd2ba15ccfd77275399c9
2024-03-04 05:27:18 +01:00
eldritch horrors 26e17eedef Merge pull request #9277 from keszybz/file-permissions
Remove stray executable permissions on source files

(cherry picked from commit a80fb9fa398cf39472be800b42020d2ff4a0df42)
Change-Id: I603b18ddda76041991101ef0597ec804c2b55dc0
2024-03-04 05:26:17 +01:00
eldritch horrors 6211e5e284 Merge pull request #9271 from keszybz/if-fix
fix: gcc complains about if which doesn't guard the indented statement
(cherry picked from commit 8d663462938a333a4e81cce1005437f141cd11fa)
Change-Id: Ifa2e65502de4000935549dde82ab1b5867e2f0ed
2024-03-04 05:26:02 +01:00
eldritch horrors 559a8c44c3 Merge pull request #6258 from obsidiansystems/gcc-bug-ergonomics
Remove bug-avoiding `StoreConfig *` casts for settings

(cherry picked from commit e3febfcd532adb23ca05ac465a2b907d6f1a3529)
Change-Id: Ifeae276582fdbc781a38581df9de3da67a7e7bf9
2024-03-04 05:24:33 +01:00
eldritch horrors 7ff1dca1fa Merge pull request #9247 from obsidiansystems/derivation-test-with-files
Turn derivation unit tests into unit characterization tests

(cherry picked from commit a6e587923c9d5d716fe0f0049bed96d1cc210bff)
Change-Id: Ia2a2e65aabfee8d5d52142b8fdaacbae4a27242c
2024-03-04 05:21:10 +01:00
eldritch horrors 4206441a12 Merge pull request #9246 from trofi/clarify-builder-uid-exhaustion
local-derivation-goal.cc: slightly clarify waiting message

(cherry picked from commit 232e23667226a3cfff9de1828f819844c27e7539)
Change-Id: Idd271d6921caba203db9971f27e156e533664935
2024-03-04 05:19:38 +01:00
eldritch horrors 89e03988ec Merge pull request #9238 from tfc/small-improvements2
Small improvements 2

(cherry picked from commit 1dc6a65d361456d0e082065eb189d9b67d93aacd)
Change-Id: I8ed573c496068c4a92f53c1caafa49da59d75967
2024-03-04 05:18:05 +01:00
eldritch horrors 622b0e9428 Merge pull request #8965 from Artturin/bindfilesinchroot
Bindmount files instead of hardlinking or copying to chroot

(cherry picked from commit 622191c2b53882a1675fed5066ff8090b4f01827)
Change-Id: I278ec1baacdfa9044992b58fdec8f14d6d7d09ce
2024-03-04 05:17:31 +01:00
eldritch horrors 8abb20390e Merge pull request #9229 from tfc/small-improvements
Remove warnings, small improvements

(cherry picked from commit 5ac87a75dd65c19c50976559a6f7810c315cd9d5)
Change-Id: I88349b6e954398dde83c845f42d41a9dd89ba9e0
2024-03-04 05:16:42 +01:00
eldritch horrors ea10088703 Merge pull request #9216 from obsidiansystems/addDrvOutputDependencies-pre
Add `builtins.addDrvOutputDependencies`

(cherry picked from commit a58d7f143ec995a45745c2176bfebcc3e011db58)
Change-Id: Ia5a1790bf29dfaf29287cc35cdae6b6d650e7a83
2024-03-04 05:06:56 +01:00
eldritch horrors 032eff7f69 Merge pull request #8470 from ncfavier/shebang-single-quotes
nix-shell: support single quotes in shebangs, fix whitespace parsing
(cherry picked from commit 3b99c6291377cbd22607896af9dfafa857d2f2dc)
Change-Id: I2a431b21c3467eefa1ef95d5a36d672f45b6937a
2024-03-04 05:06:32 +01:00
eldritch horrors 7f590ea709 Merge pull request #6223 from obsidiansystems/worker-proto-with-version
Give `nix daemon` and `nix-store --serve` protocols separate serializers with version info

(cherry picked from commit 8b68bbb77745fda0d14939b6c23d31cc89da41ce)
Change-Id: Ia3d3b9fbaf9f0ae62ab225020b7d14790e793655
2024-03-04 04:59:31 +01:00
eldritch horrors 4d9dde15ef Merge pull request #9191 from tfc/libutil-implementation
libutil: Small improvements
(cherry picked from commit edc07588ecd5053da57c2ab6c2543abf49730ce3)
Change-Id: I01a481d872d859b372a4bade9bebd3dab2fb4efb
2024-03-04 04:47:18 +01:00
Robert Hensingandeldritch horrors ab40b2c5d0 Merge pull request #9157 from obsidiansystems/protocol-versions
Add protocol versions to `{Worker,Serve}Proto::*Conn`

(cherry picked from commit 4d17c59d8d059a5b39f1d1da2b58f2ec8da44861)
Change-Id: I497af39deb792e50c157a1305d8c9e722798740b
2024-03-04 04:43:35 +01:00
eldritch horrors 5ddd1a9166 Merge pull request #9168 from obsidiansystems/fix-lang-tests-read-only
Fix language tests a bit

(cherry picked from commit e92cac789fc84b116a03db04a5f7de8df48e34cd)
Change-Id: I527e94c5af0921ff2559ce5a4ac7635be791c22e
2024-03-04 04:42:21 +01:00
eldritch horrors c0fa61340c Merge pull request #9172 from tfc/bad-moves
Fix/remove some bad std::moves

(cherry picked from commit 8c049a9f044569ebda70231709f6f15d3073894a)
Change-Id: I720273378d2506a13883acee28abd096d099b0d4
2024-03-04 04:41:52 +01:00
eldritch horrors 75fb953205 Merge pull request #9170 from tfc/fix-broken-move
Fix broken move

(cherry picked from commit aa4f41d796630004e90790bffe2239420f77f696)
Change-Id: I39d3f9f4f27328500de005c9205d905c55d6f9ea
2024-03-04 04:40:51 +01:00
eldritch horrors d28a6618a8 Merge pull request #9167 from obsidiansystems/pre-overhaul-completions
Improve tests and docs prior to refactoring completions

(cherry picked from commit 5442d9b47298389918d1f38d20f768a80ffc2369)
Change-Id: Ief99ac2cd9c92981a9a522d15b9c3daf99182c9d
2024-03-04 04:38:33 +01:00
eldritch horrors 7d8b34475a Merge pull request #9152 from obsidiansystems/split-out-perl-nix
Factor out Perl bindings Nix package

(cherry picked from commit d12c614ac75171421844f3706d89913c3d841460)
Change-Id: Ie75ccfec8cc815ea95ae9848cb03e33aa8cee5ae
2024-03-04 04:37:44 +01:00
eldritch horrors e12e9f2452 Merge pull request #9137 from obsidiansystems/serve-protocol
Introduce separate Serve protocol serialisers

(cherry picked from commit d070d8b7460f412a657745698dba291c66792402)
Change-Id: Ibcc8639e8997bcd07f7a5318330a147bcadc411b
2024-03-04 04:37:05 +01:00
eldritch horrors aeb803de9a Merge pull request #8047 from lovesegfault/always-allow-substitutes
feat: add always-allow-substitutes

(cherry picked from commit da2b59a08878b3c6c7074595e3b6d26b6928b4c1)
Change-Id: I50481cd8fe643c673c610fec28bad84519a4d650
2024-03-04 04:37:03 +01:00
eldritch horrors 6897e238bd Merge pull request #9099 from obsidiansystems/common-proto
Factor out bits of the worker protocol to use elsewhere

(cherry picked from commit 4b1a97338f517f45e6169d3d8845c5caa5724e97)
Change-Id: If93afa0f8b1cf9b0e705b34fa71e6fd708752758
2024-03-04 04:36:58 +01:00
eldritch horrors da0aa66d98 Merge pull request #9131 from obsidiansystems/delete-bootstrap-script
Get rid of `bootstrap.sh`

(cherry picked from commit aaef47a08eaf54a8856dd25c784fd85d8d7b0e22)
Change-Id: I1a74bed0c23d6fda06d5dfd8ecad443b9122da12
2024-03-04 04:36:52 +01:00
eldritch horrors 6feba52008 Merge pull request #8895 from hercules-ci/gc-before-stats
eval: Run a full GC before printing stats

(cherry picked from commit aeea49609be014b1928c95b7ec28dbedeb4f032a)
Change-Id: I47a23d3a7a47ea61d9a2b5727b638f879f3aaf1e
2024-03-04 04:36:47 +01:00
eldritch horrors fd1299cef3 Merge pull request #9106 from Ericson2314/positive-source-filtering
Use positive source filtering for the standalone functional tests job and Perl bindings

(cherry picked from commit 6b6bd9003062c86a49d4384381941cf57f269c45)
Change-Id: I896be67654f893d543ed6beb5d0d0d6c6d36e027
2024-03-04 04:36:42 +01:00
eldritch horrors 4517de00cb Merge pull request #8905 from hercules-ci/no-unknown-location
Don't print unknown locations unless requested for dev purposes

(cherry picked from commit 3dd4475826dff8052fef42d4600b61e6b91950ac)
Change-Id: I04a91277d1d9d09f5c1bf4a28fc99f0702b161e5
2024-03-04 04:36:38 +01:00
eldritch horrors c36ba796dd Merge pull request #9096 from NixOS/dont-rebuild-twice-on-ci
Don't run the tests that require building if we're not building

(cherry picked from commit 8cfa582f436db8066eff74cb084990367e014ce6)
Change-Id: I6085ca6107349669407340d7a5e52639a2febc90
2024-03-04 04:36:33 +01:00
eldritch horrors 7e966819b5 Merge pull request #9098 from obsidiansystems/test-proto
Enable most of the third `BuildResult` worker protocol test

(cherry picked from commit d344c112f772282bacacd4c66a75df4022d16e12)
Change-Id: I7b2b72aa84c19a6069f9c12128d901262db6f91c
2024-03-04 04:36:28 +01:00
eldritch horrors ea0008deea Merge pull request #9094 from obsidiansystems/test-proto
Test the rest of the worker protocol serializers

(cherry picked from commit 2f1c16dfa2378fd8616bff1b9b7cd0b4d42af69b)
Change-Id: Idfd72d32b21d14a260e02f65531d287cef7464d2
2024-03-04 04:36:23 +01:00
eldritch horrors 8867479b27 Merge pull request #9056 from aakropotkin/patch-1
Respect `NOCOLOR`

(cherry picked from commit 4b78a66bc5066fab46b4c84a5b85c3839e9d8aab)
Change-Id: I005a13dea6cb33133f7bc59926cbaf5cf51c561a
2024-03-04 04:36:19 +01:00
eldritch horrors f17e7b1855 Merge pull request #8923 from obsidiansystems/test-proto
Unit test some worker protocol serializers

(cherry picked from commit c6faef61a6f31c71146aee5d88168e861df9a22a)
Change-Id: I99e36f5f17eb7642211a4e42a16b143424f164b4
2024-03-04 04:36:14 +01:00
eldritch horrors 79dd9efe38 Merge pull request #9041 from trofi/profiles-sign
src/libstore/profiles.cc: fix comparison of sign difference

(cherry picked from commit 1da1642527f73089947b7bd2de46147a44700ac8)
Change-Id: I8f23d32ad66b797ff58eb2bd15b2f7741f47cd99
2024-03-04 04:36:10 +01:00
John Ericsonandeldritch horrors bc4aa3d5db Merge pull request #8887 from obsidiansystems/bsd-cross-ci
Support cross compiling to BSD and CI it

(cherry picked from commit 1f3fc08c5994ca69c84c9e745d59ec2bb2fd820a)
Change-Id: I415e92952afc661cfb5ef91a76c0637678a04a19
2024-03-04 04:36:04 +01:00
Eelco Dolstraandeldritch horrors 2442a40393 Merge pull request #9029 from inclyc/users/lyc/pass-value-2
libexpr: const rvalue reference -> value for nix::Expr nodes

(cherry picked from commit de99647b9c66219b2e7bc698a62377cc4f6148f6)
Change-Id: I96baf96b0a17e401548a926a7015f85e11d7c459
2024-03-04 04:35:59 +01:00
Théophane Hufschmittandeldritch horrors 68ba44c518 Merge pull request #8931 from fricklerhandwerk/nix3-config-options
do not show configuration override flags for each command

(cherry picked from commit f89b84919c1a5c796512c50311821e7779b3678b)
Change-Id: Ib98b739bd6c9a1e94f94a78a47d84d72e435e7c0
2024-03-04 04:35:54 +01:00
457 changed files with 14791 additions and 4536 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'NixOS'
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v4
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
sync-labels: false
+10
View File
@@ -21,12 +21,14 @@ perl/Makefile.config
/doc/manual/language.json
/doc/manual/xp-features.json
/doc/manual/src/SUMMARY.md
/doc/manual/src/SUMMARY-rl-next.md
/doc/manual/src/command-ref/new-cli
/doc/manual/src/command-ref/conf-file.md
/doc/manual/src/command-ref/experimental-features-shortlist.md
/doc/manual/src/contributing/experimental-feature-descriptions.md
/doc/manual/src/language/builtins.md
/doc/manual/src/language/builtin-constants.md
/doc/manual/src/release-notes/rl-next.md
# /scripts/
/scripts/nix-profile.sh
@@ -41,13 +43,16 @@ perl/Makefile.config
/src/libexpr/parser-tab.hh
/src/libexpr/parser-tab.output
/src/libexpr/nix.tbl
/src/libexpr/tests
/tests/unit/libexpr/libnixexpr-tests
# /src/libstore/
*.gen.*
/src/libstore/tests
/tests/unit/libstore/libnixstore-tests
# /src/libutil/
/src/libutil/tests
/tests/unit/libutil/libnixutil-tests
/src/nix/nix
@@ -90,6 +95,7 @@ perl/Makefile.config
/tests/functional/ca/config.nix
/tests/functional/dyn-drv/config.nix
/tests/functional/repl-result-out
/tests/functional/debugger-test-out
/tests/functional/test-libstoreconsumer/test-libstoreconsumer
# /tests/functional/lang/
@@ -137,8 +143,12 @@ compile_commands.json
nix-rust/target
result
result-*
.vscode/
# clangd and possibly more
.cache/
# Mac OS
.DS_Store
+1 -1
View File
@@ -1 +1 @@
2.18.1
2.90.0
+26 -8
View File
@@ -1,3 +1,9 @@
include mk/build-dir.mk
-include $(buildprefix)Makefile.config
clean-files += $(buildprefix)Makefile.config
ifeq ($(ENABLE_BUILD), yes)
makefiles = \
mk/precompiled-headers.mk \
local.mk \
@@ -15,17 +21,19 @@ makefiles = \
misc/zsh/local.mk \
misc/systemd/local.mk \
misc/launchd/local.mk \
misc/upstart/local.mk \
doc/manual/local.mk \
doc/internal-api/local.mk
misc/upstart/local.mk
endif
-include Makefile.config
ifeq ($(tests), yes)
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
makefiles += \
tests/unit/libutil/local.mk \
tests/unit/libutil-support/local.mk \
tests/unit/libstore/local.mk \
tests/unit/libstore/local.mk
endif
ifeq ($(ENABLE_TESTS), yes)
makefiles += \
tests/unit/libstore-support/local.mk \
tests/unit/libexpr/local.mk \
tests/unit/libexpr-support/local.mk \
@@ -39,6 +47,16 @@ makefiles += \
mk/disable-tests.mk
endif
# Some makefiles require access to built programs and must be included late.
makefiles-late =
ifeq ($(ENABLE_BUILD), yes)
makefiles-late += doc/manual/local.mk
makefiles-late += doc/internal-api/local.mk
endif
# Miscellaneous global Flags
OPTIMIZE = 1
ifeq ($(OPTIMIZE), 1)
@@ -50,4 +68,4 @@ endif
include mk/lib.mk
GLOBAL_CXXFLAGS += -g -Wall -include config.h -std=c++2a -I src
GLOBAL_CXXFLAGS += -g -Wall -Wimplicit-fallthrough -include $(buildprefix)config.h -std=c++2a -I src
+2 -1
View File
@@ -46,5 +46,6 @@ sandbox_shell = @sandbox_shell@
storedir = @storedir@
sysconfdir = @sysconfdir@
system = @system@
tests = @tests@
ENABLE_BUILD = @ENABLE_BUILD@
ENABLE_TESTS = @ENABLE_TESTS@
internal_api_docs = @internal_api_docs@
+8 -2
View File
@@ -59,12 +59,18 @@ index b5d71e62..aed7b0bf 100644
GC_bool found_me = FALSE;
size_t nthreads = 0;
int i;
@@ -851,6 +853,31 @@ GC_INNER void GC_push_all_stacks(void)
@@ -851,6 +853,37 @@ GC_INNER void GC_push_all_stacks(void)
hi = p->altstack + p->altstack_size;
/* FIXME: Need to scan the normal stack too, but how ? */
/* FIXME: Assume stack grows down */
+ } else {
+ if (pthread_getattr_np(p->id, &pattr)) {
+#ifdef HAVE_PTHREAD_ATTR_GET_NP
+ if (!pthread_attr_init(&pattr)
+ || !pthread_attr_get_np(p->id, &pattr))
+#else /* HAVE_PTHREAD_GETATTR_NP */
+ if (pthread_getattr_np(p->id, &pattr))
+#endif
+ {
+ ABORT("GC_push_all_stacks: pthread_getattr_np failed!");
+ }
+ if (pthread_attr_getstacksize(&pattr, &stack_limit)) {
+12
View File
@@ -0,0 +1,12 @@
diff --git a/include/gc_allocator.h b/include/gc_allocator.h
index 597c7f13..587286be 100644
--- a/include/gc_allocator.h
+++ b/include/gc_allocator.h
@@ -312,6 +312,7 @@ public:
template<>
class traceable_allocator<void> {
+public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
-4
View File
@@ -1,4 +0,0 @@
#! /bin/sh -e
rm -f aclocal.m4
mkdir -p config
exec autoreconf -vfi
+16 -4
View File
@@ -47,6 +47,10 @@ AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier ('cpu-os')])
# State should be stored in /nix/var, unless the user overrides it explicitly.
test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
# Assign a default value to C{,XX}FLAGS as the default configure script sets them
# to -O2 otherwise, which we don't want to have hardcoded
CFLAGS=${CFLAGS-""}
CXXFLAGS=${CXXFLAGS-""}
AC_PROG_CC
AC_PROG_CXX
@@ -68,6 +72,9 @@ case "$host_os" in
esac
ENSURE_NO_GCC_BUG_80431
# Check for pubsetbuf.
AC_MSG_CHECKING([for pubsetbuf])
AC_LANG_PUSH(C++)
@@ -152,12 +159,17 @@ if test "x$GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC" = xyes; then
LDFLAGS="-latomic $LDFLAGS"
fi
# Running the functional tests without building Nix is useful for testing
# different pre-built versions of Nix against each other.
AC_ARG_ENABLE(build, AS_HELP_STRING([--disable-build],[Do not build nix]),
ENABLE_BUILD=$enableval, ENABLE_BUILD=yes)
AC_SUBST(ENABLE_BUILD)
# Building without 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(tests, AS_HELP_STRING([--disable-tests],[Do not build the tests]),
tests=$enableval, tests=yes)
AC_SUBST(tests)
ENABLE_TESTS=$enableval, ENABLE_TESTS=yes)
AC_SUBST(ENABLE_TESTS)
# Building without API docs is the default as Nix' C++ interfaces are internal and unstable.
AC_ARG_ENABLE(internal_api_docs, AS_HELP_STRING([--enable-internal-api-docs],[Build API docs for Nix's internal unstable C++ interfaces]),
@@ -289,10 +301,10 @@ if test "$gc" = yes; then
fi
if test "$tests" = yes; then
if test "$ENABLE_TESTS" = yes; then
# Look for gtest.
PKG_CHECK_MODULES([GTEST], [gtest_main])
PKG_CHECK_MODULES([GTEST], [gtest_main gmock_main])
# Look for rapidcheck.
+30
View File
@@ -58,6 +58,23 @@ INPUT = \
src/nix-env \
src/nix-store
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
# in the source code. If set to NO, only conditional compilation will be
# performed. Macro expansion can be done in a controlled way by setting
# EXPAND_ONLY_PREDEF to YES.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# EXPAND_AS_DEFINED tags.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
@@ -65,3 +82,16 @@ INPUT = \
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH = @RAPIDCHECK_HEADERS@
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
# macro definition that is found in the sources will be used. Use the PREDEFINED
# tag if you want to use a different macro definition that overrules the
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED = \
DECLARE_COMMON_SERIALISER \
DECLARE_WORKER_SERIALISER \
DECLARE_SERVE_SERIALISER \
LENGTH_PREFIXED_PROTO_HELPER
+6 -1
View File
@@ -70,6 +70,7 @@ let
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
'';
# TODO: move this confusing special case out of here when implementing #8496
maybeStoreDocs = optionalString
(details ? doc)
(replaceStrings ["@stores@"] [storeDocs] details.doc);
@@ -78,6 +79,10 @@ let
# Options
${showOptions details.flags toplevel.flags}
> **Note**
>
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
'';
showOptions = options: commonOptions:
@@ -150,7 +155,7 @@ let
To use this store, you need to make sure the corresponding experimental feature,
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
is enabled.
For example, include the following in [`nix.conf`](#):
For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
```
extra-experimental-features = ${experimentalFeature}
+40 -17
View File
@@ -1,5 +1,10 @@
ifeq ($(doc_generate),yes)
# The version of Nix used to generate the doc. Can also be
# `$(nix_INSTALL_PATH)` or just `nix` (to grap ambient from the `PATH`),
# if one prefers.
doc_nix = $(nix_PATH)
MANUAL_SRCS := \
$(call rwildcard, $(d)/src, *.md) \
$(call rwildcard, $(d)/src, */*.md)
@@ -32,7 +37,7 @@ dummy-env = env -i \
NIX_STATE_DIR=/dummy \
NIX_CONFIG='cores = 0'
nix-eval = $(dummy-env) $(bindir)/nix eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
nix-eval = $(dummy-env) $(doc_nix) eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
# re-implement mdBook's include directive to make it usable for terminal output and for proper @docroot@ substitution
define process-includes
@@ -92,58 +97,76 @@ $(d)/nix-profiles.5: $(d)/src/command-ref/files/profiles.md
$(trace-gen) lowdown -sT man --nroff-nolinks -M section=5 $^.tmp -o $@
@rm $^.tmp
$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(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/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md
@cp $< $@
@$(call process-includes,$@,$@)
$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/utils.nix $(d)/generate-manpage.nix $(bindir)/nix
$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/utils.nix $(d)/generate-manpage.nix $(doc_nix)
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix true (builtins.readFile $<)'
@mv $@.tmp $@
$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(d)/src/command-ref/experimental-features-shortlist.md $(bindir)/nix
$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(d)/src/command-ref/experimental-features-shortlist.md $(doc_nix)
@cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings { inlineHTML = true; } (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp;
@mv $@.tmp $@
$(d)/nix.json: $(bindir)/nix
$(trace-gen) $(dummy-env) $(bindir)/nix __dump-cli > $@.tmp
$(d)/nix.json: $(doc_nix)
$(trace-gen) $(dummy-env) $(doc_nix) __dump-cli > $@.tmp
@mv $@.tmp $@
$(d)/conf-file.json: $(bindir)/nix
$(trace-gen) $(dummy-env) $(bindir)/nix show-config --json --experimental-features nix-command > $@.tmp
$(d)/conf-file.json: $(doc_nix)
$(trace-gen) $(dummy-env) $(doc_nix) show-config --json --experimental-features nix-command > $@.tmp
@mv $@.tmp $@
$(d)/src/contributing/experimental-feature-descriptions.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(bindir)/nix
$(d)/src/contributing/experimental-feature-descriptions.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(doc_nix)
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@
$(d)/src/command-ref/experimental-features-shortlist.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features-shortlist.nix $(bindir)/nix
$(d)/src/command-ref/experimental-features-shortlist.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features-shortlist.nix $(doc_nix)
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features-shortlist.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@
$(d)/xp-features.json: $(bindir)/nix
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(bindir)/nix __dump-xp-features > $@.tmp
$(d)/xp-features.json: $(doc_nix)
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(doc_nix) __dump-xp-features > $@.tmp
@mv $@.tmp $@
$(d)/src/language/builtins.md: $(d)/language.json $(d)/generate-builtins.nix $(d)/src/language/builtins-prefix.md $(bindir)/nix
$(d)/src/language/builtins.md: $(d)/language.json $(d)/generate-builtins.nix $(d)/src/language/builtins-prefix.md $(doc_nix)
@cat doc/manual/src/language/builtins-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtins.nix (builtins.fromJSON (builtins.readFile $<)).builtins' >> $@.tmp;
@cat doc/manual/src/language/builtins-suffix.md >> $@.tmp
@mv $@.tmp $@
$(d)/src/language/builtin-constants.md: $(d)/language.json $(d)/generate-builtin-constants.nix $(d)/src/language/builtin-constants-prefix.md $(bindir)/nix
$(d)/src/language/builtin-constants.md: $(d)/language.json $(d)/generate-builtin-constants.nix $(d)/src/language/builtin-constants-prefix.md $(doc_nix)
@cat doc/manual/src/language/builtin-constants-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtin-constants.nix (builtins.fromJSON (builtins.readFile $<)).constants' >> $@.tmp;
@cat doc/manual/src/language/builtin-constants-suffix.md >> $@.tmp
@mv $@.tmp $@
$(d)/language.json: $(bindir)/nix
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(bindir)/nix __dump-language > $@.tmp
$(d)/language.json: $(doc_nix)
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(doc_nix) __dump-language > $@.tmp
@mv $@.tmp $@
# Generate "Upcoming release" notes (or clear it and remove from menu)
$(d)/src/release-notes/rl-next.md: $(d)/rl-next $(d)/rl-next/*
@if type -p changelog-d > /dev/null; then \
echo " GEN " $@; \
changelog-d doc/manual/rl-next > $@; \
else \
echo " NULL " $@; \
true > $@; \
fi
$(d)/src/SUMMARY-rl-next.md: $(d)/src/release-notes/rl-next.md
$(trace-gen) true
@if [ -s $< ]; then \
echo ' - [Upcoming release](release-notes/rl-next.md)' > $@; \
else \
true > $@; \
fi
# Generate the HTML manual.
.PHONY: manual-html
manual-html: $(docdir)/manual/index.html
@@ -173,7 +196,7 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli
done
@touch $@
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(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/language/builtin-constants.md
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(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/language/builtin-constants.md $(d)/src/release-notes/rl-next.md
$(trace-gen) \
tmp="$$(mktemp -d)"; \
cp -r doc/manual "$$tmp"; \
@@ -0,0 +1,40 @@
---
synopsis: Concise error printing in `nix repl`
prs: 9928
---
Previously, if an element of a list or attribute set threw an error while
evaluating, `nix repl` would print the entire error (including source location
information) inline. This output was clumsy and difficult to parse:
```
nix-repl> { err = builtins.throw "uh oh!"; }
{ err = «error:
… while calling the 'throw' builtin
at «string»:1:9:
1| { err = builtins.throw "uh oh!"; }
| ^
error: uh oh!»; }
```
Now, only the error message is displayed, making the output much more readable.
```
nix-repl> { err = builtins.throw "uh oh!"; }
{ err = «error: uh oh!»; }
```
However, if the whole expression being evaluated throws an error, source
locations and (if applicable) a stack trace are printed, just like you'd expect:
```
nix-repl> builtins.throw "uh oh!"
error:
… while calling the 'throw' builtin
at «string»:1:1:
1| builtins.throw "uh oh!"
| ^
error: uh oh!
```
+2
View File
@@ -0,0 +1,2 @@
organization: NixOS
repository: nix
@@ -0,0 +1,9 @@
---
synopsis: "`--debugger` can now access bindings from `let` expressions"
prs: 9918
issues: 8827.
---
Breakpoints and errors in the bindings of a `let` expression can now access
those bindings in the debugger. Previously, only the body of `let` expressions
could access those bindings.
@@ -0,0 +1,6 @@
---
synopsis: Fix handling of truncated `.drv` files.
prs: 9673
---
Previously a `.drv` that was truncated in the middle of a string would case nix to enter an infinite loop, eventually exhausting all memory and crashing.
+8
View File
@@ -0,0 +1,8 @@
synopsis: Disallow empty search regex in `nix search`
prs: #9481
description: {
[`nix search`](@docroot@/command-ref/new-cli/nix3-search.md) now requires a search regex to be passed. To show all packages, use `^`.
}
@@ -0,0 +1,25 @@
---
synopsis: The `--debugger` will start more reliably in `let` expressions and function calls
prs: 9917
issues: 6649
---
Previously, if you attempted to evaluate this file with the debugger:
```nix
let
a = builtins.trace "before inner break" (
builtins.break "hello"
);
b = builtins.trace "before outer break" (
builtins.break a
);
in
b
```
Nix would correctly enter the debugger at `builtins.break a`, but if you asked
it to `:continue`, it would skip over the `builtins.break "hello"` expression
entirely.
Now, Nix will correctly enter the debugger at both breakpoints.
+7
View File
@@ -0,0 +1,7 @@
---
synopsis: Reduce eval memory usage and wall time
prs: 9658
---
Reduce the size of the `Env` struct used in the evaluator by a pointer, or 8 bytes on most modern machines.
This reduces memory usage during eval by around 2% and wall time by around 3%.
+12
View File
@@ -0,0 +1,12 @@
---
synopsis: Add new `eval-system` setting
prs: 4093
---
Add a new `eval-system` option.
Unlike `system`, it just overrides the value of `builtins.currentSystem`.
This is more useful than overriding `system`, because you can build these derivations on remote builders which can work on the given system.
In contrast, `system` also effects scheduling which will cause Nix to build those derivations locally even if that doesn't make sense.
`eval-system` only takes effect if it is non-empty.
If empty (the default) `system` is used as before, so there is no breakage.
@@ -0,0 +1,6 @@
---
synopsis: Fix `nix-env --query --drv-path --json`
prs: 9257
---
Fixed a bug where `nix-env --query` ignored `--drv-path` when `--json` was set.
@@ -0,0 +1,33 @@
---
synopsis: "`nix flake check` logs the checks"
issues: 8882
prs: 8893
---
`nix flake check` now logs the checks it runs and the derivations it evaluates:
```
$ nix flake check -v
evaluating flake...
checking flake output 'checks'...
checking derivation 'checks.aarch64-darwin.ghciwatch-tests'...
derivation evaluated to /nix/store/nh7dlvsrhds4cxl91mvgj4h5cbq6skmq-ghciwatch-test-0.3.0.drv
checking derivation 'checks.aarch64-darwin.ghciwatch-clippy'...
derivation evaluated to /nix/store/9cb5a6wmp6kf6hidqw9wphidvb8bshym-ghciwatch-clippy-0.3.0.drv
checking derivation 'checks.aarch64-darwin.ghciwatch-doc'...
derivation evaluated to /nix/store/8brdd3jbawfszpbs7vdpsrhy80as1il8-ghciwatch-doc-0.3.0.drv
checking derivation 'checks.aarch64-darwin.ghciwatch-fmt'...
derivation evaluated to /nix/store/wjhs0l1njl5pyji53xlmfjrlya0wmz8p-ghciwatch-fmt-0.3.0.drv
checking derivation 'checks.aarch64-darwin.ghciwatch-audit'...
derivation evaluated to /nix/store/z0mps8dyj2ds7c0fn0819y5h5611033z-ghciwatch-audit-0.3.0.drv
checking flake output 'packages'...
checking derivation 'packages.aarch64-darwin.default'...
derivation evaluated to /nix/store/41abbdyglw5x9vcsvd89xan3ydjf8d7r-ghciwatch-0.3.0.drv
checking flake output 'apps'...
checking flake output 'devShells'...
checking derivation 'devShells.aarch64-darwin.default'...
derivation evaluated to /nix/store/bc935gz7dylzmcpdb5cczr8gngv8pmdb-nix-shell.drv
running 5 flake checks...
warning: The check omitted these incompatible systems: aarch64-linux, x86_64-darwin, x86_64-linux
Use '--all-systems' to check all.
```
@@ -0,0 +1,24 @@
---
synopsis: Coercion errors include the failing value
issues: #561
prs: #9754
---
The `error: cannot coerce a <TYPE> to a string` message now includes the value
which caused the error.
Before:
```
error: cannot coerce a set to a string
```
After:
```
error: cannot coerce a set to a string: { aesSupport = «thunk»;
avx2Support = «thunk»; avx512Support = «thunk»; avxSupport = «thunk»;
canExecute = «thunk»; config = «thunk»; darwinArch = «thunk»; darwinMinVersion
= «thunk»; darwinMinVersionVariable = «thunk»; darwinPlatform = «thunk»; «84
attributes elided»}
```
@@ -0,0 +1,23 @@
---
synopsis: Type errors include the failing value
issues: #561
prs: #9753
---
In errors like `value is an integer while a list was expected`, the message now
includes the failing value.
Before:
```
error: value is a set while a string was expected
```
After:
```
error: expected a string but found a set: { ghc810 = «thunk»;
ghc8102Binary = «thunk»; ghc8107 = «thunk»; ghc8107Binary = «thunk»;
ghc865Binary = «thunk»; ghc90 = «thunk»; ghc902 = «thunk»; ghc92 = «thunk»;
ghc924Binary = «thunk»; ghc925 = «thunk»; «17 attributes elided»}
```
@@ -0,0 +1,37 @@
---
synopsis: "Visual clutter in `--debugger` is reduced"
prs: 9919
---
Before:
```
info: breakpoint reached
Starting REPL to allow you to inspect the current state of the evaluator.
Welcome to Nix 2.20.0pre20231222_dirty. Type :? for help.
nix-repl> :continue
error: uh oh
Starting REPL to allow you to inspect the current state of the evaluator.
Welcome to Nix 2.20.0pre20231222_dirty. Type :? for help.
nix-repl>
```
After:
```
info: breakpoint reached
Nix 2.20.0pre20231222_dirty debugger
Type :? for help.
nix-repl> :continue
error: uh oh
nix-repl>
```
@@ -0,0 +1,23 @@
---
synopsis: "In the debugger, `while evaluating the attribute` errors now include position information"
prs: 9915
---
Before:
```
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
```
@@ -0,0 +1,42 @@
---
synopsis: Source locations are printed more consistently in errors
issues: 561
prs: 9555
---
Source location information is now included in error messages more
consistently. Given this code:
```nix
let
attr = {foo = "bar";};
key = {};
in
attr.${key}
```
Previously, Nix would show this unhelpful message when attempting to evaluate
it:
```
error:
… while evaluating an attribute name
error: value is a set while a string was expected
```
Now, the error message displays where the problematic value was found:
```
error:
… while evaluating an attribute name
at bad.nix:4:11:
3| key = {};
4| in attr.${key}
| ^
5|
error: expected a string but found a set: { }
```
@@ -0,0 +1,32 @@
---
synopsis: Some stack overflow segfaults are fixed
issues: 9616
prs: 9617
---
The number of nested function calls has been restricted, to detect and report
infinite function call recursions. The default maximum call depth is 10,000 and
can be set with [the `max-call-depth`
option](@docroot@/command-ref/conf-file.md#conf-max-call-depth).
This fixes segfaults or the following unhelpful error message in many cases:
error: stack overflow (possible infinite recursion)
Before:
```
$ nix-instantiate --eval --expr '(x: x x) (x: x x)'
Segmentation fault: 11
```
After:
```
$ nix-instantiate --eval --expr '(x: x x) (x: x x)'
error: stack overflow
at «string»:1:14:
1| (x: x x) (x: x x)
| ^
```
@@ -0,0 +1,31 @@
---
synopsis: Better error reporting for `with` expressions
prs: 9658
---
`with` expressions using non-attrset values to resolve variables are now reported with proper positions.
Previously an incorrect `with` expression would report no position at all, making it hard to determine where the error originated:
```
nix-repl> with 1; a
error:
… <borked>
at «none»:0: (source not available)
error: value is an integer while a set was expected
```
Now position information is preserved and reported as with most other errors:
```
nix-repl> with 1; a
error:
… while evaluating the first subexpression of a with expression
at «string»:1:1:
1| with 1; a
| ^
error: expected a set but found an integer: 1
```
+1
View File
@@ -109,6 +109,7 @@
- [CLI guideline](contributing/cli-guideline.md)
- [C++ style guide](contributing/cxx.md)
- [Release Notes](release-notes/release-notes.md)
{{#include ./SUMMARY-rl-next.md}}
- [Release 2.18 (2023-09-20)](release-notes/rl-2.18.md)
- [Release 2.17 (2023-07-24)](release-notes/rl-2.17.md)
- [Release 2.16 (2023-05-31)](release-notes/rl-2.16.md)
+60 -26
View File
@@ -35,13 +35,51 @@ standard input.
- `--parse`\
Just parse the input files, and print their abstract syntax trees on
standard output in ATerm format.
standard output as a Nix expression.
- `--eval`\
Just parse and evaluate the input files, and print the resulting
values on standard output. No instantiation of store derivations
takes place.
> **Warning**
>
> This option produces output which can be parsed as a Nix expression which
> will produce a different result than the input expression when evaluated.
> For example, these two Nix expressions print the same result despite
> having different meaning:
>
> ```console
> $ nix-instantiate --eval --expr '{ a = {}; }'
> { a = <CODE>; }
> $ nix-instantiate --eval --expr '{ a = <CODE>; }'
> { a = <CODE>; }
> ```
>
> For human-readable output, `nix eval` (experimental) is more informative:
>
> ```console
> $ nix-instantiate --eval --expr 'a: a'
> <LAMBDA>
> $ nix eval --expr 'a: a'
> «lambda @ «string»:1:1»
> ```
>
> For machine-readable output, the `--xml` option produces unambiguous
> output:
>
> ```console
> $ nix-instantiate --eval --xml --expr '{ foo = <CODE>; }'
> <?xml version='1.0' encoding='utf-8'?>
> <expr>
> <attrs>
> <attr column="3" line="1" name="foo">
> <unevaluated />
> </attr>
> </attrs>
> </expr>
> ```
- `--find-file`\
Look up the given files in Nixs search path (as specified by the
`NIX_PATH` environment variable). If found, print the corresponding
@@ -61,11 +99,11 @@ standard input.
- `--json`\
When used with `--eval`, print the resulting value as an JSON
representation of the abstract syntax tree rather than as an ATerm.
representation of the abstract syntax tree rather than as a Nix expression.
- `--xml`\
When used with `--eval`, print the resulting value as an XML
representation of the abstract syntax tree rather than as an ATerm.
representation of the abstract syntax tree rather than as a Nix expression.
The schema is the same as that used by the [`toXML`
built-in](../language/builtins.md).
@@ -133,28 +171,24 @@ $ nix-instantiate --eval --xml --expr '1 + 2'
The difference between non-strict and strict evaluation:
```console
$ nix-instantiate --eval --xml --expr 'rec { x = "foo"; y = x; }'
...
<attr name="x">
<string value="foo" />
</attr>
<attr name="y">
<unevaluated />
</attr>
...
```
$ nix-instantiate --eval --xml --expr '{ x = {}; }'
<?xml version='1.0' encoding='utf-8'?>
<expr>
<attrs>
<attr column="3" line="1" name="x">
<unevaluated />
</attr>
</attrs>
</expr>
Note that `y` is left unevaluated (the XML representation doesnt
attempt to show non-normal forms).
```console
$ nix-instantiate --eval --xml --strict --expr 'rec { x = "foo"; y = x; }'
...
<attr name="x">
<string value="foo" />
</attr>
<attr name="y">
<string value="foo" />
</attr>
...
$ nix-instantiate --eval --xml --strict --expr '{ x = {}; }'
<?xml version='1.0' encoding='utf-8'?>
<expr>
<attrs>
<attr column="3" line="1" name="x">
<attrs>
</attrs>
</attr>
</attrs>
</expr>
```
+3 -3
View File
@@ -235,14 +235,14 @@ package like Terraform:
```bash
#! /usr/bin/env nix-shell
#! nix-shell -i bash --packages "terraform.withPlugins (plugins: [ plugins.openstack ])"
#! nix-shell -i bash --packages 'terraform.withPlugins (plugins: [ plugins.openstack ])'
terraform apply
```
> **Note**
>
> You must use double quotes (`"`) when passing a simple Nix expression
> You must use single or double quotes (`'`, `"`) when passing a simple Nix expression
> in a nix-shell shebang.
Finally, using the merging of multiple nix-shell shebangs the following
@@ -251,7 +251,7 @@ branch):
```haskell
#! /usr/bin/env nix-shell
#! nix-shell -i runghc --packages "haskellPackages.ghcWithPackages (ps: [ps.download-curl ps.tagsoup])"
#! nix-shell -i runghc --packages 'haskellPackages.ghcWithPackages (ps: [ps.download-curl ps.tagsoup])'
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-20.03.tar.gz
import Network.Curl.Download
+4
View File
@@ -203,3 +203,7 @@ Most Nix commands accept the following command-line options:
Fix corrupted or missing store paths by redownloading or rebuilding them.
Note that this is slow because it requires computing a cryptographic hash of the contents of every path in the closure of the build.
Also note the warning under `nix-store --repair-path`.
> **Note**
>
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
+67 -5
View File
@@ -31,7 +31,7 @@ This shell also adds `./outputs/bin/nix` to your `$PATH` so you can run `nix` im
To get a shell with one of the other [supported compilation environments](#compilation-environments):
```console
$ nix develop .#native-clang11StdenvPackages
$ nix develop .#native-clangStdenvPackages
```
> **Note**
@@ -42,8 +42,8 @@ $ nix develop .#native-clang11StdenvPackages
To build Nix itself in this shell:
```console
[nix-shell]$ ./bootstrap.sh
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ autoreconfPhase
[nix-shell]$ configurePhase
[nix-shell]$ make -j $NIX_BUILD_CORES
```
@@ -75,7 +75,7 @@ $ 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-clang11StdenvPackages
$ nix-shell --attr devShells.x86_64-linux.native-clangStdenvPackages
```
> **Note**
@@ -86,7 +86,7 @@ $ nix-shell --attr devShells.x86_64-linux.native-clang11StdenvPackages
To build Nix itself in this shell:
```console
[nix-shell]$ ./bootstrap.sh
[nix-shell]$ autoreconfPhase
[nix-shell]$ ./configure $configureFlags --prefix=$(pwd)/outputs/out
[nix-shell]$ make -j $NIX_BUILD_CORES
```
@@ -146,6 +146,31 @@ $ nix build .#packages.aarch64-linux.default
Cross-compiled builds are available for ARMv6 (`armv6l-linux`) and ARMv7 (`armv7l-linux`).
Add more [system types](#system-type) to `crossSystems` in `flake.nix` to bootstrap Nix on unsupported platforms.
### Building for multiple platforms at once
It is useful to perform multiple cross and native builds on the same source tree,
for example to ensure that better support for one platform doesn't break the build for another.
In order to facilitate this, Nix has some support for being built out of tree that is, placing build artefacts in a different directory than the source code:
1. Create a directory for the build, e.g.
```bash
mkdir build
```
2. Run the configure script from that directory, e.g.
```bash
cd build
../configure <configure flags>
```
3. Run make from the source directory, but with the build directory specified, e.g.
```bash
make builddir=build <make flags>
```
## System type
Nix uses a string with he following format to identify the *system type* or *platform* it runs on:
@@ -285,3 +310,40 @@ can build it yourself:
Metrics about the change in line/function coverage over time are also
[available](https://hydra.nixos.org/job/nix/master/coverage#tabs-charts).
## 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`.
Set `buildUnreleasedNotes = true;` in `flake.nix` to build the release notes on the fly.
+60 -4
View File
@@ -2,10 +2,48 @@
## Unit-tests
The unit-tests for each Nix library (`libexpr`, `libstore`, etc..) are defined
under `tests/unit/{library_name}/tests` using the
[googletest](https://google.github.io/googletest/) and
[rapidcheck](https://github.com/emil-e/rapidcheck) frameworks.
The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
[googletest]: https://google.github.io/googletest/
[rapidcheck]: https://github.com/emil-e/rapidcheck
### Source and header layout
> An example of some files, demonstrating much of what is described below
>
> ```
> src
> ├── libexpr
> │ ├── value/context.hh
> │ ├── value/context.cc
> │ │
> │ …
> └── tests
> │ ├── value/context.hh
> │ ├── value/context.cc
> │ │
> │ …
>
> ├── unit-test-data
> │ ├── libstore
> │ │ ├── worker-protocol/content-address.bin
> │ │ …
> │ …
>
> ```
The unit tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `src/${library_shortname}/tests` within the directory for the library (`src/${library_shortname}`).
The data is in `unit-test-data`, with one subdir per library, with the same name as where the code goes.
For example, `libnixstore` code is in `src/libstore`, and its test data is in `unit-test-data/libstore`.
The path to the `unit-test-data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`.
> **Note**
> Due to the way googletest works, downstream unit test executables will actually include and re-run upstream library tests.
> Therefore it is important that the same value for `_NIX_TEST_UNIT_DATA` be used with the tests for each library.
> That is why we have the test data nested within a single `unit-test-data` directory.
### Running tests
You can run the whole testsuite with `make check`, or the tests for a specific component with `make libfoo-tests_RUN`.
Finer-grained filtering is also possible using the [--gtest_filter](https://google.github.io/googletest/advanced.html#running-a-subset-of-the-tests) command-line option, or the `GTEST_FILTER` environment variable.
@@ -22,6 +60,24 @@ It is important that these testing libraries don't contain any actual tests them
On some platforms they would be run as part of every test executable that uses them, which is redundant.
On other platforms they wouldn't be run at all.
### Characterization testing
See [below](#characterization-testing-1) for a broader discussion of characterization testing.
Like with the functional characterization, `_NIX_TEST_ACCEPT=1` is also used.
For example:
```shell-session
$ _NIX_TEST_ACCEPT=1 make libstore-tests-exe_RUN
...
[ SKIPPED ] WorkerProtoTest.string_read
[ SKIPPED ] WorkerProtoTest.string_write
[ SKIPPED ] WorkerProtoTest.storePath_read
[ SKIPPED ] WorkerProtoTest.storePath_write
...
```
will regenerate the "golden master" expected result for the `libnixstore` characterization tests.
The characterization tests will mark themselves "skipped" since they regenerated the expected result instead of actually testing anything.
## Functional tests
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`.
@@ -3,7 +3,7 @@
After cloning Nix's Git repository, issue the following commands:
```console
$ ./bootstrap.sh
$ autoreconf -vfi
$ ./configure options...
$ make
$ make install
+13 -7
View File
@@ -261,6 +261,9 @@ Derivations can declare some infrequently used optional attributes.
useful for very trivial derivations (such as `writeText` in Nixpkgs)
that are cheaper to build than to substitute from a binary cache.
You may disable the effects of this attibute by enabling the
`always-allow-substitutes` configuration option in Nix.
> **Note**
>
> You need to have a builder configured which satisfies the
@@ -271,18 +274,21 @@ Derivations can declare some infrequently used optional attributes.
- [`__structuredAttrs`]{#adv-attr-structuredAttrs}\
If the special attribute `__structuredAttrs` is set to `true`, the other derivation
attributes are serialised in JSON format and made available to the
builder via the file `.attrs.json` in the builders temporary
directory. This obviates the need for [`passAsFile`](#adv-attr-passAsFile) since JSON files
have no size restrictions, unlike process environments.
attributes are serialised into a file in JSON format. The environment variable
`NIX_ATTRS_JSON_FILE` points to the exact location of that file both in a build
and a [`nix-shell`](../command-ref/nix-shell.md). This obviates the need for
[`passAsFile`](#adv-attr-passAsFile) since JSON files have no size restrictions,
unlike process environments.
It also makes it possible to tweak derivation settings in a structured way; see
[`outputChecks`](#adv-attr-outputChecks) for example.
As a convenience to Bash builders,
Nix writes a script named `.attrs.sh` to the builders directory
that initialises shell variables corresponding to all attributes
that are representable in Bash. This includes non-nested
Nix writes a script that initialises shell variables
corresponding to all attributes that are representable in Bash. The
environment variable `NIX_ATTRS_SH_FILE` points to the exact
location of the script, both in a build and a
[`nix-shell`](../command-ref/nix-shell.md). This includes non-nested
(associative) arrays. For example, the attribute `hardening.format = true`
ends up as the Bash associative array element `${hardening[format]}`.
+5
View File
@@ -123,6 +123,11 @@ The builder is executed as follows:
- `NIX_STORE` is set to the path of the top-level Nix store
directory (typically, `/nix/store`).
- `NIX_ATTRS_JSON_FILE` & `NIX_ATTRS_SH_FILE` if `__structuredAttrs`
is set to `true` for the dervation. A detailed explanation of this
behavior can be found in the
[section about structured attrs](./advanced-attributes.md#adv-attr-structuredAttrs).
- For each output declared in `outputs`, the corresponding
environment variable is set to point to the intended path in the
-1
View File
@@ -1 +0,0 @@
# Release X.Y (202?-??-??)
Generated
+4 -21
View File
@@ -16,34 +16,18 @@
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
"lastModified": 1633514407,
"narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
"owner": "kristapsdz",
"repo": "lowdown",
"rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
"type": "github"
},
"original": {
"owner": "kristapsdz",
"repo": "lowdown",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1700748986,
"narHash": "sha256-/nqLrNU297h3PCw4QyDpZKZEUHmialJdZW2ceYFobds=",
"lastModified": 1709884566,
"narHash": "sha256-NSYJg2sfdO/XS3L8XN/59Zhzn0dqWm7XtVnKI2mHq3w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9ba29e2346bc542e9909d1021e8fd7d4b3f64db0",
"rev": "2be119add7b37dc535da2dd4cba68e2cf8d1517e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05-small",
"ref": "nixos-23.11-small",
"repo": "nixpkgs",
"type": "github"
}
@@ -67,7 +51,6 @@
"root": {
"inputs": {
"flake-compat": "flake-compat",
"lowdown-src": "lowdown-src",
"nixpkgs": "nixpkgs",
"nixpkgs-regression": "nixpkgs-regression"
}
+158 -458
View File
@@ -1,18 +1,21 @@
{
description = "The purely functional package manager";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05-small";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11-small";
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
inputs.lowdown-src = { url = "github:kristapsdz/lowdown"; flake = false; };
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
outputs = { self, nixpkgs, nixpkgs-regression, lowdown-src, flake-compat }:
outputs = { self, nixpkgs, nixpkgs-regression, flake-compat }:
let
inherit (nixpkgs) lib;
inherit (lib) fileset;
officialRelease = true;
# Set to true to build the release notes for the next release.
buildUnreleasedNotes = false;
version = lib.fileContents ./.version + versionSuffix;
versionSuffix =
if officialRelease
@@ -25,9 +28,12 @@
darwinSystems = [ "x86_64-darwin" "aarch64-darwin" ];
systems = linuxSystems ++ darwinSystems;
crossSystems = [ "armv6l-linux" "armv7l-linux" ];
crossSystems = [
"armv6l-linux" "armv7l-linux"
"x86_64-freebsd13" "x86_64-netbsd"
];
stdenvs = [ "gccStdenv" "clangStdenv" "clang11Stdenv" "stdenv" "libcxxStdenv" "ccacheStdenv" ];
stdenvs = [ "gccStdenv" "clangStdenv" "stdenv" "libcxxStdenv" "ccacheStdenv" ];
forAllSystems = lib.genAttrs systems;
@@ -42,54 +48,23 @@
})
stdenvs);
# Experimental fileset library: https://github.com/NixOS/nixpkgs/pull/222981
# Not an "idiomatic" flake input because:
# - Propagation to dependent locks: https://github.com/NixOS/nix/issues/7730
# - Subflake would download redundant and huge parent flake
# - No git tree hash support: https://github.com/NixOS/nix/issues/6044
inherit (import (builtins.fetchTarball { url = "https://github.com/NixOS/nix/archive/1bdcd7fc8a6a40b2e805bad759b36e64e911036b.tar.gz"; sha256 = "sha256:14ljlpdsp4x7h1fkhbmc4bd3vsqnx8zdql4h3037wh09ad6a0893"; }))
fileset;
baseFiles =
# .gitignore has already been processed, so any changes in it are irrelevant
# at this point. It is not represented verbatim for test purposes because
# that would interfere with repo semantics.
fileset.fileFilter (f: f.name != ".gitignore") ./.;
nixSrc = fileset.toSource {
root = ./.;
fileset = fileset.intersect baseFiles (fileset.unions [
./.version
./boehmgc-coroutine-sp-fallback.diff
./bootstrap.sh
./configure.ac
./doc
./local.mk
./m4
./Makefile
./Makefile.config.in
./misc
./mk
./precompiled-headers.h
./src
./tests/functional
./tests/unit
./COPYING
./scripts/local.mk
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
# TODO: do we really need README.md? It doesn't seem used in the build.
./README.md
]);
};
# Memoize nixpkgs for different platforms for efficiency.
nixpkgsFor = forAllSystems
(system: let
make-pkgs = crossSystem: stdenv: import nixpkgs {
inherit system crossSystem;
localSystem = {
inherit system;
};
crossSystem = if crossSystem == null then null else {
system = crossSystem;
} // lib.optionalAttrs (crossSystem == "x86_64-freebsd13") {
useLLVM = true;
};
overlays = [
(overlayFor (p: p.${stdenv}))
];
config.permittedInsecurePackages = [ "nix-2.13.6" ];
};
stdenvs = forAllStdenvs (make-pkgs null);
native = stdenvs.stdenvPackages;
@@ -99,112 +74,6 @@
cross = forAllCrossSystems (crossSystem: make-pkgs crossSystem "stdenv");
});
commonDeps =
{ pkgs
, isStatic ? pkgs.stdenv.hostPlatform.isStatic
}:
with pkgs; rec {
# Use "busybox-sandbox-shell" if present,
# if not (legacy) fallback and hope it's sufficient.
sh = pkgs.busybox-sandbox-shell or (busybox.override {
useMusl = true;
enableStatic = true;
enableMinimal = true;
extraConfig = ''
CONFIG_FEATURE_FANCY_ECHO y
CONFIG_FEATURE_SH_MATH y
CONFIG_FEATURE_SH_MATH_64 y
CONFIG_ASH y
CONFIG_ASH_OPTIMIZE_FOR_SIZE y
CONFIG_ASH_ALIAS y
CONFIG_ASH_BASH_COMPAT y
CONFIG_ASH_CMDCMD y
CONFIG_ASH_ECHO y
CONFIG_ASH_GETOPTS y
CONFIG_ASH_INTERNAL_GLOB y
CONFIG_ASH_JOB_CONTROL y
CONFIG_ASH_PRINTF y
CONFIG_ASH_TEST y
'';
});
configureFlags =
lib.optionals stdenv.isLinux [
"--with-boost=${boost}/lib"
"--with-sandbox-shell=${sh}/bin/busybox"
]
++ lib.optionals (stdenv.isLinux && !(isStatic && stdenv.system == "aarch64-linux")) [
"LDFLAGS=-fuse-ld=gold"
];
testConfigureFlags = [
"RAPIDCHECK_HEADERS=${lib.getDev rapidcheck}/extras/gtest/include"
];
internalApiDocsConfigureFlags = [
"--enable-internal-api-docs"
];
nativeBuildDeps =
[
buildPackages.bison
buildPackages.flex
(lib.getBin buildPackages.lowdown-nix)
buildPackages.mdbook
buildPackages.mdbook-linkcheck
buildPackages.autoconf-archive
buildPackages.autoreconfHook
buildPackages.pkg-config
# Tests
buildPackages.git
buildPackages.mercurial # FIXME: remove? only needed for tests
buildPackages.jq # Also for custom mdBook preprocessor.
]
++ lib.optionals stdenv.hostPlatform.isLinux [(buildPackages.util-linuxMinimal or buildPackages.utillinuxMinimal)];
buildDeps =
[ curl
bzip2 xz brotli editline
openssl sqlite
libarchive
boost
lowdown-nix
]
++ lib.optionals stdenv.isLinux [libseccomp]
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid;
checkDeps = [
gtest
rapidcheck
];
internalApiDocsDeps = [
buildPackages.doxygen
];
awsDeps = lib.optional (stdenv.isLinux || stdenv.isDarwin)
(aws-sdk-cpp.override {
apis = ["s3" "transfer"];
customMemoryManagement = false;
});
propagatedDeps =
[ ((boehmgc.override {
enableLargeConfig = true;
}).overrideAttrs(o: {
patches = (o.patches or []) ++ [
./boehmgc-coroutine-sp-fallback.diff
];
})
)
nlohmann_json
];
};
installScriptFor = systems:
with nixpkgsFor.x86_64-linux.native;
runCommand "installer-script"
@@ -239,37 +108,40 @@
echo "file installer $out/install" >> $out/nix-support/hydra-build-products
'';
testNixVersions = pkgs: client: daemon: with commonDeps { inherit pkgs; }; with pkgs.lib; pkgs.stdenv.mkDerivation {
testNixVersions = pkgs: client: daemon: let
nix = pkgs.callPackage ./package.nix {
pname =
"nix-tests"
+ lib.optionalString
(lib.versionAtLeast daemon.version "2.4pre20211005" &&
lib.versionAtLeast client.version "2.4pre20211005")
"-${client.version}-against-${daemon.version}";
inherit fileset;
};
in nix.overrideAttrs (prevAttrs: {
NIX_DAEMON_PACKAGE = daemon;
NIX_CLIENT_PACKAGE = client;
name =
"nix-tests"
+ optionalString
(versionAtLeast daemon.version "2.4pre20211005" &&
versionAtLeast client.version "2.4pre20211005")
"-${client.version}-against-${daemon.version}";
inherit version;
src = nixSrc;
VERSION_SUFFIX = versionSuffix;
nativeBuildInputs = nativeBuildDeps;
buildInputs = buildDeps ++ awsDeps ++ checkDeps;
propagatedBuildInputs = propagatedDeps;
enableParallelBuilding = true;
configureFlags = testConfigureFlags; # otherwise configure fails
dontBuild = true;
doInstallCheck = true;
configureFlags = [
"RAPIDCHECK_HEADERS=${lib.getDev pkgs.rapidcheck}/extras/gtest/include"
"--disable-build"
];
installPhase = ''
mkdir -p $out
'';
installCheckPhase = "make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES";
};
installCheckPhase = (lib.optionalString pkgs.stdenv.hostPlatform.isDarwin ''
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
'') + ''
mkdir -p src/nix-channel
make installcheck -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
'';
});
binaryTarball = nix: pkgs:
let
@@ -346,165 +218,55 @@
'';
overlayFor = getStdenv: final: prev:
let currentStdenv = getStdenv final; in
{
nixStable = prev.nix;
# Forward from the previous stage as we dont want it to pick the lowdown override
nixUnstable = prev.nixUnstable;
nix =
with final;
with commonDeps {
inherit pkgs;
inherit (currentStdenv.hostPlatform) isStatic;
};
let
canRunInstalled = currentStdenv.buildPlatform.canExecute currentStdenv.hostPlatform;
in currentStdenv.mkDerivation (finalAttrs: {
name = "nix-${version}";
inherit version;
changelog-d = final.buildPackages.callPackage ./misc/changelog-d.nix { };
boehmgc-nix = (final.boehmgc.override {
enableLargeConfig = true;
}).overrideAttrs (o: {
patches = (o.patches or [ ]) ++ [
./boehmgc-coroutine-sp-fallback.diff
src = nixSrc;
VERSION_SUFFIX = versionSuffix;
outputs = [ "out" "dev" "doc" ];
nativeBuildInputs = nativeBuildDeps;
buildInputs = buildDeps
# There have been issues building these dependencies
++ lib.optionals (currentStdenv.hostPlatform == currentStdenv.buildPlatform) awsDeps
++ lib.optionals finalAttrs.doCheck checkDeps;
propagatedBuildInputs = propagatedDeps;
disallowedReferences = [ boost ];
preConfigure = lib.optionalString (! currentStdenv.hostPlatform.isStatic)
''
# Copy libboost_context so we don't get all of Boost in our closure.
# https://github.com/NixOS/nixpkgs/issues/45462
mkdir -p $out/lib
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
rm -f $out/lib/*.a
${lib.optionalString currentStdenv.hostPlatform.isLinux ''
chmod u+w $out/lib/*.so.*
patchelf --set-rpath $out/lib:${currentStdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
''}
${lib.optionalString currentStdenv.hostPlatform.isDarwin ''
for LIB in $out/lib/*.dylib; do
chmod u+w $LIB
install_name_tool -id $LIB $LIB
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
done
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
''}
'';
configureFlags = configureFlags ++
[ "--sysconfdir=/etc" ] ++
lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell" ++
[ (lib.enableFeature finalAttrs.doCheck "tests") ] ++
lib.optionals finalAttrs.doCheck testConfigureFlags ++
lib.optional (!canRunInstalled) "--disable-doc-gen";
enableParallelBuilding = true;
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
doCheck = true;
installFlags = "sysconfdir=$(out)/etc";
postInstall = ''
mkdir -p $doc/nix-support
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
${lib.optionalString currentStdenv.hostPlatform.isStatic ''
mkdir -p $out/nix-support
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
''}
${lib.optionalString currentStdenv.isDarwin ''
install_name_tool \
-change ${boost}/lib/libboost_context.dylib \
$out/lib/libboost_context.dylib \
$out/lib/libnixutil.dylib
''}
'';
doInstallCheck = finalAttrs.doCheck;
installCheckFlags = "sysconfdir=$(out)/etc";
installCheckTarget = "installcheck"; # work around buggy detection in stdenv
separateDebugInfo = !currentStdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
passthru.perl-bindings = with final; perl.pkgs.toPerlModule (currentStdenv.mkDerivation {
name = "nix-perl-${version}";
src = self;
nativeBuildInputs =
[ buildPackages.autoconf-archive
buildPackages.autoreconfHook
buildPackages.pkg-config
];
buildInputs =
[ nix
curl
bzip2
xz
pkgs.perl
boost
]
++ lib.optional (currentStdenv.isLinux || currentStdenv.isDarwin) libsodium
++ lib.optional currentStdenv.isDarwin darwin.apple_sdk.frameworks.Security;
configureFlags = [
"--with-dbi=${perlPackages.DBI}/${pkgs.perl.libPrefix}"
"--with-dbd-sqlite=${perlPackages.DBDSQLite}/${pkgs.perl.libPrefix}"
];
enableParallelBuilding = true;
postUnpack = "sourceRoot=$sourceRoot/perl";
});
meta.platforms = lib.platforms.unix;
# https://github.com/ivmai/bdwgc/pull/586
./boehmgc-traceable_allocator-public.diff
];
});
lowdown-nix = with final; currentStdenv.mkDerivation rec {
name = "lowdown-0.9.0";
default-busybox-sandbox-shell = final.busybox.override {
useMusl = true;
enableStatic = true;
enableMinimal = true;
extraConfig = ''
CONFIG_FEATURE_FANCY_ECHO y
CONFIG_FEATURE_SH_MATH y
CONFIG_FEATURE_SH_MATH_64 y
src = lowdown-src;
CONFIG_ASH y
CONFIG_ASH_OPTIMIZE_FOR_SIZE y
outputs = [ "out" "bin" "dev" ];
nativeBuildInputs = [ buildPackages.which ];
configurePhase = ''
${if (currentStdenv.isDarwin && currentStdenv.isAarch64) then "echo \"HAVE_SANDBOX_INIT=false\" > configure.local" else ""}
./configure \
PREFIX=${placeholder "dev"} \
BINDIR=${placeholder "bin"}/bin
CONFIG_ASH_ALIAS y
CONFIG_ASH_BASH_COMPAT y
CONFIG_ASH_CMDCMD y
CONFIG_ASH_ECHO y
CONFIG_ASH_GETOPTS y
CONFIG_ASH_INTERNAL_GLOB y
CONFIG_ASH_JOB_CONTROL y
CONFIG_ASH_PRINTF y
CONFIG_ASH_TEST y
'';
};
};
nixos-lib = import (nixpkgs + "/nixos/lib") { };
# https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests
runNixOSTestFor = system: test: nixos-lib.runTest {
imports = [ test ];
hostPkgs = nixpkgsFor.${system}.native;
defaults = {
nixpkgs.pkgs = nixpkgsFor.${system}.native;
nix = final.callPackage ./package.nix {
inherit (final) stdenv;
inherit versionSuffix fileset;
boehmgc = final.boehmgc-nix;
busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell;
};
};
_module.args.nixpkgs = nixpkgs;
};
in {
# A Nixpkgs overlay that overrides the 'nix' and
@@ -516,21 +278,6 @@
# Binary package for various platforms.
build = forAllSystems (system: self.packages.${system}.nix);
buildStatic = lib.genAttrs linux64BitSystems (system: self.packages.${system}.nix-static);
buildCross = forAllCrossSystems (crossSystem:
lib.genAttrs ["x86_64-linux"] (system: self.packages.${system}."nix-${crossSystem}"));
buildNoGc = forAllSystems (system: self.packages.${system}.nix.overrideAttrs (a: { configureFlags = (a.configureFlags or []) ++ ["--enable-gc=no"];}));
buildNoTests = forAllSystems (system:
self.packages.${system}.nix.overrideAttrs (a: {
doCheck =
assert ! a?dontCheck;
false;
})
);
# Perl bindings for various platforms.
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nix.perl-bindings);
@@ -539,126 +286,80 @@
# the installation script.
binaryTarball = forAllSystems (system: binaryTarball nixpkgsFor.${system}.native.nix nixpkgsFor.${system}.native);
binaryTarballCross = lib.genAttrs ["x86_64-linux"] (system:
forAllCrossSystems (crossSystem:
binaryTarball
self.packages.${system}."nix-${crossSystem}"
nixpkgsFor.${system}.cross.${crossSystem}));
# The first half of the installation script. This is uploaded
# to https://nixos.org/nix/install. It downloads the binary
# tarball for the user's system and calls the second half of the
# installation script.
installerScript = installScriptFor [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" "armv6l-linux" "armv7l-linux" ];
installerScriptForGHA = installScriptFor [ "x86_64-linux" "x86_64-darwin" "armv6l-linux" "armv7l-linux"];
# docker image with Nix inside
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
# Line coverage analysis.
coverage =
with nixpkgsFor.x86_64-linux.native;
with commonDeps { inherit pkgs; };
releaseTools.coverageAnalysis {
name = "nix-coverage-${version}";
src = nixSrc;
configureFlags = testConfigureFlags;
enableParallelBuilding = true;
nativeBuildInputs = nativeBuildDeps;
buildInputs = buildDeps ++ propagatedDeps ++ awsDeps ++ checkDeps;
dontInstall = false;
doInstallCheck = true;
installCheckTarget = "installcheck"; # work around buggy detection in stdenv
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = ["fortify"];
NIX_CFLAGS_COMPILE = "-DCOVERAGE=1";
};
# API docs for Nix's unstable internal C++ interfaces.
internal-api-docs =
with nixpkgsFor.x86_64-linux.native;
with commonDeps { inherit pkgs; };
internal-api-docs = let
nixpkgs = nixpkgsFor.x86_64-linux.native;
inherit (nixpkgs) pkgs;
stdenv.mkDerivation {
nix = pkgs.callPackage ./package.nix {
inherit versionSuffix fileset officialRelease buildUnreleasedNotes;
inherit (pkgs) changelog-d;
boehmgc = pkgs.boehmgc-nix;
busybox-sandbox-shell = pkgs.busybox-sandbox-shell;
};
in
nix.overrideAttrs (prev: {
pname = "nix-internal-api-docs";
inherit version;
src = nixSrc;
outputs = [ "out" ];
separateDebugInfo = false;
configureFlags = testConfigureFlags ++ internalApiDocsConfigureFlags;
nativeBuildInputs = prev.nativeBuildInputs ++ [ pkgs.doxygen ];
nativeBuildInputs = nativeBuildDeps;
buildInputs = buildDeps ++ propagatedDeps
++ awsDeps ++ checkDeps ++ internalApiDocsDeps;
# Depropagate the build inputs for the docs build.
propagatedBuildInputs = [ ];
buildInputs = prev.buildInputs ++ [ pkgs.buildPackages.doxygen ] ++ [
pkgs.gtest
pkgs.rapidcheck
] ++ prev.propagatedBuildInputs;
dontBuild = true;
configureFlags = prev.configureFlags ++ [
"--enable-internal-api-docs"
"RAPIDCHECK_HEADERS=${lib.getDev pkgs.rapidcheck}/extras/gtest/include"
];
installTargets = [ "internal-api-html" ];
# Convince the package.nix logic that we're building,
# but don't actually run the build phase.
env.dontBuild = true;
doCheck = false;
doInstallCheck = false;
postInstall = ''
mkdir -p $out/nix-support
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> $out/nix-support/hydra-build-products
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" > $out/nix-support/hydra-build-products
rm $out/lib -rf
'';
};
});
# System tests.
tests.authorization = runNixOSTestFor "x86_64-linux" ./tests/nixos/authorization.nix;
tests = import ./tests/nixos { inherit lib nixpkgs nixpkgsFor; } // {
tests.remoteBuilds = runNixOSTestFor "x86_64-linux" ./tests/nixos/remote-builds.nix;
# Make sure that nix-env still produces the exact same result
# on a particular version of Nixpkgs.
evalNixpkgs =
with nixpkgsFor.x86_64-linux.native;
runCommand "eval-nixos" { buildInputs = [ nix ]; }
''
type -p nix-env
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
[[ $(sha1sum < packages | cut -c1-40) = ff451c521e61e4fe72bdbe2d0ca5d1809affa733 ]]
mkdir $out
'';
tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
tests.nix-copy = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy.nix;
tests.nssPreload = runNixOSTestFor "x86_64-linux" ./tests/nixos/nss-preload.nix;
tests.githubFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/github-flakes.nix;
tests.sourcehutFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/sourcehut-flakes.nix;
tests.tarballFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/tarball-flakes.nix;
tests.containers = runNixOSTestFor "x86_64-linux" ./tests/nixos/containers/containers.nix;
tests.setuid = lib.genAttrs
["i686-linux" "x86_64-linux"]
(system: runNixOSTestFor system ./tests/nixos/setuid.nix);
# Make sure that nix-env still produces the exact same result
# on a particular version of Nixpkgs.
tests.evalNixpkgs =
with nixpkgsFor.x86_64-linux.native;
runCommand "eval-nixos" { buildInputs = [ nix ]; }
''
type -p nix-env
# Note: we're filtering out nixos-install-tools because https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1020530593.
time nix-env --store dummy:// -f ${nixpkgs-regression} -qaP --drv-path | sort | grep -v nixos-install-tools > packages
[[ $(sha1sum < packages | cut -c1-40) = ff451c521e61e4fe72bdbe2d0ca5d1809affa733 ]]
mkdir $out
'';
tests.nixpkgsLibTests =
forAllSystems (system:
import (nixpkgs + "/lib/tests/release.nix")
{ pkgs = nixpkgsFor.${system}.native;
nixVersions = [ self.packages.${system}.nix ];
}
);
metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" {
pkgs = nixpkgsFor.x86_64-linux.native;
nixpkgs = nixpkgs-regression;
nixpkgsLibTests =
forAllSystems (system:
import (nixpkgs + "/lib/tests/release.nix")
{ pkgs = nixpkgsFor.${system}.native;
nixVersions = [ self.packages.${system}.nix ];
}
);
};
installTests = forAllSystems (system:
@@ -674,12 +375,6 @@
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
# againstLatestStable = testNixVersions pkgs pkgs.nix pkgs.nixStable;
} "touch $out");
installerTests = import ./tests/installer {
binaryTarballs = self.hydraJobs.binaryTarball;
inherit nixpkgsFor;
};
};
checks = forAllSystems (system: {
@@ -687,6 +382,11 @@
perlBindings = self.hydraJobs.perlBindings.${system};
installTests = self.hydraJobs.installTests.${system};
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
rl-next =
let pkgs = nixpkgsFor.${system}.native;
in pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } ''
LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out
'';
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
dockerImage = self.hydraJobs.dockerImage.${system};
});
@@ -725,27 +425,27 @@
devShells = let
makeShell = pkgs: stdenv:
with commonDeps { inherit pkgs; };
stdenv.mkDerivation {
name = "nix";
let
nix = pkgs.callPackage ./package.nix {
inherit stdenv versionSuffix fileset;
boehmgc = pkgs.boehmgc-nix;
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or pkgs.default-busybox-sandbox;
};
in
nix.overrideAttrs (prev: {
nativeBuildInputs = prev.nativeBuildInputs
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
++ lib.optional
(stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform)
pkgs.buildPackages.clang-tools;
src = null;
outputs = [ "out" "dev" "doc" ];
doInstallCheck = false;
doCheck = false;
installFlags = "sysconfdir=$(out)/etc";
strictDeps = false;
nativeBuildInputs = nativeBuildDeps
++ (lib.optionals stdenv.cc.isClang [ pkgs.bear pkgs.clang-tools ]);
buildInputs = buildDeps ++ propagatedDeps
++ awsDeps ++ checkDeps ++ internalApiDocsDeps;
configureFlags = configureFlags
++ testConfigureFlags ++ internalApiDocsConfigureFlags;
enableParallelBuilding = true;
installFlags = "sysconfdir=$(out)/etc";
shellHook =
''
shellHook = ''
PATH=$prefix/bin:$PATH
unset PYTHONPATH
export MANPATH=$out/share/man:$MANPATH
@@ -753,7 +453,7 @@
# Make bash completion work.
XDG_DATA_DIRS+=:$out/share
'';
};
});
in
forAllSystems (system:
let
-2
View File
@@ -1,5 +1,3 @@
clean-files += Makefile.config
GLOBAL_CXXFLAGS += -Wno-deprecated-declarations -Werror=switch
# Allow switch-enum to be overridden for files that do not support it, usually because of dependency headers.
ERROR_SWITCH_ENUM = -Werror=switch-enum
+64
View File
@@ -0,0 +1,64 @@
# Ensure that this bug is not present in the C++ toolchain we are using.
#
# URL for bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431
#
# The test program is from that issue, with only a slight modification
# to set an exit status instead of printing strings.
AC_DEFUN([ENSURE_NO_GCC_BUG_80431],
[
AC_MSG_CHECKING([that GCC bug 80431 is fixed])
AC_LANG_PUSH(C++)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <cstdio>
static bool a = true;
static bool b = true;
struct Options { };
struct Option
{
Option(Options * options)
{
a = false;
}
~Option()
{
b = false;
}
};
struct MyOptions : Options { };
struct MyOptions2 : virtual MyOptions
{
Option foo{this};
};
]],
[[
{
MyOptions2 opts;
}
return (a << 1) | b;
]])],
[status_80431=0],
[status_80431=$?],
[
# Assume we're bug-free when cross-compiling
])
AC_LANG_POP(C++)
AS_CASE([$status_80431],
[0],[
AC_MSG_RESULT(yes)
],
[2],[
AC_MSG_RESULT(no)
AC_MSG_ERROR(Cannot build Nix with C++ compiler with this bug)
],
[
AC_MSG_RESULT(unexpected result $status_80431: not expected failure with bug, ignoring)
])
])
+179
View File
@@ -0,0 +1,179 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash ../shell.nix -I nixpkgs=channel:nixos-unstable-small
# ^^^^^^^
# Only used for bash. shell.nix goes to the flake.
# --- CONFIGURATION ---
# This does double duty for
# - including rl-next
# - marking where to insert new links (right after)
SUMMARY_MARKER_LINE='{{#include ./SUMMARY-rl-next.md}}'
# --- LIB ---
log() {
echo 1>&2 "release-notes:" "$@"
}
logcmd() {
local cmd="$1"
shift
logcmd2 "$cmd" "${*@Q}" "$cmd" "$@"
}
logcmd2() {
local fakecmd="$1"
local fakeargs="$2"
shift
shift
printf 1>&2 "release-notes: \033[34;1m$fakecmd\033[0m "
echo "$fakeargs" 1>&2
"$@"
}
die() {
# ANSI red
printf 1>&2 "release-notes: \033[31;1merror:\033[0m"
echo 1>&2 "" "$@"
exit 1
}
confirm() {
local answer
echo 1>&2 "$@" "[y/n]"
read -r answer
case "$answer" in
y|Y|yes|Yes|YES)
return 0
;;
n|N|no|No|NO)
return 1
;;
*)
echo 1>&2 "please answer y or n"
confirm "$@"
;;
esac
}
report_done() {
logcmd2 "git" "show" git -c pager.show=false show
printf 1>&2 "release-notes: \033[32;1mdone\033[0m\n"
}
# --- PARSE ARGS ---
if [[ $# -gt 0 ]]; then
die "Release notes takes no arguments, but make sure to set VERSION."
fi
# --- CHECKS ---
if [[ ! -e flake.nix ]] || [[ ! -e .git ]]; then
die "must run in repo root"
exit 1
fi
# repo must be clean
if ! git diff --quiet; then
die "repo is dirty, please commit or stash changes"
fi
if ! git diff --quiet --cached; then
die "repo has staged changes, please commit or stash them"
fi
if ! grep "$SUMMARY_MARKER_LINE" doc/manual/src/SUMMARY.md.in >/dev/null; then
# would have been nice to catch this early, but won't be worth the extra infra
die "SUMMARY.md.in is missing the marker line '$SUMMARY_MARKER_LINE', which would be used for inserting a new release notes page. Please fix the script."
fi
if [[ ! -n "${VERSION:-}" ]]; then
die "please set the VERSION environment variable before invoking this script"
exit 1
fi
# version_major_minor: MAJOR.MINOR
# version_full: MAJOR.MINOR.PATCH
# IS_PATCH: true if this is a patch release; append instead of create
if grep -E '^[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then
log 'is minor'
IS_PATCH=false
version_full="$VERSION.0"
version_major_minor="$VERSION"
elif grep -E '^[0-9]+\.[0-9]+\.0$' <<< "$VERSION" >/dev/null; then
log 'is minor (.0)'
IS_PATCH=false
version_full="$VERSION"
version_major_minor="$(echo "$VERSION" | sed -e 's/\.0$//')"
elif grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then
log 'is patch'
IS_PATCH=true
version_full="$VERSION"
version_major_minor="$(echo "$VERSION" | sed -e 's/\.[0-9]*$//')"
else
die "VERSION must be MAJOR.MINOR[.PATCH], where each is a number, e.g. 2.20 or 2.20.1 (VERSION was set to $VERSION)"
fi
unset VERSION
log "version_major_minor=$version_major_minor"
log "version_full=$version_full"
log "IS_PATCH=$IS_PATCH"
basename=rl-${version_major_minor}.md
file=doc/manual/src/release-notes/$basename
if ! $IS_PATCH; then
if [[ -e $file ]]; then
die "release notes file $file already exists. If you'd like to make a minor release, pass a patch version, e.g. 2.20.1"
fi
fi
# --- DEFAULTS ---
if [[ ! -n "${DATE:-}" ]]; then
DATE="$(date +%Y-%m-%d)"
log "DATE not set, using $DATE"
fi
case "$DATE" in
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])
;;
*)
die "DATE must be YYYY-MM-DD, e.g. 2021-12-31 (DATE was set to $DATE)"
;;
esac
# --- DO THE WORK ---
# menu
title="Release $version_major_minor ($DATE)"
# section on page
section_title="Release $version_full ($DATE)"
(
# TODO add minor number, and append?
echo "# $section_title"
echo
changelog-d doc/manual/rl-next | sed -e 's/ *$//'
) | tee -a $file
log "Wrote $file"
if ! $IS_PATCH; then
NEW_SUMMARY_LINE=" - [$title](release-notes/$basename)"
# find the marker line, insert new link after it
escaped_marker="$(echo "$SUMMARY_MARKER_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')"
escaped_line="$(echo "$NEW_SUMMARY_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')"
logcmd sed -i -e "/$escaped_marker/a $escaped_line" doc/manual/src/SUMMARY.md.in
fi
for f in doc/manual/rl-next/*.md; do
if [[ config != "$(basename $f)" ]]; then
logcmd git rm $f
fi
done
logcmd git add $file doc/manual/src/SUMMARY.md.in
logcmd git status
logcmd git commit -m "release notes: $version_full"
report_done
+42 -27
View File
@@ -24,34 +24,23 @@ release:
* In a checkout of the Nix repo, make sure you're on `master` and run
`git pull`.
* Move the contents of `doc/manual/src/release-notes/rl-next.md`
(except the first line) to
`doc/manual/src/release-notes/rl-$VERSION.md` (where `$VERSION` is
the contents of `.version` *without* the patch level, e.g. `2.12`
rather than `2.12.0`).
* Add a header to `doc/manual/src/release-notes/rl-$VERSION.md` like
```
# Release 2.12 (2022-12-06)
```
* Proof-read / edit / rearrange the release notes. Breaking changes
and highlights should go to the top.
* Add a link to the release notes to `doc/manual/src/SUMMARY.md.in`
(*not* `SUMMARY.md`), e.g.
```
- [Release 2.12 (2022-12-06)](release-notes/rl-2.12.md)
```
* Run
* Compile the release notes by running
```console
$ git checkout -b release-notes
$ git add doc/manual/src/release-notes/rl-$VERSION.md
$ git commit -a -m 'Release notes'
$ VERSION=X.YY ./maintainers/release-notes
```
where `X.YY` is *without* the patch level, e.g. `2.12` rather than ~~`2.12.0`~~.
A commit is created.
* Proof-read / edit / rearrange the release notes if needed. Breaking changes
and highlights should go to the top.
* Push.
```console
$ git push --set-upstream $REMOTE release-notes
```
@@ -67,15 +56,17 @@ release:
$ git checkout -b $VERSION-maintenance
```
* Mark the release as stable:
* Mark the release as official:
```console
$ git cherry-pick f673551e71942a52b6d7ae66af8b67140904a76a
$ sed -e 's/officialRelease = false;/officialRelease = true;/' -i flake.nix
```
This removes the link to `rl-next.md` from the manual and sets
`officialRelease = true` in `flake.nix`.
* Commit
* Push the release branch:
```console
@@ -159,6 +150,30 @@ release:
## Creating a point release
* Checkout.
```console
$ git checkout XX.YY-maintenance
```
* Determine the next patch version.
```console
$ export VERSION=XX.YY.ZZ
```
* Update release notes.
```console
$ ./maintainers/release-notes
```
* Push.
```console
$ git push
```
* Wait for the desired evaluation of the maintenance jobset to finish
building.
+222
View File
@@ -0,0 +1,222 @@
project('lix', 'cpp',
version : run_command('bash', '-c', 'echo -n $(cat ./.version)$VERSION_SUFFIX', check : true).stdout().strip(),
default_options : [
'cpp_std=c++20',
'warning_level=1',
'debug=true',
'optimization=3',
],
)
cxx = meson.get_compiler('cpp')
host_system = host_machine.cpu_family() + '-' + host_machine.system()
message('canonical Nix system name:', host_system)
all_sources = { }
all_deps = { }
deps = [ ]
configdata = { }
#
# Dependencies
#
boehm = dependency('bdw-gc', required : get_option('gc'))
if boehm.found()
deps += boehm
endif
configdata += {
'HAVE_BOEHMGC': boehm.found().to_int(),
}
boost = dependency('boost', required : true, modules : ['context', 'coroutine', 'container'])
deps += boost
cpuid = dependency('libcpuid', 'cpuid', required : get_option('cpuid'))
configdata += {
'HAVE_LIBCPUID': cpuid.found().to_int(),
}
deps += cpuid
seccomp = dependency('libseccomp', 'seccomp', required : get_option('seccomp-sandboxing'))
configdata += {
'HAVE_SECCOMP': seccomp.found().to_int(),
}
libarchive = dependency('libarchive', required : true)
deps += libarchive
brotli = [
dependency('libbrotlicommon', required : true),
dependency('libbrotlidec', required : true),
dependency('libbrotlienc', required : true),
]
deps += brotli
openssl = dependency('libcrypto', 'openssl', required : true)
deps += openssl
aws_sdk = dependency('aws-cpp-sdk-core', required : true)
if aws_sdk.found()
# The AWS pkg-config adds -std=c++11.
aws_sdk = aws_sdk.partial_dependency(
compile_args : false,
includes : true,
link_args : true,
links : true,
sources : true,
)
deps += aws_sdk
s = aws_sdk.version().split('.')
configdata += {
'AWS_VERSION_MAJOR': s[0].to_int(),
'AWS_VERSION_MINOR': s[1].to_int(),
'AWS_VERSION_PATCH': s[2].to_int(),
}
aws_sdk_transfer = dependency('aws-cpp-sdk-transfer', required : true).partial_dependency(
compile_args : false,
includes : true,
link_args : true,
links : true,
sources : true,
)
endif
aws_s3 = dependency('aws-cpp-sdk-s3', required : true)
if aws_s3.found()
# The AWS pkg-config adds -std=c++11.
aws_s3 = aws_s3.partial_dependency(
compile_args : false,
includes : true,
link_args : true,
links : true,
sources : true,
)
deps += aws_s3
endif
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19', required : true)
deps += sqlite
sodium = dependency('sodium', 'libsodium', required : true)
deps += sodium
curl = dependency('libcurl', 'curl', required : true)
deps += curl
editline = dependency('libeditline', 'editline', version : '>=1.14', required : true)
deps += editline
lowdown = dependency('lowdown', version : '>=0.9.0', required : true)
deps += lowdown
#
# Build-time tools
#
bash = find_program('bash')
lsof = find_program('lsof')
# This is how Nix does generated headers...
# FIXME(Qyriad): do we really need to use the shell for this?
gen_header = generator(
bash,
arguments : [
'-c',
'echo \'R"foo(\' | cat - @INPUT@ && echo \')foo"\'',
],
capture : true,
output : '@PLAINNAME@.gen.hh',
)
#
# Configuration
#
# FIXME(Qyriad): at least do this in the build directory
run_command('ln', '-s', 'bla', 'tmp_link', check : true)
can_link_symlink = run_command('ln', 'tmp_link', 'tmp_link2', check : false).returncode() == 0
run_command('rm', '-f', 'tmp_link', 'tmp_link2', check : true)
message('possible to create a link to a symlink:', can_link_symlink)
configdata += { 'CAN_LINK_SYMLINK': can_link_symlink.to_int() }
check_headers = [
# I can't use dictionaries here as they can only contain identifier-strings.
['aws/s3/S3Client.h', aws_s3]
]
foreach headerspec : check_headers
key = headerspec[0]
value = headerspec[1]
define_name = 'HAVE_' + key.underscorify().to_upper()
define_value = cxx.check_header(key, dependencies : value).to_int()
configdata += { define_name: define_value }
endforeach
check_funcs = [
'lchown',
'lutimes',
'pipe2',
'posix_fallocate',
'statvfs',
'strsignal',
'sysconf',
]
foreach funcspec : check_funcs
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
define_value = cxx.has_function(funcspec).to_int()
configdata += {
define_name: define_value,
}
endforeach
has_pubsetbuf = cxx.compiles('''
#include <iostream>
using namespace std;
static char buf[1024];
decltype(cerr.rdbuf()->pubsetbuf(buf, sizeof(buf))) _;
''')
message('have function "\x1b[1mstd::basic_streambuf::pubsetbuf\x1b[0m" :', has_pubsetbuf)
configdata += {
'HAVE_PUBSETBUF': has_pubsetbuf.to_int(),
}
configdata += {
'ENABLE_S3': aws_s3.found().to_int(),
}
configure_file(
configuration : {
'PACKAGE_NAME': '"' + meson.project_name() + '"',
'PACKAGE_VERSION': '"' + meson.project_version() + '"',
'PACKAGE_TARNAME': '"' + meson.project_name() + '"',
'PACKAGE_STRING': '"' + meson.project_name() + ' ' + meson.project_version() + '"',
'HAVE_STRUCT_DIRENT_D_TYPE': 1, # FIXME: actually check this for solaris
'SYSTEM': '"' + host_system + '"',
} + configdata,
output : 'config.h',
)
add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
# I would love to remove this.
'-include', 'config.h',
# TODO(Qyriad): would love to remove these
'-Wno-deprecated-declarations',
'-Wno-unused-parameter',
'-Wno-missing-field-initializers',
'-Wno-deprecated-copy',
'-pthread',
#'-fPIC',
language : 'cpp',
)
# FIXME(Qyriad): only if not Darwin, Solaris, or FreeBSD
# (...so only if Linux?)
add_project_link_arguments(
'-Wl,--no-copy-dt-needed-entries',
language : 'cpp',
)
subdir('src')
+24
View File
@@ -0,0 +1,24 @@
# vim: filetype=meson
option('gc', type : 'feature',
description : 'enable garbage collection in the Nix expression evaluator (requires Boehm GC)',
)
# TODO(Qyriad): is this feature maintained?
option('embedded-sandbox-shell', type : 'feature',
description : 'include the sandbox shell in the Nix bindary',
)
option('cpuid', type : 'feature',
description : 'determine microarchitecture levels with libcpuid (only relevant on x86_64)',
)
option('seccomp-sandboxing', type : 'feature',
description : 'build support for seccomp sandboxing (recommended unless your arch doesn\'t support libseccomp, only relevant on Linux)',
)
option('store-dir', type : 'string', value : '/nix/store',
description : 'path of the Nix store',
)
option('sandbox-shell', type : 'string',
description : 'path to a statically-linked shell to use as /bin/sh in sandboxes (usually busybox)',
)
+31
View File
@@ -0,0 +1,31 @@
{ mkDerivation, aeson, base, bytestring, cabal-install-parsers
, Cabal-syntax, containers, directory, filepath, frontmatter
, generic-lens-lite, lib, mtl, optparse-applicative, parsec, pretty
, regex-applicative, text, pkgs
}:
let rev = "f30f6969e9cd8b56242309639d58acea21c99d06";
in
mkDerivation {
pname = "changelog-d";
version = "0.1";
src = pkgs.fetchurl {
name = "changelog-d-${rev}.tar.gz";
url = "https://codeberg.org/roberth/changelog-d/archive/${rev}.tar.gz";
hash = "sha256-8a2+i5u7YoszAgd5OIEW0eYUcP8yfhtoOIhLJkylYJ4=";
} // { inherit rev; };
isLibrary = false;
isExecutable = true;
libraryHaskellDepends = [
aeson base bytestring cabal-install-parsers Cabal-syntax containers
directory filepath frontmatter generic-lens-lite mtl parsec pretty
regex-applicative text
];
executableHaskellDepends = [
base bytestring Cabal-syntax directory filepath
optparse-applicative
];
doHaddock = false;
description = "Concatenate changelog entries into a single one";
license = lib.licenses.gpl3Plus;
mainProgram = "changelog-d";
}
+31
View File
@@ -0,0 +1,31 @@
# Taken temporarily from <nixpkgs/pkgs/by-name/ch/changelog-d/package.nix>
{
callPackage,
lib,
haskell,
haskellPackages,
}:
let
hsPkg = haskellPackages.callPackage ./changelog-d.cabal.nix { };
addCompletions = haskellPackages.generateOptparseApplicativeCompletions ["changelog-d"];
haskellModifications =
lib.flip lib.pipe [
addCompletions
haskell.lib.justStaticExecutables
];
mkDerivationOverrides = finalAttrs: oldAttrs: {
version = oldAttrs.version + "-git-${lib.strings.substring 0 7 oldAttrs.src.rev}";
meta = oldAttrs.meta // {
homepage = "https://codeberg.org/roberth/changelog-d";
maintainers = [ lib.maintainers.roberth ];
};
};
in
(haskellModifications hsPkg).overrideAttrs mkDerivationOverrides
+10
View File
@@ -0,0 +1,10 @@
# Initialise support for build directories.
builddir ?=
ifdef builddir
buildprefix = $(builddir)/
buildprefixrel = $(builddir)
else
buildprefix =
buildprefixrel = .
endif
+11
View File
@@ -0,0 +1,11 @@
# Default installation paths.
prefix ?= /usr/local
libdir ?= $(prefix)/lib
bindir ?= $(prefix)/bin
libexecdir ?= $(prefix)/libexec
datadir ?= $(prefix)/share
localstatedir ?= $(prefix)/var
sysconfdir ?= $(prefix)/etc
mandir ?= $(prefix)/share/man
DESTDIR ?=
+7 -22
View File
@@ -43,27 +43,6 @@ define newline
endef
# Default installation paths.
prefix ?= /usr/local
libdir ?= $(prefix)/lib
bindir ?= $(prefix)/bin
libexecdir ?= $(prefix)/libexec
datadir ?= $(prefix)/share
localstatedir ?= $(prefix)/var
sysconfdir ?= $(prefix)/etc
mandir ?= $(prefix)/share/man
# Initialise support for build directories.
builddir ?=
ifdef builddir
buildprefix = $(builddir)/
else
buildprefix =
endif
# Pass -fPIC if we're building dynamic libraries.
BUILD_SHARED_LIBS ?= 1
@@ -94,6 +73,8 @@ ifeq ($(BUILD_DEBUG), 1)
endif
include mk/build-dir.mk
include mk/install-dirs.mk
include mk/functions.mk
include mk/tracing.mk
include mk/clean.mk
@@ -112,7 +93,7 @@ define include-sub-makefile
include $(1)
endef
$(foreach mf, $(makefiles), $(eval $(call include-sub-makefile, $(mf))))
$(foreach mf, $(makefiles), $(eval $(call include-sub-makefile,$(mf))))
# Instantiate stuff.
@@ -132,6 +113,10 @@ $(foreach test-group, $(install-tests-groups), \
$(eval $(call run-install-test,$(test))) \
$(eval $(test-group).test-group: $(test).test)))
# Include makefiles requiring built programs.
$(foreach mf, $(makefiles-late), $(eval $(call include-sub-makefile,$(mf))))
$(foreach file, $(man-pages), $(eval $(call install-data-in, $(file), $(mandir)/man$(patsubst .%,%,$(suffix $(file))))))
+1 -1
View File
@@ -87,6 +87,6 @@ define build-program
# Phony target to run this program (typically as a dependency of 'check').
.PHONY: $(1)_RUN
$(1)_RUN: $$($(1)_PATH)
$(trace-test) $$($(1)_PATH)
$(trace-test) $$(UNIT_TEST_ENV) $$($(1)_PATH)
endef
+4 -4
View File
@@ -10,10 +10,10 @@ endef
ifneq ($(MAKECMDGOALS), clean)
%.h: %.h.in
$(trace-gen) rm -f $@ && ./config.status --quiet --header=$@
$(buildprefix)%.h: %.h.in
$(trace-gen) rm -f $@ && cd $(buildprefixrel) && ./config.status --quiet --header=$(@:$(buildprefix)%=%)
%: %.in
$(trace-gen) rm -f $@ && ./config.status --quiet --file=$@
$(buildprefix)%: %.in
$(trace-gen) rm -f $@ && cd $(buildprefixrel) && ./config.status --quiet --file=$(@:$(buildprefix)%=%)
endif
+258
View File
@@ -0,0 +1,258 @@
{
pkgs,
lib,
stdenv,
autoconf-archive,
autoreconfHook,
aws-sdk-cpp,
boehmgc,
nlohmann_json,
bison,
changelog-d,
cmake,
boost,
brotli,
bzip2,
curl,
editline,
fileset,
flex,
git,
gtest,
jq,
libarchive,
libcpuid,
libseccomp,
libsodium,
lsof,
lowdown,
mdbook,
mdbook-linkcheck,
mercurial,
meson,
ninja,
openssl,
pkg-config,
rapidcheck,
sqlite,
util-linuxMinimal ? utillinuxMinimal,
utillinuxMinimal ? null,
xz,
busybox-sandbox-shell,
pname ? "nix",
versionSuffix ? "",
officialRelease ? true,
# Set to true to build the release notes for the next release.
buildUnreleasedNotes ? false,
# Not a real argument, just the only way to approximate let-binding some
# stuff for argument defaults.
__forDefaults ? {
canRunInstalled = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
},
}: let
inherit (__forDefaults) canRunInstalled;
version = lib.fileContents ./.version + versionSuffix;
aws-sdk-cpp-nix = aws-sdk-cpp.override {
apis = [ "s3" "transfer" ];
customMemoryManagement = false;
};
testConfigureFlags = [
"RAPIDCHECK_HEADERS=${lib.getDev rapidcheck}/extras/gtest/include"
];
# .gitignore has already been processed, so any changes in it are irrelevant
# at this point. It is not represented verbatim for test purposes because
# that would interfere with repo semantics.
baseFiles = fileset.fileFilter (f: f.name != ".gitignore") ./.;
configureFiles = fileset.unions [
./.version
./configure.ac
./m4
# TODO: do we really need README.md? It doesn't seem used in the build.
./README.md
];
topLevelBuildFiles = fileset.unions [
./local.mk
./Makefile
./Makefile.config.in
./mk
];
functionalTestFiles = fileset.unions [
./tests/functional
./tests/unit
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
];
in stdenv.mkDerivation (finalAttrs: {
inherit pname version;
src = fileset.toSource {
root = ./.;
fileset = fileset.intersection baseFiles (fileset.unions ([
configureFiles
topLevelBuildFiles
functionalTestFiles
./unit-test-data
] ++ lib.optionals finalAttrs.doBuild [
./boehmgc-coroutine-sp-fallback.diff
./doc
./misc
./precompiled-headers.h
./src
./COPYING
./scripts/local.mk
]));
};
VERSION_SUFFIX = versionSuffix;
outputs = [ "out" ]
++ lib.optionals finalAttrs.doBuild [ "dev" "doc" ];
# dontBuild isn't specified most of the time, where it is implicitly false.
doBuild = !(finalAttrs.dontBuild or false);
nativeBuildInputs = [
bison
flex
] ++ [
(lib.getBin lowdown)
mdbook
mdbook-linkcheck
autoconf-archive
autoreconfHook
pkg-config
# Tests
git
mercurial
jq
cmake
meson
ninja
lsof
] ++ lib.optional stdenv.hostPlatform.isLinux util-linuxMinimal
++ lib.optional (!officialRelease && buildUnreleasedNotes) changelog-d;
buildInputs = [
curl
bzip2
xz
brotli
editline
openssl
sqlite
libarchive
boost
lowdown
libsodium
]
++ lib.optionals stdenv.isLinux [ libseccomp ]
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
# There have been issues building these dependencies
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform) aws-sdk-cpp-nix
;
checkInputs = [
gtest
rapidcheck
];
propagatedBuildInputs = [
boehmgc
nlohmann_json
];
disallowedReferences = [
boost
];
# Needed for Meson to find Boost.
# https://github.com/NixOS/nixpkgs/issues/86131.
env.BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
env.BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
preConfigure = lib.optionalString (finalAttrs.doBuild && (! stdenv.hostPlatform.isStatic)) ''
# Copy libboost_context so we don't get all of Boost in our closure.
# https://github.com/NixOS/nixpkgs/issues/45462
mkdir -p $out/lib
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
rm -f $out/lib/*.a
${lib.optionalString stdenv.hostPlatform.isLinux ''
chmod u+w $out/lib/*.so.*
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
''}
${lib.optionalString stdenv.hostPlatform.isDarwin ''
for LIB in $out/lib/*.dylib; do
chmod u+w $LIB
install_name_tool -id $LIB $LIB
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
done
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
''}
'';
configureFlags = lib.optionals stdenv.isLinux [
"--with-boost=${boost}/lib"
"--with-sandbox-shell=${busybox-sandbox-shell}/bin/busybox"
] ++ lib.optionals (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) [
"LDFLAGS=-fuse-ld=gold"
] ++ [ "--sysconfdir=/etc" ]
++ lib.optional stdenv.hostPlatform.isStatic "--enable-embedded-sandbox-shell"
++ [ (lib.enableFeature finalAttrs.doCheck "tests") ]
++ lib.optionals finalAttrs.doCheck testConfigureFlags
++ lib.optional (!canRunInstalled) "--disable-doc-gen"
;
enableParallelBuilding = true;
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
doCheck = true;
installFlags = "sysconfdir=$(out)/etc";
postInstall = ''
mkdir -p $doc/nix-support
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
${lib.optionalString stdenv.hostPlatform.isStatic ''
mkdir -p $out/nix-support
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
''}
${lib.optionalString stdenv.isDarwin ''
install_name_tool \
-change ${boost}/lib/libboost_context.dylib \
$out/lib/libboost_context.dylib \
$out/lib/libnixutil.dylib
''}
'';
doInstallCheck = finalAttrs.doCheck;
installCheckFlags = "sysconfdir=$(out)/etc";
installCheckTarget = "installcheck"; # work around buggy detection in stdenv
preInstallCheck = lib.optionalString stdenv.hostPlatform.isDarwin ''
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
'';
separateDebugInfo = !stdenv.hostPlatform.isStatic && finalAttrs.doBuild;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta.platforms = lib.platforms.unix;
passthru.perl-bindings = pkgs.callPackage ./perl {
inherit fileset stdenv;
};
})
+7 -1
View File
@@ -1,6 +1,12 @@
makefiles = local.mk
GLOBAL_CXXFLAGS += -g -Wall -std=c++2a -I ../src
GLOBAL_CXXFLAGS += -g -Wall -std=c++2a
# A convenience for concurrent development of Nix and its Perl bindings.
# Not needed in a standalone build of the Perl bindings.
ifneq ("$(wildcard ../src)", "")
GLOBAL_CXXFLAGS += -I ../src
endif
-include Makefile.config
+51
View File
@@ -0,0 +1,51 @@
{ lib, fileset
, stdenv
, perl, perlPackages
, autoconf-archive, autoreconfHook, pkg-config
, nix, curl, bzip2, xz, boost, libsodium, darwin
}:
perl.pkgs.toPerlModule (stdenv.mkDerivation {
name = "nix-perl-${nix.version}";
src = fileset.toSource {
root = ../.;
fileset = fileset.unions [
../.version
../m4
../mk
./MANIFEST
./Makefile
./Makefile.config.in
./configure.ac
./lib
./local.mk
];
};
nativeBuildInputs =
[ autoconf-archive
autoreconfHook
pkg-config
];
buildInputs =
[ nix
curl
bzip2
xz
perl
boost
]
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security;
configureFlags = [
"--with-dbi=${perlPackages.DBI}/${perl.libPrefix}"
"--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}"
];
enableParallelBuilding = true;
postUnpack = "sourceRoot=$sourceRoot/perl";
})
+5 -3
View File
@@ -3,11 +3,13 @@
set -eu
set -o pipefail
# System specific settings
export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-301}"
export NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d"
readonly NIX_DAEMON_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist
# create by default; set 0 to DIY, use a symlink, etc.
readonly NIX_VOLUME_CREATE=${NIX_VOLUME_CREATE:-1} # now default
NIX_FIRST_BUILD_UID="301"
NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d"
# caution: may update times on / if not run as normal non-root user
read_only_root() {
@@ -100,7 +102,7 @@ poly_extra_try_me_commands() {
poly_configure_nix_daemon_service() {
task "Setting up the nix-daemon LaunchDaemon"
_sudo "to set up the nix-daemon as a LaunchDaemon" \
/usr/bin/install -m -rw-r--r-- "/nix/var/nix/profiles/default$NIX_DAEMON_DEST" "$NIX_DAEMON_DEST"
/usr/bin/install -m "u=rw,go=r" "/nix/var/nix/profiles/default$NIX_DAEMON_DEST" "$NIX_DAEMON_DEST"
_sudo "to load the LaunchDaemon plist for nix-daemon" \
launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
+15 -4
View File
@@ -25,9 +25,9 @@ readonly RED='\033[31m'
readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32}
readonly NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-30000}"
readonly NIX_BUILD_GROUP_NAME="nixbld"
# darwin installer needs to override these
NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
# each system specific installer must set these:
# NIX_FIRST_BUILD_UID
# NIX_BUILD_USER_NAME_TEMPLATE
# Please don't change this. We don't support it, because the
# default shell profile that comes with Nix doesn't support it.
readonly NIX_ROOT="/nix"
@@ -699,6 +699,12 @@ EOF
fi
}
check_required_system_specific_settings() {
if [ -z "${NIX_FIRST_BUILD_UID+x}" ] || [ -z "${NIX_BUILD_USER_NAME_TEMPLATE+x}" ]; then
failure "Internal error: System specific installer for $(uname) ($1) does not export required settings."
fi
}
welcome_to_nix() {
local -r NIX_UID_RANGES="${NIX_FIRST_BUILD_UID}..$((NIX_FIRST_BUILD_UID + NIX_USER_COUNT - 1))"
local -r RANGE_TEXT=$(echo -ne "${BLUE}(uids [${NIX_UID_RANGES}])${ESC}")
@@ -718,7 +724,9 @@ manager. This will happen in a few stages:
if you are ready to continue.
3. Create the system users ${RANGE_TEXT} and groups ${GROUP_TEXT}
that the Nix daemon uses to run builds.
that the Nix daemon uses to run builds. To create system users
in a different range, exit and run this tool again with
NIX_FIRST_BUILD_UID set.
4. Perform the basic installation of the Nix files daemon.
@@ -960,13 +968,16 @@ main() {
if is_os_darwin; then
# shellcheck source=./install-darwin-multi-user.sh
. "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
check_required_system_specific_settings "install-darwin-multi-user.sh"
elif is_os_linux; then
# shellcheck source=./install-systemd-multi-user.sh
. "$EXTRACTED_NIX_PATH/install-systemd-multi-user.sh" # most of this works on non-systemd distros also
check_required_system_specific_settings "install-systemd-multi-user.sh"
else
failure "Sorry, I don't know what to do on $(uname)"
fi
welcome_to_nix
if ! is_root; then
+4
View File
@@ -3,6 +3,10 @@
set -eu
set -o pipefail
# System specific settings
export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
export NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
readonly SERVICE_SRC=/lib/systemd/system/nix-daemon.service
readonly SERVICE_DEST=/etc/systemd/system/nix-daemon.service
+8
View File
@@ -19,6 +19,14 @@ set __ETC_PROFILE_NIX_SOURCED 1
set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile"
# Populate bash completions, .desktop files, etc
if test -z "$XDG_DATA_DIRS"
# According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default
set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:/nix/var/nix/profiles/default/share"
else
set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:/nix/var/nix/profiles/default/share"
end
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if test -n "$NIX_SSH_CERT_FILE"
: # Allow users to override the NIX_SSL_CERT_FILE
+8
View File
@@ -30,6 +30,14 @@ fi
export NIX_PROFILES="@localstatedir@/nix/profiles/default $NIX_LINK"
# Populate bash completions, .desktop files, etc
if [ -z "${XDG_DATA_DIRS-}" ]; then
# According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default
export XDG_DATA_DIRS="/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
else
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
fi
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if [ -n "${NIX_SSL_CERT_FILE:-}" ]; then
: # Allow users to override the NIX_SSL_CERT_FILE
+8
View File
@@ -20,6 +20,14 @@ if test -n "$HOME" && test -n "$USER"
# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
set --export NIX_PROFILES "@localstatedir@/nix/profiles/default $HOME/.nix-profile"
# Populate bash completions, .desktop files, etc
if test -z "$XDG_DATA_DIRS"
# According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default
set --export XDG_DATA_DIRS "/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
else
set --export XDG_DATA_DIRS "$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
end
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if test -n "$NIX_SSH_CERT_FILE"
: # Allow users to override the NIX_SSL_CERT_FILE
+8
View File
@@ -32,6 +32,14 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
export NIX_PROFILES="@localstatedir@/nix/profiles/default $NIX_LINK"
# Populate bash completions, .desktop files, etc
if [ -z "${XDG_DATA_DIRS-}" ]; then
# According to XDG spec the default is /usr/local/share:/usr/share, don't set something that prevents that default
export XDG_DATA_DIRS="/usr/local/share:/usr/share:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
else
export XDG_DATA_DIRS="$XDG_DATA_DIRS:$NIX_LINK/share:/nix/var/nix/profiles/default/share"
fi
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
+4 -7
View File
@@ -137,11 +137,8 @@ static int main_build_remote(int argc, char * * argv)
for (auto & m : machines) {
debug("considering building on remote machine '%s'", m.storeUri);
if (m.enabled
&& (neededSystem == "builtin"
|| std::find(m.systemTypes.begin(),
m.systemTypes.end(),
neededSystem) != m.systemTypes.end()) &&
if (m.enabled &&
m.systemSupported(neededSystem) &&
m.allSupported(requiredFeatures) &&
m.mandatoryMet(requiredFeatures))
{
@@ -205,7 +202,7 @@ static int main_build_remote(int argc, char * * argv)
else
drvstr = "<unknown>";
auto error = hintformat(errorText);
auto error = HintFmt(errorText);
error
% drvstr
% neededSystem
@@ -214,7 +211,7 @@ static int main_build_remote(int argc, char * * argv)
for (auto & m : machines)
error
% concatStringsSep<std::vector<std::string>>(", ", m.systemTypes)
% concatStringsSep<StringSet>(", ", m.systemTypes)
% m.maxJobs
% concatStringsSep<StringSet>(", ", m.supportedFeatures)
% concatStringsSep<StringSet>(", ", m.mandatoryFeatures);
+2 -2
View File
@@ -12,9 +12,9 @@ namespace nix {
bool MY_TYPE ::operator COMPARATOR (const MY_TYPE & other) const \
{ \
const MY_TYPE* me = this; \
auto fields1 = std::make_tuple<const CHILD_TYPE &, const FIELD_TYPE &>(*me->drvPath, me->FIELD); \
auto fields1 = std::tie(*me->drvPath, me->FIELD); \
me = &other; \
auto fields2 = std::make_tuple<const CHILD_TYPE &, const FIELD_TYPE &>(*me->drvPath, me->FIELD); \
auto fields2 = std::tie(*me->drvPath, me->FIELD); \
return fields1 COMPARATOR fields2; \
}
#define CMP(CHILD_TYPE, MY_TYPE, FIELD) \
+3 -3
View File
@@ -98,7 +98,7 @@ EvalCommand::EvalCommand()
EvalCommand::~EvalCommand()
{
if (evalState)
evalState->printStats();
evalState->maybePrintStats();
}
ref<Store> EvalCommand::getEvalStore()
@@ -175,7 +175,7 @@ void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
throw UsageError("'--all' does not expect arguments");
// XXX: Only uses opaque paths, ignores all the realisations
for (auto & p : store->queryAllValidPaths())
paths.push_back(BuiltPath::Opaque{p});
paths.emplace_back(BuiltPath::Opaque{p});
} else {
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
if (recursive) {
@@ -188,7 +188,7 @@ void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
}
store->computeFSClosure(pathsRoots, pathsClosure);
for (auto & path : pathsClosure)
paths.push_back(BuiltPath::Opaque{path});
paths.emplace_back(BuiltPath::Opaque{path});
}
}
+66 -12
View File
@@ -34,21 +34,28 @@ struct NixMultiCommand : virtual MultiCommand, virtual Command
// For the overloaded run methods
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
/* A command that requires a Nix store. */
/**
* A command that requires a \ref Store "Nix store".
*/
struct StoreCommand : virtual Command
{
StoreCommand();
void run() override;
ref<Store> getStore();
virtual ref<Store> createStore();
/**
* Main entry point, with a `Store` provided
*/
virtual void run(ref<Store>) = 0;
private:
std::shared_ptr<Store> _store;
};
/* A command that copies something between `--from` and `--to`
stores. */
/**
* A command that copies something between `--from` and `--to` \ref
* Store stores.
*/
struct CopyCommand : virtual StoreCommand
{
std::string srcUri, dstUri;
@@ -60,6 +67,9 @@ struct CopyCommand : virtual StoreCommand
ref<Store> getDstStore();
};
/**
* A command that needs to evaluate Nix language expressions.
*/
struct EvalCommand : virtual StoreCommand, MixEvalArgs
{
bool startReplOnEvalErrors = false;
@@ -79,6 +89,10 @@ private:
std::shared_ptr<EvalState> evalState;
};
/**
* A mixin class for commands that process flakes, adding a few standard
* flake-related options/flags.
*/
struct MixFlakeOptions : virtual Args, EvalCommand
{
flake::LockFlags lockFlags;
@@ -87,6 +101,14 @@ struct MixFlakeOptions : virtual Args, EvalCommand
MixFlakeOptions();
/**
* The completion for some of these flags depends on the flake(s) in
* question.
*
* This method should be implemented to gather all flakerefs the
* command is operating with (presumably specified via some other
* arguments) so that the completions for these flags can use them.
*/
virtual std::vector<std::string> getFlakesForCompletion()
{ return {}; }
@@ -112,15 +134,29 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
virtual Strings getDefaultFlakeAttrPathPrefixes();
/**
* Complete an installable from the given prefix.
*/
void completeInstallable(std::string_view prefix);
};
/**
* A mixin class for commands that need a read-only flag.
*
* What exactly is "read-only" is unspecified, but it will usually be
* the \ref Store "Nix store".
*/
struct MixReadOnlyOption : virtual Args
{
MixReadOnlyOption();
};
/* Like InstallablesCommand but the installables are not loaded */
/**
* Like InstallablesCommand but the installables are not loaded.
*
* This is needed by `CmdRepl` which wants to load (and reload) the
* installables itself.
*/
struct RawInstallablesCommand : virtual Args, SourceExprCommand
{
RawInstallablesCommand();
@@ -129,7 +165,7 @@ struct RawInstallablesCommand : virtual Args, SourceExprCommand
void run(ref<Store> store) override;
// FIXME make const after CmdRepl's override is fixed up
// FIXME make const after `CmdRepl`'s override is fixed up
virtual void applyDefaultInstallables(std::vector<std::string> & rawInstallables);
bool readFromStdIn = false;
@@ -140,8 +176,11 @@ private:
std::vector<std::string> rawInstallables;
};
/* A command that operates on a list of "installables", which can be
store paths, attribute paths, Nix expressions, etc. */
/**
* A command that operates on a list of "installables", which can be
* store paths, attribute paths, Nix expressions, etc.
*/
struct InstallablesCommand : RawInstallablesCommand
{
virtual void run(ref<Store> store, Installables && installables) = 0;
@@ -149,7 +188,9 @@ struct InstallablesCommand : RawInstallablesCommand
void run(ref<Store> store, std::vector<std::string> && rawInstallables) override;
};
/* A command that operates on exactly one "installable" */
/**
* A command that operates on exactly one "installable".
*/
struct InstallableCommand : virtual Args, SourceExprCommand
{
InstallableCommand();
@@ -175,7 +216,12 @@ struct MixOperateOnOptions : virtual Args
MixOperateOnOptions();
};
/* A command that operates on zero or more store paths. */
/**
* A command that operates on zero or more extant store paths.
*
* If the argument the user passes is a some sort of recipe for a path
* not yet built, it must be built first.
*/
struct BuiltPathsCommand : InstallablesCommand, virtual MixOperateOnOptions
{
private:
@@ -207,7 +253,9 @@ struct StorePathsCommand : public BuiltPathsCommand
void run(ref<Store> store, BuiltPaths && paths) override;
};
/* A command that operates on exactly one store path. */
/**
* A command that operates on exactly one store path.
*/
struct StorePathCommand : public StorePathsCommand
{
virtual void run(ref<Store> store, const StorePath & storePath) = 0;
@@ -215,7 +263,9 @@ struct StorePathCommand : public StorePathsCommand
void run(ref<Store> store, StorePaths && storePaths) override;
};
/* A helper class for registering commands globally. */
/**
* A helper class for registering \ref Command commands globally.
*/
struct RegisterCommand
{
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
@@ -271,7 +321,11 @@ struct MixEnvironment : virtual Args {
MixEnvironment();
/* Modify global environ based on ignoreEnvironment, keep, and unset. It's expected that exec will be called before this class goes out of scope, otherwise environ will become invalid. */
/***
* Modify global environ based on `ignoreEnvironment`, `keep`, and
* `unset`. It's expected that exec will be called before this class
* goes out of scope, otherwise `environ` will become invalid.
*/
void setEnviron();
};
+1
View File
@@ -1,5 +1,6 @@
#include "util.hh"
#include "editor-for.hh"
#include "source-path.hh"
namespace nix {
+1 -1
View File
@@ -2,7 +2,7 @@
///@file
#include "types.hh"
#include "input-accessor.hh"
#include "source-path.hh"
namespace nix {
+1 -1
View File
@@ -47,7 +47,7 @@ Value * InstallableFlake::getFlakeOutputs(EvalState & state, const flake::Locked
auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
assert(aOutputs);
state.forceValue(*aOutputs->value, [&]() { return aOutputs->value->determinePos(noPos); });
state.forceValue(*aOutputs->value, aOutputs->value->determinePos(noPos));
return aOutputs->value;
}
+2 -1
View File
@@ -1,5 +1,6 @@
#include "installable-value.hh"
#include "eval-cache.hh"
#include "fetch-to-store.hh"
namespace nix {
@@ -44,7 +45,7 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
{
if (v.type() == nPath) {
auto storePath = v.path().fetchToStore(state->store);
auto storePath = fetchToStore(*state->store, v.path());
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
+17 -3
View File
@@ -669,12 +669,12 @@ BuiltPaths Installable::toBuiltPaths(
BuiltPaths res;
for (auto & drvPath : Installable::toDerivations(store, installables, true))
res.push_back(BuiltPath::Opaque{drvPath});
res.emplace_back(BuiltPath::Opaque{drvPath});
return res;
}
}
StorePathSet Installable::toStorePaths(
StorePathSet Installable::toStorePathSet(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
@@ -688,13 +688,27 @@ StorePathSet Installable::toStorePaths(
return outPaths;
}
StorePaths Installable::toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
{
StorePaths outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
auto thisOutPaths = path.outPaths();
outPaths.insert(outPaths.end(), thisOutPaths.begin(), thisOutPaths.end());
}
return outPaths;
}
StorePath Installable::toStorePath(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
ref<Installable> installable)
{
auto paths = toStorePaths(evalStore, store, mode, operateOn, {installable});
auto paths = toStorePathSet(evalStore, store, mode, operateOn, {installable});
if (paths.size() != 1)
throw Error("argument '%s' should evaluate to one store path", installable->what());
+8 -1
View File
@@ -166,7 +166,14 @@ struct Installable
const Installables & installables,
BuildMode bMode = bmNormal);
static std::set<StorePath> toStorePaths(
static std::set<StorePath> toStorePathSet(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables);
static std::vector<StorePath> toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
+1 -1
View File
@@ -12,4 +12,4 @@ libcmd_LDFLAGS = $(EDITLINE_LIBS) $(LOWDOWN_LIBS) -pthread
libcmd_LIBS = libstore libutil libexpr libmain libfetchers
$(eval $(call install-file-in, $(d)/nix-cmd.pc, $(libdir)/pkgconfig, 0644))
$(eval $(call install-file-in, $(buildprefix)$(d)/nix-cmd.pc, $(libdir)/pkgconfig, 0644))
+35
View File
@@ -0,0 +1,35 @@
libcmd_sources = files(
'built-path.cc',
'command-installable-value.cc',
'command.cc',
'common-eval-args.cc',
'editor-for.cc',
'installable-attr-path.cc',
'installable-derived-path.cc',
'installable-flake.cc',
'installable-value.cc',
'installables.cc',
'legacy.cc',
'markdown.cc',
'repl.cc',
)
libcmd = library(
'nixcmd',
libcmd_sources,
dependencies : [
liblixutil,
liblixstore,
liblixexpr,
liblixfetchers,
liblixmain,
boehm,
editline,
lowdown,
],
)
liblixcmd = declare_dependency(
include_directories : '.',
link_with : libcmd,
)
+33 -157
View File
@@ -40,7 +40,6 @@ extern "C" {
#include "finally.hh"
#include "markdown.hh"
#include "local-fs-store.hh"
#include "progress-bar.hh"
#include "print.hh"
#if HAVE_BOEHMGC
@@ -91,9 +90,17 @@ struct NixRepl
void evalString(std::string s, Value & v);
void loadDebugTraceEnv(DebugTrace & dt);
typedef std::set<Value *> ValuesSeen;
std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth);
std::ostream & printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen);
void printValue(std::ostream & str,
Value & v,
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
{
::nix::printValue(*state, str, v, PrintOptions {
.ansiColors = true,
.force = true,
.derivationPaths = true,
.maxDepth = maxDepth
});
}
};
std::string removeWhitespace(std::string s)
@@ -110,7 +117,7 @@ NixRepl::NixRepl(const SearchPath & searchPath, nix::ref<Store> store, ref<EvalS
: AbstractNixRepl(state)
, debugTraceIndex(0)
, getValues(getValues)
, staticEnv(new StaticEnv(false, state->staticBaseEnv.get()))
, staticEnv(new StaticEnv(nullptr, state->staticBaseEnv.get()))
, historyFile(getDataDir() + "/nix/repl-history")
{
}
@@ -219,10 +226,10 @@ static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positi
// prefer direct pos, but if noPos then try the expr.
auto pos = dt.pos
? dt.pos
: static_cast<std::shared_ptr<AbstractPos>>(positions[dt.expr.getPos() ? dt.expr.getPos() : noPos]);
: positions[dt.expr.getPos() ? dt.expr.getPos() : noPos];
if (pos) {
out << pos;
out << *pos;
if (auto loc = pos->getCodeLines()) {
out << "\n";
printCodeLines(out, "", *pos, *loc);
@@ -233,10 +240,19 @@ static std::ostream & showDebugTrace(std::ostream & out, const PosTable & positi
return out;
}
static bool isFirstRepl = true;
void NixRepl::mainLoop()
{
std::string error = ANSI_RED "error:" ANSI_NORMAL " ";
notice("Welcome to Nix " + nixVersion + ". Type :? for help.\n");
if (isFirstRepl) {
std::string_view debuggerNotice = "";
if (state->debugRepl) {
debuggerNotice = " debugger";
}
notice("Nix %1%%2%\nType :? for help.", nixVersion, debuggerNotice);
}
isFirstRepl = false;
loadFiles();
@@ -259,13 +275,11 @@ void NixRepl::mainLoop()
rl_set_list_possib_func(listPossibleCallback);
#endif
/* Stop the progress bar because it interferes with the display of
the repl. */
stopProgressBar();
std::string input;
while (true) {
// Hide the progress bar while waiting for user input, so that it won't interfere.
logger->pause();
// When continuing input from previous lines, don't print a prompt, just align to the same
// number of chars as the prompt.
if (!getLine(input, input.empty() ? "nix-repl> " : " ")) {
@@ -275,6 +289,7 @@ void NixRepl::mainLoop()
logger->cout("");
break;
}
logger->resume();
try {
if (!removeWhitespace(input).empty() && !processLine(input)) return;
} catch (ParseError & e) {
@@ -333,7 +348,6 @@ bool NixRepl::getLine(std::string & input, const std::string & prompt)
};
setupSignals();
Finally resetTerminal([&]() { rl_deprep_terminal(); });
char * s = readline(prompt.c_str());
Finally doFree([&]() { free(s); });
restoreSignals();
@@ -413,8 +427,6 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
// Quietly ignore parse errors.
} catch (EvalError & e) {
// Quietly ignore evaluation errors.
} catch (UndefinedVarError & e) {
// Quietly ignore undefined variable errors.
} catch (BadURL & e) {
// Quietly ignore BadURL flake-related errors.
}
@@ -707,7 +719,8 @@ bool NixRepl::processLine(std::string line)
else if (command == ":p" || command == ":print") {
Value v;
evalString(arg, v);
printValue(std::cout, v, 1000000000) << std::endl;
printValue(std::cout, v);
std::cout << std::endl;
}
else if (command == ":q" || command == ":quit") {
@@ -769,7 +782,8 @@ bool NixRepl::processLine(std::string line)
} else {
Value v;
evalString(line, v);
printValue(std::cout, v, 1) << std::endl;
printValue(std::cout, v, 1);
std::cout << std::endl;
}
}
@@ -887,145 +901,7 @@ void NixRepl::evalString(std::string s, Value & v)
{
Expr * e = parseString(s);
e->eval(*state, *env, v);
state->forceValue(v, [&]() { return v.determinePos(noPos); });
}
std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth)
{
ValuesSeen seen;
return printValue(str, v, maxDepth, seen);
}
// FIXME: lot of cut&paste from Nix's eval.cc.
std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int maxDepth, ValuesSeen & seen)
{
str.flush();
checkInterrupt();
state->forceValue(v, [&]() { return v.determinePos(noPos); });
switch (v.type()) {
case nInt:
str << ANSI_CYAN << v.integer << ANSI_NORMAL;
break;
case nBool:
str << ANSI_CYAN;
printLiteralBool(str, v.boolean);
str << ANSI_NORMAL;
break;
case nString:
str << ANSI_WARNING;
printLiteralString(str, v.string.s);
str << ANSI_NORMAL;
break;
case nPath:
str << ANSI_GREEN << v.path().to_string() << ANSI_NORMAL; // !!! escaping?
break;
case nNull:
str << ANSI_CYAN "null" ANSI_NORMAL;
break;
case nAttrs: {
seen.insert(&v);
bool isDrv = state->isDerivation(v);
if (isDrv) {
str << "«derivation ";
Bindings::iterator i = v.attrs->find(state->sDrvPath);
NixStringContext context;
if (i != v.attrs->end())
str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context, "while evaluating the drvPath of a derivation"));
else
str << "???";
str << "»";
}
else if (maxDepth > 0) {
str << "{ ";
typedef std::map<std::string, Value *> Sorted;
Sorted sorted;
for (auto & i : *v.attrs)
sorted.emplace(state->symbols[i.name], i.value);
for (auto & i : sorted) {
printAttributeName(str, i.first);
str << " = ";
if (seen.count(i.second))
str << "«repeated»";
else
try {
printValue(str, *i.second, maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << "; ";
}
str << "}";
} else
str << "{ ... }";
break;
}
case nList:
seen.insert(&v);
str << "[ ";
if (maxDepth > 0)
for (auto elem : v.listItems()) {
if (seen.count(elem))
str << "«repeated»";
else
try {
printValue(str, *elem, maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << " ";
}
else
str << "... ";
str << "]";
break;
case nFunction:
if (v.isLambda()) {
std::ostringstream s;
s << state->positions[v.lambda.fun->pos];
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
} else if (v.isPrimOp()) {
str << ANSI_MAGENTA "«primop»" ANSI_NORMAL;
} else if (v.isPrimOpApp()) {
str << ANSI_BLUE "«primop-app»" ANSI_NORMAL;
} else {
abort();
}
break;
case nFloat:
str << v.fpoint;
break;
case nThunk:
case nExternal:
default:
str << ANSI_RED "«unknown»" ANSI_NORMAL;
break;
}
return str;
state->forceValue(v, v.determinePos(noPos));
}
+4 -4
View File
@@ -66,10 +66,10 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
if (!attrIndex) {
if (v->type() != nAttrs)
throw TypeError(
state.error<TypeError>(
"the expression selected by the selection path '%1%' should be a set but is %2%",
attrPath,
showType(*v));
showType(*v)).debugThrow();
if (attr.empty())
throw Error("empty attribute name in selection path '%1%'", attrPath);
@@ -89,10 +89,10 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
else {
if (!v->isList())
throw TypeError(
state.error<TypeError>(
"the expression selected by the selection path '%1%' should be a list but is %2%",
attrPath,
showType(*v));
showType(*v)).debugThrow();
if (*attrIndex >= v->listSize())
throw AttrPathNotFound("list index %1% in selection path '%2%' is out of range", *attrIndex, attrPath);
+31
View File
@@ -0,0 +1,31 @@
pkg = import('pkgconfig')
libexprc_sources = files(
'nix_api_expr.cc',
'nix_api_external.cc',
'nix_api_value.cc',
)
all_sources += {
'libexprc': libexprc_sources
}
libexprc = library(
'nix-expr-c',
libexprc_sources,
dependencies : [
liblixutil,
liblixstore,
liblixexpr,
liblixutilc,
liblixstorec,
boehm,
],
)
pkg.generate(libexprc, requires: [ 'nix-store-c' ])
liblixexprc = declare_dependency(
include_directories : include_directories('.'),
link_with : libexprc,
)
+178
View File
@@ -0,0 +1,178 @@
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include "config.hh"
#include "eval.hh"
#include "globals.hh"
#include "util.hh"
#include "nix_api_expr.h"
#include "nix_api_expr_internal.h"
#include "nix_api_store.h"
#include "nix_api_store_internal.h"
#include "nix_api_util.h"
#include "nix_api_util_internal.h"
#ifdef HAVE_BOEHMGC
#include <mutex>
#define GC_INCLUDE_NEW 1
#include "gc_cpp.h"
#endif
nix_err nix_libexpr_init(nix_c_context * context)
{
if (context)
context->last_err_code = NIX_OK;
{
auto ret = nix_libutil_init(context);
if (ret != NIX_OK)
return ret;
}
{
auto ret = nix_libstore_init(context);
if (ret != NIX_OK)
return ret;
}
try {
nix::initGC();
}
NIXC_CATCH_ERRS
}
nix_err nix_expr_eval_from_string(
nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path)));
state->state.eval(parsedExpr, *(nix::Value *) value);
state->state.forceValue(*(nix::Value *) value, nix::noPos);
}
NIXC_CATCH_ERRS
}
nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
state->state.callFunction(*(nix::Value *) fn, *(nix::Value *) arg, *(nix::Value *) value, nix::noPos);
state->state.forceValue(*(nix::Value *) value, nix::noPos);
}
NIXC_CATCH_ERRS
}
nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
state->state.forceValue(*(nix::Value *) value, nix::noPos);
}
NIXC_CATCH_ERRS
}
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
state->state.forceValueDeep(*(nix::Value *) value);
}
NIXC_CATCH_ERRS
}
EvalState * nix_state_create(nix_c_context * context, const char ** searchPath_c, Store * store)
{
if (context)
context->last_err_code = NIX_OK;
try {
nix::Strings searchPath;
if (searchPath_c != nullptr)
for (size_t i = 0; searchPath_c[i] != nullptr; i++)
searchPath.push_back(searchPath_c[i]);
return new EvalState{nix::EvalState(nix::SearchPath::parse(searchPath), store->ptr)};
}
NIXC_CATCH_ERRS_NULL
}
void nix_state_free(EvalState * state)
{
delete state;
}
#ifdef HAVE_BOEHMGC
std::unordered_map<
const void *,
unsigned int,
std::hash<const void *>,
std::equal_to<const void *>,
traceable_allocator<std::pair<const void * const, unsigned int>>>
nix_refcounts;
std::mutex nix_refcount_lock;
nix_err nix_gc_incref(nix_c_context * context, const void * p)
{
if (context)
context->last_err_code = NIX_OK;
try {
std::scoped_lock lock(nix_refcount_lock);
auto f = nix_refcounts.find(p);
if (f != nix_refcounts.end()) {
f->second++;
} else {
nix_refcounts[p] = 1;
}
}
NIXC_CATCH_ERRS
}
nix_err nix_gc_decref(nix_c_context * context, const void * p)
{
if (context)
context->last_err_code = NIX_OK;
try {
std::scoped_lock lock(nix_refcount_lock);
auto f = nix_refcounts.find(p);
if (f != nix_refcounts.end()) {
if (--f->second == 0)
nix_refcounts.erase(f);
} else
throw std::runtime_error("nix_gc_decref: object was not referenced");
}
NIXC_CATCH_ERRS
}
void nix_gc_now()
{
GC_gcollect();
}
#else
void nix_gc_incref(nix_c_context * context, const void *)
{
if (context)
context->last_err_code = NIX_OK;
return NIX_OK;
}
void nix_gc_decref(nix_c_context * context, const void *)
{
if (context)
context->last_err_code = NIX_OK;
return NIX_OK;
}
void nix_gc_now() {}
#endif
void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * obj, void * cd))
{
#ifdef HAVE_BOEHMGC
GC_REGISTER_FINALIZER(obj, finalizer, cd, 0, 0);
#endif
}
+213
View File
@@ -0,0 +1,213 @@
#ifndef NIX_API_EXPR_H
#define NIX_API_EXPR_H
/** @defgroup libexpr libexpr
* @brief Bindings to the Nix language evaluator
*
* Example (without error handling):
* @code{.c}
* int main() {
* nix_libexpr_init(NULL);
*
* Store* store = nix_store_open(NULL, "dummy", NULL);
* EvalState* state = nix_state_create(NULL, NULL, store); // empty nix path
* Value *value = nix_alloc_value(NULL, state);
*
* nix_expr_eval_from_string(NULL, state, "builtins.nixVersion", ".", value);
* nix_value_force(NULL, state, value);
* printf("nix version: %s\n", nix_get_string(NULL, value));
*
* nix_gc_decref(NULL, value);
* nix_state_free(state);
* nix_store_free(store);
* return 0;
* }
* @endcode
* @{
*/
/** @file
* @brief Main entry for the libexpr C bindings
*/
#include "nix_api_store.h"
#include "nix_api_util.h"
#ifdef __cplusplus
extern "C" {
#endif
// cffi start
// Type definitions
/**
* @brief Represents a state of the Nix language evaluator.
*
* Multiple states can be created for multi-threaded
* operation.
* @struct EvalState
* @see nix_state_create
*/
typedef struct EvalState EvalState; // nix::EvalState
/**
* @brief Represents a value in the Nix language.
*
* Owned by the garbage collector.
* @struct Value
* @see value_manip
*/
typedef void Value; // nix::Value
// Function prototypes
/**
* @brief Initialize the Nix language evaluator.
*
* This function must be called at least once,
* at some point before constructing a EvalState for the first time.
* This function can be called multiple times, and is idempotent.
*
* @param[out] context Optional, stores error information
* @return NIX_OK if the initialization was successful, an error code otherwise.
*/
nix_err nix_libexpr_init(nix_c_context * context);
/**
* @brief Parses and evaluates a Nix expression from a string.
*
* @param[out] context Optional, stores error information
* @param[in] state The state of the evaluation.
* @param[in] expr The Nix expression to parse.
* @param[in] path The file path to associate with the expression.
* This is required for expressions that contain relative paths (such as `./.`) that are resolved relative to the given
* directory.
* @param[out] value The result of the evaluation. You must allocate this
* yourself.
* @return NIX_OK if the evaluation was successful, an error code otherwise.
*/
nix_err nix_expr_eval_from_string(
nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value);
/**
* @brief Calls a Nix function with an argument.
*
* @param[out] context Optional, stores error information
* @param[in] state The state of the evaluation.
* @param[in] fn The Nix function to call.
* @param[in] arg The argument to pass to the function.
* @param[out] value The result of the function call.
* @return NIX_OK if the function call was successful, an error code otherwise.
*/
nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value);
/**
* @brief Forces the evaluation of a Nix value.
*
* The Nix interpreter is lazy, and not-yet-evaluated Values can be
* of type NIX_TYPE_THUNK instead of their actual value.
*
* This function converts these Values into their final type.
*
* @note You don't need this function for basic API usage, since all functions
* that return a value call it for you. The only place you will see a
* NIX_TYPE_THUNK is in the arguments that are passed to a PrimOp function
* you supplied to nix_alloc_primop.
*
* @param[out] context Optional, stores error information
* @param[in] state The state of the evaluation.
* @param[in,out] value The Nix value to force.
* @post value is not of type NIX_TYPE_THUNK
* @return NIX_OK if the force operation was successful, an error code
* otherwise.
*/
nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value);
/**
* @brief Forces the deep evaluation of a Nix value.
*
* Recursively calls nix_value_force
*
* @see nix_value_force
* @warning Calling this function on a recursive data structure will cause a
* stack overflow.
* @param[out] context Optional, stores error information
* @param[in] state The state of the evaluation.
* @param[in,out] value The Nix value to force.
* @return NIX_OK if the deep force operation was successful, an error code
* otherwise.
*/
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value);
/**
* @brief Create a new Nix language evaluator state.
*
* @param[out] context Optional, stores error information
* @param[in] searchPath Array of strings corresponding to entries in NIX_PATH.
* @param[in] store The Nix store to use.
* @return A new Nix state or NULL on failure.
*/
EvalState * nix_state_create(nix_c_context * context, const char ** searchPath, Store * store);
/**
* @brief Frees a Nix state.
*
* Does not fail.
*
* @param[in] state The state to free.
*/
void nix_state_free(EvalState * state);
/** @addtogroup GC
* @brief Reference counting and garbage collector operations
*
* The Nix language evaluator uses a garbage collector. To ease C interop, we implement
* a reference counting scheme, where objects will be deallocated
* when there are no references from the Nix side, and the reference count kept
* by the C API reaches `0`.
*
* Functions returning a garbage-collected object will automatically increase
* the refcount for you. You should make sure to call `nix_gc_decref` when
* you're done with a value returned by the evaluator.
* @{
*/
/**
* @brief Increment the garbage collector reference counter for the given object.
*
* The Nix language evaluator C API keeps track of alive objects by reference counting.
* When you're done with a refcounted pointer, call nix_gc_decref().
*
* @param[out] context Optional, stores error information
* @param[in] object The object to keep alive
*/
nix_err nix_gc_incref(nix_c_context * context, const void * object);
/**
* @brief Decrement the garbage collector reference counter for the given object
*
* @param[out] context Optional, stores error information
* @param[in] object The object to stop referencing
*/
nix_err nix_gc_decref(nix_c_context * context, const void * object);
/**
* @brief Trigger the garbage collector manually
*
* You should not need to do this, but it can be useful for debugging.
*/
void nix_gc_now();
/**
* @brief Register a callback that gets called when the object is garbage
* collected.
* @note Objects can only have a single finalizer. This function overwrites existing values
* silently.
* @param[in] obj the object to watch
* @param[in] cd the data to pass to the finalizer
* @param[in] finalizer the callback function, called with obj and cd
*/
void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * obj, void * cd));
/** @} */
// cffi end
#ifdef __cplusplus
}
#endif
/** @} */
#endif // NIX_API_EXPR_H
+64
View File
@@ -0,0 +1,64 @@
#ifndef NIX_API_EXPR_INTERNAL_H
#define NIX_API_EXPR_INTERNAL_H
#include "eval.hh"
#include "attr-set.hh"
#include "nix_api_value.h"
class CListBuilder
{
private:
std::vector<nix::Value *> values;
public:
CListBuilder(size_t capacity)
{
values.reserve(capacity);
}
void push_back(nix::Value * value)
{
values.push_back(value);
}
Value * finish(nix::EvalState * state, nix::Value * list)
{
state->mkList(*list, values.size());
for (size_t n = 0; n < list->listSize(); ++n) {
list->listElems()[n] = values[n];
}
return list;
}
};
struct EvalState
{
nix::EvalState state;
};
struct BindingsBuilder
{
nix::BindingsBuilder builder;
};
struct ListBuilder
{
CListBuilder builder;
};
struct nix_string_return
{
std::string str;
};
struct nix_printer
{
std::ostream & s;
};
struct nix_string_context
{
nix::NixStringContext & ctx;
};
#endif // NIX_API_EXPR_INTERNAL_H
+198
View File
@@ -0,0 +1,198 @@
#include "attr-set.hh"
#include "config.hh"
#include "eval.hh"
#include "gc/gc.h"
#include "globals.hh"
#include "value.hh"
#include "nix_api_expr.h"
#include "nix_api_expr_internal.h"
#include "nix_api_external.h"
#include "nix_api_util.h"
#include "nix_api_util_internal.h"
#include "nix_api_value.h"
#include "value/context.hh"
#include <nlohmann/json.hpp>
#ifdef HAVE_BOEHMGC
#define GC_INCLUDE_NEW 1
#include "gc_cpp.h"
#endif
void nix_set_string_return(nix_string_return * str, const char * c)
{
str->str = c;
}
nix_err nix_external_print(nix_c_context * context, nix_printer * printer, const char * c)
{
if (context)
context->last_err_code = NIX_OK;
try {
printer->s << c;
}
NIXC_CATCH_ERRS
}
nix_err nix_external_add_string_context(nix_c_context * context, nix_string_context * ctx, const char * c)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto r = nix::NixStringContextElem::parse(c);
ctx->ctx.insert(r);
}
NIXC_CATCH_ERRS
}
class NixCExternalValue : public nix::ExternalValueBase
{
NixCExternalValueDesc & desc;
void * v;
public:
NixCExternalValue(NixCExternalValueDesc & desc, void * v)
: desc(desc)
, v(v){};
void * get_ptr()
{
return v;
}
/**
* Print out the value
*/
virtual std::ostream & print(std::ostream & str) const override
{
nix_printer p{str};
desc.print(v, &p);
return str;
}
/**
* Return a simple string describing the type
*/
virtual std::string showType() const override
{
nix_string_return res;
desc.showType(v, &res);
return std::move(res.str);
}
/**
* Return a string to be used in builtins.typeOf
*/
virtual std::string typeOf() const override
{
nix_string_return res;
desc.typeOf(v, &res);
return std::move(res.str);
}
/**
* Coerce the value to a string.
*/
virtual std::string coerceToString(
nix::EvalState & state,
const nix::PosIdx & pos,
nix::NixStringContext & context,
bool copyMore,
bool copyToStore) const override
{
if (!desc.coerceToString) {
return nix::ExternalValueBase::coerceToString(state, pos, context, copyMore, copyToStore);
}
nix_string_context ctx{context};
nix_string_return res{""};
// todo: pos, errors
desc.coerceToString(v, &ctx, copyMore, copyToStore, &res);
if (res.str.empty()) {
return nix::ExternalValueBase::coerceToString(state, pos, context, copyMore, copyToStore);
}
return std::move(res.str);
}
/**
* Compare to another value of the same type.
*/
virtual bool operator==(const ExternalValueBase & b) const override
{
if (!desc.equal) {
return false;
}
auto r = dynamic_cast<const NixCExternalValue *>(&b);
if (!r)
return false;
return desc.equal(v, r->v);
}
/**
* Print the value as JSON.
*/
virtual nlohmann::json printValueAsJSON(
nix::EvalState & state, bool strict, nix::NixStringContext & context, bool copyToStore = true) const override
{
if (!desc.printValueAsJSON) {
return nix::ExternalValueBase::printValueAsJSON(state, strict, context, copyToStore);
}
nix_string_context ctx{context};
nix_string_return res{""};
desc.printValueAsJSON(v, (EvalState *) &state, strict, &ctx, copyToStore, &res);
if (res.str.empty()) {
return nix::ExternalValueBase::printValueAsJSON(state, strict, context, copyToStore);
}
return nlohmann::json::parse(res.str);
}
/**
* Print the value as XML.
*/
virtual void printValueAsXML(
nix::EvalState & state,
bool strict,
bool location,
nix::XMLWriter & doc,
nix::NixStringContext & context,
nix::PathSet & drvsSeen,
const nix::PosIdx pos) const override
{
if (!desc.printValueAsXML) {
return nix::ExternalValueBase::printValueAsXML(state, strict, location, doc, context, drvsSeen, pos);
}
nix_string_context ctx{context};
desc.printValueAsXML(
v, (EvalState *) &state, strict, location, &doc, &ctx, &drvsSeen,
*reinterpret_cast<const uint32_t *>(&pos));
}
virtual ~NixCExternalValue() override{};
};
ExternalValue * nix_create_external_value(nix_c_context * context, NixCExternalValueDesc * desc, void * v)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto ret = new
#ifdef HAVE_BOEHMGC
(GC)
#endif
NixCExternalValue(*desc, v);
nix_gc_incref(nullptr, ret);
return (ExternalValue *) ret;
}
NIXC_CATCH_ERRS_NULL
}
void * nix_get_external_value_content(nix_c_context * context, ExternalValue * b)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto r = dynamic_cast<NixCExternalValue *>((nix::ExternalValueBase *) b);
if (r)
return r->get_ptr();
return nullptr;
}
NIXC_CATCH_ERRS_NULL
}
+196
View File
@@ -0,0 +1,196 @@
#ifndef NIX_API_EXTERNAL_H
#define NIX_API_EXTERNAL_H
/** @ingroup libexpr
* @addtogroup Externals
* @brief Deal with external values
* @{
*/
/** @file
* @brief libexpr C bindings dealing with external values
*/
#include "nix_api_expr.h"
#include "nix_api_util.h"
#include "nix_api_value.h"
#include "stdbool.h"
#include "stddef.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
// cffi start
/**
* @brief Represents a string owned by the Nix language evaluator.
* @see nix_set_owned_string
*/
typedef struct nix_string_return nix_string_return;
/**
* @brief Wraps a stream that can output multiple string pieces.
*/
typedef struct nix_printer nix_printer;
/**
* @brief A list of string context items
*/
typedef struct nix_string_context nix_string_context;
/**
* @brief Sets the contents of a nix_string_return
*
* Copies the passed string.
* @param[out] str the nix_string_return to write to
* @param[in] c The string to copy
*/
void nix_set_string_return(nix_string_return * str, const char * c);
/**
* Print to the nix_printer
*
* @param[out] context Optional, stores error information
* @param printer The nix_printer to print to
* @param[in] str The string to print
* @returns NIX_OK if everything worked
*/
nix_err nix_external_print(nix_c_context * context, nix_printer * printer, const char * str);
/**
* Add string context to the nix_string_context object
* @param[out] context Optional, stores error information
* @param[out] string_context The nix_string_context to add to
* @param[in] c The context string to add
* @returns NIX_OK if everything worked
*/
nix_err nix_external_add_string_context(nix_c_context * context, nix_string_context * string_context, const char * c);
/**
* @brief Definition for a class of external values
*
* Create and implement one of these, then pass it to nix_create_external_value
* Make sure to keep it alive while the external value lives.
*
* Optional functions can be set to NULL
*
* @see nix_create_external_value
*/
typedef struct NixCExternalValueDesc
{
/**
* @brief Called when printing the external value
*
* @param[in] self the void* passed to nix_create_external_value
* @param[out] printer The printer to print to, pass to nix_external_print
*/
void (*print)(void * self, nix_printer * printer);
/**
* @brief Called on :t
* @param[in] self the void* passed to nix_create_external_value
* @param[out] res the return value
*/
void (*showType)(void * self, nix_string_return * res);
/**
* @brief Called on `builtins.typeOf`
* @param self the void* passed to nix_create_external_value
* @param[out] res the return value
*/
void (*typeOf)(void * self, nix_string_return * res);
/**
* @brief Called on "${str}" and builtins.toString.
*
* The latter with coerceMore=true
* Optional, the default is to throw an error.
* @param[in] self the void* passed to nix_create_external_value
* @param[out] c writable string context for the resulting string
* @param[in] coerceMore boolean, try to coerce to strings in more cases
* instead of throwing an error
* @param[in] copyToStore boolean, whether to copy referenced paths to store
* or keep them as-is
* @param[out] res the return value. Not touching this, or setting it to the
* empty string, will make the conversion throw an error.
*/
void (*coerceToString)(
void * self, nix_string_context * c, int coerceMore, int copyToStore, nix_string_return * res);
/**
* @brief Try to compare two external values
*
* Optional, the default is always false.
* If the other object was not a Nix C external value, this comparison will
* also return false
* @param[in] self the void* passed to nix_create_external_value
* @param[in] other the void* passed to the other object's
* nix_create_external_value
* @returns true if the objects are deemed to be equal
*/
int (*equal)(void * self, void * other);
/**
* @brief Convert the external value to json
*
* Optional, the default is to throw an error
* @param[in] self the void* passed to nix_create_external_value
* @param[in] state The evaluator state
* @param[in] strict boolean Whether to force the value before printing
* @param[out] c writable string context for the resulting string
* @param[in] copyToStore whether to copy referenced paths to store or keep
* them as-is
* @param[out] res the return value. Gets parsed as JSON. Not touching this,
* or setting it to the empty string, will make the conversion throw an error.
*/
void (*printValueAsJSON)(
void * self, EvalState *, bool strict, nix_string_context * c, bool copyToStore, nix_string_return * res);
/**
* @brief Convert the external value to XML
*
* Optional, the default is to throw an error
* @todo The mechanisms for this call are incomplete. There are no C
* bindings to work with XML, pathsets and positions.
* @param[in] self the void* passed to nix_create_external_value
* @param[in] state The evaluator state
* @param[in] strict boolean Whether to force the value before printing
* @param[in] location boolean Whether to include position information in the
* xml
* @param[out] doc XML document to output to
* @param[out] c writable string context for the resulting string
* @param[in,out] drvsSeen a path set to avoid duplicating derivations
* @param[in] pos The position of the call.
*/
void (*printValueAsXML)(
void * self,
EvalState *,
int strict,
int location,
void * doc,
nix_string_context * c,
void * drvsSeen,
int pos);
} NixCExternalValueDesc;
/**
* @brief Create an external value, that can be given to nix_init_external
*
* Owned by the GC. Use nix_gc_decref when you're done with the pointer.
*
* @param[out] context Optional, stores error information
* @param[in] desc a NixCExternalValueDesc, you should keep this alive as long
* as the ExternalValue lives
* @param[in] v the value to store
* @returns external value, owned by the garbage collector
* @see nix_init_external
*/
ExternalValue * nix_create_external_value(nix_c_context * context, NixCExternalValueDesc * desc, void * v);
/**
* @brief Extract the pointer from a nix c external value.
* @param[out] context Optional, stores error information
* @param[in] b The external value
* @returns The pointer, or null if the external value was not from nix c.
* @see nix_get_external
*/
void * nix_get_external_value_content(nix_c_context * context, ExternalValue * b);
// cffi end
#ifdef __cplusplus
}
#endif
/** @} */
#endif // NIX_API_EXTERNAL_H
+521
View File
@@ -0,0 +1,521 @@
#include "attr-set.hh"
#include "config.hh"
#include "eval.hh"
#include "gc/gc.h"
#include "globals.hh"
#include "primops.hh"
#include "value.hh"
#include "nix_api_expr.h"
#include "nix_api_expr_internal.h"
#include "nix_api_util.h"
#include "nix_api_util_internal.h"
#include "nix_api_value.h"
#ifdef HAVE_BOEHMGC
#define GC_INCLUDE_NEW 1
#include "gc_cpp.h"
#endif
// Helper function to throw an exception if value is null
static const nix::Value & check_value_not_null(const Value * value)
{
if (!value) {
throw std::runtime_error("Value is null");
}
return *((const nix::Value *) value);
}
static nix::Value & check_value_not_null(Value * value)
{
if (!value) {
throw std::runtime_error("Value is null");
}
return *((nix::Value *) value);
}
/**
* Helper function to convert calls from nix into C API.
*
* Deals with errors and converts arguments from C++ into C types.
*/
static void nix_c_primop_wrapper(
PrimOpFun f, void * userdata, nix::EvalState & state, const nix::PosIdx pos, nix::Value ** args, nix::Value & v)
{
nix_c_context ctx;
f(userdata, &ctx, (EvalState *) &state, (Value **) args, (Value *) &v);
/* TODO: In the future, this should throw different errors depending on the error code */
if (ctx.last_err_code != NIX_OK)
state.error<nix::EvalError>("Error from builtin function: %s", *ctx.last_err).atPos(pos).debugThrow();
}
PrimOp * nix_alloc_primop(
nix_c_context * context,
PrimOpFun fun,
int arity,
const char * name,
const char ** args,
const char * doc,
void * user_data)
{
if (context)
context->last_err_code = NIX_OK;
try {
using namespace std::placeholders;
auto p = new
#ifdef HAVE_BOEHMGC
(GC)
#endif
nix::PrimOp{
.name = name,
.args = {},
.arity = (size_t) arity,
.doc = doc,
.fun = std::bind(nix_c_primop_wrapper, fun, user_data, _1, _2, _3, _4)};
if (args)
for (size_t i = 0; args[i]; i++)
p->args.emplace_back(*args);
nix_gc_incref(nullptr, p);
return (PrimOp *) p;
}
NIXC_CATCH_ERRS_NULL
}
nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp)
{
if (context)
context->last_err_code = NIX_OK;
try {
nix::RegisterPrimOp r(std::move(*((nix::PrimOp *) primOp)));
}
NIXC_CATCH_ERRS
}
Value * nix_alloc_value(nix_c_context * context, EvalState * state)
{
if (context)
context->last_err_code = NIX_OK;
try {
Value * res = state->state.allocValue();
nix_gc_incref(nullptr, res);
return res;
}
NIXC_CATCH_ERRS_NULL
}
ValueType nix_get_type(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
using namespace nix;
switch (v.type()) {
case nThunk:
return NIX_TYPE_THUNK;
case nInt:
return NIX_TYPE_INT;
case nFloat:
return NIX_TYPE_FLOAT;
case nBool:
return NIX_TYPE_BOOL;
case nString:
return NIX_TYPE_STRING;
case nPath:
return NIX_TYPE_PATH;
case nNull:
return NIX_TYPE_NULL;
case nAttrs:
return NIX_TYPE_ATTRS;
case nList:
return NIX_TYPE_LIST;
case nFunction:
return NIX_TYPE_FUNCTION;
case nExternal:
return NIX_TYPE_EXTERNAL;
}
return NIX_TYPE_NULL;
}
NIXC_CATCH_ERRS_RES(NIX_TYPE_NULL);
}
const char * nix_get_typename(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
auto s = nix::showType(v);
return strdup(s.c_str());
}
NIXC_CATCH_ERRS_NULL
}
bool nix_get_bool(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nBool);
return v.boolean;
}
NIXC_CATCH_ERRS_RES(false);
}
const char * nix_get_string(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nString);
return v.string.s;
}
NIXC_CATCH_ERRS_NULL
}
const char * nix_get_path_string(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nPath);
return v._path;
}
NIXC_CATCH_ERRS_NULL
}
unsigned int nix_get_list_size(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nList);
return v.listSize();
}
NIXC_CATCH_ERRS_RES(0);
}
unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nAttrs);
return v.attrs->size();
}
NIXC_CATCH_ERRS_RES(0);
}
double nix_get_float(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nFloat);
return v.fpoint;
}
NIXC_CATCH_ERRS_RES(NAN);
}
int64_t nix_get_int(nix_c_context * context, const Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nInt);
return v.integer;
}
NIXC_CATCH_ERRS_RES(0);
}
ExternalValue * nix_get_external(nix_c_context * context, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nExternal);
return (ExternalValue *) v.external;
}
NIXC_CATCH_ERRS_NULL;
}
Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nList);
auto * p = v.listElems()[ix];
nix_gc_incref(nullptr, p);
state->state.forceValue(*p, nix::noPos);
return (Value *) p;
}
NIXC_CATCH_ERRS_NULL
}
Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nAttrs);
nix::Symbol s = state->state.symbols.create(name);
auto attr = v.attrs->get(s);
if (attr) {
nix_gc_incref(nullptr, attr->value);
state->state.forceValue(*attr->value, nix::noPos);
return attr->value;
}
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
return nullptr;
}
NIXC_CATCH_ERRS_NULL
}
bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
assert(v.type() == nix::nAttrs);
nix::Symbol s = state->state.symbols.create(name);
auto attr = v.attrs->get(s);
if (attr)
return true;
return false;
}
NIXC_CATCH_ERRS_RES(false);
}
Value *
nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
const nix::Attr & a = (*v.attrs)[i];
*name = ((const std::string &) (state->state.symbols[a.name])).c_str();
nix_gc_incref(nullptr, a.value);
state->state.forceValue(*a.value, nix::noPos);
return a.value;
}
NIXC_CATCH_ERRS_NULL
}
const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
const nix::Attr & a = (*v.attrs)[i];
return ((const std::string &) (state->state.symbols[a.name])).c_str();
}
NIXC_CATCH_ERRS_NULL
}
nix_err nix_init_bool(nix_c_context * context, Value * value, bool b)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkBool(b);
}
NIXC_CATCH_ERRS
}
// todo string context
nix_err nix_init_string(nix_c_context * context, Value * value, const char * str)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkString(std::string_view(str));
}
NIXC_CATCH_ERRS
}
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkPath(s->state.rootPath(nix::CanonPath(str)));
}
NIXC_CATCH_ERRS
}
nix_err nix_init_float(nix_c_context * context, Value * value, double d)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkFloat(d);
}
NIXC_CATCH_ERRS
}
nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkInt(i);
}
NIXC_CATCH_ERRS
}
nix_err nix_init_null(nix_c_context * context, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkNull();
}
NIXC_CATCH_ERRS
}
nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
auto r = (nix::ExternalValueBase *) val;
v.mkExternal(r);
}
NIXC_CATCH_ERRS
}
ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, size_t capacity)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto builder = CListBuilder(capacity);
return new
#if HAVE_BOEHMGC
(NoGC)
#endif
ListBuilder{std::move(builder)};
}
NIXC_CATCH_ERRS_NULL
}
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
list_builder->builder.push_back((nix::Value *) value);
}
NIXC_CATCH_ERRS
}
void nix_list_builder_free(ListBuilder * bb)
{
#if HAVE_BOEHMGC
GC_FREE(bb);
#else
delete bb;
#endif
}
nix_err nix_make_list(nix_c_context * context, EvalState * s, ListBuilder * list_builder, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
list_builder->builder.finish(&(s->state), &v);
}
NIXC_CATCH_ERRS
}
nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkPrimOp((nix::PrimOp *) p);
}
NIXC_CATCH_ERRS
}
nix_err nix_copy_value(nix_c_context * context, Value * value, Value * source)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
auto & s = check_value_not_null(source);
v = s;
}
NIXC_CATCH_ERRS
}
nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
v.mkAttrs(b->builder);
}
NIXC_CATCH_ERRS
}
BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * state, size_t capacity)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto bb = state->state.buildBindings(capacity);
return new
#if HAVE_BOEHMGC
(NoGC)
#endif
BindingsBuilder{std::move(bb)};
}
NIXC_CATCH_ERRS_NULL
}
nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, Value * value)
{
if (context)
context->last_err_code = NIX_OK;
try {
auto & v = check_value_not_null(value);
nix::Symbol s = bb->builder.state.symbols.create(name);
bb->builder.insert(s, &v);
}
NIXC_CATCH_ERRS
}
void nix_bindings_builder_free(BindingsBuilder * bb)
{
#if HAVE_BOEHMGC
GC_FREE((nix::BindingsBuilder *) bb);
#else
delete (nix::BindingsBuilder *) bb;
#endif
}
+433
View File
@@ -0,0 +1,433 @@
#ifndef NIX_API_VALUE_H
#define NIX_API_VALUE_H
/** @addtogroup libexpr
* @{
*/
/** @file
* @brief libexpr C bindings dealing with values
*/
#include "nix_api_util.h"
#include "stdbool.h"
#include "stddef.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
// cffi start
// Type definitions
typedef enum {
NIX_TYPE_THUNK,
NIX_TYPE_INT,
NIX_TYPE_FLOAT,
NIX_TYPE_BOOL,
NIX_TYPE_STRING,
NIX_TYPE_PATH,
NIX_TYPE_NULL,
NIX_TYPE_ATTRS,
NIX_TYPE_LIST,
NIX_TYPE_FUNCTION,
NIX_TYPE_EXTERNAL
} ValueType;
// forward declarations
typedef void Value;
typedef struct EvalState EvalState;
// type defs
/** @brief Stores an under-construction set of bindings
* @ingroup value_manip
*
* Do not reuse.
* @see nix_make_bindings_builder, nix_bindings_builder_free, nix_make_attrs
* @see nix_bindings_builder_insert
*/
typedef struct BindingsBuilder BindingsBuilder;
/** @brief Stores an under-construction list
* @ingroup value_manip
*
* Do not reuse.
* @see nix_make_list_builder, nix_list_builder_free, nix_make_list
* @see nix_list_builder_insert
*/
typedef struct ListBuilder ListBuilder;
/** @brief PrimOp function
* @ingroup primops
*
* Owned by the GC
* @see nix_alloc_primop, nix_init_primop
*/
typedef struct PrimOp PrimOp;
/** @brief External Value
* @ingroup Externals
*
* Owned by the GC
*/
typedef struct ExternalValue ExternalValue;
/** @defgroup primops
* @brief Create your own primops
* @{
*/
/** @brief Function pointer for primops
* When you want to return an error, call nix_set_err_msg(context, NIX_ERR_UNKNOWN, "your error message here").
*
* @param[in] user_data Arbitrary data that was initially supplied to nix_alloc_primop
* @param[out] context Stores error information.
* @param[in] state Evaluator state
* @param[in] args list of arguments. Note that these can be thunks and should be forced using nix_value_force before
* use.
* @param[out] ret return value
* @see nix_alloc_primop, nix_init_primop
*/
typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret);
/** @brief Allocate a PrimOp
*
* Owned by the garbage collector.
* Use nix_gc_decref() when you're done with the returned PrimOp.
*
* @param[out] context Optional, stores error information
* @param[in] fun callback
* @param[in] arity expected number of function arguments
* @param[in] name function name
* @param[in] args array of argument names, NULL-terminated
* @param[in] doc optional, documentation for this primop
* @param[in] user_data optional, arbitrary data, passed to the callback when it's called
* @return primop, or null in case of errors
* @see nix_init_primop
*/
PrimOp * nix_alloc_primop(
nix_c_context * context,
PrimOpFun fun,
int arity,
const char * name,
const char ** args,
const char * doc,
void * user_data);
/** @brief add a primop to the `builtins` attribute set
*
* Only applies to States created after this call.
*
* Moves your PrimOp content into the global evaluator
* registry, meaning your input PrimOp pointer is no longer usable.
* You are free to remove your references to it,
* after which it will be garbage collected.
*
* @param[out] context Optional, stores error information
* @return primop, or null in case of errors
*
*/
nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp);
/** @} */
// Function prototypes
/** @brief Allocate a Nix value
*
* Owned by the GC. Use nix_gc_decref() when you're done with the pointer
* @param[out] context Optional, stores error information
* @param[in] state nix evaluator state
* @return value, or null in case of errors
*
*/
Value * nix_alloc_value(nix_c_context * context, EvalState * state);
/** @addtogroup value_manip Manipulating values
* @brief Functions to inspect and change Nix language values, represented by Value.
* @{
*/
/** @name Getters
*/
/**@{*/
/** @brief Get value type
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return type of nix value
*/
ValueType nix_get_type(nix_c_context * context, const Value * value);
/** @brief Get type name of value as defined in the evaluator
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return type name, owned string
* @todo way to free the result
*/
const char * nix_get_typename(nix_c_context * context, const Value * value);
/** @brief Get boolean value
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return true or false, error info via context
*/
bool nix_get_bool(nix_c_context * context, const Value * value);
/** @brief Get string
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return string
* @return NULL in case of error.
*/
const char * nix_get_string(nix_c_context * context, const Value * value);
/** @brief Get path as string
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return string
* @return NULL in case of error.
*/
const char * nix_get_path_string(nix_c_context * context, const Value * value);
/** @brief Get the length of a list
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return length of list, error info via context
*/
unsigned int nix_get_list_size(nix_c_context * context, const Value * value);
/** @brief Get the element count of an attrset
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return attrset element count, error info via context
*/
unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value);
/** @brief Get float value in 64 bits
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return float contents, error info via context
*/
double nix_get_float(nix_c_context * context, const Value * value);
/** @brief Get int value
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return int contents, error info via context
*/
int64_t nix_get_int(nix_c_context * context, const Value * value);
/** @brief Get external reference
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @return reference to external, NULL in case of error
*/
ExternalValue * nix_get_external(nix_c_context * context, Value *);
/** @brief Get the ix'th element of a list
*
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @param[in] state nix evaluator state
* @param[in] ix list element to get
* @return value, NULL in case of errors
*/
Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix);
/** @brief Get an attr by name
*
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @param[in] state nix evaluator state
* @param[in] name attribute name
* @return value, NULL in case of errors
*/
Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name);
/** @brief Check if an attribute name exists on a value
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @param[in] state nix evaluator state
* @param[in] name attribute name
* @return value, error info via context
*/
bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name);
/** @brief Get an attribute by index in the sorted bindings
*
* Also gives you the name.
*
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @param[in] state nix evaluator state
* @param[in] i attribute index
* @param[out] name will store a pointer to the attribute name
* @return value, NULL in case of errors
*/
Value *
nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name);
/** @brief Get an attribute name by index in the sorted bindings
*
* Useful when you want the name but want to avoid evaluation.
*
* Owned by the nix EvalState
* @param[out] context Optional, stores error information
* @param[in] value Nix value to inspect
* @param[in] state nix evaluator state
* @param[in] i attribute index
* @return name, NULL in case of errors
*/
const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i);
/**@}*/
/** @name Initializers
*
* Values are typically "returned" by initializing already allocated memory that serves as the return value.
* For this reason, the construction of values is not tied their allocation.
* Nix is a language with immutable values. Respect this property by only initializing Values once; and only initialize
* Values that are meant to be initialized by you. Failing to adhere to these rules may lead to undefined behavior.
*/
/**@{*/
/** @brief Set boolean value
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] b the boolean value
* @return error code, NIX_OK on success.
*/
nix_err nix_init_bool(nix_c_context * context, Value * value, bool b);
/** @brief Set a string
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] str the string, copied
* @return error code, NIX_OK on success.
*/
nix_err nix_init_string(nix_c_context * context, Value * value, const char * str);
/** @brief Set a path
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] str the path string, copied
* @return error code, NIX_OK on success.
*/
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str);
/** @brief Set a float
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] d the float, 64-bits
* @return error code, NIX_OK on success.
*/
nix_err nix_init_float(nix_c_context * context, Value * value, double d);
/** @brief Set an int
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] i the int
* @return error code, NIX_OK on success.
*/
nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i);
/** @brief Set null
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @return error code, NIX_OK on success.
*/
nix_err nix_init_null(nix_c_context * context, Value * value);
/** @brief Set an external value
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] val the external value to set. Will be GC-referenced by the value.
* @return error code, NIX_OK on success.
*/
nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val);
/** @brief Create a list from a list builder
* @param[out] context Optional, stores error information
* @param[in] list_builder list builder to use. Make sure to unref this afterwards.
* @param[out] value Nix value to modify
* @return error code, NIX_OK on success.
*/
nix_err nix_make_list(nix_c_context * context, EvalState * s, ListBuilder * list_builder, Value * value);
/** @brief Create a list builder
* @param[out] context Optional, stores error information
* @param[in] state nix evaluator state
* @param[in] capacity how many bindings you'll add. Don't exceed.
* @return owned reference to a list builder. Make sure to unref when you're done.
*/
ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state, size_t capacity);
/** @brief Insert bindings into a builder
* @param[out] context Optional, stores error information
* @param[in] list_builder ListBuilder to insert into
* @param[in] value value to insert
* @return error code, NIX_OK on success.
*/
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, Value * value);
/** @brief Free a list builder
*
* Does not fail.
* @param[in] builder the builder to free
*/
void nix_list_builder_free(ListBuilder * builder);
/** @brief Create an attribute set from a bindings builder
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] b bindings builder to use. Make sure to unref this afterwards.
* @return error code, NIX_OK on success.
*/
nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b);
/** @brief Set primop
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] op primop, will be gc-referenced by the value
* @see nix_alloc_primop
* @return error code, NIX_OK on success.
*/
nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * op);
/** @brief Copy from another value
* @param[out] context Optional, stores error information
* @param[out] value Nix value to modify
* @param[in] source value to copy from
* @return error code, NIX_OK on success.
*/
nix_err nix_copy_value(nix_c_context * context, Value * value, Value * source);
/**@}*/
/** @brief Create a bindings builder
* @param[out] context Optional, stores error information
* @param[in] state nix evaluator state
* @param[in] capacity how many bindings you'll add. Don't exceed.
* @return owned reference to a bindings builder. Make sure to unref when you're
done.
*/
BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState * state, size_t capacity);
/** @brief Insert bindings into a builder
* @param[out] context Optional, stores error information
* @param[in] builder BindingsBuilder to insert into
* @param[in] name attribute name, copied into the symbol store
* @param[in] value value to give the binding
* @return error code, NIX_OK on success.
*/
nix_err
nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * builder, const char * name, Value * value);
/** @brief Free a bindings builder
*
* Does not fail.
* @param[in] builder the builder to free
*/
void nix_bindings_builder_free(BindingsBuilder * builder);
/**@}*/
// cffi end
#ifdef __cplusplus
}
#endif
/** @} */
#endif // NIX_API_VALUE_H
+15 -15
View File
@@ -490,7 +490,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErro
if (forceErrors)
debug("reevaluating failed cached attribute '%s'", getAttrPathStr(name));
else
throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(name));
throw CachedEvalError(root->state, "cached failure of attribute '%s'", getAttrPathStr(name));
} else
return std::make_shared<AttrCursor>(root,
std::make_pair(shared_from_this(), name), nullptr, std::move(attr));
@@ -499,7 +499,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErro
// evaluate to see whether 'name' exists
} else
return nullptr;
//throw TypeError("'%s' is not an attribute set", getAttrPathStr());
//error<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
}
}
@@ -507,7 +507,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErro
if (v.type() != nAttrs)
return nullptr;
//throw TypeError("'%s' is not an attribute set", getAttrPathStr());
//error<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
auto attr = v.attrs->get(name);
@@ -573,14 +573,14 @@ std::string AttrCursor::getString()
debug("using cached string attribute '%s'", getAttrPathStr());
return s->first;
} else
root->state.error("'%s' is not a string", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a string", getAttrPathStr()).debugThrow();
}
}
auto & v = forceValue();
if (v.type() != nString && v.type() != nPath)
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr()).debugThrow();
return v.type() == nString ? v.string.s : v.path().to_string();
}
@@ -615,7 +615,7 @@ string_t AttrCursor::getStringWithContext()
return *s;
}
} else
root->state.error("'%s' is not a string", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a string", getAttrPathStr()).debugThrow();
}
}
@@ -629,7 +629,7 @@ string_t AttrCursor::getStringWithContext()
else if (v.type() == nPath)
return {v.path().to_string(), {}};
else
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr()).debugThrow();
}
bool AttrCursor::getBool()
@@ -642,14 +642,14 @@ bool AttrCursor::getBool()
debug("using cached Boolean attribute '%s'", getAttrPathStr());
return *b;
} else
root->state.error("'%s' is not a Boolean", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a Boolean", getAttrPathStr()).debugThrow();
}
}
auto & v = forceValue();
if (v.type() != nBool)
root->state.error("'%s' is not a Boolean", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not a Boolean", getAttrPathStr()).debugThrow();
return v.boolean;
}
@@ -664,14 +664,14 @@ NixInt AttrCursor::getInt()
debug("using cached integer attribute '%s'", getAttrPathStr());
return i->x;
} else
throw TypeError("'%s' is not an integer", getAttrPathStr());
root->state.error<TypeError>("'%s' is not an integer", getAttrPathStr()).debugThrow();
}
}
auto & v = forceValue();
if (v.type() != nInt)
throw TypeError("'%s' is not an integer", getAttrPathStr());
root->state.error<TypeError>("'%s' is not an integer", getAttrPathStr()).debugThrow();
return v.integer;
}
@@ -686,7 +686,7 @@ std::vector<std::string> AttrCursor::getListOfStrings()
debug("using cached list of strings attribute '%s'", getAttrPathStr());
return *l;
} else
throw TypeError("'%s' is not a list of strings", getAttrPathStr());
root->state.error<TypeError>("'%s' is not a list of strings", getAttrPathStr()).debugThrow();
}
}
@@ -696,7 +696,7 @@ std::vector<std::string> AttrCursor::getListOfStrings()
root->state.forceValue(v, noPos);
if (v.type() != nList)
throw TypeError("'%s' is not a list", getAttrPathStr());
root->state.error<TypeError>("'%s' is not a list", getAttrPathStr()).debugThrow();
std::vector<std::string> res;
@@ -719,14 +719,14 @@ std::vector<Symbol> AttrCursor::getAttrs()
debug("using cached attrset attribute '%s'", getAttrPathStr());
return *attrs;
} else
root->state.error("'%s' is not an attribute set", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
}
}
auto & v = forceValue();
if (v.type() != nAttrs)
root->state.error("'%s' is not an attribute set", getAttrPathStr()).debugThrow<TypeError>();
root->state.error<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
std::vector<Symbol> attrs;
for (auto & attr : *getValue().attrs)
-2
View File
@@ -10,8 +10,6 @@
namespace nix::eval_cache {
MakeError(CachedEvalError, EvalError);
struct AttrDb;
class AttrCursor;
+113
View File
@@ -0,0 +1,113 @@
#include "eval-error.hh"
#include "eval.hh"
#include "value.hh"
namespace nix {
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withExitStatus(unsigned int exitStatus)
{
error.withExitStatus(exitStatus);
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::atPos(PosIdx pos)
{
error.err.pos = error.state.positions[pos];
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::atPos(Value & value, PosIdx fallback)
{
return atPos(value.determinePos(fallback));
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withTrace(PosIdx pos, const std::string_view text)
{
error.err.traces.push_front(
Trace{.pos = error.state.positions[pos], .hint = HintFmt(std::string(text)), .frame = false});
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrameTrace(PosIdx pos, const std::string_view text)
{
error.err.traces.push_front(
Trace{.pos = error.state.positions[pos], .hint = HintFmt(std::string(text)), .frame = true});
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withSuggestions(Suggestions & s)
{
error.err.suggestions = s;
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrame(const Env & env, const Expr & expr)
{
// NOTE: This is abusing side-effects.
// TODO: check compatibility with nested debugger calls.
// TODO: What side-effects??
error.state.debugTraces.push_front(DebugTrace{
.pos = error.state.positions[expr.getPos()],
.expr = expr,
.env = env,
.hint = HintFmt("Fake frame for debugging purposes"),
.isError = true});
return *this;
}
template<class T>
EvalErrorBuilder<T> & EvalErrorBuilder<T>::addTrace(PosIdx pos, HintFmt hint, bool frame)
{
error.addTrace(error.state.positions[pos], hint, frame);
return *this;
}
template<class T>
template<typename... Args>
EvalErrorBuilder<T> &
EvalErrorBuilder<T>::addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs)
{
addTrace(error.state.positions[pos], HintFmt(std::string(formatString), formatArgs...));
return *this;
}
template<class T>
void EvalErrorBuilder<T>::debugThrow()
{
if (error.state.debugRepl && !error.state.debugTraces.empty()) {
const DebugTrace & last = error.state.debugTraces.front();
const Env * env = &last.env;
const Expr * expr = &last.expr;
error.state.runDebugRepl(&error, *env, *expr);
}
// `EvalState` is the only class that can construct an `EvalErrorBuilder`,
// and it does so in dynamic storage. This is the final method called on
// any such instance and must delete itself before throwing the underlying
// error.
auto error = std::move(this->error);
delete this;
throw error;
}
template class EvalErrorBuilder<EvalError>;
template class EvalErrorBuilder<AssertionError>;
template class EvalErrorBuilder<ThrownError>;
template class EvalErrorBuilder<Abort>;
template class EvalErrorBuilder<TypeError>;
template class EvalErrorBuilder<UndefinedVarError>;
template class EvalErrorBuilder<MissingArgumentError>;
template class EvalErrorBuilder<InfiniteRecursionError>;
template class EvalErrorBuilder<CachedEvalError>;
template class EvalErrorBuilder<InvalidPathError>;
}
+105
View File
@@ -0,0 +1,105 @@
#pragma once
#include <algorithm>
#include "error.hh"
#include "pos-idx.hh"
namespace nix {
struct Env;
struct Expr;
struct Value;
class EvalState;
template<class T>
class EvalErrorBuilder;
class EvalError : public Error
{
template<class T>
friend class EvalErrorBuilder;
public:
EvalState & state;
EvalError(EvalState & state, ErrorInfo && errorInfo)
: Error(errorInfo)
, state(state)
{
}
template<typename... Args>
explicit EvalError(EvalState & state, const std::string & formatString, const Args &... formatArgs)
: Error(formatString, formatArgs...)
, state(state)
{
}
};
MakeError(ParseError, Error);
MakeError(AssertionError, EvalError);
MakeError(ThrownError, AssertionError);
MakeError(Abort, EvalError);
MakeError(TypeError, EvalError);
MakeError(UndefinedVarError, EvalError);
MakeError(MissingArgumentError, EvalError);
MakeError(RestrictedPathError, Error);
MakeError(CachedEvalError, EvalError);
MakeError(InfiniteRecursionError, EvalError);
struct InvalidPathError : public EvalError
{
public:
Path path;
InvalidPathError(EvalState & state, const Path & path)
: EvalError(state, "path '%s' is not valid", path)
{
}
};
/**
* `EvalErrorBuilder`s may only be constructed by `EvalState`. The `debugThrow`
* method must be the final method in any such `EvalErrorBuilder` usage, and it
* handles deleting the object.
*/
template<class T>
class EvalErrorBuilder final
{
friend class EvalState;
template<typename... Args>
explicit EvalErrorBuilder(EvalState & state, const Args &... args)
: error(T(state, args...))
{
}
public:
T error;
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withExitStatus(unsigned int exitStatus);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & atPos(PosIdx pos);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & atPos(Value & value, PosIdx fallback = noPos);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrameTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withSuggestions(Suggestions & s);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrame(const Env & e, const Expr & ex);
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & addTrace(PosIdx pos, HintFmt hint, bool frame = false);
template<typename... Args>
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> &
addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs);
/**
* Delete the `EvalErrorBuilder` and throw the underlying exception.
*/
[[gnu::noinline, gnu::noreturn]] void debugThrow();
};
}
+17 -17
View File
@@ -1,7 +1,9 @@
#pragma once
///@file
#include "print.hh"
#include "eval.hh"
#include "eval-error.hh"
namespace nix {
@@ -73,8 +75,6 @@ Env & EvalState::allocEnv(size_t size)
#endif
env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *));
env->type = Env::Plain;
/* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */
return *env;
@@ -83,13 +83,6 @@ Env & EvalState::allocEnv(size_t size)
[[gnu::always_inline]]
void EvalState::forceValue(Value & v, const PosIdx pos)
{
forceValue(v, [&]() { return pos; });
}
template<typename Callable>
void EvalState::forceValue(Value & v, Callable getPos)
{
if (v.isThunk()) {
Env * env = v.thunk.env;
@@ -100,13 +93,12 @@ void EvalState::forceValue(Value & v, Callable getPos)
expr->eval(*this, *env, v);
} catch (...) {
v.mkThunk(env, expr);
tryFixupBlackHolePos(v, pos);
throw;
}
}
else if (v.isApp())
callFunction(*v.app.left, *v.app.right, v, noPos);
else if (v.isBlackhole())
error("infinite recursion encountered").atPos(getPos()).template debugThrow<EvalError>();
callFunction(*v.app.left, *v.app.right, v, pos);
}
@@ -121,10 +113,14 @@ template <typename Callable>
[[gnu::always_inline]]
inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view errorCtx)
{
forceValue(v, noPos);
PosIdx pos = getPos();
forceValue(v, pos);
if (v.type() != nAttrs) {
PosIdx pos = getPos();
error("value is %1% while a set was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
error<TypeError>(
"expected a set but found %1%: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions)
).withTrace(pos, errorCtx).debugThrow();
}
}
@@ -132,9 +128,13 @@ inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view e
[[gnu::always_inline]]
inline void EvalState::forceList(Value & v, const PosIdx pos, std::string_view errorCtx)
{
forceValue(v, noPos);
forceValue(v, pos);
if (!v.isList()) {
error("value is %1% while a list was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
error<TypeError>(
"expected a list but found %1%: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions)
).withTrace(pos, errorCtx).debugThrow();
}
}
+6
View File
@@ -88,6 +88,12 @@ std::string EvalSettings::resolvePseudoUrl(std::string_view url)
return std::string(url);
}
const std::string & EvalSettings::getCurrentSystem()
{
const auto & evalSystem = currentSystem.get();
return evalSystem != "" ? evalSystem : settings.thisSystem.get();
}
EvalSettings evalSettings;
static GlobalConfig::Register rEvalSettings(&evalSettings);
+23
View File
@@ -25,6 +25,26 @@ struct EvalSettings : Config
[`builtins.nixPath`](@docroot@/language/builtin-constants.md#builtins-nixPath).
)"};
Setting<std::string> currentSystem{
this, "", "eval-system",
R"(
This option defines
[`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem)
in the Nix language if it is set as a non-empty string.
Otherwise, if it is defined as the empty string (the default), the value of the
[`system` ](#conf-system)
configuration setting is used instead.
Unlike `system`, this setting does not change what kind of derivations can be built locally.
This is useful for evaluating Nix code on one system to produce derivations to be built on another type of system.
)"};
/**
* Implements the `eval-system` vs `system` defaulting logic
* described for `eval-system`.
*/
const std::string & getCurrentSystem();
Setting<bool> restrictEval{
this, false, "restrict-eval",
R"(
@@ -91,6 +111,9 @@ struct EvalSettings : Config
Setting<bool> traceVerbose{this, false, "trace-verbose",
"Whether `builtins.traceVerbose` should trace its first argument when evaluated."};
Setting<unsigned int> maxCallDepth{this, 10000, "max-call-depth",
"The maximum function call depth to allow before erroring."};
};
extern EvalSettings evalSettings;
+569 -333
View File
File diff suppressed because it is too large Load Diff
+54 -99
View File
@@ -2,6 +2,7 @@
///@file
#include "attr-set.hh"
#include "eval-error.hh"
#include "types.hh"
#include "value.hh"
#include "nixexpr.hh"
@@ -18,6 +19,12 @@
namespace nix {
/**
* We put a limit on primop arity because it lets us use a fixed size array on
* the stack. 8 is already an impractical number of arguments. Use an attrset
* argument for such overly complicated functions.
*/
constexpr size_t maxPrimOpArity = 8;
class Store;
class EvalState;
@@ -29,7 +36,7 @@ enum RepairFlag : bool;
/**
* Function that implements a primop.
*/
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
typedef std::function<void (EvalState &, const PosIdx, Value **, Value &)> PrimOpFun;
/**
* Info about a primitive operation, and its implementation
@@ -69,8 +76,16 @@ struct PrimOp
* Optional experimental for this to be gated on.
*/
std::optional<ExperimentalFeature> experimentalFeature;
/**
* Validity check to be performed by functions that introduce primops,
* such as RegisterPrimOp() and Value::mkPrimOp().
*/
void check();
};
std::ostream & operator<<(std::ostream & output, PrimOp & primOp);
/**
* Info about a constant
*/
@@ -103,11 +118,6 @@ struct Constant
struct Env
{
Env * up;
/**
* Number of of levels up to next `with` environment
*/
unsigned short prevWith:14;
enum { Plain = 0, HasWithExpr, HasWithAttrs } type:2;
Value * values[0];
};
@@ -119,7 +129,7 @@ std::unique_ptr<ValMap> mapStaticEnvBindings(const SymbolTable & st, const Stati
void copyContext(const Value & v, NixStringContext & context);
std::string printValue(const EvalState & state, const Value & v);
std::string printValue(EvalState & state, Value & v);
std::ostream & operator << (std::ostream & os, const ValueType t);
@@ -134,52 +144,13 @@ struct RegexCache;
std::shared_ptr<RegexCache> makeRegexCache();
struct DebugTrace {
std::shared_ptr<AbstractPos> pos;
std::shared_ptr<Pos> pos;
const Expr & expr;
const Env & env;
hintformat hint;
HintFmt hint;
bool isError;
};
void debugError(Error * e, Env & env, Expr & expr);
class ErrorBuilder
{
private:
EvalState & state;
ErrorInfo info;
ErrorBuilder(EvalState & s, ErrorInfo && i): state(s), info(i) { }
public:
template<typename... Args>
[[nodiscard, gnu::noinline]]
static ErrorBuilder * create(EvalState & s, const Args & ... args)
{
return new ErrorBuilder(s, ErrorInfo { .msg = hintfmt(args...) });
}
[[nodiscard, gnu::noinline]]
ErrorBuilder & atPos(PosIdx pos);
[[nodiscard, gnu::noinline]]
ErrorBuilder & withTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]]
ErrorBuilder & withFrameTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]]
ErrorBuilder & withSuggestions(Suggestions & s);
[[nodiscard, gnu::noinline]]
ErrorBuilder & withFrame(const Env & e, const Expr & ex);
template<class ErrorType>
[[gnu::noinline, gnu::noreturn]]
void debugThrow();
};
class EvalState : public std::enable_shared_from_this<EvalState>
{
public:
@@ -197,6 +168,8 @@ public:
sPrefix,
sOutputSpecified;
const Expr::AstSymbols exprSymbols;
/**
* If set, force copying files to the Nix store even if they
* already exist there.
@@ -211,6 +184,11 @@ public:
Bindings emptyBindings;
/**
* Empty list constant.
*/
Value vEmptyList;
const SourcePath derivationInternal;
/**
@@ -246,39 +224,11 @@ public:
void runDebugRepl(const Error * error, const Env & env, const Expr & expr);
template<class E>
[[gnu::noinline, gnu::noreturn]]
void debugThrowLastTrace(E && error)
{
debugThrow(error, nullptr, nullptr);
}
template<class E>
[[gnu::noinline, gnu::noreturn]]
void debugThrow(E && error, const Env * env, const Expr * expr)
{
if (debugRepl && ((env && expr) || !debugTraces.empty())) {
if (!env || !expr) {
const DebugTrace & last = debugTraces.front();
env = &last.env;
expr = &last.expr;
}
runDebugRepl(&error, *env, *expr);
}
throw std::move(error);
}
// This is dangerous, but gets in line with the idea that error creation and
// throwing should not allocate on the stack of hot functions.
// as long as errors are immediately thrown, it works.
ErrorBuilder * errorBuilder;
template<typename... Args>
template<class T, typename... Args>
[[nodiscard, gnu::noinline]]
ErrorBuilder & error(const Args & ... args) {
errorBuilder = ErrorBuilder::create(*this, args...);
return *errorBuilder;
EvalErrorBuilder<T> & error(const Args & ... args) {
// `EvalErrorBuilder::debugThrow` performs the corresponding `delete`.
return *new EvalErrorBuilder<T>(*this, args...);
}
private:
@@ -455,8 +405,7 @@ public:
*/
inline void forceValue(Value & v, const PosIdx pos);
template <typename Callable>
inline void forceValue(Value & v, Callable getPos);
void tryFixupBlackHolePos(Value & v, PosIdx pos);
/**
* Force a value, then recursively force list elements and
@@ -618,6 +567,11 @@ private:
const SourcePath & basePath,
std::shared_ptr<StaticEnv> & staticEnv);
/**
* Current Nix call stack depth, used with `max-call-depth` setting to throw stack overflow hopefully before we run out of system stack.
*/
size_t callDepth = 0;
public:
/**
@@ -709,9 +663,25 @@ public:
void concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos, std::string_view errorCtx);
/**
* Print statistics.
* Print statistics, if enabled.
*
* Performs a full memory GC before printing the statistics, so that the
* GC statistics are more accurate.
*/
void printStats();
void maybePrintStats();
/**
* Print statistics, unconditionally, cheaply, without performing a GC first.
*/
void printStatistics();
/**
* Perform a full memory garbage collection - not incremental.
*
* @return true if Nix was built with GC and a GC was performed, false if not.
* The return value is currently not thread safe - just the return value.
*/
bool fullGC();
/**
* Realise the given context, and return a mapping from the placeholders
@@ -804,23 +774,8 @@ std::string showType(const Value & v);
*/
SourcePath resolveExprPath(SourcePath path);
struct InvalidPathError : EvalError
{
Path path;
InvalidPathError(const Path & path);
#ifdef EXCEPTION_NEEDS_THROW_SPEC
~InvalidPathError() throw () { };
#endif
};
static const std::string corepkgsPrefix{"/__corepkgs__/"};
template<class ErrorType>
void ErrorBuilder::debugThrow()
{
// NOTE: We always use the -LastTrace version as we push the new trace in withFrame()
state.debugThrowLastTrace(ErrorType(info));
}
}
+19 -14
View File
@@ -140,15 +140,15 @@ static FlakeInput parseFlakeInput(EvalState & state,
attrs.emplace(state.symbols[attr.name], (long unsigned int)attr.value->integer);
break;
default:
throw TypeError("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
state.symbols[attr.name], showType(*attr.value));
state.error<TypeError>("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
state.symbols[attr.name], showType(*attr.value)).debugThrow();
}
#pragma GCC diagnostic pop
}
} catch (Error & e) {
e.addTrace(
state.positions[attr.pos],
hintfmt("while evaluating flake attribute '%s'", state.symbols[attr.name]));
HintFmt("while evaluating flake attribute '%s'", state.symbols[attr.name]));
throw;
}
}
@@ -157,7 +157,7 @@ static FlakeInput parseFlakeInput(EvalState & state,
try {
input.ref = FlakeRef::fromAttrs(attrs);
} catch (Error & e) {
e.addTrace(state.positions[pos], hintfmt("while evaluating flake input"));
e.addTrace(state.positions[pos], HintFmt("while evaluating flake input"));
throw;
}
else {
@@ -205,8 +205,16 @@ static Flake getFlake(
auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree(
state, originalRef, allowLookup, flakeCache);
// We need to guard against symlink attacks, but before we start doing
// filesystem operations we should make sure there's a flake.nix in the
// first place.
auto unsafeFlakeDir = sourceInfo.actualPath + "/" + lockedRef.subdir;
auto unsafeFlakeFile = unsafeFlakeDir + "/flake.nix";
if (!pathExists(unsafeFlakeFile))
throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", lockedRef, lockedRef.subdir);
// Guard against symlink attacks.
auto flakeDir = canonPath(sourceInfo.actualPath + "/" + lockedRef.subdir, true);
auto flakeDir = canonPath(unsafeFlakeDir, true);
auto flakeFile = canonPath(flakeDir + "/flake.nix", true);
if (!isInDir(flakeFile, sourceInfo.actualPath))
throw Error("'flake.nix' file of flake '%s' escapes from '%s'",
@@ -219,9 +227,6 @@ static Flake getFlake(
.sourceInfo = std::make_shared<fetchers::Tree>(std::move(sourceInfo))
};
if (!pathExists(flakeFile))
throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", lockedRef, lockedRef.subdir);
Value vInfo;
state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack
@@ -283,15 +288,15 @@ static Flake getFlake(
std::vector<std::string> ss;
for (auto elem : setting.value->listItems()) {
if (elem->type() != nString)
throw TypeError("list element in flake configuration setting '%s' is %s while a string is expected",
state.symbols[setting.name], showType(*setting.value));
state.error<TypeError>("list element in flake configuration setting '%s' is %s while a string is expected",
state.symbols[setting.name], showType(*setting.value)).debugThrow();
ss.emplace_back(state.forceStringNoCtx(*elem, setting.pos, ""));
}
flake.config.settings.emplace(state.symbols[setting.name], ss);
}
else
throw TypeError("flake configuration setting '%s' is %s",
state.symbols[setting.name], showType(*setting.value));
state.error<TypeError>("flake configuration setting '%s' is %s",
state.symbols[setting.name], showType(*setting.value)).debugThrow();
}
}
@@ -852,11 +857,11 @@ static void prim_flakeRefToString(
attrs.emplace(state.symbols[attr.name],
std::string(attr.value->str()));
} else {
state.error(
state.error<EvalError>(
"flake reference attribute sets may only contain integers, Booleans, "
"and strings, but attribute '%s' is %s",
state.symbols[attr.name],
showType(*attr.value)).debugThrow<EvalError>();
showType(*attr.value)).debugThrow();
}
}
auto flakeRef = FlakeRef::fromAttrs(attrs);
+1 -1
View File
@@ -89,7 +89,7 @@ LockFile::LockFile(const nlohmann::json & json, const Path & path)
std::string inputKey = i.value();
auto k = nodeMap.find(inputKey);
if (k == nodeMap.end()) {
auto nodes = json["nodes"];
auto & nodes = json["nodes"];
auto jsonNode2 = nodes.find(inputKey);
if (jsonNode2 == nodes.end())
throw Error("lock file references missing node '%s'", inputKey);
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <boost/container/small_vector.hpp>
#if HAVE_BOEHMGC
#include <gc/gc.h>
#include <gc/gc_cpp.h>
#include <gc/gc_allocator.h>
#endif
namespace nix {
struct Value;
/**
* A GC compatible vector that may used a reserved portion of `nItems` on the stack instead of allocating on the heap.
*/
#if HAVE_BOEHMGC
template <typename T, size_t nItems>
using SmallVector = boost::container::small_vector<T, nItems, traceable_allocator<T>>;
#else
template <typename T, size_t nItems>
using SmallVector = boost::container::small_vector<T, nItems>;
#endif
/**
* A vector of value pointers. See `SmallVector`.
*/
template <size_t nItems>
using SmallValueVector = SmallVector<Value *, nItems>;
/**
* A vector of values that must not be referenced after the vector is destroyed.
*
* See also `SmallValueVector`.
*/
template <size_t nItems>
using SmallTemporaryValueVector = SmallVector<Value, nItems>;
}
+5 -4
View File
@@ -50,7 +50,7 @@ std::string DrvInfo::queryName() const
{
if (name == "" && attrs) {
auto i = attrs->find(state->sName);
if (i == attrs->end()) throw TypeError("derivation name missing");
if (i == attrs->end()) state->error<TypeError>("derivation name missing").debugThrow();
name = state->forceStringNoCtx(*i->value, noPos, "while evaluating the 'name' attribute of a derivation");
}
return name;
@@ -199,7 +199,7 @@ StringSet DrvInfo::queryMetaNames()
bool DrvInfo::checkMeta(Value & v)
{
state->forceValue(v, [&]() { return v.determinePos(noPos); });
state->forceValue(v, v.determinePos(noPos));
if (v.type() == nList) {
for (auto elem : v.listItems())
if (!checkMeta(*elem)) return false;
@@ -305,7 +305,7 @@ static bool getDerivation(EvalState & state, Value & v,
bool ignoreAssertionFailures)
{
try {
state.forceValue(v, [&]() { return v.determinePos(noPos); });
state.forceValue(v, v.determinePos(noPos));
if (!state.isDerivation(v)) return true;
/* Remove spurious duplicates (e.g., a set like `rec { x =
@@ -397,7 +397,8 @@ static void getDerivations(EvalState & state, Value & vIn,
}
}
else throw TypeError("expression does not evaluate to a derivation (or a set or list of those)");
else
state.error<TypeError>("expression does not evaluate to a derivation (or a set or list of those)").debugThrow();
}
+3 -1
View File
@@ -1,4 +1,6 @@
#include "json-to-value.hh"
#include "value.hh"
#include "eval.hh"
#include <variant>
#include <nlohmann/json.hpp>
@@ -159,7 +161,7 @@ public:
}
bool parse_error(std::size_t, const std::string&, const nlohmann::detail::exception& ex) {
throw JSONParseError(ex.what());
throw JSONParseError("%s", ex.what());
}
};

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