mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 06:42:28 +00:00
Merge remote-tracking branch 'upstream/master' into package-nix
This commit is contained in:
commit
c9838bb9ee
8
.gitignore
vendored
8
.gitignore
vendored
@ -22,6 +22,8 @@ perl/Makefile.config
|
||||
/doc/manual/xp-features.json
|
||||
/doc/manual/src/SUMMARY.md
|
||||
/doc/manual/src/SUMMARY-rl-next.md
|
||||
/doc/manual/src/store/types/*
|
||||
!/doc/manual/src/store/types/index.md.in
|
||||
/doc/manual/src/command-ref/new-cli
|
||||
/doc/manual/src/command-ref/conf-file.md
|
||||
/doc/manual/src/command-ref/experimental-features-shortlist.md
|
||||
@ -43,14 +45,14 @@ perl/Makefile.config
|
||||
/src/libexpr/parser-tab.hh
|
||||
/src/libexpr/parser-tab.output
|
||||
/src/libexpr/nix.tbl
|
||||
/src/libexpr/tests/libnixexpr-tests
|
||||
/tests/unit/libexpr/libnixexpr-tests
|
||||
|
||||
# /src/libstore/
|
||||
*.gen.*
|
||||
/src/libstore/tests/libnixstore-tests
|
||||
/tests/unit/libstore/libnixstore-tests
|
||||
|
||||
# /src/libutil/
|
||||
/src/libutil/tests/libnixutil-tests
|
||||
/tests/unit/libutil/libnixutil-tests
|
||||
|
||||
/src/nix/nix
|
||||
|
||||
|
10
Makefile
10
Makefile
@ -25,11 +25,13 @@ makefiles = \
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
|
||||
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
|
||||
makefiles += \
|
||||
src/libutil/tests/local.mk \
|
||||
src/libstore/tests/local.mk \
|
||||
src/libexpr/tests/local.mk
|
||||
tests/unit/libutil/local.mk \
|
||||
tests/unit/libutil-support/local.mk \
|
||||
tests/unit/libstore/local.mk \
|
||||
tests/unit/libstore-support/local.mk \
|
||||
tests/unit/libexpr/local.mk \
|
||||
tests/unit/libexpr-support/local.mk
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_TESTS), yes)
|
||||
|
@ -39,17 +39,21 @@ INPUT = \
|
||||
src/libcmd \
|
||||
src/libexpr \
|
||||
src/libexpr/flake \
|
||||
src/libexpr/tests \
|
||||
src/libexpr/tests/value \
|
||||
tests/unit/libexpr \
|
||||
tests/unit/libexpr/value \
|
||||
tests/unit/libexpr/test \
|
||||
tests/unit/libexpr/test/value \
|
||||
src/libexpr/value \
|
||||
src/libfetchers \
|
||||
src/libmain \
|
||||
src/libstore \
|
||||
src/libstore/build \
|
||||
src/libstore/builtins \
|
||||
src/libstore/tests \
|
||||
tests/unit/libstore \
|
||||
tests/unit/libstore/test \
|
||||
src/libutil \
|
||||
src/libutil/tests \
|
||||
tests/unit/libutil \
|
||||
tests/unit/libutil/test \
|
||||
src/nix \
|
||||
src/nix-env \
|
||||
src/nix-store
|
||||
|
@ -51,7 +51,7 @@ let
|
||||
|
||||
${maybeSubcommands}
|
||||
|
||||
${maybeStoreDocs}
|
||||
${maybeProse}
|
||||
|
||||
${maybeOptions}
|
||||
'';
|
||||
@ -91,25 +91,55 @@ let
|
||||
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
|
||||
'';
|
||||
|
||||
# FIXME: this is a hack.
|
||||
# store parameters should not be part of command documentation to begin
|
||||
# with, but instead be rendered on separate pages.
|
||||
maybeStoreDocs = optionalString (details ? doc)
|
||||
(replaceStrings [ "@stores@" ] [ (showStoreDocs inlineHTML commandInfo.stores) ] details.doc);
|
||||
maybeProse =
|
||||
# FIXME: this is a horrible hack to keep `nix help-stores` working.
|
||||
# the correct answer to this is to remove that command and replace it
|
||||
# by statically generated manpages or the output of something like `nix
|
||||
# store info <store type>`.
|
||||
let
|
||||
help-stores = ''
|
||||
${index}
|
||||
|
||||
maybeOptions = let
|
||||
allVisibleOptions = filterAttrs
|
||||
(_: o: ! o.hiddenCategory)
|
||||
(details.flags // toplevel.flags);
|
||||
in optionalString (allVisibleOptions != {}) ''
|
||||
# Options
|
||||
${allStores}
|
||||
'';
|
||||
index = replaceStrings
|
||||
[ "@store-types@" ] [ storesOverview ]
|
||||
details.doc;
|
||||
storesOverview =
|
||||
let
|
||||
showEntry = store:
|
||||
"- [${store.name}](#${store.slug})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList) + "\n";
|
||||
allStores = concatStringsSep "\n" (attrValues storePages);
|
||||
storePages = listToAttrs
|
||||
(map (s: { name = s.filename; value = s.page; }) storesList);
|
||||
storesList = showStoreDocs {
|
||||
storeInfo = commandInfo.stores;
|
||||
inherit inlineHTML;
|
||||
};
|
||||
in
|
||||
optionalString (details ? doc) (
|
||||
if match "@store-types@" details.doc != [ ]
|
||||
then help-stores
|
||||
else details.doc
|
||||
);
|
||||
|
||||
${showOptions inlineHTML allVisibleOptions}
|
||||
maybeOptions =
|
||||
let
|
||||
allVisibleOptions = filterAttrs
|
||||
(_: o: ! o.hiddenCategory)
|
||||
(details.flags // toplevel.flags);
|
||||
in
|
||||
optionalString (allVisibleOptions != { }) ''
|
||||
# Options
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
|
||||
'';
|
||||
${showOptions inlineHTML allVisibleOptions}
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
|
||||
'';
|
||||
|
||||
showOptions = inlineHTML: allOptions:
|
||||
let
|
||||
|
@ -31,18 +31,19 @@ let
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
>
|
||||
> This setting is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
|
||||
To change this setting, 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`](#):
|
||||
|
||||
```
|
||||
extra-experimental-features = ${experimentalFeature}
|
||||
${setting} = ...
|
||||
```
|
||||
>
|
||||
> To change this setting, make sure the
|
||||
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature})
|
||||
> is enabled.
|
||||
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ${experimentalFeature}
|
||||
> ${setting} = ...
|
||||
> ```
|
||||
'';
|
||||
|
||||
showDefault = documentDefault: defaultValue:
|
||||
|
@ -1,45 +1,57 @@
|
||||
let
|
||||
inherit (builtins) attrValues mapAttrs;
|
||||
inherit (import <nix/utils.nix>) concatStrings optionalString;
|
||||
inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings;
|
||||
inherit (import <nix/utils.nix>) optionalString filterAttrs trim squash toLower unique indent;
|
||||
showSettings = import <nix/generate-settings.nix>;
|
||||
in
|
||||
|
||||
inlineHTML: storesInfo:
|
||||
{
|
||||
# data structure describing all stores and their parameters
|
||||
storeInfo,
|
||||
# whether to add inline HTML tags
|
||||
# `lowdown` does not eat those for one of the output modes
|
||||
inlineHTML,
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
showStore = name: { settings, doc, experimentalFeature }:
|
||||
showStore = { name, slug }: { settings, doc, experimentalFeature }:
|
||||
let
|
||||
result = squash ''
|
||||
# ${name}
|
||||
|
||||
result = ''
|
||||
## ${name}
|
||||
${doc}
|
||||
|
||||
${doc}
|
||||
${experimentalFeatureNote}
|
||||
|
||||
${experimentalFeatureNote}
|
||||
## Settings
|
||||
|
||||
### Settings
|
||||
${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings}
|
||||
'';
|
||||
|
||||
${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings}
|
||||
'';
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
>
|
||||
> This store is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
>
|
||||
> To use this store, make sure the
|
||||
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature})
|
||||
> is enabled.
|
||||
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||
>
|
||||
> ```
|
||||
> extra-experimental-features = ${experimentalFeature}
|
||||
> ```
|
||||
'';
|
||||
in result;
|
||||
|
||||
# markdown doesn't like spaces in URLs
|
||||
slug = builtins.replaceStrings [ " " ] [ "-" ] name;
|
||||
storesList = map
|
||||
(name: rec {
|
||||
inherit name;
|
||||
slug = replaceStrings [ " " ] [ "-" ] (toLower name);
|
||||
filename = "${slug}.md";
|
||||
page = showStore { inherit name slug; } storeInfo.${name};
|
||||
})
|
||||
(attrNames storeInfo);
|
||||
|
||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||
> **Warning**
|
||||
> This store is part of an
|
||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||
|
||||
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`](#):
|
||||
|
||||
```
|
||||
extra-experimental-features = ${experimentalFeature}
|
||||
```
|
||||
'';
|
||||
in result;
|
||||
|
||||
in concatStrings (attrValues (mapAttrs showStore storesInfo))
|
||||
in storesList
|
||||
|
39
doc/manual/generate-store-types.nix
Normal file
39
doc/manual/generate-store-types.nix
Normal file
@ -0,0 +1,39 @@
|
||||
let
|
||||
inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings;
|
||||
showSettings = import <nix/generate-settings.nix>;
|
||||
showStoreDocs = import <nix/generate-store-info.nix>;
|
||||
in
|
||||
|
||||
storeInfo:
|
||||
|
||||
let
|
||||
storesList = showStoreDocs {
|
||||
inherit storeInfo;
|
||||
inlineHTML = true;
|
||||
};
|
||||
|
||||
index =
|
||||
let
|
||||
showEntry = store:
|
||||
"- [${store.name}](./${store.filename})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList);
|
||||
|
||||
"index.md" = replaceStrings
|
||||
[ "@store-types@" ] [ index ]
|
||||
(readFile ./src/store/types/index.md.in);
|
||||
|
||||
tableOfContents =
|
||||
let
|
||||
showEntry = store:
|
||||
" - [${store.name}](store/types/${store.filename})";
|
||||
in
|
||||
concatStringsSep "\n" (map showEntry storesList) + "\n";
|
||||
|
||||
"SUMMARY.md" = tableOfContents;
|
||||
|
||||
storePages = listToAttrs
|
||||
(map (s: { name = s.filename; value = s.page; }) storesList);
|
||||
|
||||
in
|
||||
storePages // { inherit "index.md" "SUMMARY.md"; }
|
@ -8,4 +8,6 @@ let
|
||||
|
||||
${doc}
|
||||
'';
|
||||
in xps: (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
in
|
||||
|
||||
xps: (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps)))
|
||||
|
@ -97,10 +97,17 @@ $(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/SUMMARY-rl-next.md $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md
|
||||
$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/SUMMARY-rl-next.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md
|
||||
@cp $< $@
|
||||
@$(call process-includes,$@,$@)
|
||||
|
||||
$(d)/src/store/types: $(d)/nix.json $(d)/utils.nix $(d)/generate-store-info.nix $(d)/generate-store-types.nix $(d)/src/store/types/index.md.in $(doc_nix)
|
||||
@# FIXME: build out of tree!
|
||||
@rm -rf $@.tmp
|
||||
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-store-types.nix (builtins.fromJSON (builtins.readFile $<)).stores'
|
||||
@# do not destroy existing contents
|
||||
@mv $@.tmp/* $@/
|
||||
|
||||
$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/utils.nix $(d)/generate-manpage.nix $(d)/generate-settings.nix $(d)/generate-store-info.nix $(doc_nix)
|
||||
@rm -rf $@ $@.tmp
|
||||
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix true (builtins.readFile $<)'
|
||||
@ -200,7 +207,7 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli
|
||||
# `@docroot@` is to be preserved for documenting the mechanism
|
||||
# FIXME: maybe contributing guides should live right next to the code
|
||||
# instead of in the manual
|
||||
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/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
|
||||
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/store/types $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-feature-descriptions.md $(d)/src/command-ref/conf-file.md $(d)/src/language/builtins.md $(d)/src/language/builtin-constants.md $(d)/src/release-notes/rl-next.md
|
||||
$(trace-gen) \
|
||||
tmp="$$(mktemp -d)"; \
|
||||
cp -r doc/manual "$$tmp"; \
|
||||
|
@ -3,6 +3,6 @@ issues: #7672
|
||||
prs: #9477
|
||||
description: {
|
||||
|
||||
`nix show-config` was renamed to `nix config show` to be more consistent with the rest of the command-line interface.
|
||||
`nix show-config` was renamed to `nix config show`, and `nix doctor` was renamed to `nix config check`, to be more consistent with the rest of the command-line interface.
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
- [File System Object](store/file-system-object.md)
|
||||
- [Store Object](store/store-object.md)
|
||||
- [Store Path](store/store-path.md)
|
||||
- [Store Types](store/types/index.md)
|
||||
{{#include ./store/types/SUMMARY.md}}
|
||||
- [Nix Language](language/index.md)
|
||||
- [Data Types](language/values.md)
|
||||
- [Language Constructs](language/constructs.md)
|
||||
|
@ -87,7 +87,7 @@ impacted the most by bad user experience.
|
||||
and [aligning of text](#text-alignment).
|
||||
- [Autocomplete](#shell-completion) of options.
|
||||
|
||||
Examples of such commands: `nix doctor`, `nix edit`, `nix eval`, ...
|
||||
Examples of such commands: `nix edit`, `nix eval`, ...
|
||||
|
||||
- **Utility and scripting commands**
|
||||
|
||||
@ -426,7 +426,7 @@ This leads to the following guidelines:
|
||||
### Examples
|
||||
|
||||
|
||||
This is bad, because all keys must be assumed to be store implementations:
|
||||
This is bad, because all keys must be assumed to be store types:
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
|
||||
[googletest]: https://google.github.io/googletest/
|
||||
[rapidcheck]: https://github.com/emil-e/rapidcheck
|
||||
[property testing]: https://en.wikipedia.org/wiki/Property_testing
|
||||
|
||||
### Source and header layout
|
||||
|
||||
@ -28,34 +29,50 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
||||
> ```
|
||||
> src
|
||||
> ├── libexpr
|
||||
> │ ├── local.mk
|
||||
> │ ├── value/context.hh
|
||||
> │ ├── value/context.cc
|
||||
> │ …
|
||||
> │
|
||||
> ├── tests
|
||||
> │ │
|
||||
> │ …
|
||||
> └── tests
|
||||
> │ ├── value/context.hh
|
||||
> │ ├── value/context.cc
|
||||
> │ └── unit
|
||||
> │ ├── libutil
|
||||
> │ │ ├── local.mk
|
||||
> │ │ …
|
||||
> │ │ └── data
|
||||
> │ │ ├── git/tree.txt
|
||||
> │ │ …
|
||||
> │ │
|
||||
> │ …
|
||||
> │
|
||||
> ├── unit-test-data
|
||||
> │ ├── libstore
|
||||
> │ │ ├── worker-protocol/content-address.bin
|
||||
> │ │ …
|
||||
> │ …
|
||||
> │ ├── libexpr-support
|
||||
> │ │ ├── local.mk
|
||||
> │ │ └── tests
|
||||
> │ │ ├── value/context.hh
|
||||
> │ │ ├── value/context.cc
|
||||
> │ │ …
|
||||
> │ │
|
||||
> │ ├── libexpr
|
||||
> │ … ├── local.mk
|
||||
> │ ├── value/context.cc
|
||||
> │ …
|
||||
> …
|
||||
> ```
|
||||
|
||||
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 tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `tests/unit/${library_name_without-nix}`.
|
||||
Given a interface (header) and implementation pair in the original library, say, `src/libexpr/value/context.{hh,cc}`, we write tests for it in `tests/unit/libexpr/tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `tests/unit/libexpr-support/tests/value/context.{hh,cc}`.
|
||||
|
||||
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`.
|
||||
Data for unit tests is stored in a `data` subdir of the directory for each unit test executable.
|
||||
For example, `libnixstore` code is in `src/libstore`, and its test data is in `tests/unit/libstore/data`.
|
||||
The path to the `tests/unit/data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`.
|
||||
Note that each executable only gets the data for its tests.
|
||||
|
||||
> **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.
|
||||
The unit test libraries are in `tests/unit/${library_name_without-nix}-lib`.
|
||||
All headers are in a `tests` subdirectory so they are included with `#include "tests/"`.
|
||||
|
||||
The use of all these separate directories for the unit tests might seem inconvenient, as for example the tests are not "right next to" the part of the code they are testing.
|
||||
But organizing the tests this way has one big benefit:
|
||||
there is no risk of any build-system wildcards for the library accidentally picking up test code that should not built and installed as part of the library.
|
||||
|
||||
### Running tests
|
||||
|
||||
@ -69,7 +86,7 @@ See [functional characterisation testing](#characterisation-testing-functional)
|
||||
Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used.
|
||||
For example:
|
||||
```shell-session
|
||||
$ _NIX_TEST_ACCEPT=1 make libstore-tests-exe_RUN
|
||||
$ _NIX_TEST_ACCEPT=1 make libstore-tests_RUN
|
||||
...
|
||||
[ SKIPPED ] WorkerProtoTest.string_read
|
||||
[ SKIPPED ] WorkerProtoTest.string_write
|
||||
@ -80,6 +97,18 @@ $ _NIX_TEST_ACCEPT=1 make libstore-tests-exe_RUN
|
||||
will regenerate the "golden master" expected result for the `libnixstore` characterisation tests.
|
||||
The characterisation tests will mark themselves "skipped" since they regenerated the expected result instead of actually testing anything.
|
||||
|
||||
### Unit test support libraries
|
||||
|
||||
There are headers and code which are not just used to test the library in question, but also downstream libraries.
|
||||
For example, we do [property testing] with the [rapidcheck] library.
|
||||
This requires writing `Arbitrary` "instances", which are used to describe how to generate values of a given type for the sake of running property tests.
|
||||
Because types contain other types, `Arbitrary` "instances" for some type are not just useful for testing that type, but also any other type that contains it.
|
||||
Downstream types frequently contain upstream types, so it is very important that we share arbitrary instances so that downstream libraries' property tests can also use them.
|
||||
|
||||
It is important that these testing libraries don't contain any actual tests themselves.
|
||||
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.
|
||||
|
||||
## Functional tests
|
||||
|
||||
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
The *Nix store* is an abstraction to store immutable file system data (such as software packages) that can have dependencies on other such data.
|
||||
|
||||
There are multiple implementations of Nix stores with different capabilities, such as the actual filesystem (`/nix/store`) or binary caches.
|
||||
There are [multiple types of Nix stores](./types/index.md) with different capabilities, such as the default one on the [local filesystem](./types/local-store.md) (`/nix/store`) or [binary caches](./types/http-binary-cache-store.md).
|
||||
|
@ -1,4 +1,6 @@
|
||||
Nix supports different types of stores. These are described below.
|
||||
Nix supports different types of stores:
|
||||
|
||||
@store-types@
|
||||
|
||||
## Store URL format
|
||||
|
||||
@ -39,4 +41,3 @@ store as follows:
|
||||
|
||||
* Otherwise, use the [local store](#local-store) `/nix/store`.
|
||||
|
||||
@stores@
|
||||
|
@ -1,5 +1,11 @@
|
||||
with builtins;
|
||||
|
||||
let
|
||||
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
|
||||
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
stringToCharacters = s: genList (p: substring p 1 s) (stringLength s);
|
||||
in
|
||||
|
||||
rec {
|
||||
splitLines = s: filter (x: !isList x) (split "\n" s);
|
||||
|
||||
@ -18,6 +24,8 @@ rec {
|
||||
in
|
||||
if replaced == string then string else replaceStringsRec from to replaced;
|
||||
|
||||
toLower = replaceStrings upperChars lowerChars;
|
||||
|
||||
squash = replaceStringsRec "\n\n\n" "\n\n";
|
||||
|
||||
trim = string:
|
||||
|
@ -196,7 +196,6 @@
|
||||
versionSuffix
|
||||
;
|
||||
busybox-sandbox-shell = final.busybox-sandbox-shell or default-busybox-sandbox-shell;
|
||||
boost = final.boost.override { enableIcu = false; };
|
||||
libgit2 = final.libgit2.overrideAttrs (attrs: {
|
||||
src = libgit2;
|
||||
version = libgit2.lastModifiedDate;
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Remove overall test dir (at most one of the two should match) and
|
||||
# remove file extension.
|
||||
test_name=$(echo -n "$test" | sed \
|
||||
-e "s|^unit-test-data/||" \
|
||||
-e "s|^tests/unit/[^/]*/data/||" \
|
||||
-e "s|^tests/functional/||" \
|
||||
-e "s|\.sh$||" \
|
||||
)
|
||||
|
@ -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) $$(UNIT_TEST_ENV) $$($(1)_PATH)
|
||||
$(trace-test) $$($(1)_ENV) $$($(1)_PATH)
|
||||
|
||||
endef
|
||||
|
@ -152,7 +152,7 @@ in {
|
||||
./misc
|
||||
./precompiled-headers.h
|
||||
./src
|
||||
./unit-test-data
|
||||
./tests/unit
|
||||
./COPYING
|
||||
./scripts/local.mk
|
||||
] ++ lib.optionals anySortOfTesting [
|
||||
@ -297,10 +297,7 @@ in {
|
||||
-change ${boost}/lib/libboost_context.dylib \
|
||||
$out/lib/libboost_context.dylib \
|
||||
$out/lib/libnixutil.dylib
|
||||
install_name_tool \
|
||||
-change ${boost}/lib/libboost_regex.dylib \
|
||||
$out/lib/libboost_regex.dylib \
|
||||
$out/lib/libnixexpr.dylib
|
||||
install_name_tool
|
||||
''
|
||||
) + lib.optionalString enableInternalAPIDocs ''
|
||||
mkdir -p ''${!outputDoc}/nix-support
|
||||
|
@ -9,6 +9,7 @@
|
||||
#undef do_close
|
||||
|
||||
#include "derivations.hh"
|
||||
#include "realisation.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "crypto.hh"
|
||||
|
@ -80,7 +80,7 @@ SingleDerivedPath SingleBuiltPath::discardOutputPath() const
|
||||
);
|
||||
}
|
||||
|
||||
nlohmann::json BuiltPath::Built::toJSON(const Store & store) const
|
||||
nlohmann::json BuiltPath::Built::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
nlohmann::json res;
|
||||
res["drvPath"] = drvPath->toJSON(store);
|
||||
@ -90,7 +90,7 @@ nlohmann::json BuiltPath::Built::toJSON(const Store & store) const
|
||||
return res;
|
||||
}
|
||||
|
||||
nlohmann::json SingleBuiltPath::Built::toJSON(const Store & store) const
|
||||
nlohmann::json SingleBuiltPath::Built::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
nlohmann::json res;
|
||||
res["drvPath"] = drvPath->toJSON(store);
|
||||
@ -100,14 +100,14 @@ nlohmann::json SingleBuiltPath::Built::toJSON(const Store & store) const
|
||||
return res;
|
||||
}
|
||||
|
||||
nlohmann::json SingleBuiltPath::toJSON(const Store & store) const
|
||||
nlohmann::json SingleBuiltPath::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit([&](const auto & buildable) {
|
||||
return buildable.toJSON(store);
|
||||
}, raw());
|
||||
}
|
||||
|
||||
nlohmann::json BuiltPath::toJSON(const Store & store) const
|
||||
nlohmann::json BuiltPath::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit([&](const auto & buildable) {
|
||||
return buildable.toJSON(store);
|
||||
|
@ -14,9 +14,9 @@ struct SingleBuiltPathBuilt {
|
||||
|
||||
SingleDerivedPathBuilt discardOutputPath() const;
|
||||
|
||||
std::string to_string(const Store & store) const;
|
||||
static SingleBuiltPathBuilt parse(const Store & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
static SingleBuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
|
||||
DECLARE_CMP(SingleBuiltPathBuilt);
|
||||
};
|
||||
@ -41,8 +41,8 @@ struct SingleBuiltPath : _SingleBuiltPathRaw {
|
||||
|
||||
SingleDerivedPath discardOutputPath() const;
|
||||
|
||||
static SingleBuiltPath parse(const Store & store, std::string_view);
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
static SingleBuiltPath parse(const StoreDirConfig & store, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
};
|
||||
|
||||
static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
|
||||
@ -59,9 +59,9 @@ struct BuiltPathBuilt {
|
||||
ref<SingleBuiltPath> drvPath;
|
||||
std::map<std::string, StorePath> outputs;
|
||||
|
||||
std::string to_string(const Store & store) const;
|
||||
static BuiltPathBuilt parse(const Store & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
static BuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
|
||||
DECLARE_CMP(BuiltPathBuilt);
|
||||
};
|
||||
@ -89,7 +89,7 @@ struct BuiltPath : _BuiltPathRaw {
|
||||
StorePathSet outPaths() const;
|
||||
RealisedPath::Set toRealisedPaths(Store & store) const;
|
||||
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
};
|
||||
|
||||
typedef std::vector<BuiltPath> BuiltPaths;
|
||||
|
@ -141,7 +141,7 @@ MixEvalArgs::MixEvalArgs()
|
||||
.longName = "eval-store",
|
||||
.description =
|
||||
R"(
|
||||
The [URL of the Nix store](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format)
|
||||
The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format)
|
||||
to use for evaluation, i.e. to store derivations (`.drv` files) and inputs referenced by them.
|
||||
)",
|
||||
.category = category,
|
||||
|
@ -22,7 +22,7 @@ struct AttrDb
|
||||
{
|
||||
std::atomic_bool failed{false};
|
||||
|
||||
const Store & cfg;
|
||||
const StoreDirConfig & cfg;
|
||||
|
||||
struct State
|
||||
{
|
||||
@ -39,7 +39,7 @@ struct AttrDb
|
||||
SymbolTable & symbols;
|
||||
|
||||
AttrDb(
|
||||
const Store & cfg,
|
||||
const StoreDirConfig & cfg,
|
||||
const Hash & fingerprint,
|
||||
SymbolTable & symbols)
|
||||
: cfg(cfg)
|
||||
@ -323,7 +323,7 @@ struct AttrDb
|
||||
};
|
||||
|
||||
static std::shared_ptr<AttrDb> makeAttrDb(
|
||||
const Store & cfg,
|
||||
const StoreDirConfig & cfg,
|
||||
const Hash & fingerprint,
|
||||
SymbolTable & symbols)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/lib
|
||||
|
||||
libexpr_LIBS = libutil libstore libfetchers
|
||||
|
||||
libexpr_LDFLAGS += -lboost_context -lboost_regex -pthread
|
||||
libexpr_LDFLAGS += -lboost_context -pthread
|
||||
ifdef HOST_LINUX
|
||||
libexpr_LDFLAGS += -ldl
|
||||
endif
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "primops.hh"
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -26,6 +25,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <cmath>
|
||||
@ -3886,30 +3886,19 @@ static RegisterPrimOp primop_convertHash({
|
||||
.fun = prim_convertHash,
|
||||
});
|
||||
|
||||
// regex aliases, switch between boost and std
|
||||
using regex = boost::regex;
|
||||
using regex_error = boost::regex_error;
|
||||
using cmatch = boost::cmatch;
|
||||
using cregex_iterator = boost::cregex_iterator;
|
||||
namespace regex_constants = boost::regex_constants;
|
||||
// overloaded function alias
|
||||
constexpr auto regex_match = [] (auto &&...args) {
|
||||
return boost::regex_match(std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
|
||||
struct RegexCache
|
||||
{
|
||||
// TODO use C++20 transparent comparison when available
|
||||
std::unordered_map<std::string_view, regex> cache;
|
||||
std::unordered_map<std::string_view, std::regex> cache;
|
||||
std::list<std::string> keys;
|
||||
|
||||
regex get(std::string_view re)
|
||||
std::regex get(std::string_view re)
|
||||
{
|
||||
auto it = cache.find(re);
|
||||
if (it != cache.end())
|
||||
return it->second;
|
||||
keys.emplace_back(re);
|
||||
return cache.emplace(keys.back(), regex(keys.back(), regex::extended)).first->second;
|
||||
return cache.emplace(keys.back(), std::regex(keys.back(), std::regex::extended)).first->second;
|
||||
}
|
||||
};
|
||||
|
||||
@ -3929,8 +3918,8 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
NixStringContext context;
|
||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
||||
|
||||
cmatch match;
|
||||
if (!regex_match(str.begin(), str.end(), match, regex)) {
|
||||
std::cmatch match;
|
||||
if (!std::regex_match(str.begin(), str.end(), match, regex)) {
|
||||
v.mkNull();
|
||||
return;
|
||||
}
|
||||
@ -3945,8 +3934,8 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
(v.listElems()[i] = state.allocValue())->mkString(match[i + 1].str());
|
||||
}
|
||||
|
||||
} catch (regex_error & e) {
|
||||
if (e.code() == regex_constants::error_space) {
|
||||
} catch (std::regex_error & e) {
|
||||
if (e.code() == std::regex_constants::error_space) {
|
||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||
state.debugThrowLastTrace(EvalError({
|
||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
||||
@ -4009,8 +3998,8 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
NixStringContext context;
|
||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
||||
|
||||
auto begin = cregex_iterator(str.begin(), str.end(), regex);
|
||||
auto end = cregex_iterator();
|
||||
auto begin = std::cregex_iterator(str.begin(), str.end(), regex);
|
||||
auto end = std::cregex_iterator();
|
||||
|
||||
// Any matches results are surrounded by non-matching results.
|
||||
const size_t len = std::distance(begin, end);
|
||||
@ -4049,8 +4038,8 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
|
||||
assert(idx == 2 * len + 1);
|
||||
|
||||
} catch (regex_error & e) {
|
||||
if (e.code() == regex_constants::error_space) {
|
||||
} catch (std::regex_error & e) {
|
||||
if (e.code() == std::regex_constants::error_space) {
|
||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||
state.debugThrowLastTrace(EvalError({
|
||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
||||
@ -4411,7 +4400,7 @@ void EvalState::createBaseEnv()
|
||||
addConstant("__currentSystem", v, {
|
||||
.type = nString,
|
||||
.doc = R"(
|
||||
The value of the [`system` configuration option](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||
The value of the [`system` configuration option](@docroot@/command-ref/conf-file.md#conf-system).
|
||||
|
||||
It can be used to set the `system` attribute for [`builtins.derivation`](@docroot@/language/derivations.md) such that the resulting derivation can be built on the same system that evaluates the Nix expression:
|
||||
|
||||
@ -4460,7 +4449,7 @@ void EvalState::createBaseEnv()
|
||||
.doc = R"(
|
||||
Logical file system location of the [Nix store](@docroot@/glossary.md#gloss-store) currently in use.
|
||||
|
||||
This value is determined by the `store` parameter in [Store URLs](@docroot@/command-ref/new-cli/nix3-help-stores.md):
|
||||
This value is determined by the `store` parameter in [Store URLs](@docroot@/store/types/index.md#store-url-format):
|
||||
|
||||
```shell-session
|
||||
$ nix-instantiate --store 'dummy://?store=/blah' --eval --expr builtins.storeDir
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "primops.hh"
|
||||
#include "store-api.hh"
|
||||
#include "realisation.hh"
|
||||
#include "make-content-addressed.hh"
|
||||
#include "url.hh"
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
check: libexpr-tests_RUN
|
||||
|
||||
programs += libexpr-tests
|
||||
|
||||
libexpr-tests_NAME := libnixexpr-tests
|
||||
|
||||
libexpr-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libexpr-tests_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libexpr-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libexpr-tests_SOURCES := \
|
||||
$(wildcard $(d)/*.cc) \
|
||||
$(wildcard $(d)/value/*.cc)
|
||||
|
||||
libexpr-tests_CXXFLAGS += -I src/libexpr -I src/libutil -I src/libstore -I src/libexpr/tests -I src/libfetchers
|
||||
|
||||
libexpr-tests_LIBS = libstore-tests libutils-tests libexpr libutil libstore libfetchers
|
||||
|
||||
libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock
|
@ -67,7 +67,6 @@ class Symbol;
|
||||
class PosIdx;
|
||||
struct Pos;
|
||||
class StorePath;
|
||||
class Store;
|
||||
class EvalState;
|
||||
class XMLWriter;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "buildenv.hh"
|
||||
#include "derivations.hh"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
namespace nix {
|
||||
|
@ -16,11 +16,11 @@ namespace nix {
|
||||
/* protocol-agnostic templates */
|
||||
|
||||
#define COMMON_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
||||
TEMPLATE T CommonProto::Serialise< T >::read(const Store & store, CommonProto::ReadConn conn) \
|
||||
TEMPLATE T CommonProto::Serialise< T >::read(const StoreDirConfig & store, CommonProto::ReadConn conn) \
|
||||
{ \
|
||||
return LengthPrefixedProtoHelper<CommonProto, T >::read(store, conn); \
|
||||
} \
|
||||
TEMPLATE void CommonProto::Serialise< T >::write(const Store & store, CommonProto::WriteConn conn, const T & t) \
|
||||
TEMPLATE void CommonProto::Serialise< T >::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const T & t) \
|
||||
{ \
|
||||
LengthPrefixedProtoHelper<CommonProto, T >::write(store, conn, t); \
|
||||
}
|
||||
|
@ -13,40 +13,40 @@ namespace nix {
|
||||
|
||||
/* protocol-agnostic definitions */
|
||||
|
||||
std::string CommonProto::Serialise<std::string>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
std::string CommonProto::Serialise<std::string>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
return readString(conn.from);
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<std::string>::write(const Store & store, CommonProto::WriteConn conn, const std::string & str)
|
||||
void CommonProto::Serialise<std::string>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const std::string & str)
|
||||
{
|
||||
conn.to << str;
|
||||
}
|
||||
|
||||
|
||||
StorePath CommonProto::Serialise<StorePath>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
StorePath CommonProto::Serialise<StorePath>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
return store.parseStorePath(readString(conn.from));
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<StorePath>::write(const Store & store, CommonProto::WriteConn conn, const StorePath & storePath)
|
||||
void CommonProto::Serialise<StorePath>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const StorePath & storePath)
|
||||
{
|
||||
conn.to << store.printStorePath(storePath);
|
||||
}
|
||||
|
||||
|
||||
ContentAddress CommonProto::Serialise<ContentAddress>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
ContentAddress CommonProto::Serialise<ContentAddress>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
return ContentAddress::parse(readString(conn.from));
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<ContentAddress>::write(const Store & store, CommonProto::WriteConn conn, const ContentAddress & ca)
|
||||
void CommonProto::Serialise<ContentAddress>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const ContentAddress & ca)
|
||||
{
|
||||
conn.to << renderContentAddress(ca);
|
||||
}
|
||||
|
||||
|
||||
Realisation CommonProto::Serialise<Realisation>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
Realisation CommonProto::Serialise<Realisation>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
std::string rawInput = readString(conn.from);
|
||||
return Realisation::fromJSON(
|
||||
@ -55,41 +55,41 @@ Realisation CommonProto::Serialise<Realisation>::read(const Store & store, Commo
|
||||
);
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<Realisation>::write(const Store & store, CommonProto::WriteConn conn, const Realisation & realisation)
|
||||
void CommonProto::Serialise<Realisation>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const Realisation & realisation)
|
||||
{
|
||||
conn.to << realisation.toJSON().dump();
|
||||
}
|
||||
|
||||
|
||||
DrvOutput CommonProto::Serialise<DrvOutput>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
DrvOutput CommonProto::Serialise<DrvOutput>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
return DrvOutput::parse(readString(conn.from));
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<DrvOutput>::write(const Store & store, CommonProto::WriteConn conn, const DrvOutput & drvOutput)
|
||||
void CommonProto::Serialise<DrvOutput>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const DrvOutput & drvOutput)
|
||||
{
|
||||
conn.to << drvOutput.to_string();
|
||||
}
|
||||
|
||||
|
||||
std::optional<StorePath> CommonProto::Serialise<std::optional<StorePath>>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
std::optional<StorePath> CommonProto::Serialise<std::optional<StorePath>>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
auto s = readString(conn.from);
|
||||
return s == "" ? std::optional<StorePath> {} : store.parseStorePath(s);
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<std::optional<StorePath>>::write(const Store & store, CommonProto::WriteConn conn, const std::optional<StorePath> & storePathOpt)
|
||||
void CommonProto::Serialise<std::optional<StorePath>>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const std::optional<StorePath> & storePathOpt)
|
||||
{
|
||||
conn.to << (storePathOpt ? store.printStorePath(*storePathOpt) : "");
|
||||
}
|
||||
|
||||
|
||||
std::optional<ContentAddress> CommonProto::Serialise<std::optional<ContentAddress>>::read(const Store & store, CommonProto::ReadConn conn)
|
||||
std::optional<ContentAddress> CommonProto::Serialise<std::optional<ContentAddress>>::read(const StoreDirConfig & store, CommonProto::ReadConn conn)
|
||||
{
|
||||
return ContentAddress::parseOpt(readString(conn.from));
|
||||
}
|
||||
|
||||
void CommonProto::Serialise<std::optional<ContentAddress>>::write(const Store & store, CommonProto::WriteConn conn, const std::optional<ContentAddress> & caOpt)
|
||||
void CommonProto::Serialise<std::optional<ContentAddress>>::write(const StoreDirConfig & store, CommonProto::WriteConn conn, const std::optional<ContentAddress> & caOpt)
|
||||
{
|
||||
conn.to << (caOpt ? renderContentAddress(*caOpt) : "");
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
class Store;
|
||||
struct StoreDirConfig;
|
||||
struct Source;
|
||||
|
||||
// items being serialized
|
||||
@ -48,7 +48,7 @@ struct CommonProto
|
||||
* infer the type instead of having to write it down explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
static void write(const Store & store, WriteConn conn, const T & t)
|
||||
static void write(const StoreDirConfig & store, WriteConn conn, const T & t)
|
||||
{
|
||||
CommonProto::Serialise<T>::write(store, conn, t);
|
||||
}
|
||||
@ -57,8 +57,8 @@ struct CommonProto
|
||||
#define DECLARE_COMMON_SERIALISER(T) \
|
||||
struct CommonProto::Serialise< T > \
|
||||
{ \
|
||||
static T read(const Store & store, CommonProto::ReadConn conn); \
|
||||
static void write(const Store & store, CommonProto::WriteConn conn, const T & str); \
|
||||
static T read(const StoreDirConfig & store, CommonProto::ReadConn conn); \
|
||||
static void write(const StoreDirConfig & store, CommonProto::WriteConn conn, const T & str); \
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::optional<StorePath> DerivationOutput::path(const Store & store, std::string_view drvName, OutputNameView outputName) const
|
||||
std::optional<StorePath> DerivationOutput::path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[](const DerivationOutput::InputAddressed & doi) -> std::optional<StorePath> {
|
||||
@ -35,7 +35,7 @@ std::optional<StorePath> DerivationOutput::path(const Store & store, std::string
|
||||
}
|
||||
|
||||
|
||||
StorePath DerivationOutput::CAFixed::path(const Store & store, std::string_view drvName, OutputNameView outputName) const
|
||||
StorePath DerivationOutput::CAFixed::path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const
|
||||
{
|
||||
return store.makeFixedOutputPathFromCA(
|
||||
outputPathName(drvName, outputName),
|
||||
@ -214,7 +214,7 @@ static StringSet parseStrings(std::istream & str, bool arePaths)
|
||||
|
||||
|
||||
static DerivationOutput parseDerivationOutput(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view pathS, std::string_view hashAlgo, std::string_view hashS,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -261,7 +261,7 @@ static DerivationOutput parseDerivationOutput(
|
||||
}
|
||||
|
||||
static DerivationOutput parseDerivationOutput(
|
||||
const Store & store, std::istringstream & str,
|
||||
const StoreDirConfig & store, std::istringstream & str,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings)
|
||||
{
|
||||
expect(str, ","); const auto pathS = parseString(str);
|
||||
@ -290,7 +290,7 @@ enum struct DerivationATermVersion {
|
||||
};
|
||||
|
||||
static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::istringstream & str,
|
||||
DerivationATermVersion version)
|
||||
{
|
||||
@ -337,7 +337,7 @@ static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
|
||||
|
||||
|
||||
Derivation parseDerivation(
|
||||
const Store & store, std::string && s, std::string_view name,
|
||||
const StoreDirConfig & store, std::string && s, std::string_view name,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
Derivation drv;
|
||||
@ -470,7 +470,7 @@ static void printUnquotedStrings(std::string & res, ForwardIterator i, ForwardIt
|
||||
}
|
||||
|
||||
|
||||
static void unparseDerivedPathMapNode(const Store & store, std::string & s, const DerivedPathMap<StringSet>::ChildNode & node)
|
||||
static void unparseDerivedPathMapNode(const StoreDirConfig & store, std::string & s, const DerivedPathMap<StringSet>::ChildNode & node)
|
||||
{
|
||||
s += ',';
|
||||
if (node.childMap.empty()) {
|
||||
@ -511,7 +511,7 @@ static bool hasDynamicDrvDep(const Derivation & drv)
|
||||
}
|
||||
|
||||
|
||||
std::string Derivation::unparse(const Store & store, bool maskOutputs,
|
||||
std::string Derivation::unparse(const StoreDirConfig & store, bool maskOutputs,
|
||||
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs) const
|
||||
{
|
||||
std::string s;
|
||||
@ -845,7 +845,7 @@ std::map<std::string, Hash> staticOutputHashes(Store & store, const Derivation &
|
||||
}
|
||||
|
||||
|
||||
static DerivationOutput readDerivationOutput(Source & in, const Store & store)
|
||||
static DerivationOutput readDerivationOutput(Source & in, const StoreDirConfig & store)
|
||||
{
|
||||
const auto pathS = readString(in);
|
||||
const auto hashAlgo = readString(in);
|
||||
@ -862,7 +862,7 @@ StringSet BasicDerivation::outputNames() const
|
||||
return names;
|
||||
}
|
||||
|
||||
DerivationOutputsAndOptPaths BasicDerivation::outputsAndOptPaths(const Store & store) const
|
||||
DerivationOutputsAndOptPaths BasicDerivation::outputsAndOptPaths(const StoreDirConfig & store) const
|
||||
{
|
||||
DerivationOutputsAndOptPaths outsAndOptPaths;
|
||||
for (auto & [outputName, output] : outputs)
|
||||
@ -884,7 +884,7 @@ std::string_view BasicDerivation::nameFromPath(const StorePath & drvPath)
|
||||
}
|
||||
|
||||
|
||||
Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv, std::string_view name)
|
||||
Source & readDerivation(Source & in, const StoreDirConfig & store, BasicDerivation & drv, std::string_view name)
|
||||
{
|
||||
drv.name = name;
|
||||
|
||||
@ -912,7 +912,7 @@ Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv,
|
||||
}
|
||||
|
||||
|
||||
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv)
|
||||
void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDerivation & drv)
|
||||
{
|
||||
out << drv.outputs.size();
|
||||
for (auto & i : drv.outputs) {
|
||||
@ -1153,7 +1153,7 @@ void Derivation::checkInvariants(Store & store, const StorePath & drvPath) const
|
||||
const Hash impureOutputHash = hashString(htSHA256, "impure");
|
||||
|
||||
nlohmann::json DerivationOutput::toJSON(
|
||||
const Store & store, std::string_view drvName, OutputNameView outputName) const
|
||||
const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const
|
||||
{
|
||||
nlohmann::json res = nlohmann::json::object();
|
||||
std::visit(overloaded {
|
||||
@ -1180,7 +1180,7 @@ nlohmann::json DerivationOutput::toJSON(
|
||||
|
||||
|
||||
DerivationOutput DerivationOutput::fromJSON(
|
||||
const Store & store, std::string_view drvName, OutputNameView outputName,
|
||||
const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName,
|
||||
const nlohmann::json & _json,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -1249,7 +1249,7 @@ DerivationOutput DerivationOutput::fromJSON(
|
||||
}
|
||||
|
||||
|
||||
nlohmann::json Derivation::toJSON(const Store & store) const
|
||||
nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
nlohmann::json res = nlohmann::json::object();
|
||||
|
||||
@ -1302,7 +1302,7 @@ nlohmann::json Derivation::toJSON(const Store & store) const
|
||||
|
||||
|
||||
Derivation Derivation::fromJSON(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
const nlohmann::json & json,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
class Store;
|
||||
struct StoreDirConfig;
|
||||
|
||||
/* Abstract syntax of derivations. */
|
||||
|
||||
@ -55,7 +55,7 @@ struct DerivationOutput
|
||||
* @param drvName The name of the derivation this is an output of, without the `.drv`.
|
||||
* @param outputName The name of this output.
|
||||
*/
|
||||
StorePath path(const Store & store, std::string_view drvName, OutputNameView outputName) const;
|
||||
StorePath path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const;
|
||||
|
||||
GENERATE_CMP(CAFixed, me->ca);
|
||||
};
|
||||
@ -132,17 +132,17 @@ struct DerivationOutput
|
||||
* the safer interface provided by
|
||||
* BasicDerivation::outputsAndOptPaths
|
||||
*/
|
||||
std::optional<StorePath> path(const Store & store, std::string_view drvName, OutputNameView outputName) const;
|
||||
std::optional<StorePath> path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const;
|
||||
|
||||
nlohmann::json toJSON(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view drvName,
|
||||
OutputNameView outputName) const;
|
||||
/**
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static DerivationOutput fromJSON(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view drvName,
|
||||
OutputNameView outputName,
|
||||
const nlohmann::json & json,
|
||||
@ -304,7 +304,7 @@ struct BasicDerivation
|
||||
* augmented with knowledge of the Store paths they would be written
|
||||
* into.
|
||||
*/
|
||||
DerivationOutputsAndOptPaths outputsAndOptPaths(const Store & store) const;
|
||||
DerivationOutputsAndOptPaths outputsAndOptPaths(const StoreDirConfig & store) const;
|
||||
|
||||
static std::string_view nameFromPath(const StorePath & storePath);
|
||||
|
||||
@ -318,6 +318,8 @@ struct BasicDerivation
|
||||
me->name);
|
||||
};
|
||||
|
||||
class Store;
|
||||
|
||||
struct Derivation : BasicDerivation
|
||||
{
|
||||
/**
|
||||
@ -328,7 +330,7 @@ struct Derivation : BasicDerivation
|
||||
/**
|
||||
* Print a derivation.
|
||||
*/
|
||||
std::string unparse(const Store & store, bool maskOutputs,
|
||||
std::string unparse(const StoreDirConfig & store, bool maskOutputs,
|
||||
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs = nullptr) const;
|
||||
|
||||
/**
|
||||
@ -365,9 +367,9 @@ struct Derivation : BasicDerivation
|
||||
Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
|
||||
Derivation(BasicDerivation && bd) : BasicDerivation(std::move(bd)) { }
|
||||
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
static Derivation fromJSON(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
const nlohmann::json & json,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
|
||||
@ -391,7 +393,7 @@ StorePath writeDerivation(Store & store,
|
||||
* Read a derivation from a file.
|
||||
*/
|
||||
Derivation parseDerivation(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string && s,
|
||||
std::string_view name,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
@ -493,8 +495,8 @@ extern Sync<DrvHashes> drvHashes;
|
||||
struct Source;
|
||||
struct Sink;
|
||||
|
||||
Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv, std::string_view name);
|
||||
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);
|
||||
Source & readDerivation(Source & in, const StoreDirConfig & store, BasicDerivation & drv, std::string_view name);
|
||||
void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDerivation & drv);
|
||||
|
||||
/**
|
||||
* This creates an opaque and almost certainly unique string
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "derived-path.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@ -32,7 +33,7 @@ CMP(SingleDerivedPath, DerivedPathBuilt, outputs)
|
||||
#undef CMP
|
||||
#undef CMP_ONE
|
||||
|
||||
nlohmann::json DerivedPath::Opaque::toJSON(const Store & store) const
|
||||
nlohmann::json DerivedPath::Opaque::toJSON(const StoreDirConfig & store) const
|
||||
{
|
||||
return store.printStorePath(path);
|
||||
}
|
||||
@ -86,50 +87,50 @@ nlohmann::json DerivedPath::toJSON(Store & store) const
|
||||
}, raw());
|
||||
}
|
||||
|
||||
std::string DerivedPath::Opaque::to_string(const Store & store) const
|
||||
std::string DerivedPath::Opaque::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return store.printStorePath(path);
|
||||
}
|
||||
|
||||
std::string SingleDerivedPath::Built::to_string(const Store & store) const
|
||||
std::string SingleDerivedPath::Built::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return drvPath->to_string(store) + "^" + output;
|
||||
}
|
||||
|
||||
std::string SingleDerivedPath::Built::to_string_legacy(const Store & store) const
|
||||
std::string SingleDerivedPath::Built::to_string_legacy(const StoreDirConfig & store) const
|
||||
{
|
||||
return drvPath->to_string(store) + "!" + output;
|
||||
}
|
||||
|
||||
std::string DerivedPath::Built::to_string(const Store & store) const
|
||||
std::string DerivedPath::Built::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return drvPath->to_string(store)
|
||||
+ '^'
|
||||
+ outputs.to_string();
|
||||
}
|
||||
|
||||
std::string DerivedPath::Built::to_string_legacy(const Store & store) const
|
||||
std::string DerivedPath::Built::to_string_legacy(const StoreDirConfig & store) const
|
||||
{
|
||||
return drvPath->to_string_legacy(store)
|
||||
+ "!"
|
||||
+ outputs.to_string();
|
||||
}
|
||||
|
||||
std::string SingleDerivedPath::to_string(const Store & store) const
|
||||
std::string SingleDerivedPath::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit(
|
||||
[&](const auto & req) { return req.to_string(store); },
|
||||
raw());
|
||||
}
|
||||
|
||||
std::string DerivedPath::to_string(const Store & store) const
|
||||
std::string DerivedPath::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit(
|
||||
[&](const auto & req) { return req.to_string(store); },
|
||||
raw());
|
||||
}
|
||||
|
||||
std::string SingleDerivedPath::to_string_legacy(const Store & store) const
|
||||
std::string SingleDerivedPath::to_string_legacy(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[&](const SingleDerivedPath::Built & req) { return req.to_string_legacy(store); },
|
||||
@ -137,7 +138,7 @@ std::string SingleDerivedPath::to_string_legacy(const Store & store) const
|
||||
}, this->raw());
|
||||
}
|
||||
|
||||
std::string DerivedPath::to_string_legacy(const Store & store) const
|
||||
std::string DerivedPath::to_string_legacy(const StoreDirConfig & store) const
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[&](const DerivedPath::Built & req) { return req.to_string_legacy(store); },
|
||||
@ -146,7 +147,7 @@ std::string DerivedPath::to_string_legacy(const Store & store) const
|
||||
}
|
||||
|
||||
|
||||
DerivedPath::Opaque DerivedPath::Opaque::parse(const Store & store, std::string_view s)
|
||||
DerivedPath::Opaque DerivedPath::Opaque::parse(const StoreDirConfig & store, std::string_view s)
|
||||
{
|
||||
return {store.parseStorePath(s)};
|
||||
}
|
||||
@ -166,7 +167,7 @@ void drvRequireExperiment(
|
||||
}
|
||||
|
||||
SingleDerivedPath::Built SingleDerivedPath::Built::parse(
|
||||
const Store & store, ref<SingleDerivedPath> drv,
|
||||
const StoreDirConfig & store, ref<SingleDerivedPath> drv,
|
||||
OutputNameView output,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -178,7 +179,7 @@ SingleDerivedPath::Built SingleDerivedPath::Built::parse(
|
||||
}
|
||||
|
||||
DerivedPath::Built DerivedPath::Built::parse(
|
||||
const Store & store, ref<SingleDerivedPath> drv,
|
||||
const StoreDirConfig & store, ref<SingleDerivedPath> drv,
|
||||
OutputNameView outputsS,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -190,7 +191,7 @@ DerivedPath::Built DerivedPath::Built::parse(
|
||||
}
|
||||
|
||||
static SingleDerivedPath parseWithSingle(
|
||||
const Store & store, std::string_view s, std::string_view separator,
|
||||
const StoreDirConfig & store, std::string_view s, std::string_view separator,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
size_t n = s.rfind(separator);
|
||||
@ -207,7 +208,7 @@ static SingleDerivedPath parseWithSingle(
|
||||
}
|
||||
|
||||
SingleDerivedPath SingleDerivedPath::parse(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view s,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -215,7 +216,7 @@ SingleDerivedPath SingleDerivedPath::parse(
|
||||
}
|
||||
|
||||
SingleDerivedPath SingleDerivedPath::parseLegacy(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view s,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -223,7 +224,7 @@ SingleDerivedPath SingleDerivedPath::parseLegacy(
|
||||
}
|
||||
|
||||
static DerivedPath parseWith(
|
||||
const Store & store, std::string_view s, std::string_view separator,
|
||||
const StoreDirConfig & store, std::string_view s, std::string_view separator,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
size_t n = s.rfind(separator);
|
||||
@ -240,7 +241,7 @@ static DerivedPath parseWith(
|
||||
}
|
||||
|
||||
DerivedPath DerivedPath::parse(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view s,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
@ -248,7 +249,7 @@ DerivedPath DerivedPath::parse(
|
||||
}
|
||||
|
||||
DerivedPath DerivedPath::parseLegacy(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view s,
|
||||
const ExperimentalFeatureSettings & xpSettings)
|
||||
{
|
||||
|
@ -12,6 +12,9 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct StoreDirConfig;
|
||||
|
||||
// TODO stop needing this, `toJSON` below should be pure
|
||||
class Store;
|
||||
|
||||
/**
|
||||
@ -24,9 +27,9 @@ class Store;
|
||||
struct DerivedPathOpaque {
|
||||
StorePath path;
|
||||
|
||||
std::string to_string(const Store & store) const;
|
||||
static DerivedPathOpaque parse(const Store & store, std::string_view);
|
||||
nlohmann::json toJSON(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
static DerivedPathOpaque parse(const StoreDirConfig & store, std::string_view);
|
||||
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||
|
||||
GENERATE_CMP(DerivedPathOpaque, me->path);
|
||||
};
|
||||
@ -59,18 +62,18 @@ struct SingleDerivedPathBuilt {
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*/
|
||||
std::string to_string(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `!` as the separator
|
||||
*/
|
||||
std::string to_string_legacy(const Store & store) const;
|
||||
std::string to_string_legacy(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* The caller splits on the separator, so it works for both variants.
|
||||
*
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static SingleDerivedPathBuilt parse(
|
||||
const Store & store, ref<SingleDerivedPath> drvPath,
|
||||
const StoreDirConfig & store, ref<SingleDerivedPath> drvPath,
|
||||
OutputNameView outputs,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
nlohmann::json toJSON(Store & store) const;
|
||||
@ -120,18 +123,18 @@ struct SingleDerivedPath : _SingleDerivedPathRaw {
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*/
|
||||
std::string to_string(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `!` as the separator
|
||||
*/
|
||||
std::string to_string_legacy(const Store & store) const;
|
||||
std::string to_string_legacy(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static SingleDerivedPath parse(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
/**
|
||||
@ -140,7 +143,7 @@ struct SingleDerivedPath : _SingleDerivedPathRaw {
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static SingleDerivedPath parseLegacy(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
nlohmann::json toJSON(Store & store) const;
|
||||
@ -182,18 +185,18 @@ struct DerivedPathBuilt {
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*/
|
||||
std::string to_string(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `!` as the separator
|
||||
*/
|
||||
std::string to_string_legacy(const Store & store) const;
|
||||
std::string to_string_legacy(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* The caller splits on the separator, so it works for both variants.
|
||||
*
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static DerivedPathBuilt parse(
|
||||
const Store & store, ref<SingleDerivedPath>,
|
||||
const StoreDirConfig & store, ref<SingleDerivedPath>,
|
||||
std::string_view,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
nlohmann::json toJSON(Store & store) const;
|
||||
@ -242,18 +245,18 @@ struct DerivedPath : _DerivedPathRaw {
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*/
|
||||
std::string to_string(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `!` as the separator
|
||||
*/
|
||||
std::string to_string_legacy(const Store & store) const;
|
||||
std::string to_string_legacy(const StoreDirConfig & store) const;
|
||||
/**
|
||||
* Uses `^` as the separator
|
||||
*
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static DerivedPath parse(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
/**
|
||||
@ -262,7 +265,7 @@ struct DerivedPath : _DerivedPathRaw {
|
||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||
*/
|
||||
static DerivedPath parseLegacy(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string_view,
|
||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||
|
||||
|
@ -116,7 +116,14 @@ Settings::Settings()
|
||||
|
||||
void loadConfFile()
|
||||
{
|
||||
globalConfig.applyConfigFile(settings.nixConfDir + "/nix.conf");
|
||||
auto applyConfigFile = [&](const Path & path) {
|
||||
try {
|
||||
std::string contents = readFile(path);
|
||||
globalConfig.applyConfig(contents, path);
|
||||
} catch (SysError &) { }
|
||||
};
|
||||
|
||||
applyConfigFile(settings.nixConfDir + "/nix.conf");
|
||||
|
||||
/* We only want to send overrides to the daemon, i.e. stuff from
|
||||
~/.nix/nix.conf or the command line. */
|
||||
@ -124,7 +131,7 @@ void loadConfFile()
|
||||
|
||||
auto files = settings.nixUserConfFiles;
|
||||
for (auto file = files.rbegin(); file != files.rend(); file++) {
|
||||
globalConfig.applyConfigFile(*file);
|
||||
applyConfigFile(*file);
|
||||
}
|
||||
|
||||
auto nixConfEnv = getEnv("NIX_CONFIG");
|
||||
|
@ -117,10 +117,11 @@ public:
|
||||
|
||||
Setting<std::string> storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store",
|
||||
R"(
|
||||
The [URL of the Nix store](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format)
|
||||
The [URL of the Nix store](@docroot@/store/types/index.md#store-url-format)
|
||||
to use for most operations.
|
||||
See [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md)
|
||||
for supported store types and settings.
|
||||
See the
|
||||
[Store Types](@docroot@/store/types/index.md)
|
||||
section of the manual for supported store types and settings.
|
||||
)"};
|
||||
|
||||
Setting<bool> keepFailed{this, false, "keep-failed",
|
||||
@ -200,7 +201,7 @@ public:
|
||||
Nix will only build a given [derivation](@docroot@/language/derivations.md) locally when its `system` attribute equals any of the values specified here or in [`extra-platforms`](#conf-extra-platforms).
|
||||
|
||||
The default value is set when Nix itself is compiled for the system it will run on.
|
||||
The following system types are widely used, as [Nix is actively supported on these platforms](@docroot@/contributing/hacking.md#platforms):
|
||||
The following system types are widely used, as Nix is actively supported on these platforms:
|
||||
|
||||
- `x86_64-linux`
|
||||
- `x86_64-darwin`
|
||||
@ -759,8 +760,8 @@ public:
|
||||
Strings{"https://cache.nixos.org/"},
|
||||
"substituters",
|
||||
R"(
|
||||
A list of [URLs of Nix stores](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format) to be used as substituters, separated by whitespace.
|
||||
A substituter is an additional [store]{@docroot@/glossary.md##gloss-store} from which Nix can obtain [store objects](@docroot@/glossary.md#gloss-store-object) instead of building them.
|
||||
A list of [URLs of Nix stores](@docroot@/store/types/index.md#store-url-format) to be used as substituters, separated by whitespace.
|
||||
A substituter is an additional [store](@docroot@/glossary.md#gloss-store) from which Nix can obtain [store objects](@docroot@/glossary.md#gloss-store-object) instead of building them.
|
||||
|
||||
Substituters are tried based on their priority value, which each substituter can set independently.
|
||||
Lower value means higher priority.
|
||||
@ -778,7 +779,7 @@ public:
|
||||
Setting<StringSet> trustedSubstituters{
|
||||
this, {}, "trusted-substituters",
|
||||
R"(
|
||||
A list of [Nix store URLs](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format), separated by whitespace.
|
||||
A list of [Nix store URLs](@docroot@/store/types/index.md#store-url-format), separated by whitespace.
|
||||
These are not used by default, but users of the Nix daemon can enable them by specifying [`substituters`](#conf-substituters).
|
||||
|
||||
Unprivileged users (those set in only [`allowed-users`](#conf-allowed-users) but not [`trusted-users`](#conf-trusted-users)) can pass as `substituters` only those URLs listed in `trusted-substituters`.
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
class Store;
|
||||
struct StoreDirConfig;
|
||||
|
||||
/**
|
||||
* Reusable serialisers for serialization container types in a
|
||||
@ -44,8 +44,8 @@ struct LengthPrefixedProtoHelper;
|
||||
#define LENGTH_PREFIXED_PROTO_HELPER(Inner, T) \
|
||||
struct LengthPrefixedProtoHelper< Inner, T > \
|
||||
{ \
|
||||
static T read(const Store & store, typename Inner::ReadConn conn); \
|
||||
static void write(const Store & store, typename Inner::WriteConn conn, const T & str); \
|
||||
static T read(const StoreDirConfig & store, typename Inner::ReadConn conn); \
|
||||
static void write(const StoreDirConfig & store, typename Inner::WriteConn conn, const T & str); \
|
||||
private: \
|
||||
template<typename U> using S = typename Inner::template Serialise<U>; \
|
||||
}
|
||||
@ -67,7 +67,7 @@ LENGTH_PREFIXED_PROTO_HELPER(Inner, _X);
|
||||
template<class Inner, typename T>
|
||||
std::vector<T>
|
||||
LengthPrefixedProtoHelper<Inner, std::vector<T>>::read(
|
||||
const Store & store, typename Inner::ReadConn conn)
|
||||
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||
{
|
||||
std::vector<T> resSet;
|
||||
auto size = readNum<size_t>(conn.from);
|
||||
@ -80,7 +80,7 @@ LengthPrefixedProtoHelper<Inner, std::vector<T>>::read(
|
||||
template<class Inner, typename T>
|
||||
void
|
||||
LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
|
||||
const Store & store, typename Inner::WriteConn conn, const std::vector<T> & resSet)
|
||||
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::vector<T> & resSet)
|
||||
{
|
||||
conn.to << resSet.size();
|
||||
for (auto & key : resSet) {
|
||||
@ -91,7 +91,7 @@ LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
|
||||
template<class Inner, typename T>
|
||||
std::set<T>
|
||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
||||
const Store & store, typename Inner::ReadConn conn)
|
||||
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||
{
|
||||
std::set<T> resSet;
|
||||
auto size = readNum<size_t>(conn.from);
|
||||
@ -104,7 +104,7 @@ LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
||||
template<class Inner, typename T>
|
||||
void
|
||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::write(
|
||||
const Store & store, typename Inner::WriteConn conn, const std::set<T> & resSet)
|
||||
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::set<T> & resSet)
|
||||
{
|
||||
conn.to << resSet.size();
|
||||
for (auto & key : resSet) {
|
||||
@ -115,7 +115,7 @@ LengthPrefixedProtoHelper<Inner, std::set<T>>::write(
|
||||
template<class Inner, typename K, typename V>
|
||||
std::map<K, V>
|
||||
LengthPrefixedProtoHelper<Inner, std::map<K, V>>::read(
|
||||
const Store & store, typename Inner::ReadConn conn)
|
||||
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||
{
|
||||
std::map<K, V> resMap;
|
||||
auto size = readNum<size_t>(conn.from);
|
||||
@ -130,7 +130,7 @@ LengthPrefixedProtoHelper<Inner, std::map<K, V>>::read(
|
||||
template<class Inner, typename K, typename V>
|
||||
void
|
||||
LengthPrefixedProtoHelper<Inner, std::map<K, V>>::write(
|
||||
const Store & store, typename Inner::WriteConn conn, const std::map<K, V> & resMap)
|
||||
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::map<K, V> & resMap)
|
||||
{
|
||||
conn.to << resMap.size();
|
||||
for (auto & i : resMap) {
|
||||
@ -142,7 +142,7 @@ LengthPrefixedProtoHelper<Inner, std::map<K, V>>::write(
|
||||
template<class Inner, typename... Ts>
|
||||
std::tuple<Ts...>
|
||||
LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
|
||||
const Store & store, typename Inner::ReadConn conn)
|
||||
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||
{
|
||||
return std::tuple<Ts...> {
|
||||
S<Ts>::read(store, conn)...,
|
||||
@ -152,7 +152,7 @@ LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
|
||||
template<class Inner, typename... Ts>
|
||||
void
|
||||
LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::write(
|
||||
const Store & store, typename Inner::WriteConn conn, const std::tuple<Ts...> & res)
|
||||
const StoreDirConfig & store, typename Inner::WriteConn conn, const std::tuple<Ts...> & res)
|
||||
{
|
||||
std::apply([&]<typename... Us>(const Us &... args) {
|
||||
(S<Us>::write(store, conn, args), ...);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "pathlocks.hh"
|
||||
#include "worker-protocol.hh"
|
||||
#include "derivations.hh"
|
||||
#include "realisation.hh"
|
||||
#include "nar-info.hh"
|
||||
#include "references.hh"
|
||||
#include "callback.hh"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "local-store.hh"
|
||||
#include "store-api.hh"
|
||||
#include "thread-pool.hh"
|
||||
#include "realisation.hh"
|
||||
#include "topo-sort.hh"
|
||||
#include "callback.hh"
|
||||
#include "closure.hh"
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string StorePathWithOutputs::to_string(const Store & store) const
|
||||
std::string StorePathWithOutputs::to_string(const StoreDirConfig & store) const
|
||||
{
|
||||
return outputs.empty()
|
||||
? store.printStorePath(path)
|
||||
@ -85,7 +85,7 @@ std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s)
|
||||
}
|
||||
|
||||
|
||||
StorePathWithOutputs parsePathWithOutputs(const Store & store, std::string_view pathWithOutputs)
|
||||
StorePathWithOutputs parsePathWithOutputs(const StoreDirConfig & store, std::string_view pathWithOutputs)
|
||||
{
|
||||
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
|
||||
return StorePathWithOutputs { store.parseStorePath(path), std::move(outputs) };
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct StoreDirConfig;
|
||||
|
||||
/**
|
||||
* This is a deprecated old type just for use by the old CLI, and older
|
||||
* versions of the RPC protocols. In new code don't use it; you want
|
||||
@ -19,7 +21,7 @@ struct StorePathWithOutputs
|
||||
StorePath path;
|
||||
std::set<std::string> outputs;
|
||||
|
||||
std::string to_string(const Store & store) const;
|
||||
std::string to_string(const StoreDirConfig & store) const;
|
||||
|
||||
DerivedPath toDerivedPath() const;
|
||||
|
||||
@ -32,14 +34,14 @@ std::vector<DerivedPath> toDerivedPaths(const std::vector<StorePathWithOutputs>)
|
||||
|
||||
std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s);
|
||||
|
||||
class Store;
|
||||
|
||||
/**
|
||||
* Split a string specifying a derivation and a set of outputs
|
||||
* (/nix/store/hash-foo!out1,out2,...) into the derivation path
|
||||
* and the outputs.
|
||||
*/
|
||||
StorePathWithOutputs parsePathWithOutputs(const Store & store, std::string_view pathWithOutputs);
|
||||
StorePathWithOutputs parsePathWithOutputs(const StoreDirConfig & store, std::string_view pathWithOutputs);
|
||||
|
||||
class Store;
|
||||
|
||||
StorePathWithOutputs followLinksToStorePathWithOutputs(const Store & store, std::string_view pathWithOutputs);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "store-api.hh"
|
||||
#include "store-dir-config.hh"
|
||||
|
||||
#include <sodium.h>
|
||||
|
||||
@ -54,7 +54,7 @@ StorePath StorePath::random(std::string_view name)
|
||||
return StorePath(hash, name);
|
||||
}
|
||||
|
||||
StorePath Store::parseStorePath(std::string_view path) const
|
||||
StorePath StoreDirConfig::parseStorePath(std::string_view path) const
|
||||
{
|
||||
auto p = canonPath(std::string(path));
|
||||
if (dirOf(p) != storeDir)
|
||||
@ -62,7 +62,7 @@ StorePath Store::parseStorePath(std::string_view path) const
|
||||
return StorePath(baseNameOf(p));
|
||||
}
|
||||
|
||||
std::optional<StorePath> Store::maybeParseStorePath(std::string_view path) const
|
||||
std::optional<StorePath> StoreDirConfig::maybeParseStorePath(std::string_view path) const
|
||||
{
|
||||
try {
|
||||
return parseStorePath(path);
|
||||
@ -71,24 +71,24 @@ std::optional<StorePath> Store::maybeParseStorePath(std::string_view path) const
|
||||
}
|
||||
}
|
||||
|
||||
bool Store::isStorePath(std::string_view path) const
|
||||
bool StoreDirConfig::isStorePath(std::string_view path) const
|
||||
{
|
||||
return (bool) maybeParseStorePath(path);
|
||||
}
|
||||
|
||||
StorePathSet Store::parseStorePathSet(const PathSet & paths) const
|
||||
StorePathSet StoreDirConfig::parseStorePathSet(const PathSet & paths) const
|
||||
{
|
||||
StorePathSet res;
|
||||
for (auto & i : paths) res.insert(parseStorePath(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string Store::printStorePath(const StorePath & path) const
|
||||
std::string StoreDirConfig::printStorePath(const StorePath & path) const
|
||||
{
|
||||
return (storeDir + "/").append(path.to_string());
|
||||
}
|
||||
|
||||
PathSet Store::printStorePathSet(const StorePathSet & paths) const
|
||||
PathSet StoreDirConfig::printStorePathSet(const StorePathSet & paths) const
|
||||
{
|
||||
PathSet res;
|
||||
for (auto & i : paths) res.insert(printStorePath(i));
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
/* TODO: Separate these store impls into different files, give them better names */
|
||||
/* TODO: Separate these store types into different files, give them better names */
|
||||
RemoteStore::RemoteStore(const Params & params)
|
||||
: RemoteStoreConfig(params)
|
||||
, Store(params)
|
||||
|
@ -16,11 +16,11 @@ namespace nix {
|
||||
/* protocol-agnostic templates */
|
||||
|
||||
#define SERVE_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
||||
TEMPLATE T ServeProto::Serialise< T >::read(const Store & store, ServeProto::ReadConn conn) \
|
||||
TEMPLATE T ServeProto::Serialise< T >::read(const StoreDirConfig & store, ServeProto::ReadConn conn) \
|
||||
{ \
|
||||
return LengthPrefixedProtoHelper<ServeProto, T >::read(store, conn); \
|
||||
} \
|
||||
TEMPLATE void ServeProto::Serialise< T >::write(const Store & store, ServeProto::WriteConn conn, const T & t) \
|
||||
TEMPLATE void ServeProto::Serialise< T >::write(const StoreDirConfig & store, ServeProto::WriteConn conn, const T & t) \
|
||||
{ \
|
||||
LengthPrefixedProtoHelper<ServeProto, T >::write(store, conn, t); \
|
||||
}
|
||||
@ -41,12 +41,12 @@ SERVE_USE_LENGTH_PREFIX_SERIALISER(
|
||||
template<typename T>
|
||||
struct ServeProto::Serialise
|
||||
{
|
||||
static T read(const Store & store, ServeProto::ReadConn conn)
|
||||
static T read(const StoreDirConfig & store, ServeProto::ReadConn conn)
|
||||
{
|
||||
return CommonProto::Serialise<T>::read(store,
|
||||
CommonProto::ReadConn { .from = conn.from });
|
||||
}
|
||||
static void write(const Store & store, ServeProto::WriteConn conn, const T & t)
|
||||
static void write(const StoreDirConfig & store, ServeProto::WriteConn conn, const T & t)
|
||||
{
|
||||
CommonProto::Serialise<T>::write(store,
|
||||
CommonProto::WriteConn { .to = conn.to },
|
||||
|
@ -12,7 +12,7 @@ namespace nix {
|
||||
|
||||
/* protocol-specific definitions */
|
||||
|
||||
BuildResult ServeProto::Serialise<BuildResult>::read(const Store & store, ServeProto::ReadConn conn)
|
||||
BuildResult ServeProto::Serialise<BuildResult>::read(const StoreDirConfig & store, ServeProto::ReadConn conn)
|
||||
{
|
||||
BuildResult status;
|
||||
status.status = (BuildResult::Status) readInt(conn.from);
|
||||
@ -34,7 +34,7 @@ BuildResult ServeProto::Serialise<BuildResult>::read(const Store & store, ServeP
|
||||
return status;
|
||||
}
|
||||
|
||||
void ServeProto::Serialise<BuildResult>::write(const Store & store, ServeProto::WriteConn conn, const BuildResult & status)
|
||||
void ServeProto::Serialise<BuildResult>::write(const StoreDirConfig & store, ServeProto::WriteConn conn, const BuildResult & status)
|
||||
{
|
||||
conn.to
|
||||
<< status.status
|
||||
|
@ -13,7 +13,7 @@ namespace nix {
|
||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||
|
||||
|
||||
class Store;
|
||||
struct StoreDirConfig;
|
||||
struct Source;
|
||||
|
||||
// items being serialised
|
||||
@ -72,8 +72,8 @@ struct ServeProto
|
||||
// See `worker-protocol.hh` for a longer explanation.
|
||||
#if 0
|
||||
{
|
||||
static T read(const Store & store, ReadConn conn);
|
||||
static void write(const Store & store, WriteConn conn, const T & t);
|
||||
static T read(const StoreDirConfig & store, ReadConn conn);
|
||||
static void write(const StoreDirConfig & store, WriteConn conn, const T & t);
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -82,7 +82,7 @@ struct ServeProto
|
||||
* infer the type instead of having to write it down explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
static void write(const Store & store, WriteConn conn, const T & t)
|
||||
static void write(const StoreDirConfig & store, WriteConn conn, const T & t)
|
||||
{
|
||||
ServeProto::Serialise<T>::write(store, conn, t);
|
||||
}
|
||||
@ -135,8 +135,8 @@ inline std::ostream & operator << (std::ostream & s, ServeProto::Command op)
|
||||
#define DECLARE_SERVE_SERIALISER(T) \
|
||||
struct ServeProto::Serialise< T > \
|
||||
{ \
|
||||
static T read(const Store & store, ServeProto::ReadConn conn); \
|
||||
static void write(const Store & store, ServeProto::WriteConn conn, const T & t); \
|
||||
static T read(const StoreDirConfig & store, ServeProto::ReadConn conn); \
|
||||
static void write(const StoreDirConfig & store, ServeProto::WriteConn conn, const T & t); \
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -20,7 +20,7 @@ struct CommonSSHStoreConfig : virtual StoreConfig
|
||||
|
||||
const Setting<std::string> remoteStore{this, "", "remote-store",
|
||||
R"(
|
||||
[Store URL](@docroot@/command-ref/new-cli/nix3-help-stores.md#store-url-format)
|
||||
[Store URL](@docroot@/store/types/index.md#store-url-format)
|
||||
to be used on the remote machine. The default is `auto`
|
||||
(i.e. use the Nix daemon or `/nix/store` directly).
|
||||
)"};
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "crypto.hh"
|
||||
#include "source-accessor.hh"
|
||||
#include "globals.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "realisation.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
@ -25,13 +27,13 @@ using json = nlohmann::json;
|
||||
namespace nix {
|
||||
|
||||
|
||||
bool Store::isInStore(PathView path) const
|
||||
bool StoreDirConfig::isInStore(PathView path) const
|
||||
{
|
||||
return isInDir(path, storeDir);
|
||||
}
|
||||
|
||||
|
||||
std::pair<StorePath, Path> Store::toStorePath(PathView path) const
|
||||
std::pair<StorePath, Path> StoreDirConfig::toStorePath(PathView path) const
|
||||
{
|
||||
if (!isInStore(path))
|
||||
throw Error("path '%1%' is not in the Nix store", path);
|
||||
@ -145,7 +147,7 @@ StorePath Store::followLinksToStorePath(std::string_view path) const
|
||||
*/
|
||||
|
||||
|
||||
StorePath Store::makeStorePath(std::string_view type,
|
||||
StorePath StoreDirConfig::makeStorePath(std::string_view type,
|
||||
std::string_view hash, std::string_view name) const
|
||||
{
|
||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
||||
@ -156,14 +158,14 @@ StorePath Store::makeStorePath(std::string_view type,
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::makeStorePath(std::string_view type,
|
||||
StorePath StoreDirConfig::makeStorePath(std::string_view type,
|
||||
const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath(type, hash.to_string(HashFormat::Base16, true), name);
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::makeOutputPath(std::string_view id,
|
||||
StorePath StoreDirConfig::makeOutputPath(std::string_view id,
|
||||
const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath("output:" + std::string { id }, hash, outputPathName(name, id));
|
||||
@ -174,7 +176,7 @@ StorePath Store::makeOutputPath(std::string_view id,
|
||||
hacky, but we can't put them in, say, <s2> (per the grammar above)
|
||||
since that would be ambiguous. */
|
||||
static std::string makeType(
|
||||
const Store & store,
|
||||
const StoreDirConfig & store,
|
||||
std::string && type,
|
||||
const StoreReferences & references)
|
||||
{
|
||||
@ -187,7 +189,7 @@ static std::string makeType(
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const
|
||||
StorePath StoreDirConfig::makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const
|
||||
{
|
||||
if (info.hash.type == htSHA256 && info.method == FileIngestionMethod::Recursive) {
|
||||
return makeStorePath(makeType(*this, "source", info.references), info.hash, name);
|
||||
@ -203,7 +205,7 @@ StorePath Store::makeFixedOutputPath(std::string_view name, const FixedOutputInf
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::makeTextPath(std::string_view name, const TextInfo & info) const
|
||||
StorePath StoreDirConfig::makeTextPath(std::string_view name, const TextInfo & info) const
|
||||
{
|
||||
assert(info.hash.type == htSHA256);
|
||||
return makeStorePath(
|
||||
@ -216,7 +218,7 @@ StorePath Store::makeTextPath(std::string_view name, const TextInfo & info) cons
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const
|
||||
StorePath StoreDirConfig::makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const
|
||||
{
|
||||
// New template
|
||||
return std::visit(overloaded {
|
||||
@ -230,7 +232,7 @@ StorePath Store::makeFixedOutputPathFromCA(std::string_view name, const ContentA
|
||||
}
|
||||
|
||||
|
||||
std::pair<StorePath, Hash> Store::computeStorePathFromDump(
|
||||
std::pair<StorePath, Hash> StoreDirConfig::computeStorePathFromDump(
|
||||
Source & dump,
|
||||
std::string_view name,
|
||||
FileIngestionMethod method,
|
||||
@ -249,7 +251,7 @@ std::pair<StorePath, Hash> Store::computeStorePathFromDump(
|
||||
}
|
||||
|
||||
|
||||
StorePath Store::computeStorePathForText(
|
||||
StorePath StoreDirConfig::computeStorePathForText(
|
||||
std::string_view name,
|
||||
std::string_view s,
|
||||
const StorePathSet & references) const
|
||||
@ -1227,7 +1229,7 @@ std::optional<ValidPathInfo> decodeValidPathInfo(const Store & store, std::istre
|
||||
}
|
||||
|
||||
|
||||
std::string Store::showPaths(const StorePathSet & paths)
|
||||
std::string StoreDirConfig::showPaths(const StorePathSet & paths)
|
||||
{
|
||||
std::string s;
|
||||
for (auto & i : paths) {
|
||||
|
@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "nar-info.hh"
|
||||
#include "realisation.hh"
|
||||
#include "path.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "hash.hh"
|
||||
@ -14,6 +12,7 @@
|
||||
#include "config.hh"
|
||||
#include "path-info.hh"
|
||||
#include "repair-flag.hh"
|
||||
#include "store-dir-config.hh"
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <atomic>
|
||||
@ -30,7 +29,7 @@
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* About the class hierarchy of the store implementations:
|
||||
* About the class hierarchy of the store types:
|
||||
*
|
||||
* Each store type `Foo` consists of two classes:
|
||||
*
|
||||
@ -64,12 +63,16 @@ MakeError(InvalidPath, Error);
|
||||
MakeError(Unsupported, Error);
|
||||
MakeError(SubstituteGone, Error);
|
||||
MakeError(SubstituterDisabled, Error);
|
||||
MakeError(BadStorePath, Error);
|
||||
|
||||
MakeError(InvalidStoreURI, Error);
|
||||
|
||||
struct Realisation;
|
||||
struct RealisedPath;
|
||||
struct DrvOutput;
|
||||
|
||||
struct BasicDerivation;
|
||||
struct Derivation;
|
||||
|
||||
struct SourceAccessor;
|
||||
class NarInfoDiskCache;
|
||||
class Store;
|
||||
@ -96,11 +99,11 @@ struct KeyedBuildResult;
|
||||
|
||||
typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
|
||||
|
||||
struct StoreConfig : public Config
|
||||
struct StoreConfig : public StoreDirConfig
|
||||
{
|
||||
typedef std::map<std::string, std::string> Params;
|
||||
|
||||
using Config::Config;
|
||||
using StoreDirConfig::StoreDirConfig;
|
||||
|
||||
StoreConfig() = delete;
|
||||
|
||||
@ -130,15 +133,6 @@ struct StoreConfig : public Config
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const PathSetting storeDir_{this, settings.nixStore,
|
||||
"store",
|
||||
R"(
|
||||
Logical location of the Nix store, usually
|
||||
`/nix/store`. Note that you can only copy store paths
|
||||
between stores if they have the same `store` setting.
|
||||
)"};
|
||||
const Path storeDir = storeDir_;
|
||||
|
||||
const Setting<int> pathInfoCacheSize{this, 65536, "path-info-cache-size",
|
||||
"Size of the in-memory store path metadata cache."};
|
||||
|
||||
@ -226,45 +220,6 @@ public:
|
||||
|
||||
virtual std::string getUri() = 0;
|
||||
|
||||
StorePath parseStorePath(std::string_view path) const;
|
||||
|
||||
std::optional<StorePath> maybeParseStorePath(std::string_view path) const;
|
||||
|
||||
std::string printStorePath(const StorePath & path) const;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*
|
||||
* \todo remove
|
||||
*/
|
||||
StorePathSet parseStorePathSet(const PathSet & paths) const;
|
||||
|
||||
PathSet printStorePathSet(const StorePathSet & path) const;
|
||||
|
||||
/**
|
||||
* Display a set of paths in human-readable form (i.e., between quotes
|
||||
* and separated by commas).
|
||||
*/
|
||||
std::string showPaths(const StorePathSet & paths);
|
||||
|
||||
/**
|
||||
* @return true if ‘path’ is in the Nix store (but not the Nix
|
||||
* store itself).
|
||||
*/
|
||||
bool isInStore(PathView path) const;
|
||||
|
||||
/**
|
||||
* @return true if ‘path’ is a store path, i.e. a direct child of the
|
||||
* Nix store.
|
||||
*/
|
||||
bool isStorePath(std::string_view path) const;
|
||||
|
||||
/**
|
||||
* Split a path like /nix/store/<hash>-<name>/<bla> into
|
||||
* /nix/store/<hash>-<name> and /<bla>.
|
||||
*/
|
||||
std::pair<StorePath, Path> toStorePath(PathView path) const;
|
||||
|
||||
/**
|
||||
* Follow symlinks until we end up with a path in the Nix store.
|
||||
*/
|
||||
@ -276,55 +231,6 @@ public:
|
||||
*/
|
||||
StorePath followLinksToStorePath(std::string_view path) const;
|
||||
|
||||
/**
|
||||
* Constructs a unique store path name.
|
||||
*/
|
||||
StorePath makeStorePath(std::string_view type,
|
||||
std::string_view hash, std::string_view name) const;
|
||||
StorePath makeStorePath(std::string_view type,
|
||||
const Hash & hash, std::string_view name) const;
|
||||
|
||||
StorePath makeOutputPath(std::string_view id,
|
||||
const Hash & hash, std::string_view name) const;
|
||||
|
||||
StorePath makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const;
|
||||
|
||||
StorePath makeTextPath(std::string_view name, const TextInfo & info) const;
|
||||
|
||||
StorePath makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const;
|
||||
|
||||
/**
|
||||
* Read-only variant of addToStoreFromDump(). It returns the store
|
||||
* path to which a NAR or flat file would be written.
|
||||
*/
|
||||
std::pair<StorePath, Hash> computeStorePathFromDump(
|
||||
Source & dump,
|
||||
std::string_view name,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive,
|
||||
HashType hashAlgo = htSHA256,
|
||||
const StorePathSet & references = {}) const;
|
||||
|
||||
/**
|
||||
* Preparatory part of addTextToStore().
|
||||
*
|
||||
* !!! Computation of the path should take the references given to
|
||||
* addTextToStore() into account, otherwise we have a (relatively
|
||||
* minor) security hole: a caller can register a source file with
|
||||
* bogus references. If there are too many references, the path may
|
||||
* not be garbage collected when it has to be (not really a problem,
|
||||
* the caller could create a root anyway), or it may be garbage
|
||||
* collected when it shouldn't be (more serious).
|
||||
*
|
||||
* Hashing the references would solve this (bogus references would
|
||||
* simply yield a different store path, so other users wouldn't be
|
||||
* affected), but it has some backwards compatibility issues (the
|
||||
* hashing scheme changes), so I'm not doing that for now.
|
||||
*/
|
||||
StorePath computeStorePathForText(
|
||||
std::string_view name,
|
||||
std::string_view s,
|
||||
const StorePathSet & references) const;
|
||||
|
||||
/**
|
||||
* Check whether a path is valid.
|
||||
*/
|
||||
@ -888,7 +794,7 @@ void copyStorePath(
|
||||
*/
|
||||
std::map<StorePath, StorePath> copyPaths(
|
||||
Store & srcStore, Store & dstStore,
|
||||
const RealisedPath::Set &,
|
||||
const std::set<RealisedPath> &,
|
||||
RepairFlag repair = NoRepair,
|
||||
CheckSigsFlag checkSigs = CheckSigs,
|
||||
SubstituteFlag substitute = NoSubstitute);
|
||||
@ -905,7 +811,7 @@ std::map<StorePath, StorePath> copyPaths(
|
||||
*/
|
||||
void copyClosure(
|
||||
Store & srcStore, Store & dstStore,
|
||||
const RealisedPath::Set & paths,
|
||||
const std::set<RealisedPath> & paths,
|
||||
RepairFlag repair = NoRepair,
|
||||
CheckSigsFlag checkSigs = CheckSigs,
|
||||
SubstituteFlag substitute = NoSubstitute);
|
||||
@ -962,7 +868,7 @@ OutputPathMap resolveDerivedPath(Store &, const DerivedPath::Built &, Store * ev
|
||||
* - ‘ssh://[user@]<host>’: A remote Nix store accessed by running
|
||||
* ‘nix-store --serve’ via SSH.
|
||||
*
|
||||
* You can pass parameters to the store implementation by appending
|
||||
* You can pass parameters to the store type by appending
|
||||
* ‘?key=value&key=value&...’ to the URI.
|
||||
*/
|
||||
ref<Store> openStore(const std::string & uri = settings.storeUri.get(),
|
||||
|
126
src/libstore/store-dir-config.hh
Normal file
126
src/libstore/store-dir-config.hh
Normal file
@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
#include "path.hh"
|
||||
#include "hash.hh"
|
||||
#include "content-address.hh"
|
||||
#include "globals.hh"
|
||||
#include "config.hh"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
MakeError(BadStorePath, Error);
|
||||
|
||||
struct StoreDirConfig : public Config
|
||||
{
|
||||
using Config::Config;
|
||||
|
||||
StoreDirConfig() = delete;
|
||||
|
||||
virtual ~StoreDirConfig() = default;
|
||||
|
||||
const PathSetting storeDir_{this, settings.nixStore,
|
||||
"store",
|
||||
R"(
|
||||
Logical location of the Nix store, usually
|
||||
`/nix/store`. Note that you can only copy store paths
|
||||
between stores if they have the same `store` setting.
|
||||
)"};
|
||||
const Path storeDir = storeDir_;
|
||||
|
||||
// pure methods
|
||||
|
||||
StorePath parseStorePath(std::string_view path) const;
|
||||
|
||||
std::optional<StorePath> maybeParseStorePath(std::string_view path) const;
|
||||
|
||||
std::string printStorePath(const StorePath & path) const;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*
|
||||
* \todo remove
|
||||
*/
|
||||
StorePathSet parseStorePathSet(const PathSet & paths) const;
|
||||
|
||||
PathSet printStorePathSet(const StorePathSet & path) const;
|
||||
|
||||
/**
|
||||
* Display a set of paths in human-readable form (i.e., between quotes
|
||||
* and separated by commas).
|
||||
*/
|
||||
std::string showPaths(const StorePathSet & paths);
|
||||
|
||||
/**
|
||||
* @return true if ‘path’ is in the Nix store (but not the Nix
|
||||
* store itself).
|
||||
*/
|
||||
bool isInStore(PathView path) const;
|
||||
|
||||
/**
|
||||
* @return true if ‘path’ is a store path, i.e. a direct child of the
|
||||
* Nix store.
|
||||
*/
|
||||
bool isStorePath(std::string_view path) const;
|
||||
|
||||
/**
|
||||
* Split a path like /nix/store/<hash>-<name>/<bla> into
|
||||
* /nix/store/<hash>-<name> and /<bla>.
|
||||
*/
|
||||
std::pair<StorePath, Path> toStorePath(PathView path) const;
|
||||
|
||||
/**
|
||||
* Constructs a unique store path name.
|
||||
*/
|
||||
StorePath makeStorePath(std::string_view type,
|
||||
std::string_view hash, std::string_view name) const;
|
||||
StorePath makeStorePath(std::string_view type,
|
||||
const Hash & hash, std::string_view name) const;
|
||||
|
||||
StorePath makeOutputPath(std::string_view id,
|
||||
const Hash & hash, std::string_view name) const;
|
||||
|
||||
StorePath makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const;
|
||||
|
||||
StorePath makeTextPath(std::string_view name, const TextInfo & info) const;
|
||||
|
||||
StorePath makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const;
|
||||
|
||||
/**
|
||||
* Read-only variant of addToStoreFromDump(). It returns the store
|
||||
* path to which a NAR or flat file would be written.
|
||||
*/
|
||||
std::pair<StorePath, Hash> computeStorePathFromDump(
|
||||
Source & dump,
|
||||
std::string_view name,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive,
|
||||
HashType hashAlgo = htSHA256,
|
||||
const StorePathSet & references = {}) const;
|
||||
|
||||
/**
|
||||
* Preparatory part of addTextToStore().
|
||||
*
|
||||
* !!! Computation of the path should take the references given to
|
||||
* addTextToStore() into account, otherwise we have a (relatively
|
||||
* minor) security hole: a caller can register a source file with
|
||||
* bogus references. If there are too many references, the path may
|
||||
* not be garbage collected when it has to be (not really a problem,
|
||||
* the caller could create a root anyway), or it may be garbage
|
||||
* collected when it shouldn't be (more serious).
|
||||
*
|
||||
* Hashing the references would solve this (bogus references would
|
||||
* simply yield a different store path, so other users wouldn't be
|
||||
* affected), but it has some backwards compatibility issues (the
|
||||
* hashing scheme changes), so I'm not doing that for now.
|
||||
*/
|
||||
StorePath computeStorePathForText(
|
||||
std::string_view name,
|
||||
std::string_view s,
|
||||
const StorePathSet & references) const;
|
||||
};
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
check: libstore-tests-exe_RUN
|
||||
|
||||
programs += libstore-tests-exe
|
||||
|
||||
libstore-tests-exe_NAME = libnixstore-tests
|
||||
|
||||
libstore-tests-exe_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libstore-tests-exe_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libstore-tests-exe_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libstore-tests-exe_LIBS = libstore-tests
|
||||
|
||||
libstore-tests-exe_LDFLAGS := $(GTEST_LIBS)
|
||||
|
||||
libraries += libstore-tests
|
||||
|
||||
libstore-tests_NAME = libnixstore-tests
|
||||
|
||||
libstore-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libstore-tests_INSTALL_DIR := $(checklibdir)
|
||||
else
|
||||
libstore-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libstore-tests_SOURCES := $(wildcard $(d)/*.cc)
|
||||
|
||||
libstore-tests_CXXFLAGS += -I src/libstore -I src/libutil
|
||||
|
||||
libstore-tests_LIBS = libutil-tests libstore libutil
|
||||
|
||||
libstore-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)
|
@ -16,11 +16,11 @@ namespace nix {
|
||||
/* protocol-agnostic templates */
|
||||
|
||||
#define WORKER_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
||||
TEMPLATE T WorkerProto::Serialise< T >::read(const Store & store, WorkerProto::ReadConn conn) \
|
||||
TEMPLATE T WorkerProto::Serialise< T >::read(const StoreDirConfig & store, WorkerProto::ReadConn conn) \
|
||||
{ \
|
||||
return LengthPrefixedProtoHelper<WorkerProto, T >::read(store, conn); \
|
||||
} \
|
||||
TEMPLATE void WorkerProto::Serialise< T >::write(const Store & store, WorkerProto::WriteConn conn, const T & t) \
|
||||
TEMPLATE void WorkerProto::Serialise< T >::write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const T & t) \
|
||||
{ \
|
||||
LengthPrefixedProtoHelper<WorkerProto, T >::write(store, conn, t); \
|
||||
}
|
||||
@ -41,12 +41,12 @@ WORKER_USE_LENGTH_PREFIX_SERIALISER(
|
||||
template<typename T>
|
||||
struct WorkerProto::Serialise
|
||||
{
|
||||
static T read(const Store & store, WorkerProto::ReadConn conn)
|
||||
static T read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
return CommonProto::Serialise<T>::read(store,
|
||||
CommonProto::ReadConn { .from = conn.from });
|
||||
}
|
||||
static void write(const Store & store, WorkerProto::WriteConn conn, const T & t)
|
||||
static void write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const T & t)
|
||||
{
|
||||
CommonProto::Serialise<T>::write(store,
|
||||
CommonProto::WriteConn { .to = conn.to },
|
||||
|
@ -13,7 +13,7 @@ namespace nix {
|
||||
|
||||
/* protocol-specific definitions */
|
||||
|
||||
std::optional<TrustedFlag> WorkerProto::Serialise<std::optional<TrustedFlag>>::read(const Store & store, WorkerProto::ReadConn conn)
|
||||
std::optional<TrustedFlag> WorkerProto::Serialise<std::optional<TrustedFlag>>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
auto temp = readNum<uint8_t>(conn.from);
|
||||
switch (temp) {
|
||||
@ -28,7 +28,7 @@ std::optional<TrustedFlag> WorkerProto::Serialise<std::optional<TrustedFlag>>::r
|
||||
}
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<std::optional<TrustedFlag>>::write(const Store & store, WorkerProto::WriteConn conn, const std::optional<TrustedFlag> & optTrusted)
|
||||
void WorkerProto::Serialise<std::optional<TrustedFlag>>::write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const std::optional<TrustedFlag> & optTrusted)
|
||||
{
|
||||
if (!optTrusted)
|
||||
conn.to << uint8_t{0};
|
||||
@ -47,7 +47,7 @@ void WorkerProto::Serialise<std::optional<TrustedFlag>>::write(const Store & sto
|
||||
}
|
||||
|
||||
|
||||
DerivedPath WorkerProto::Serialise<DerivedPath>::read(const Store & store, WorkerProto::ReadConn conn)
|
||||
DerivedPath WorkerProto::Serialise<DerivedPath>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
auto s = readString(conn.from);
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
||||
@ -57,7 +57,7 @@ DerivedPath WorkerProto::Serialise<DerivedPath>::read(const Store & store, Worke
|
||||
}
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<DerivedPath>::write(const Store & store, WorkerProto::WriteConn conn, const DerivedPath & req)
|
||||
void WorkerProto::Serialise<DerivedPath>::write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const DerivedPath & req)
|
||||
{
|
||||
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
||||
conn.to << req.to_string_legacy(store);
|
||||
@ -81,7 +81,7 @@ void WorkerProto::Serialise<DerivedPath>::write(const Store & store, WorkerProto
|
||||
}
|
||||
|
||||
|
||||
KeyedBuildResult WorkerProto::Serialise<KeyedBuildResult>::read(const Store & store, WorkerProto::ReadConn conn)
|
||||
KeyedBuildResult WorkerProto::Serialise<KeyedBuildResult>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
auto path = WorkerProto::Serialise<DerivedPath>::read(store, conn);
|
||||
auto br = WorkerProto::Serialise<BuildResult>::read(store, conn);
|
||||
@ -91,14 +91,14 @@ KeyedBuildResult WorkerProto::Serialise<KeyedBuildResult>::read(const Store & st
|
||||
};
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<KeyedBuildResult>::write(const Store & store, WorkerProto::WriteConn conn, const KeyedBuildResult & res)
|
||||
void WorkerProto::Serialise<KeyedBuildResult>::write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const KeyedBuildResult & res)
|
||||
{
|
||||
WorkerProto::write(store, conn, res.path);
|
||||
WorkerProto::write(store, conn, static_cast<const BuildResult &>(res));
|
||||
}
|
||||
|
||||
|
||||
BuildResult WorkerProto::Serialise<BuildResult>::read(const Store & store, WorkerProto::ReadConn conn)
|
||||
BuildResult WorkerProto::Serialise<BuildResult>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
BuildResult res;
|
||||
res.status = static_cast<BuildResult::Status>(readInt(conn.from));
|
||||
@ -120,7 +120,7 @@ BuildResult WorkerProto::Serialise<BuildResult>::read(const Store & store, Worke
|
||||
return res;
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<BuildResult>::write(const Store & store, WorkerProto::WriteConn conn, const BuildResult & res)
|
||||
void WorkerProto::Serialise<BuildResult>::write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const BuildResult & res)
|
||||
{
|
||||
conn.to
|
||||
<< res.status
|
||||
@ -141,7 +141,7 @@ void WorkerProto::Serialise<BuildResult>::write(const Store & store, WorkerProto
|
||||
}
|
||||
|
||||
|
||||
ValidPathInfo WorkerProto::Serialise<ValidPathInfo>::read(const Store & store, ReadConn conn)
|
||||
ValidPathInfo WorkerProto::Serialise<ValidPathInfo>::read(const StoreDirConfig & store, ReadConn conn)
|
||||
{
|
||||
auto path = WorkerProto::Serialise<StorePath>::read(store, conn);
|
||||
return ValidPathInfo {
|
||||
@ -150,14 +150,14 @@ ValidPathInfo WorkerProto::Serialise<ValidPathInfo>::read(const Store & store, R
|
||||
};
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<ValidPathInfo>::write(const Store & store, WriteConn conn, const ValidPathInfo & pathInfo)
|
||||
void WorkerProto::Serialise<ValidPathInfo>::write(const StoreDirConfig & store, WriteConn conn, const ValidPathInfo & pathInfo)
|
||||
{
|
||||
WorkerProto::write(store, conn, pathInfo.path);
|
||||
WorkerProto::write(store, conn, static_cast<const UnkeyedValidPathInfo &>(pathInfo));
|
||||
}
|
||||
|
||||
|
||||
UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const Store & store, ReadConn conn)
|
||||
UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const StoreDirConfig & store, ReadConn conn)
|
||||
{
|
||||
auto deriver = readString(conn.from);
|
||||
auto narHash = Hash::parseAny(readString(conn.from), htSHA256);
|
||||
@ -173,7 +173,7 @@ UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const St
|
||||
return info;
|
||||
}
|
||||
|
||||
void WorkerProto::Serialise<UnkeyedValidPathInfo>::write(const Store & store, WriteConn conn, const UnkeyedValidPathInfo & pathInfo)
|
||||
void WorkerProto::Serialise<UnkeyedValidPathInfo>::write(const StoreDirConfig & store, WriteConn conn, const UnkeyedValidPathInfo & pathInfo)
|
||||
{
|
||||
conn.to
|
||||
<< (pathInfo.deriver ? store.printStorePath(*pathInfo.deriver) : "")
|
||||
|
@ -24,7 +24,7 @@ namespace nix {
|
||||
#define STDERR_RESULT 0x52534c54
|
||||
|
||||
|
||||
class Store;
|
||||
struct StoreDirConfig;
|
||||
struct Source;
|
||||
|
||||
// items being serialised
|
||||
@ -100,8 +100,8 @@ struct WorkerProto
|
||||
// This makes for a quicker debug cycle, as desired.
|
||||
#if 0
|
||||
{
|
||||
static T read(const Store & store, ReadConn conn);
|
||||
static void write(const Store & store, WriteConn conn, const T & t);
|
||||
static T read(const StoreDirConfig & store, ReadConn conn);
|
||||
static void write(const StoreDirConfig & store, WriteConn conn, const T & t);
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -110,7 +110,7 @@ struct WorkerProto
|
||||
* infer the type instead of having to write it down explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
static void write(const Store & store, WriteConn conn, const T & t)
|
||||
static void write(const StoreDirConfig & store, WriteConn conn, const T & t)
|
||||
{
|
||||
WorkerProto::Serialise<T>::write(store, conn, t);
|
||||
}
|
||||
@ -198,8 +198,8 @@ inline std::ostream & operator << (std::ostream & s, WorkerProto::Op op)
|
||||
#define DECLARE_WORKER_SERIALISER(T) \
|
||||
struct WorkerProto::Serialise< T > \
|
||||
{ \
|
||||
static T read(const Store & store, WorkerProto::ReadConn conn); \
|
||||
static void write(const Store & store, WorkerProto::WriteConn conn, const T & t); \
|
||||
static T read(const StoreDirConfig & store, WorkerProto::ReadConn conn); \
|
||||
static void write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const T & t); \
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -88,10 +88,9 @@ void Config::getSettings(std::map<std::string, SettingInfo> & res, bool overridd
|
||||
res.emplace(opt.first, SettingInfo{opt.second.setting->to_string(), opt.second.setting->description});
|
||||
}
|
||||
|
||||
void AbstractConfig::applyConfig(const std::string & contents, const std::string & path) {
|
||||
unsigned int pos = 0;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> parsedContents;
|
||||
static void applyConfigInner(const std::string & contents, const std::string & path, std::vector<std::pair<std::string, std::string>> & parsedContents) {
|
||||
unsigned int pos = 0;
|
||||
|
||||
while (pos < contents.size()) {
|
||||
std::string line;
|
||||
@ -122,7 +121,12 @@ void AbstractConfig::applyConfig(const std::string & contents, const std::string
|
||||
throw UsageError("illegal configuration line '%1%' in '%2%'", line, path);
|
||||
auto p = absPath(tokens[1], dirOf(path));
|
||||
if (pathExists(p)) {
|
||||
applyConfigFile(p);
|
||||
try {
|
||||
std::string includedContents = readFile(path);
|
||||
applyConfigInner(includedContents, p, parsedContents);
|
||||
} catch (SysError &) {
|
||||
// TODO: Do we actually want to ignore this? Or is it better to fail?
|
||||
}
|
||||
} else if (!ignoreMissing) {
|
||||
throw Error("file '%1%' included from '%2%' not found", p, path);
|
||||
}
|
||||
@ -142,6 +146,12 @@ void AbstractConfig::applyConfig(const std::string & contents, const std::string
|
||||
concatStringsSep(" ", Strings(i, tokens.end())),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
void AbstractConfig::applyConfig(const std::string & contents, const std::string & path) {
|
||||
std::vector<std::pair<std::string, std::string>> parsedContents;
|
||||
|
||||
applyConfigInner(contents, path, parsedContents);
|
||||
|
||||
// First apply experimental-feature related settings
|
||||
for (const auto & [name, value] : parsedContents)
|
||||
@ -154,14 +164,6 @@ void AbstractConfig::applyConfig(const std::string & contents, const std::string
|
||||
set(name, value);
|
||||
}
|
||||
|
||||
void AbstractConfig::applyConfigFile(const Path & path)
|
||||
{
|
||||
try {
|
||||
std::string contents = readFile(path);
|
||||
applyConfig(contents, path);
|
||||
} catch (SysError &) { }
|
||||
}
|
||||
|
||||
void Config::resetOverridden()
|
||||
{
|
||||
for (auto & s : _settings)
|
||||
|
@ -82,12 +82,6 @@ public:
|
||||
*/
|
||||
void applyConfig(const std::string & contents, const std::string & path = "<unknown>");
|
||||
|
||||
/**
|
||||
* Applies a nix configuration file
|
||||
* - path: the location of the config file to apply
|
||||
*/
|
||||
void applyConfigFile(const Path & path);
|
||||
|
||||
/**
|
||||
* Resets the `overridden` flag of all Settings
|
||||
*/
|
||||
|
@ -159,11 +159,11 @@ static std::string indent(std::string_view indentFirst, std::string_view indentR
|
||||
/**
|
||||
* A development aid for finding missing positions, to improve error messages. Example use:
|
||||
*
|
||||
* NIX_DEVELOPER_SHOW_UNKNOWN_LOCATIONS=1 _NIX_TEST_ACCEPT=1 make tests/lang.sh.test
|
||||
* _NIX_EVAL_SHOW_UNKNOWN_LOCATIONS=1 _NIX_TEST_ACCEPT=1 make tests/lang.sh.test
|
||||
* git diff -U20 tests
|
||||
*
|
||||
*/
|
||||
static bool printUnknownLocations = getEnv("_NIX_DEVELOPER_SHOW_UNKNOWN_LOCATIONS").has_value();
|
||||
static bool printUnknownLocations = getEnv("_NIX_EVAL_SHOW_UNKNOWN_LOCATIONS").has_value();
|
||||
|
||||
/**
|
||||
* Print a position, if it is known.
|
||||
|
@ -252,7 +252,7 @@ constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails
|
||||
.tag = Xp::ReadOnlyLocalStore,
|
||||
.name = "read-only-local-store",
|
||||
.description = R"(
|
||||
Allow the use of the `read-only` parameter in [local store](@docroot@/command-ref/new-cli/nix3-help-stores.md#local-store) URIs.
|
||||
Allow the use of the `read-only` parameter in [local store](@docroot@/store/types/local-store.md) URIs.
|
||||
)",
|
||||
},
|
||||
{
|
||||
|
@ -1,41 +0,0 @@
|
||||
check: libutil-tests-exe_RUN
|
||||
|
||||
programs += libutil-tests-exe
|
||||
|
||||
libutil-tests-exe_NAME = libnixutil-tests
|
||||
|
||||
libutil-tests-exe_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libutil-tests-exe_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libutil-tests-exe_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libutil-tests-exe_LIBS = libutil-tests
|
||||
|
||||
libutil-tests-exe_LDFLAGS := $(GTEST_LIBS)
|
||||
|
||||
libraries += libutil-tests
|
||||
|
||||
libutil-tests_NAME = libnixutil-tests
|
||||
|
||||
libutil-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libutil-tests_INSTALL_DIR := $(checklibdir)
|
||||
else
|
||||
libutil-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libutil-tests_SOURCES := $(wildcard $(d)/*.cc)
|
||||
|
||||
libutil-tests_CXXFLAGS += -I src/libutil
|
||||
|
||||
libutil-tests_LIBS = libutil
|
||||
|
||||
libutil-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)
|
||||
|
||||
check: unit-test-data/libutil/git/check-data.sh.test
|
||||
|
||||
$(eval $(call run-test,unit-test-data/libutil/git/check-data.sh))
|
@ -14,6 +14,7 @@
|
||||
#include "store-api.hh"
|
||||
#include "local-fs-store.hh"
|
||||
#include "globals.hh"
|
||||
#include "realisation.hh"
|
||||
#include "derivations.hh"
|
||||
#include "shared.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "shared.hh"
|
||||
#include "realisation.hh"
|
||||
#include "store-api.hh"
|
||||
#include "legacy.hh"
|
||||
|
||||
|
@ -38,7 +38,7 @@ void checkInfo(const std::string & msg) {
|
||||
|
||||
}
|
||||
|
||||
struct CmdDoctor : StoreCommand
|
||||
struct CmdConfigCheck : StoreCommand
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@ -152,4 +152,4 @@ struct CmdDoctor : StoreCommand
|
||||
}
|
||||
};
|
||||
|
||||
static auto rCmdDoctor = registerCommand<CmdDoctor>("doctor");
|
||||
static auto rCmdConfigCheck = registerCommand2<CmdConfigCheck>({ "config", "check" });
|
@ -662,7 +662,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||
}
|
||||
}
|
||||
|
||||
runProgramInStore(store, shell, args, buildEnvironment.getSystem());
|
||||
runProgramInStore(store, UseSearchPath::Use, shell, args, buildEnvironment.getSystem());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -49,7 +49,7 @@ struct CmdFmt : SourceExprCommand {
|
||||
}
|
||||
}
|
||||
|
||||
runProgramInStore(store, app.program, programArgs);
|
||||
runProgramInStore(store, UseSearchPath::DontUse, app.program, programArgs);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -139,6 +139,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs, virtual RootArgs
|
||||
{"to-base32", {"hash", "to-base32"}},
|
||||
{"to-base64", {"hash", "to-base64"}},
|
||||
{"verify", {"store", "verify"}},
|
||||
{"doctor", {"config", "check"}},
|
||||
};
|
||||
|
||||
bool aliasUsed = false;
|
||||
|
@ -235,10 +235,14 @@ operate are determined as follows:
|
||||
|
||||
# Nix stores
|
||||
|
||||
Most `nix` subcommands operate on a *Nix store*. These are documented
|
||||
in [`nix help-stores`](./nix3-help-stores.md).
|
||||
Most `nix` subcommands operate on a *Nix store*.
|
||||
The various store types are documented in the
|
||||
[Store Types](@docroot@/store/types/index.md)
|
||||
section of the manual.
|
||||
|
||||
# Shebang interpreter
|
||||
The same information is also available from the [`nix help-stores`](./nix3-help-stores.md) command.
|
||||
|
||||
# Shebang interpreter
|
||||
|
||||
The `nix` command can be used as a `#!` interpreter.
|
||||
Arguments to Nix can be passed on subsequent lines in the script.
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
#include "common-args.hh"
|
||||
#include "nar-info.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
@ -25,6 +25,7 @@ std::string chrootHelperName = "__run_in_chroot";
|
||||
namespace nix {
|
||||
|
||||
void runProgramInStore(ref<Store> store,
|
||||
UseSearchPath useSearchPath,
|
||||
const std::string & program,
|
||||
const Strings & args,
|
||||
std::optional<std::string_view> system)
|
||||
@ -58,7 +59,10 @@ void runProgramInStore(ref<Store> store,
|
||||
if (system)
|
||||
setPersonality(*system);
|
||||
|
||||
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
||||
if (useSearchPath == UseSearchPath::Use)
|
||||
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
||||
else
|
||||
execv(program.c_str(), stringsToCharPtrs(args).data());
|
||||
|
||||
throw SysError("unable to execute '%s'", program);
|
||||
}
|
||||
@ -132,7 +136,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment
|
||||
Strings args;
|
||||
for (auto & arg : command) args.push_back(arg);
|
||||
|
||||
runProgramInStore(store, *command.begin(), args);
|
||||
runProgramInStore(store, UseSearchPath::Use, *command.begin(), args);
|
||||
}
|
||||
};
|
||||
|
||||
@ -194,7 +198,7 @@ struct CmdRun : InstallableValueCommand
|
||||
Strings allArgs{app.program};
|
||||
for (auto & i : args) allArgs.push_back(i);
|
||||
|
||||
runProgramInStore(store, app.program, allArgs);
|
||||
runProgramInStore(store, UseSearchPath::DontUse, app.program, allArgs);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,13 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
enum struct UseSearchPath {
|
||||
Use,
|
||||
DontUse
|
||||
};
|
||||
|
||||
void runProgramInStore(ref<Store> store,
|
||||
UseSearchPath useSearchPath,
|
||||
const std::string & program,
|
||||
const Strings & args,
|
||||
std::optional<std::string_view> system = std::nullopt);
|
||||
|
@ -20,7 +20,7 @@ cat > "$NIX_CONF_DIR"/nix.conf <<EOF
|
||||
build-users-group =
|
||||
keep-derivations = false
|
||||
sandbox = false
|
||||
experimental-features = nix-command flakes
|
||||
experimental-features = nix-command
|
||||
gc-reserved-space = 0
|
||||
substituters =
|
||||
flake-registry = $TEST_ROOT/registry.json
|
||||
@ -31,6 +31,7 @@ EOF
|
||||
|
||||
cat > "$NIX_CONF_DIR"/nix.conf.extra <<EOF
|
||||
fsync-metadata = false
|
||||
extra-experimental-features = flakes
|
||||
!include nix.conf.extra.not-there
|
||||
EOF
|
||||
|
||||
|
23
tests/unit/libexpr-support/local.mk
Normal file
23
tests/unit/libexpr-support/local.mk
Normal file
@ -0,0 +1,23 @@
|
||||
libraries += libexpr-test-support
|
||||
|
||||
libexpr-test-support_NAME = libnixexpr-test-support
|
||||
|
||||
libexpr-test-support_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libexpr-test-support_INSTALL_DIR := $(checklibdir)
|
||||
else
|
||||
libexpr-test-support_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libexpr-test-support_SOURCES := \
|
||||
$(wildcard $(d)/tests/*.cc) \
|
||||
$(wildcard $(d)/tests/value/*.cc)
|
||||
|
||||
libexpr-test-support_CXXFLAGS += $(libexpr-tests_EXTRA_INCLUDES)
|
||||
|
||||
libexpr-test-support_LIBS = \
|
||||
libstore-test-support libutil-test-support \
|
||||
libexpr libstore libutil
|
||||
|
||||
libexpr-test-support_LDFLAGS := -lrapidcheck
|
30
tests/unit/libexpr-support/tests/value/context.cc
Normal file
30
tests/unit/libexpr-support/tests/value/context.cc
Normal file
@ -0,0 +1,30 @@
|
||||
#include <rapidcheck.h>
|
||||
|
||||
#include "tests/path.hh"
|
||||
#include "tests/value/context.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
|
||||
{
|
||||
return gen::just(NixStringContextElem::DrvDeep {
|
||||
.drvPath = *gen::arbitrary<StorePath>(),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
|
||||
case 0:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
|
||||
case 1:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
|
||||
case 2:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <rapidcheck/gen/Arbitrary.h>
|
||||
|
||||
#include <value/context.hh>
|
||||
#include "value/context.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
36
tests/unit/libexpr/local.mk
Normal file
36
tests/unit/libexpr/local.mk
Normal file
@ -0,0 +1,36 @@
|
||||
check: libexpr-tests_RUN
|
||||
|
||||
programs += libexpr-tests
|
||||
|
||||
libexpr-tests_NAME := libnixexpr-tests
|
||||
|
||||
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
|
||||
libexpr-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libexpr-tests_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libexpr-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libexpr-tests_SOURCES := \
|
||||
$(wildcard $(d)/*.cc) \
|
||||
$(wildcard $(d)/value/*.cc)
|
||||
|
||||
libexpr-tests_EXTRA_INCLUDES = \
|
||||
-I tests/unit/libexpr-support \
|
||||
-I tests/unit/libstore-support \
|
||||
-I tests/unit/libutil-support \
|
||||
-I src/libexpr \
|
||||
-I src/libfetchers \
|
||||
-I src/libstore \
|
||||
-I src/libutil
|
||||
|
||||
libexpr-tests_CXXFLAGS += $(libexpr-tests_EXTRA_INCLUDES)
|
||||
|
||||
libexpr-tests_LIBS = \
|
||||
libexpr-test-support libstore-test-support libutils-test-support \
|
||||
libexpr libfetchers libstore libutil
|
||||
|
||||
libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock
|
@ -814,6 +814,14 @@ namespace nix {
|
||||
ASSERT_THAT(*v.listElems()[0], IsStringEq("FOO"));
|
||||
}
|
||||
|
||||
TEST_F(PrimOpTest, match5) {
|
||||
// The regex "\\{}" is valid and matches the string "{}".
|
||||
// Caused a regression before when trying to switch from std::regex to boost::regex.
|
||||
// See https://github.com/NixOS/nix/pull/7762#issuecomment-1834303659
|
||||
auto v = eval("builtins.match \"\\\\{}\" \"{}\"");
|
||||
ASSERT_THAT(v, IsListOfSize(0));
|
||||
}
|
||||
|
||||
TEST_F(PrimOpTest, attrNames) {
|
||||
auto v = eval("builtins.attrNames { x = 1; y = 2; z = 3; a = 2; }");
|
||||
ASSERT_THAT(v, IsListOfSize(4));
|
@ -117,36 +117,6 @@ TEST(NixStringContextElemTest, built_built_xp) {
|
||||
NixStringContextElem::parse("!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv"), MissingExperimentalFeature);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
|
||||
{
|
||||
return gen::just(NixStringContextElem::DrvDeep {
|
||||
.drvPath = *gen::arbitrary<StorePath>(),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
|
||||
case 0:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
|
||||
case 1:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
|
||||
case 2:
|
||||
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace nix {
|
||||
|
||||
#ifndef COVERAGE
|
||||
|
||||
RC_GTEST_PROP(
|
21
tests/unit/libstore-support/local.mk
Normal file
21
tests/unit/libstore-support/local.mk
Normal file
@ -0,0 +1,21 @@
|
||||
libraries += libstore-test-support
|
||||
|
||||
libstore-test-support_NAME = libnixstore-test-support
|
||||
|
||||
libstore-test-support_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libstore-test-support_INSTALL_DIR := $(checklibdir)
|
||||
else
|
||||
libstore-test-support_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libstore-test-support_SOURCES := $(wildcard $(d)/tests/*.cc)
|
||||
|
||||
libstore-test-support_CXXFLAGS += $(libstore-tests_EXTRA_INCLUDES)
|
||||
|
||||
libstore-test-support_LIBS = \
|
||||
libutil-test-support \
|
||||
libstore libutil
|
||||
|
||||
libstore-test-support_LDFLAGS := -lrapidcheck
|
57
tests/unit/libstore-support/tests/derived-path.cc
Normal file
57
tests/unit/libstore-support/tests/derived-path.cc
Normal file
@ -0,0 +1,57 @@
|
||||
#include <regex>
|
||||
|
||||
#include <rapidcheck.h>
|
||||
|
||||
#include "tests/derived-path.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<DerivedPath::Opaque> Arbitrary<DerivedPath::Opaque>::arbitrary()
|
||||
{
|
||||
return gen::just(DerivedPath::Opaque {
|
||||
.path = *gen::arbitrary<StorePath>(),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<SingleDerivedPath::Built> Arbitrary<SingleDerivedPath::Built>::arbitrary()
|
||||
{
|
||||
return gen::just(SingleDerivedPath::Built {
|
||||
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
|
||||
.output = (*gen::arbitrary<StorePathName>()).name,
|
||||
});
|
||||
}
|
||||
|
||||
Gen<DerivedPath::Built> Arbitrary<DerivedPath::Built>::arbitrary()
|
||||
{
|
||||
return gen::just(DerivedPath::Built {
|
||||
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
|
||||
.outputs = *gen::arbitrary<OutputsSpec>(),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<SingleDerivedPath> Arbitrary<SingleDerivedPath>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<SingleDerivedPath::Raw>)) {
|
||||
case 0:
|
||||
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Opaque>());
|
||||
case 1:
|
||||
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Built>());
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
Gen<DerivedPath> Arbitrary<DerivedPath>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<DerivedPath::Raw>)) {
|
||||
case 0:
|
||||
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Opaque>());
|
||||
case 1:
|
||||
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Built>());
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
24
tests/unit/libstore-support/tests/outputs-spec.cc
Normal file
24
tests/unit/libstore-support/tests/outputs-spec.cc
Normal file
@ -0,0 +1,24 @@
|
||||
#include "tests/outputs-spec.hh"
|
||||
|
||||
#include <rapidcheck.h>
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<OutputsSpec> Arbitrary<OutputsSpec>::arbitrary()
|
||||
{
|
||||
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<OutputsSpec::Raw>)) {
|
||||
case 0:
|
||||
return gen::just((OutputsSpec) OutputsSpec::All { });
|
||||
case 1:
|
||||
return gen::just((OutputsSpec) OutputsSpec::Names {
|
||||
*gen::nonEmpty(gen::container<StringSet>(gen::map(
|
||||
gen::arbitrary<StorePathName>(),
|
||||
[](StorePathName n) { return n.name; }))),
|
||||
});
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <outputs-spec.hh>
|
||||
|
||||
#include <tests/path.hh>
|
||||
#include "tests/path.hh"
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
82
tests/unit/libstore-support/tests/path.cc
Normal file
82
tests/unit/libstore-support/tests/path.cc
Normal file
@ -0,0 +1,82 @@
|
||||
#include <regex>
|
||||
|
||||
#include <rapidcheck.h>
|
||||
|
||||
#include "path-regex.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include "tests/hash.hh"
|
||||
#include "tests/path.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void showValue(const StorePath & p, std::ostream & os)
|
||||
{
|
||||
os << p.to_string();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace rc {
|
||||
using namespace nix;
|
||||
|
||||
Gen<StorePathName> Arbitrary<StorePathName>::arbitrary()
|
||||
{
|
||||
auto len = *gen::inRange<size_t>(
|
||||
1,
|
||||
StorePath::MaxPathLen - StorePath::HashLen);
|
||||
|
||||
std::string pre;
|
||||
pre.reserve(len);
|
||||
|
||||
for (size_t c = 0; c < len; ++c) {
|
||||
switch (auto i = *gen::inRange<uint8_t>(0, 10 + 2 * 26 + 6)) {
|
||||
case 0 ... 9:
|
||||
pre += '0' + i;
|
||||
case 10 ... 35:
|
||||
pre += 'A' + (i - 10);
|
||||
break;
|
||||
case 36 ... 61:
|
||||
pre += 'a' + (i - 36);
|
||||
break;
|
||||
case 62:
|
||||
pre += '+';
|
||||
break;
|
||||
case 63:
|
||||
pre += '-';
|
||||
break;
|
||||
case 64:
|
||||
// names aren't permitted to start with a period,
|
||||
// so just fall through to the next case here
|
||||
if (c != 0) {
|
||||
pre += '.';
|
||||
break;
|
||||
}
|
||||
case 65:
|
||||
pre += '_';
|
||||
break;
|
||||
case 66:
|
||||
pre += '?';
|
||||
break;
|
||||
case 67:
|
||||
pre += '=';
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return gen::just(StorePathName {
|
||||
.name = std::move(pre),
|
||||
});
|
||||
}
|
||||
|
||||
Gen<StorePath> Arbitrary<StorePath>::arbitrary()
|
||||
{
|
||||
return gen::just(StorePath {
|
||||
*gen::arbitrary<Hash>(),
|
||||
(*gen::arbitrary<StorePathName>()).name,
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace rc
|
@ -11,6 +11,9 @@ struct StorePathName {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
// For rapidcheck
|
||||
void showValue(const StorePath & p, std::ostream & os);
|
||||
|
||||
}
|
||||
|
||||
namespace rc {
|
@ -12,7 +12,7 @@ namespace nix {
|
||||
template<class Proto, const char * protocolDir>
|
||||
class ProtoTest : public CharacterizationTest, public LibStoreTest
|
||||
{
|
||||
Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir;
|
||||
Path unitTestData = getUnitTestData() + "/" + protocolDir;
|
||||
|
||||
Path goldenMaster(std::string_view testStem) const override {
|
||||
return unitTestData + "/" + testStem + ".bin";
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user