mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 14:52:55 +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/xp-features.json
|
||||||
/doc/manual/src/SUMMARY.md
|
/doc/manual/src/SUMMARY.md
|
||||||
/doc/manual/src/SUMMARY-rl-next.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/new-cli
|
||||||
/doc/manual/src/command-ref/conf-file.md
|
/doc/manual/src/command-ref/conf-file.md
|
||||||
/doc/manual/src/command-ref/experimental-features-shortlist.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.hh
|
||||||
/src/libexpr/parser-tab.output
|
/src/libexpr/parser-tab.output
|
||||||
/src/libexpr/nix.tbl
|
/src/libexpr/nix.tbl
|
||||||
/src/libexpr/tests/libnixexpr-tests
|
/tests/unit/libexpr/libnixexpr-tests
|
||||||
|
|
||||||
# /src/libstore/
|
# /src/libstore/
|
||||||
*.gen.*
|
*.gen.*
|
||||||
/src/libstore/tests/libnixstore-tests
|
/tests/unit/libstore/libnixstore-tests
|
||||||
|
|
||||||
# /src/libutil/
|
# /src/libutil/
|
||||||
/src/libutil/tests/libnixutil-tests
|
/tests/unit/libutil/libnixutil-tests
|
||||||
|
|
||||||
/src/nix/nix
|
/src/nix/nix
|
||||||
|
|
||||||
|
10
Makefile
10
Makefile
@ -25,11 +25,13 @@ makefiles = \
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
|
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
|
||||||
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
|
|
||||||
makefiles += \
|
makefiles += \
|
||||||
src/libutil/tests/local.mk \
|
tests/unit/libutil/local.mk \
|
||||||
src/libstore/tests/local.mk \
|
tests/unit/libutil-support/local.mk \
|
||||||
src/libexpr/tests/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
|
endif
|
||||||
|
|
||||||
ifeq ($(ENABLE_TESTS), yes)
|
ifeq ($(ENABLE_TESTS), yes)
|
||||||
|
@ -39,17 +39,21 @@ INPUT = \
|
|||||||
src/libcmd \
|
src/libcmd \
|
||||||
src/libexpr \
|
src/libexpr \
|
||||||
src/libexpr/flake \
|
src/libexpr/flake \
|
||||||
src/libexpr/tests \
|
tests/unit/libexpr \
|
||||||
src/libexpr/tests/value \
|
tests/unit/libexpr/value \
|
||||||
|
tests/unit/libexpr/test \
|
||||||
|
tests/unit/libexpr/test/value \
|
||||||
src/libexpr/value \
|
src/libexpr/value \
|
||||||
src/libfetchers \
|
src/libfetchers \
|
||||||
src/libmain \
|
src/libmain \
|
||||||
src/libstore \
|
src/libstore \
|
||||||
src/libstore/build \
|
src/libstore/build \
|
||||||
src/libstore/builtins \
|
src/libstore/builtins \
|
||||||
src/libstore/tests \
|
tests/unit/libstore \
|
||||||
|
tests/unit/libstore/test \
|
||||||
src/libutil \
|
src/libutil \
|
||||||
src/libutil/tests \
|
tests/unit/libutil \
|
||||||
|
tests/unit/libutil/test \
|
||||||
src/nix \
|
src/nix \
|
||||||
src/nix-env \
|
src/nix-env \
|
||||||
src/nix-store
|
src/nix-store
|
||||||
|
@ -51,7 +51,7 @@ let
|
|||||||
|
|
||||||
${maybeSubcommands}
|
${maybeSubcommands}
|
||||||
|
|
||||||
${maybeStoreDocs}
|
${maybeProse}
|
||||||
|
|
||||||
${maybeOptions}
|
${maybeOptions}
|
||||||
'';
|
'';
|
||||||
@ -91,17 +91,47 @@ let
|
|||||||
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
|
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# FIXME: this is a hack.
|
maybeProse =
|
||||||
# store parameters should not be part of command documentation to begin
|
# FIXME: this is a horrible hack to keep `nix help-stores` working.
|
||||||
# with, but instead be rendered on separate pages.
|
# the correct answer to this is to remove that command and replace it
|
||||||
maybeStoreDocs = optionalString (details ? doc)
|
# by statically generated manpages or the output of something like `nix
|
||||||
(replaceStrings [ "@stores@" ] [ (showStoreDocs inlineHTML commandInfo.stores) ] details.doc);
|
# store info <store type>`.
|
||||||
|
let
|
||||||
|
help-stores = ''
|
||||||
|
${index}
|
||||||
|
|
||||||
maybeOptions = let
|
${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
|
||||||
|
);
|
||||||
|
|
||||||
|
maybeOptions =
|
||||||
|
let
|
||||||
allVisibleOptions = filterAttrs
|
allVisibleOptions = filterAttrs
|
||||||
(_: o: ! o.hiddenCategory)
|
(_: o: ! o.hiddenCategory)
|
||||||
(details.flags // toplevel.flags);
|
(details.flags // toplevel.flags);
|
||||||
in optionalString (allVisibleOptions != {}) ''
|
in
|
||||||
|
optionalString (allVisibleOptions != { }) ''
|
||||||
# Options
|
# Options
|
||||||
|
|
||||||
${showOptions inlineHTML allVisibleOptions}
|
${showOptions inlineHTML allVisibleOptions}
|
||||||
|
@ -31,18 +31,19 @@ let
|
|||||||
|
|
||||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||||
> **Warning**
|
> **Warning**
|
||||||
|
>
|
||||||
> This setting is part of an
|
> This setting is part of an
|
||||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||||
|
>
|
||||||
To change this setting, you need to make sure the corresponding experimental feature,
|
> To change this setting, make sure the
|
||||||
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
|
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature})
|
||||||
is enabled.
|
> is enabled.
|
||||||
For example, include the following in [`nix.conf`](#):
|
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||||
|
>
|
||||||
```
|
> ```
|
||||||
extra-experimental-features = ${experimentalFeature}
|
> extra-experimental-features = ${experimentalFeature}
|
||||||
${setting} = ...
|
> ${setting} = ...
|
||||||
```
|
> ```
|
||||||
'';
|
'';
|
||||||
|
|
||||||
showDefault = documentDefault: defaultValue:
|
showDefault = documentDefault: defaultValue:
|
||||||
|
@ -1,45 +1,57 @@
|
|||||||
let
|
let
|
||||||
inherit (builtins) attrValues mapAttrs;
|
inherit (builtins) attrNames listToAttrs concatStringsSep readFile replaceStrings;
|
||||||
inherit (import <nix/utils.nix>) concatStrings optionalString;
|
inherit (import <nix/utils.nix>) optionalString filterAttrs trim squash toLower unique indent;
|
||||||
showSettings = import <nix/generate-settings.nix>;
|
showSettings = import <nix/generate-settings.nix>;
|
||||||
in
|
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
|
let
|
||||||
|
|
||||||
showStore = name: { settings, doc, experimentalFeature }:
|
showStore = { name, slug }: { settings, doc, experimentalFeature }:
|
||||||
let
|
let
|
||||||
|
result = squash ''
|
||||||
result = ''
|
# ${name}
|
||||||
## ${name}
|
|
||||||
|
|
||||||
${doc}
|
${doc}
|
||||||
|
|
||||||
${experimentalFeatureNote}
|
${experimentalFeatureNote}
|
||||||
|
|
||||||
### Settings
|
## Settings
|
||||||
|
|
||||||
${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings}
|
${showSettings { prefix = "store-${slug}"; inherit inlineHTML; } settings}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# markdown doesn't like spaces in URLs
|
|
||||||
slug = builtins.replaceStrings [ " " ] [ "-" ] name;
|
|
||||||
|
|
||||||
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
|
||||||
> **Warning**
|
> **Warning**
|
||||||
|
>
|
||||||
> This store is part of an
|
> This store is part of an
|
||||||
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
> [experimental feature](@docroot@/contributing/experimental-features.md).
|
||||||
|
>
|
||||||
To use this store, you need to make sure the corresponding experimental feature,
|
> To use this store, make sure the
|
||||||
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
|
> [`${experimentalFeature}` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature})
|
||||||
is enabled.
|
> is enabled.
|
||||||
For example, include the following in [`nix.conf`](#):
|
> For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
|
||||||
|
>
|
||||||
```
|
> ```
|
||||||
extra-experimental-features = ${experimentalFeature}
|
> extra-experimental-features = ${experimentalFeature}
|
||||||
```
|
> ```
|
||||||
'';
|
'';
|
||||||
in result;
|
in result;
|
||||||
|
|
||||||
in concatStrings (attrValues (mapAttrs showStore storesInfo))
|
storesList = map
|
||||||
|
(name: rec {
|
||||||
|
inherit name;
|
||||||
|
slug = replaceStrings [ " " ] [ "-" ] (toLower name);
|
||||||
|
filename = "${slug}.md";
|
||||||
|
page = showStore { inherit name slug; } storeInfo.${name};
|
||||||
|
})
|
||||||
|
(attrNames storeInfo);
|
||||||
|
|
||||||
|
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}
|
${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 $@
|
$(trace-gen) lowdown -sT man --nroff-nolinks -M section=5 $^.tmp -o $@
|
||||||
@rm $^.tmp
|
@rm $^.tmp
|
||||||
|
|
||||||
$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/SUMMARY-rl-next.md $(d)/src/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 $< $@
|
@cp $< $@
|
||||||
@$(call process-includes,$@,$@)
|
@$(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)
|
$(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
|
@rm -rf $@ $@.tmp
|
||||||
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix true (builtins.readFile $<)'
|
$(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
|
# `@docroot@` is to be preserved for documenting the mechanism
|
||||||
# FIXME: maybe contributing guides should live right next to the code
|
# FIXME: maybe contributing guides should live right next to the code
|
||||||
# instead of in the manual
|
# instead of in the manual
|
||||||
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/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) \
|
$(trace-gen) \
|
||||||
tmp="$$(mktemp -d)"; \
|
tmp="$$(mktemp -d)"; \
|
||||||
cp -r doc/manual "$$tmp"; \
|
cp -r doc/manual "$$tmp"; \
|
||||||
|
@ -3,6 +3,6 @@ issues: #7672
|
|||||||
prs: #9477
|
prs: #9477
|
||||||
description: {
|
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)
|
- [File System Object](store/file-system-object.md)
|
||||||
- [Store Object](store/store-object.md)
|
- [Store Object](store/store-object.md)
|
||||||
- [Store Path](store/store-path.md)
|
- [Store Path](store/store-path.md)
|
||||||
|
- [Store Types](store/types/index.md)
|
||||||
|
{{#include ./store/types/SUMMARY.md}}
|
||||||
- [Nix Language](language/index.md)
|
- [Nix Language](language/index.md)
|
||||||
- [Data Types](language/values.md)
|
- [Data Types](language/values.md)
|
||||||
- [Language Constructs](language/constructs.md)
|
- [Language Constructs](language/constructs.md)
|
||||||
|
@ -87,7 +87,7 @@ impacted the most by bad user experience.
|
|||||||
and [aligning of text](#text-alignment).
|
and [aligning of text](#text-alignment).
|
||||||
- [Autocomplete](#shell-completion) of options.
|
- [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**
|
- **Utility and scripting commands**
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ This leads to the following guidelines:
|
|||||||
### Examples
|
### 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
|
```json
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
|||||||
|
|
||||||
[googletest]: https://google.github.io/googletest/
|
[googletest]: https://google.github.io/googletest/
|
||||||
[rapidcheck]: https://github.com/emil-e/rapidcheck
|
[rapidcheck]: https://github.com/emil-e/rapidcheck
|
||||||
|
[property testing]: https://en.wikipedia.org/wiki/Property_testing
|
||||||
|
|
||||||
### Source and header layout
|
### Source and header layout
|
||||||
|
|
||||||
@ -28,34 +29,50 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
|
|||||||
> ```
|
> ```
|
||||||
> src
|
> src
|
||||||
> ├── libexpr
|
> ├── libexpr
|
||||||
|
> │ ├── local.mk
|
||||||
> │ ├── value/context.hh
|
> │ ├── value/context.hh
|
||||||
> │ ├── value/context.cc
|
> │ ├── value/context.cc
|
||||||
> │ │
|
|
||||||
> │ …
|
|
||||||
> └── tests
|
|
||||||
> │ ├── value/context.hh
|
|
||||||
> │ ├── value/context.cc
|
|
||||||
> │ │
|
|
||||||
> │ …
|
> │ …
|
||||||
> │
|
> │
|
||||||
> ├── unit-test-data
|
> ├── tests
|
||||||
> │ ├── libstore
|
> │ │
|
||||||
> │ │ ├── worker-protocol/content-address.bin
|
> │ …
|
||||||
|
> │ └── unit
|
||||||
|
> │ ├── libutil
|
||||||
|
> │ │ ├── local.mk
|
||||||
> │ │ …
|
> │ │ …
|
||||||
|
> │ │ └── data
|
||||||
|
> │ │ ├── git/tree.txt
|
||||||
|
> │ │ …
|
||||||
|
> │ │
|
||||||
|
> │ ├── 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.
|
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 `unit-test-data/libstore`.
|
For example, `libnixstore` code is in `src/libstore`, and its test data is in `tests/unit/libstore/data`.
|
||||||
The path to the `unit-test-data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_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**
|
The unit test libraries are in `tests/unit/${library_name_without-nix}-lib`.
|
||||||
> Due to the way googletest works, downstream unit test executables will actually include and re-run upstream library tests.
|
All headers are in a `tests` subdirectory so they are included with `#include "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 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
|
### 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.
|
Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used.
|
||||||
For example:
|
For example:
|
||||||
```shell-session
|
```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_read
|
||||||
[ SKIPPED ] WorkerProtoTest.string_write
|
[ 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.
|
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.
|
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
|
## Functional tests
|
||||||
|
|
||||||
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`.
|
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.
|
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
|
## Store URL format
|
||||||
|
|
||||||
@ -39,4 +41,3 @@ store as follows:
|
|||||||
|
|
||||||
* Otherwise, use the [local store](#local-store) `/nix/store`.
|
* Otherwise, use the [local store](#local-store) `/nix/store`.
|
||||||
|
|
||||||
@stores@
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
with builtins;
|
with builtins;
|
||||||
|
|
||||||
|
let
|
||||||
|
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
stringToCharacters = s: genList (p: substring p 1 s) (stringLength s);
|
||||||
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
splitLines = s: filter (x: !isList x) (split "\n" s);
|
splitLines = s: filter (x: !isList x) (split "\n" s);
|
||||||
|
|
||||||
@ -18,6 +24,8 @@ rec {
|
|||||||
in
|
in
|
||||||
if replaced == string then string else replaceStringsRec from to replaced;
|
if replaced == string then string else replaceStringsRec from to replaced;
|
||||||
|
|
||||||
|
toLower = replaceStrings upperChars lowerChars;
|
||||||
|
|
||||||
squash = replaceStringsRec "\n\n\n" "\n\n";
|
squash = replaceStringsRec "\n\n\n" "\n\n";
|
||||||
|
|
||||||
trim = string:
|
trim = string:
|
||||||
|
@ -196,7 +196,6 @@
|
|||||||
versionSuffix
|
versionSuffix
|
||||||
;
|
;
|
||||||
busybox-sandbox-shell = final.busybox-sandbox-shell or default-busybox-sandbox-shell;
|
busybox-sandbox-shell = final.busybox-sandbox-shell or default-busybox-sandbox-shell;
|
||||||
boost = final.boost.override { enableIcu = false; };
|
|
||||||
libgit2 = final.libgit2.overrideAttrs (attrs: {
|
libgit2 = final.libgit2.overrideAttrs (attrs: {
|
||||||
src = libgit2;
|
src = libgit2;
|
||||||
version = libgit2.lastModifiedDate;
|
version = libgit2.lastModifiedDate;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Remove overall test dir (at most one of the two should match) and
|
# Remove overall test dir (at most one of the two should match) and
|
||||||
# remove file extension.
|
# remove file extension.
|
||||||
test_name=$(echo -n "$test" | sed \
|
test_name=$(echo -n "$test" | sed \
|
||||||
-e "s|^unit-test-data/||" \
|
-e "s|^tests/unit/[^/]*/data/||" \
|
||||||
-e "s|^tests/functional/||" \
|
-e "s|^tests/functional/||" \
|
||||||
-e "s|\.sh$||" \
|
-e "s|\.sh$||" \
|
||||||
)
|
)
|
||||||
|
@ -87,6 +87,6 @@ define build-program
|
|||||||
# Phony target to run this program (typically as a dependency of 'check').
|
# Phony target to run this program (typically as a dependency of 'check').
|
||||||
.PHONY: $(1)_RUN
|
.PHONY: $(1)_RUN
|
||||||
$(1)_RUN: $$($(1)_PATH)
|
$(1)_RUN: $$($(1)_PATH)
|
||||||
$(trace-test) $$(UNIT_TEST_ENV) $$($(1)_PATH)
|
$(trace-test) $$($(1)_ENV) $$($(1)_PATH)
|
||||||
|
|
||||||
endef
|
endef
|
||||||
|
@ -152,7 +152,7 @@ in {
|
|||||||
./misc
|
./misc
|
||||||
./precompiled-headers.h
|
./precompiled-headers.h
|
||||||
./src
|
./src
|
||||||
./unit-test-data
|
./tests/unit
|
||||||
./COPYING
|
./COPYING
|
||||||
./scripts/local.mk
|
./scripts/local.mk
|
||||||
] ++ lib.optionals anySortOfTesting [
|
] ++ lib.optionals anySortOfTesting [
|
||||||
@ -297,10 +297,7 @@ in {
|
|||||||
-change ${boost}/lib/libboost_context.dylib \
|
-change ${boost}/lib/libboost_context.dylib \
|
||||||
$out/lib/libboost_context.dylib \
|
$out/lib/libboost_context.dylib \
|
||||||
$out/lib/libnixutil.dylib
|
$out/lib/libnixutil.dylib
|
||||||
install_name_tool \
|
install_name_tool
|
||||||
-change ${boost}/lib/libboost_regex.dylib \
|
|
||||||
$out/lib/libboost_regex.dylib \
|
|
||||||
$out/lib/libnixexpr.dylib
|
|
||||||
''
|
''
|
||||||
) + lib.optionalString enableInternalAPIDocs ''
|
) + lib.optionalString enableInternalAPIDocs ''
|
||||||
mkdir -p ''${!outputDoc}/nix-support
|
mkdir -p ''${!outputDoc}/nix-support
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#undef do_close
|
#undef do_close
|
||||||
|
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "crypto.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;
|
nlohmann::json res;
|
||||||
res["drvPath"] = drvPath->toJSON(store);
|
res["drvPath"] = drvPath->toJSON(store);
|
||||||
@ -90,7 +90,7 @@ nlohmann::json BuiltPath::Built::toJSON(const Store & store) const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json SingleBuiltPath::Built::toJSON(const Store & store) const
|
nlohmann::json SingleBuiltPath::Built::toJSON(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
nlohmann::json res;
|
nlohmann::json res;
|
||||||
res["drvPath"] = drvPath->toJSON(store);
|
res["drvPath"] = drvPath->toJSON(store);
|
||||||
@ -100,14 +100,14 @@ nlohmann::json SingleBuiltPath::Built::toJSON(const Store & store) const
|
|||||||
return res;
|
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 std::visit([&](const auto & buildable) {
|
||||||
return buildable.toJSON(store);
|
return buildable.toJSON(store);
|
||||||
}, raw());
|
}, raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json BuiltPath::toJSON(const Store & store) const
|
nlohmann::json BuiltPath::toJSON(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
return std::visit([&](const auto & buildable) {
|
return std::visit([&](const auto & buildable) {
|
||||||
return buildable.toJSON(store);
|
return buildable.toJSON(store);
|
||||||
|
@ -14,9 +14,9 @@ struct SingleBuiltPathBuilt {
|
|||||||
|
|
||||||
SingleDerivedPathBuilt discardOutputPath() const;
|
SingleDerivedPathBuilt discardOutputPath() const;
|
||||||
|
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
static SingleBuiltPathBuilt parse(const Store & store, std::string_view, std::string_view);
|
static SingleBuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||||
nlohmann::json toJSON(const Store & store) const;
|
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||||
|
|
||||||
DECLARE_CMP(SingleBuiltPathBuilt);
|
DECLARE_CMP(SingleBuiltPathBuilt);
|
||||||
};
|
};
|
||||||
@ -41,8 +41,8 @@ struct SingleBuiltPath : _SingleBuiltPathRaw {
|
|||||||
|
|
||||||
SingleDerivedPath discardOutputPath() const;
|
SingleDerivedPath discardOutputPath() const;
|
||||||
|
|
||||||
static SingleBuiltPath parse(const Store & store, std::string_view);
|
static SingleBuiltPath parse(const StoreDirConfig & store, std::string_view);
|
||||||
nlohmann::json toJSON(const Store & store) const;
|
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
|
static inline ref<SingleBuiltPath> staticDrv(StorePath drvPath)
|
||||||
@ -59,9 +59,9 @@ struct BuiltPathBuilt {
|
|||||||
ref<SingleBuiltPath> drvPath;
|
ref<SingleBuiltPath> drvPath;
|
||||||
std::map<std::string, StorePath> outputs;
|
std::map<std::string, StorePath> outputs;
|
||||||
|
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
static BuiltPathBuilt parse(const Store & store, std::string_view, std::string_view);
|
static BuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view);
|
||||||
nlohmann::json toJSON(const Store & store) const;
|
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||||
|
|
||||||
DECLARE_CMP(BuiltPathBuilt);
|
DECLARE_CMP(BuiltPathBuilt);
|
||||||
};
|
};
|
||||||
@ -89,7 +89,7 @@ struct BuiltPath : _BuiltPathRaw {
|
|||||||
StorePathSet outPaths() const;
|
StorePathSet outPaths() const;
|
||||||
RealisedPath::Set toRealisedPaths(Store & store) 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;
|
typedef std::vector<BuiltPath> BuiltPaths;
|
||||||
|
@ -141,7 +141,7 @@ MixEvalArgs::MixEvalArgs()
|
|||||||
.longName = "eval-store",
|
.longName = "eval-store",
|
||||||
.description =
|
.description =
|
||||||
R"(
|
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.
|
to use for evaluation, i.e. to store derivations (`.drv` files) and inputs referenced by them.
|
||||||
)",
|
)",
|
||||||
.category = category,
|
.category = category,
|
||||||
|
@ -22,7 +22,7 @@ struct AttrDb
|
|||||||
{
|
{
|
||||||
std::atomic_bool failed{false};
|
std::atomic_bool failed{false};
|
||||||
|
|
||||||
const Store & cfg;
|
const StoreDirConfig & cfg;
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ struct AttrDb
|
|||||||
SymbolTable & symbols;
|
SymbolTable & symbols;
|
||||||
|
|
||||||
AttrDb(
|
AttrDb(
|
||||||
const Store & cfg,
|
const StoreDirConfig & cfg,
|
||||||
const Hash & fingerprint,
|
const Hash & fingerprint,
|
||||||
SymbolTable & symbols)
|
SymbolTable & symbols)
|
||||||
: cfg(cfg)
|
: cfg(cfg)
|
||||||
@ -323,7 +323,7 @@ struct AttrDb
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::shared_ptr<AttrDb> makeAttrDb(
|
static std::shared_ptr<AttrDb> makeAttrDb(
|
||||||
const Store & cfg,
|
const StoreDirConfig & cfg,
|
||||||
const Hash & fingerprint,
|
const Hash & fingerprint,
|
||||||
SymbolTable & symbols)
|
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_LIBS = libutil libstore libfetchers
|
||||||
|
|
||||||
libexpr_LDFLAGS += -lboost_context -lboost_regex -pthread
|
libexpr_LDFLAGS += -lboost_context -pthread
|
||||||
ifdef HOST_LINUX
|
ifdef HOST_LINUX
|
||||||
libexpr_LDFLAGS += -ldl
|
libexpr_LDFLAGS += -ldl
|
||||||
endif
|
endif
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "primops.hh"
|
#include "primops.hh"
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/regex.hpp>
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -26,6 +25,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <regex>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -3886,30 +3886,19 @@ static RegisterPrimOp primop_convertHash({
|
|||||||
.fun = prim_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
|
struct RegexCache
|
||||||
{
|
{
|
||||||
// TODO use C++20 transparent comparison when available
|
// 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;
|
std::list<std::string> keys;
|
||||||
|
|
||||||
regex get(std::string_view re)
|
std::regex get(std::string_view re)
|
||||||
{
|
{
|
||||||
auto it = cache.find(re);
|
auto it = cache.find(re);
|
||||||
if (it != cache.end())
|
if (it != cache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
keys.emplace_back(re);
|
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;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.match");
|
||||||
|
|
||||||
cmatch match;
|
std::cmatch match;
|
||||||
if (!regex_match(str.begin(), str.end(), match, regex)) {
|
if (!std::regex_match(str.begin(), str.end(), match, regex)) {
|
||||||
v.mkNull();
|
v.mkNull();
|
||||||
return;
|
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());
|
(v.listElems()[i] = state.allocValue())->mkString(match[i + 1].str());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (regex_error & e) {
|
} catch (std::regex_error & e) {
|
||||||
if (e.code() == regex_constants::error_space) {
|
if (e.code() == std::regex_constants::error_space) {
|
||||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
.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;
|
NixStringContext context;
|
||||||
const auto str = state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.split");
|
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 begin = std::cregex_iterator(str.begin(), str.end(), regex);
|
||||||
auto end = cregex_iterator();
|
auto end = std::cregex_iterator();
|
||||||
|
|
||||||
// Any matches results are surrounded by non-matching results.
|
// Any matches results are surrounded by non-matching results.
|
||||||
const size_t len = std::distance(begin, end);
|
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);
|
assert(idx == 2 * len + 1);
|
||||||
|
|
||||||
} catch (regex_error & e) {
|
} catch (std::regex_error & e) {
|
||||||
if (e.code() == regex_constants::error_space) {
|
if (e.code() == std::regex_constants::error_space) {
|
||||||
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
// limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
.msg = hintfmt("memory limit exceeded by regular expression '%s'", re),
|
||||||
@ -4411,7 +4400,7 @@ void EvalState::createBaseEnv()
|
|||||||
addConstant("__currentSystem", v, {
|
addConstant("__currentSystem", v, {
|
||||||
.type = nString,
|
.type = nString,
|
||||||
.doc = R"(
|
.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:
|
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"(
|
.doc = R"(
|
||||||
Logical file system location of the [Nix store](@docroot@/glossary.md#gloss-store) currently in use.
|
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
|
```shell-session
|
||||||
$ nix-instantiate --store 'dummy://?store=/blah' --eval --expr builtins.storeDir
|
$ nix-instantiate --store 'dummy://?store=/blah' --eval --expr builtins.storeDir
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "primops.hh"
|
#include "primops.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "make-content-addressed.hh"
|
#include "make-content-addressed.hh"
|
||||||
#include "url.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;
|
class PosIdx;
|
||||||
struct Pos;
|
struct Pos;
|
||||||
class StorePath;
|
class StorePath;
|
||||||
class Store;
|
|
||||||
class EvalState;
|
class EvalState;
|
||||||
class XMLWriter;
|
class XMLWriter;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "buildenv.hh"
|
#include "buildenv.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "derivations.hh"
|
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -16,11 +16,11 @@ namespace nix {
|
|||||||
/* protocol-agnostic templates */
|
/* protocol-agnostic templates */
|
||||||
|
|
||||||
#define COMMON_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
#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); \
|
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); \
|
LengthPrefixedProtoHelper<CommonProto, T >::write(store, conn, t); \
|
||||||
}
|
}
|
||||||
|
@ -13,40 +13,40 @@ namespace nix {
|
|||||||
|
|
||||||
/* protocol-agnostic definitions */
|
/* 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);
|
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;
|
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));
|
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);
|
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));
|
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);
|
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);
|
std::string rawInput = readString(conn.from);
|
||||||
return Realisation::fromJSON(
|
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();
|
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));
|
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();
|
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);
|
auto s = readString(conn.from);
|
||||||
return s == "" ? std::optional<StorePath> {} : store.parseStorePath(s);
|
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) : "");
|
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));
|
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) : "");
|
conn.to << (caOpt ? renderContentAddress(*caOpt) : "");
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
class Store;
|
struct StoreDirConfig;
|
||||||
struct Source;
|
struct Source;
|
||||||
|
|
||||||
// items being serialized
|
// items being serialized
|
||||||
@ -48,7 +48,7 @@ struct CommonProto
|
|||||||
* infer the type instead of having to write it down explicitly.
|
* infer the type instead of having to write it down explicitly.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
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);
|
CommonProto::Serialise<T>::write(store, conn, t);
|
||||||
}
|
}
|
||||||
@ -57,8 +57,8 @@ struct CommonProto
|
|||||||
#define DECLARE_COMMON_SERIALISER(T) \
|
#define DECLARE_COMMON_SERIALISER(T) \
|
||||||
struct CommonProto::Serialise< T > \
|
struct CommonProto::Serialise< T > \
|
||||||
{ \
|
{ \
|
||||||
static T read(const Store & store, CommonProto::ReadConn conn); \
|
static T read(const StoreDirConfig & store, CommonProto::ReadConn conn); \
|
||||||
static void write(const Store & store, CommonProto::WriteConn conn, const T & str); \
|
static void write(const StoreDirConfig & store, CommonProto::WriteConn conn, const T & str); \
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace nix {
|
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 {
|
return std::visit(overloaded {
|
||||||
[](const DerivationOutput::InputAddressed & doi) -> std::optional<StorePath> {
|
[](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(
|
return store.makeFixedOutputPathFromCA(
|
||||||
outputPathName(drvName, outputName),
|
outputPathName(drvName, outputName),
|
||||||
@ -214,7 +214,7 @@ static StringSet parseStrings(std::istream & str, bool arePaths)
|
|||||||
|
|
||||||
|
|
||||||
static DerivationOutput parseDerivationOutput(
|
static DerivationOutput parseDerivationOutput(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view pathS, std::string_view hashAlgo, std::string_view hashS,
|
std::string_view pathS, std::string_view hashAlgo, std::string_view hashS,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -261,7 +261,7 @@ static DerivationOutput parseDerivationOutput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DerivationOutput parseDerivationOutput(
|
static DerivationOutput parseDerivationOutput(
|
||||||
const Store & store, std::istringstream & str,
|
const StoreDirConfig & store, std::istringstream & str,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings)
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings)
|
||||||
{
|
{
|
||||||
expect(str, ","); const auto pathS = parseString(str);
|
expect(str, ","); const auto pathS = parseString(str);
|
||||||
@ -290,7 +290,7 @@ enum struct DerivationATermVersion {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
|
static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::istringstream & str,
|
std::istringstream & str,
|
||||||
DerivationATermVersion version)
|
DerivationATermVersion version)
|
||||||
{
|
{
|
||||||
@ -337,7 +337,7 @@ static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
|
|||||||
|
|
||||||
|
|
||||||
Derivation parseDerivation(
|
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)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
Derivation drv;
|
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 += ',';
|
s += ',';
|
||||||
if (node.childMap.empty()) {
|
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
|
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs) const
|
||||||
{
|
{
|
||||||
std::string s;
|
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 pathS = readString(in);
|
||||||
const auto hashAlgo = readString(in);
|
const auto hashAlgo = readString(in);
|
||||||
@ -862,7 +862,7 @@ StringSet BasicDerivation::outputNames() const
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
DerivationOutputsAndOptPaths BasicDerivation::outputsAndOptPaths(const Store & store) const
|
DerivationOutputsAndOptPaths BasicDerivation::outputsAndOptPaths(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
DerivationOutputsAndOptPaths outsAndOptPaths;
|
DerivationOutputsAndOptPaths outsAndOptPaths;
|
||||||
for (auto & [outputName, output] : outputs)
|
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;
|
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();
|
out << drv.outputs.size();
|
||||||
for (auto & i : drv.outputs) {
|
for (auto & i : drv.outputs) {
|
||||||
@ -1153,7 +1153,7 @@ void Derivation::checkInvariants(Store & store, const StorePath & drvPath) const
|
|||||||
const Hash impureOutputHash = hashString(htSHA256, "impure");
|
const Hash impureOutputHash = hashString(htSHA256, "impure");
|
||||||
|
|
||||||
nlohmann::json DerivationOutput::toJSON(
|
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();
|
nlohmann::json res = nlohmann::json::object();
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
@ -1180,7 +1180,7 @@ nlohmann::json DerivationOutput::toJSON(
|
|||||||
|
|
||||||
|
|
||||||
DerivationOutput DerivationOutput::fromJSON(
|
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 nlohmann::json & _json,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
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();
|
nlohmann::json res = nlohmann::json::object();
|
||||||
|
|
||||||
@ -1302,7 +1302,7 @@ nlohmann::json Derivation::toJSON(const Store & store) const
|
|||||||
|
|
||||||
|
|
||||||
Derivation Derivation::fromJSON(
|
Derivation Derivation::fromJSON(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
const nlohmann::json & json,
|
const nlohmann::json & json,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
class Store;
|
struct StoreDirConfig;
|
||||||
|
|
||||||
/* Abstract syntax of derivations. */
|
/* 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 drvName The name of the derivation this is an output of, without the `.drv`.
|
||||||
* @param outputName The name of this output.
|
* @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);
|
GENERATE_CMP(CAFixed, me->ca);
|
||||||
};
|
};
|
||||||
@ -132,17 +132,17 @@ struct DerivationOutput
|
|||||||
* the safer interface provided by
|
* the safer interface provided by
|
||||||
* BasicDerivation::outputsAndOptPaths
|
* 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(
|
nlohmann::json toJSON(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view drvName,
|
std::string_view drvName,
|
||||||
OutputNameView outputName) const;
|
OutputNameView outputName) const;
|
||||||
/**
|
/**
|
||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static DerivationOutput fromJSON(
|
static DerivationOutput fromJSON(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view drvName,
|
std::string_view drvName,
|
||||||
OutputNameView outputName,
|
OutputNameView outputName,
|
||||||
const nlohmann::json & json,
|
const nlohmann::json & json,
|
||||||
@ -304,7 +304,7 @@ struct BasicDerivation
|
|||||||
* augmented with knowledge of the Store paths they would be written
|
* augmented with knowledge of the Store paths they would be written
|
||||||
* into.
|
* into.
|
||||||
*/
|
*/
|
||||||
DerivationOutputsAndOptPaths outputsAndOptPaths(const Store & store) const;
|
DerivationOutputsAndOptPaths outputsAndOptPaths(const StoreDirConfig & store) const;
|
||||||
|
|
||||||
static std::string_view nameFromPath(const StorePath & storePath);
|
static std::string_view nameFromPath(const StorePath & storePath);
|
||||||
|
|
||||||
@ -318,6 +318,8 @@ struct BasicDerivation
|
|||||||
me->name);
|
me->name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Store;
|
||||||
|
|
||||||
struct Derivation : BasicDerivation
|
struct Derivation : BasicDerivation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -328,7 +330,7 @@ struct Derivation : BasicDerivation
|
|||||||
/**
|
/**
|
||||||
* Print a derivation.
|
* 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;
|
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs = nullptr) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -365,9 +367,9 @@ struct Derivation : BasicDerivation
|
|||||||
Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
|
Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
|
||||||
Derivation(BasicDerivation && bd) : BasicDerivation(std::move(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(
|
static Derivation fromJSON(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
const nlohmann::json & json,
|
const nlohmann::json & json,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
|
|
||||||
@ -391,7 +393,7 @@ StorePath writeDerivation(Store & store,
|
|||||||
* Read a derivation from a file.
|
* Read a derivation from a file.
|
||||||
*/
|
*/
|
||||||
Derivation parseDerivation(
|
Derivation parseDerivation(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string && s,
|
std::string && s,
|
||||||
std::string_view name,
|
std::string_view name,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
@ -493,8 +495,8 @@ extern Sync<DrvHashes> drvHashes;
|
|||||||
struct Source;
|
struct Source;
|
||||||
struct Sink;
|
struct Sink;
|
||||||
|
|
||||||
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);
|
||||||
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);
|
void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDerivation & drv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This creates an opaque and almost certainly unique string
|
* This creates an opaque and almost certainly unique string
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "derived-path.hh"
|
#include "derived-path.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@ -32,7 +33,7 @@ CMP(SingleDerivedPath, DerivedPathBuilt, outputs)
|
|||||||
#undef CMP
|
#undef CMP
|
||||||
#undef CMP_ONE
|
#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);
|
return store.printStorePath(path);
|
||||||
}
|
}
|
||||||
@ -86,50 +87,50 @@ nlohmann::json DerivedPath::toJSON(Store & store) const
|
|||||||
}, raw());
|
}, 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);
|
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;
|
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;
|
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)
|
return drvPath->to_string(store)
|
||||||
+ '^'
|
+ '^'
|
||||||
+ outputs.to_string();
|
+ 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)
|
return drvPath->to_string_legacy(store)
|
||||||
+ "!"
|
+ "!"
|
||||||
+ outputs.to_string();
|
+ outputs.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SingleDerivedPath::to_string(const Store & store) const
|
std::string SingleDerivedPath::to_string(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
return std::visit(
|
return std::visit(
|
||||||
[&](const auto & req) { return req.to_string(store); },
|
[&](const auto & req) { return req.to_string(store); },
|
||||||
raw());
|
raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DerivedPath::to_string(const Store & store) const
|
std::string DerivedPath::to_string(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
return std::visit(
|
return std::visit(
|
||||||
[&](const auto & req) { return req.to_string(store); },
|
[&](const auto & req) { return req.to_string(store); },
|
||||||
raw());
|
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 {
|
return std::visit(overloaded {
|
||||||
[&](const SingleDerivedPath::Built & req) { return req.to_string_legacy(store); },
|
[&](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());
|
}, 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 {
|
return std::visit(overloaded {
|
||||||
[&](const DerivedPath::Built & req) { return req.to_string_legacy(store); },
|
[&](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)};
|
return {store.parseStorePath(s)};
|
||||||
}
|
}
|
||||||
@ -166,7 +167,7 @@ void drvRequireExperiment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SingleDerivedPath::Built SingleDerivedPath::Built::parse(
|
SingleDerivedPath::Built SingleDerivedPath::Built::parse(
|
||||||
const Store & store, ref<SingleDerivedPath> drv,
|
const StoreDirConfig & store, ref<SingleDerivedPath> drv,
|
||||||
OutputNameView output,
|
OutputNameView output,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -178,7 +179,7 @@ SingleDerivedPath::Built SingleDerivedPath::Built::parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DerivedPath::Built DerivedPath::Built::parse(
|
DerivedPath::Built DerivedPath::Built::parse(
|
||||||
const Store & store, ref<SingleDerivedPath> drv,
|
const StoreDirConfig & store, ref<SingleDerivedPath> drv,
|
||||||
OutputNameView outputsS,
|
OutputNameView outputsS,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -190,7 +191,7 @@ DerivedPath::Built DerivedPath::Built::parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SingleDerivedPath parseWithSingle(
|
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)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
size_t n = s.rfind(separator);
|
size_t n = s.rfind(separator);
|
||||||
@ -207,7 +208,7 @@ static SingleDerivedPath parseWithSingle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SingleDerivedPath SingleDerivedPath::parse(
|
SingleDerivedPath SingleDerivedPath::parse(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view s,
|
std::string_view s,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -215,7 +216,7 @@ SingleDerivedPath SingleDerivedPath::parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SingleDerivedPath SingleDerivedPath::parseLegacy(
|
SingleDerivedPath SingleDerivedPath::parseLegacy(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view s,
|
std::string_view s,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -223,7 +224,7 @@ SingleDerivedPath SingleDerivedPath::parseLegacy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DerivedPath parseWith(
|
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)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
size_t n = s.rfind(separator);
|
size_t n = s.rfind(separator);
|
||||||
@ -240,7 +241,7 @@ static DerivedPath parseWith(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DerivedPath DerivedPath::parse(
|
DerivedPath DerivedPath::parse(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view s,
|
std::string_view s,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
@ -248,7 +249,7 @@ DerivedPath DerivedPath::parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DerivedPath DerivedPath::parseLegacy(
|
DerivedPath DerivedPath::parseLegacy(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view s,
|
std::string_view s,
|
||||||
const ExperimentalFeatureSettings & xpSettings)
|
const ExperimentalFeatureSettings & xpSettings)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
struct StoreDirConfig;
|
||||||
|
|
||||||
|
// TODO stop needing this, `toJSON` below should be pure
|
||||||
class Store;
|
class Store;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,9 +27,9 @@ class Store;
|
|||||||
struct DerivedPathOpaque {
|
struct DerivedPathOpaque {
|
||||||
StorePath path;
|
StorePath path;
|
||||||
|
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
static DerivedPathOpaque parse(const Store & store, std::string_view);
|
static DerivedPathOpaque parse(const StoreDirConfig & store, std::string_view);
|
||||||
nlohmann::json toJSON(const Store & store) const;
|
nlohmann::json toJSON(const StoreDirConfig & store) const;
|
||||||
|
|
||||||
GENERATE_CMP(DerivedPathOpaque, me->path);
|
GENERATE_CMP(DerivedPathOpaque, me->path);
|
||||||
};
|
};
|
||||||
@ -59,18 +62,18 @@ struct SingleDerivedPathBuilt {
|
|||||||
/**
|
/**
|
||||||
* Uses `^` as the separator
|
* Uses `^` as the separator
|
||||||
*/
|
*/
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
/**
|
/**
|
||||||
* Uses `!` as the separator
|
* 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.
|
* The caller splits on the separator, so it works for both variants.
|
||||||
*
|
*
|
||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static SingleDerivedPathBuilt parse(
|
static SingleDerivedPathBuilt parse(
|
||||||
const Store & store, ref<SingleDerivedPath> drvPath,
|
const StoreDirConfig & store, ref<SingleDerivedPath> drvPath,
|
||||||
OutputNameView outputs,
|
OutputNameView outputs,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
nlohmann::json toJSON(Store & store) const;
|
nlohmann::json toJSON(Store & store) const;
|
||||||
@ -120,18 +123,18 @@ struct SingleDerivedPath : _SingleDerivedPathRaw {
|
|||||||
/**
|
/**
|
||||||
* Uses `^` as the separator
|
* Uses `^` as the separator
|
||||||
*/
|
*/
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
/**
|
/**
|
||||||
* Uses `!` as the separator
|
* 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
|
* Uses `^` as the separator
|
||||||
*
|
*
|
||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static SingleDerivedPath parse(
|
static SingleDerivedPath parse(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view,
|
std::string_view,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
/**
|
/**
|
||||||
@ -140,7 +143,7 @@ struct SingleDerivedPath : _SingleDerivedPathRaw {
|
|||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static SingleDerivedPath parseLegacy(
|
static SingleDerivedPath parseLegacy(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view,
|
std::string_view,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
nlohmann::json toJSON(Store & store) const;
|
nlohmann::json toJSON(Store & store) const;
|
||||||
@ -182,18 +185,18 @@ struct DerivedPathBuilt {
|
|||||||
/**
|
/**
|
||||||
* Uses `^` as the separator
|
* Uses `^` as the separator
|
||||||
*/
|
*/
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
/**
|
/**
|
||||||
* Uses `!` as the separator
|
* 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.
|
* The caller splits on the separator, so it works for both variants.
|
||||||
*
|
*
|
||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static DerivedPathBuilt parse(
|
static DerivedPathBuilt parse(
|
||||||
const Store & store, ref<SingleDerivedPath>,
|
const StoreDirConfig & store, ref<SingleDerivedPath>,
|
||||||
std::string_view,
|
std::string_view,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
nlohmann::json toJSON(Store & store) const;
|
nlohmann::json toJSON(Store & store) const;
|
||||||
@ -242,18 +245,18 @@ struct DerivedPath : _DerivedPathRaw {
|
|||||||
/**
|
/**
|
||||||
* Uses `^` as the separator
|
* Uses `^` as the separator
|
||||||
*/
|
*/
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
/**
|
/**
|
||||||
* Uses `!` as the separator
|
* 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
|
* Uses `^` as the separator
|
||||||
*
|
*
|
||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static DerivedPath parse(
|
static DerivedPath parse(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view,
|
std::string_view,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
/**
|
/**
|
||||||
@ -262,7 +265,7 @@ struct DerivedPath : _DerivedPathRaw {
|
|||||||
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
||||||
*/
|
*/
|
||||||
static DerivedPath parseLegacy(
|
static DerivedPath parseLegacy(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string_view,
|
std::string_view,
|
||||||
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
||||||
|
|
||||||
|
@ -116,7 +116,14 @@ Settings::Settings()
|
|||||||
|
|
||||||
void loadConfFile()
|
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
|
/* We only want to send overrides to the daemon, i.e. stuff from
|
||||||
~/.nix/nix.conf or the command line. */
|
~/.nix/nix.conf or the command line. */
|
||||||
@ -124,7 +131,7 @@ void loadConfFile()
|
|||||||
|
|
||||||
auto files = settings.nixUserConfFiles;
|
auto files = settings.nixUserConfFiles;
|
||||||
for (auto file = files.rbegin(); file != files.rend(); file++) {
|
for (auto file = files.rbegin(); file != files.rend(); file++) {
|
||||||
globalConfig.applyConfigFile(*file);
|
applyConfigFile(*file);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nixConfEnv = getEnv("NIX_CONFIG");
|
auto nixConfEnv = getEnv("NIX_CONFIG");
|
||||||
|
@ -117,10 +117,11 @@ public:
|
|||||||
|
|
||||||
Setting<std::string> storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store",
|
Setting<std::string> storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), "store",
|
||||||
R"(
|
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.
|
to use for most operations.
|
||||||
See [`nix help-stores`](@docroot@/command-ref/new-cli/nix3-help-stores.md)
|
See the
|
||||||
for supported store types and settings.
|
[Store Types](@docroot@/store/types/index.md)
|
||||||
|
section of the manual for supported store types and settings.
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
Setting<bool> keepFailed{this, false, "keep-failed",
|
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).
|
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 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-linux`
|
||||||
- `x86_64-darwin`
|
- `x86_64-darwin`
|
||||||
@ -759,8 +760,8 @@ public:
|
|||||||
Strings{"https://cache.nixos.org/"},
|
Strings{"https://cache.nixos.org/"},
|
||||||
"substituters",
|
"substituters",
|
||||||
R"(
|
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 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.
|
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.
|
Substituters are tried based on their priority value, which each substituter can set independently.
|
||||||
Lower value means higher priority.
|
Lower value means higher priority.
|
||||||
@ -778,7 +779,7 @@ public:
|
|||||||
Setting<StringSet> trustedSubstituters{
|
Setting<StringSet> trustedSubstituters{
|
||||||
this, {}, "trusted-substituters",
|
this, {}, "trusted-substituters",
|
||||||
R"(
|
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).
|
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`.
|
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 {
|
namespace nix {
|
||||||
|
|
||||||
class Store;
|
struct StoreDirConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable serialisers for serialization container types in a
|
* Reusable serialisers for serialization container types in a
|
||||||
@ -44,8 +44,8 @@ struct LengthPrefixedProtoHelper;
|
|||||||
#define LENGTH_PREFIXED_PROTO_HELPER(Inner, T) \
|
#define LENGTH_PREFIXED_PROTO_HELPER(Inner, T) \
|
||||||
struct LengthPrefixedProtoHelper< Inner, T > \
|
struct LengthPrefixedProtoHelper< Inner, T > \
|
||||||
{ \
|
{ \
|
||||||
static T read(const Store & store, typename Inner::ReadConn conn); \
|
static T read(const StoreDirConfig & store, typename Inner::ReadConn conn); \
|
||||||
static void write(const Store & store, typename Inner::WriteConn conn, const T & str); \
|
static void write(const StoreDirConfig & store, typename Inner::WriteConn conn, const T & str); \
|
||||||
private: \
|
private: \
|
||||||
template<typename U> using S = typename Inner::template Serialise<U>; \
|
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>
|
template<class Inner, typename T>
|
||||||
std::vector<T>
|
std::vector<T>
|
||||||
LengthPrefixedProtoHelper<Inner, std::vector<T>>::read(
|
LengthPrefixedProtoHelper<Inner, std::vector<T>>::read(
|
||||||
const Store & store, typename Inner::ReadConn conn)
|
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||||
{
|
{
|
||||||
std::vector<T> resSet;
|
std::vector<T> resSet;
|
||||||
auto size = readNum<size_t>(conn.from);
|
auto size = readNum<size_t>(conn.from);
|
||||||
@ -80,7 +80,7 @@ LengthPrefixedProtoHelper<Inner, std::vector<T>>::read(
|
|||||||
template<class Inner, typename T>
|
template<class Inner, typename T>
|
||||||
void
|
void
|
||||||
LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
|
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();
|
conn.to << resSet.size();
|
||||||
for (auto & key : resSet) {
|
for (auto & key : resSet) {
|
||||||
@ -91,7 +91,7 @@ LengthPrefixedProtoHelper<Inner, std::vector<T>>::write(
|
|||||||
template<class Inner, typename T>
|
template<class Inner, typename T>
|
||||||
std::set<T>
|
std::set<T>
|
||||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
||||||
const Store & store, typename Inner::ReadConn conn)
|
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||||
{
|
{
|
||||||
std::set<T> resSet;
|
std::set<T> resSet;
|
||||||
auto size = readNum<size_t>(conn.from);
|
auto size = readNum<size_t>(conn.from);
|
||||||
@ -104,7 +104,7 @@ LengthPrefixedProtoHelper<Inner, std::set<T>>::read(
|
|||||||
template<class Inner, typename T>
|
template<class Inner, typename T>
|
||||||
void
|
void
|
||||||
LengthPrefixedProtoHelper<Inner, std::set<T>>::write(
|
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();
|
conn.to << resSet.size();
|
||||||
for (auto & key : resSet) {
|
for (auto & key : resSet) {
|
||||||
@ -115,7 +115,7 @@ LengthPrefixedProtoHelper<Inner, std::set<T>>::write(
|
|||||||
template<class Inner, typename K, typename V>
|
template<class Inner, typename K, typename V>
|
||||||
std::map<K, V>
|
std::map<K, V>
|
||||||
LengthPrefixedProtoHelper<Inner, std::map<K, V>>::read(
|
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;
|
std::map<K, V> resMap;
|
||||||
auto size = readNum<size_t>(conn.from);
|
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>
|
template<class Inner, typename K, typename V>
|
||||||
void
|
void
|
||||||
LengthPrefixedProtoHelper<Inner, std::map<K, V>>::write(
|
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();
|
conn.to << resMap.size();
|
||||||
for (auto & i : resMap) {
|
for (auto & i : resMap) {
|
||||||
@ -142,7 +142,7 @@ LengthPrefixedProtoHelper<Inner, std::map<K, V>>::write(
|
|||||||
template<class Inner, typename... Ts>
|
template<class Inner, typename... Ts>
|
||||||
std::tuple<Ts...>
|
std::tuple<Ts...>
|
||||||
LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
|
LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
|
||||||
const Store & store, typename Inner::ReadConn conn)
|
const StoreDirConfig & store, typename Inner::ReadConn conn)
|
||||||
{
|
{
|
||||||
return std::tuple<Ts...> {
|
return std::tuple<Ts...> {
|
||||||
S<Ts>::read(store, conn)...,
|
S<Ts>::read(store, conn)...,
|
||||||
@ -152,7 +152,7 @@ LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::read(
|
|||||||
template<class Inner, typename... Ts>
|
template<class Inner, typename... Ts>
|
||||||
void
|
void
|
||||||
LengthPrefixedProtoHelper<Inner, std::tuple<Ts...>>::write(
|
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) {
|
std::apply([&]<typename... Us>(const Us &... args) {
|
||||||
(S<Us>::write(store, conn, args), ...);
|
(S<Us>::write(store, conn, args), ...);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "pathlocks.hh"
|
#include "pathlocks.hh"
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "nar-info.hh"
|
#include "nar-info.hh"
|
||||||
#include "references.hh"
|
#include "references.hh"
|
||||||
#include "callback.hh"
|
#include "callback.hh"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "local-store.hh"
|
#include "local-store.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "topo-sort.hh"
|
#include "topo-sort.hh"
|
||||||
#include "callback.hh"
|
#include "callback.hh"
|
||||||
#include "closure.hh"
|
#include "closure.hh"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
std::string StorePathWithOutputs::to_string(const Store & store) const
|
std::string StorePathWithOutputs::to_string(const StoreDirConfig & store) const
|
||||||
{
|
{
|
||||||
return outputs.empty()
|
return outputs.empty()
|
||||||
? store.printStorePath(path)
|
? 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);
|
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
|
||||||
return StorePathWithOutputs { store.parseStorePath(path), std::move(outputs) };
|
return StorePathWithOutputs { store.parseStorePath(path), std::move(outputs) };
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
struct StoreDirConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a deprecated old type just for use by the old CLI, and older
|
* 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
|
* versions of the RPC protocols. In new code don't use it; you want
|
||||||
@ -19,7 +21,7 @@ struct StorePathWithOutputs
|
|||||||
StorePath path;
|
StorePath path;
|
||||||
std::set<std::string> outputs;
|
std::set<std::string> outputs;
|
||||||
|
|
||||||
std::string to_string(const Store & store) const;
|
std::string to_string(const StoreDirConfig & store) const;
|
||||||
|
|
||||||
DerivedPath toDerivedPath() 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);
|
std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s);
|
||||||
|
|
||||||
class Store;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split a string specifying a derivation and a set of outputs
|
* Split a string specifying a derivation and a set of outputs
|
||||||
* (/nix/store/hash-foo!out1,out2,...) into the derivation path
|
* (/nix/store/hash-foo!out1,out2,...) into the derivation path
|
||||||
* and the outputs.
|
* 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);
|
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>
|
#include <sodium.h>
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ StorePath StorePath::random(std::string_view name)
|
|||||||
return StorePath(hash, 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));
|
auto p = canonPath(std::string(path));
|
||||||
if (dirOf(p) != storeDir)
|
if (dirOf(p) != storeDir)
|
||||||
@ -62,7 +62,7 @@ StorePath Store::parseStorePath(std::string_view path) const
|
|||||||
return StorePath(baseNameOf(p));
|
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 {
|
try {
|
||||||
return parseStorePath(path);
|
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);
|
return (bool) maybeParseStorePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
StorePathSet Store::parseStorePathSet(const PathSet & paths) const
|
StorePathSet StoreDirConfig::parseStorePathSet(const PathSet & paths) const
|
||||||
{
|
{
|
||||||
StorePathSet res;
|
StorePathSet res;
|
||||||
for (auto & i : paths) res.insert(parseStorePath(i));
|
for (auto & i : paths) res.insert(parseStorePath(i));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Store::printStorePath(const StorePath & path) const
|
std::string StoreDirConfig::printStorePath(const StorePath & path) const
|
||||||
{
|
{
|
||||||
return (storeDir + "/").append(path.to_string());
|
return (storeDir + "/").append(path.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
PathSet Store::printStorePathSet(const StorePathSet & paths) const
|
PathSet StoreDirConfig::printStorePathSet(const StorePathSet & paths) const
|
||||||
{
|
{
|
||||||
PathSet res;
|
PathSet res;
|
||||||
for (auto & i : paths) res.insert(printStorePath(i));
|
for (auto & i : paths) res.insert(printStorePath(i));
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
namespace nix {
|
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)
|
RemoteStore::RemoteStore(const Params & params)
|
||||||
: RemoteStoreConfig(params)
|
: RemoteStoreConfig(params)
|
||||||
, Store(params)
|
, Store(params)
|
||||||
|
@ -16,11 +16,11 @@ namespace nix {
|
|||||||
/* protocol-agnostic templates */
|
/* protocol-agnostic templates */
|
||||||
|
|
||||||
#define SERVE_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
#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); \
|
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); \
|
LengthPrefixedProtoHelper<ServeProto, T >::write(store, conn, t); \
|
||||||
}
|
}
|
||||||
@ -41,12 +41,12 @@ SERVE_USE_LENGTH_PREFIX_SERIALISER(
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct ServeProto::Serialise
|
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,
|
return CommonProto::Serialise<T>::read(store,
|
||||||
CommonProto::ReadConn { .from = conn.from });
|
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::Serialise<T>::write(store,
|
||||||
CommonProto::WriteConn { .to = conn.to },
|
CommonProto::WriteConn { .to = conn.to },
|
||||||
|
@ -12,7 +12,7 @@ namespace nix {
|
|||||||
|
|
||||||
/* protocol-specific definitions */
|
/* 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;
|
BuildResult status;
|
||||||
status.status = (BuildResult::Status) readInt(conn.from);
|
status.status = (BuildResult::Status) readInt(conn.from);
|
||||||
@ -34,7 +34,7 @@ BuildResult ServeProto::Serialise<BuildResult>::read(const Store & store, ServeP
|
|||||||
return status;
|
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
|
conn.to
|
||||||
<< status.status
|
<< status.status
|
||||||
|
@ -13,7 +13,7 @@ namespace nix {
|
|||||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||||
|
|
||||||
|
|
||||||
class Store;
|
struct StoreDirConfig;
|
||||||
struct Source;
|
struct Source;
|
||||||
|
|
||||||
// items being serialised
|
// items being serialised
|
||||||
@ -72,8 +72,8 @@ struct ServeProto
|
|||||||
// See `worker-protocol.hh` for a longer explanation.
|
// See `worker-protocol.hh` for a longer explanation.
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
static T read(const Store & store, ReadConn conn);
|
static T read(const StoreDirConfig & store, ReadConn conn);
|
||||||
static void write(const Store & store, WriteConn conn, const T & t);
|
static void write(const StoreDirConfig & store, WriteConn conn, const T & t);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ struct ServeProto
|
|||||||
* infer the type instead of having to write it down explicitly.
|
* infer the type instead of having to write it down explicitly.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
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);
|
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) \
|
#define DECLARE_SERVE_SERIALISER(T) \
|
||||||
struct ServeProto::Serialise< T > \
|
struct ServeProto::Serialise< T > \
|
||||||
{ \
|
{ \
|
||||||
static T read(const Store & store, ServeProto::ReadConn conn); \
|
static T read(const StoreDirConfig & store, ServeProto::ReadConn conn); \
|
||||||
static void write(const Store & store, ServeProto::WriteConn conn, const T & t); \
|
static void write(const StoreDirConfig & store, ServeProto::WriteConn conn, const T & t); \
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -20,7 +20,7 @@ struct CommonSSHStoreConfig : virtual StoreConfig
|
|||||||
|
|
||||||
const Setting<std::string> remoteStore{this, "", "remote-store",
|
const Setting<std::string> remoteStore{this, "", "remote-store",
|
||||||
R"(
|
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`
|
to be used on the remote machine. The default is `auto`
|
||||||
(i.e. use the Nix daemon or `/nix/store` directly).
|
(i.e. use the Nix daemon or `/nix/store` directly).
|
||||||
)"};
|
)"};
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "crypto.hh"
|
#include "crypto.hh"
|
||||||
#include "source-accessor.hh"
|
#include "source-accessor.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
#include "derived-path.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
@ -25,13 +27,13 @@ using json = nlohmann::json;
|
|||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
bool Store::isInStore(PathView path) const
|
bool StoreDirConfig::isInStore(PathView path) const
|
||||||
{
|
{
|
||||||
return isInDir(path, storeDir);
|
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))
|
if (!isInStore(path))
|
||||||
throw Error("path '%1%' is not in the Nix store", 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
|
std::string_view hash, std::string_view name) const
|
||||||
{
|
{
|
||||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
/* 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
|
const Hash & hash, std::string_view name) const
|
||||||
{
|
{
|
||||||
return makeStorePath(type, hash.to_string(HashFormat::Base16, true), name);
|
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
|
const Hash & hash, std::string_view name) const
|
||||||
{
|
{
|
||||||
return makeStorePath("output:" + std::string { id }, hash, outputPathName(name, id));
|
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)
|
hacky, but we can't put them in, say, <s2> (per the grammar above)
|
||||||
since that would be ambiguous. */
|
since that would be ambiguous. */
|
||||||
static std::string makeType(
|
static std::string makeType(
|
||||||
const Store & store,
|
const StoreDirConfig & store,
|
||||||
std::string && type,
|
std::string && type,
|
||||||
const StoreReferences & references)
|
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) {
|
if (info.hash.type == htSHA256 && info.method == FileIngestionMethod::Recursive) {
|
||||||
return makeStorePath(makeType(*this, "source", info.references), info.hash, name);
|
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);
|
assert(info.hash.type == htSHA256);
|
||||||
return makeStorePath(
|
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
|
// New template
|
||||||
return std::visit(overloaded {
|
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,
|
Source & dump,
|
||||||
std::string_view name,
|
std::string_view name,
|
||||||
FileIngestionMethod method,
|
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 name,
|
||||||
std::string_view s,
|
std::string_view s,
|
||||||
const StorePathSet & references) const
|
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;
|
std::string s;
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "nar-info.hh"
|
|
||||||
#include "realisation.hh"
|
|
||||||
#include "path.hh"
|
#include "path.hh"
|
||||||
#include "derived-path.hh"
|
#include "derived-path.hh"
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
@ -14,6 +12,7 @@
|
|||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "path-info.hh"
|
#include "path-info.hh"
|
||||||
#include "repair-flag.hh"
|
#include "repair-flag.hh"
|
||||||
|
#include "store-dir-config.hh"
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@ -30,7 +29,7 @@
|
|||||||
namespace nix {
|
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:
|
* Each store type `Foo` consists of two classes:
|
||||||
*
|
*
|
||||||
@ -64,12 +63,16 @@ MakeError(InvalidPath, Error);
|
|||||||
MakeError(Unsupported, Error);
|
MakeError(Unsupported, Error);
|
||||||
MakeError(SubstituteGone, Error);
|
MakeError(SubstituteGone, Error);
|
||||||
MakeError(SubstituterDisabled, Error);
|
MakeError(SubstituterDisabled, Error);
|
||||||
MakeError(BadStorePath, Error);
|
|
||||||
|
|
||||||
MakeError(InvalidStoreURI, Error);
|
MakeError(InvalidStoreURI, Error);
|
||||||
|
|
||||||
|
struct Realisation;
|
||||||
|
struct RealisedPath;
|
||||||
|
struct DrvOutput;
|
||||||
|
|
||||||
struct BasicDerivation;
|
struct BasicDerivation;
|
||||||
struct Derivation;
|
struct Derivation;
|
||||||
|
|
||||||
struct SourceAccessor;
|
struct SourceAccessor;
|
||||||
class NarInfoDiskCache;
|
class NarInfoDiskCache;
|
||||||
class Store;
|
class Store;
|
||||||
@ -96,11 +99,11 @@ struct KeyedBuildResult;
|
|||||||
|
|
||||||
typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
|
typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
|
||||||
|
|
||||||
struct StoreConfig : public Config
|
struct StoreConfig : public StoreDirConfig
|
||||||
{
|
{
|
||||||
typedef std::map<std::string, std::string> Params;
|
typedef std::map<std::string, std::string> Params;
|
||||||
|
|
||||||
using Config::Config;
|
using StoreDirConfig::StoreDirConfig;
|
||||||
|
|
||||||
StoreConfig() = delete;
|
StoreConfig() = delete;
|
||||||
|
|
||||||
@ -130,15 +133,6 @@ struct StoreConfig : public Config
|
|||||||
return std::nullopt;
|
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",
|
const Setting<int> pathInfoCacheSize{this, 65536, "path-info-cache-size",
|
||||||
"Size of the in-memory store path metadata cache."};
|
"Size of the in-memory store path metadata cache."};
|
||||||
|
|
||||||
@ -226,45 +220,6 @@ public:
|
|||||||
|
|
||||||
virtual std::string getUri() = 0;
|
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.
|
* 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;
|
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.
|
* Check whether a path is valid.
|
||||||
*/
|
*/
|
||||||
@ -888,7 +794,7 @@ void copyStorePath(
|
|||||||
*/
|
*/
|
||||||
std::map<StorePath, StorePath> copyPaths(
|
std::map<StorePath, StorePath> copyPaths(
|
||||||
Store & srcStore, Store & dstStore,
|
Store & srcStore, Store & dstStore,
|
||||||
const RealisedPath::Set &,
|
const std::set<RealisedPath> &,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
CheckSigsFlag checkSigs = CheckSigs,
|
CheckSigsFlag checkSigs = CheckSigs,
|
||||||
SubstituteFlag substitute = NoSubstitute);
|
SubstituteFlag substitute = NoSubstitute);
|
||||||
@ -905,7 +811,7 @@ std::map<StorePath, StorePath> copyPaths(
|
|||||||
*/
|
*/
|
||||||
void copyClosure(
|
void copyClosure(
|
||||||
Store & srcStore, Store & dstStore,
|
Store & srcStore, Store & dstStore,
|
||||||
const RealisedPath::Set & paths,
|
const std::set<RealisedPath> & paths,
|
||||||
RepairFlag repair = NoRepair,
|
RepairFlag repair = NoRepair,
|
||||||
CheckSigsFlag checkSigs = CheckSigs,
|
CheckSigsFlag checkSigs = CheckSigs,
|
||||||
SubstituteFlag substitute = NoSubstitute);
|
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
|
* - ‘ssh://[user@]<host>’: A remote Nix store accessed by running
|
||||||
* ‘nix-store --serve’ via SSH.
|
* ‘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.
|
* ‘?key=value&key=value&...’ to the URI.
|
||||||
*/
|
*/
|
||||||
ref<Store> openStore(const std::string & uri = settings.storeUri.get(),
|
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 */
|
/* protocol-agnostic templates */
|
||||||
|
|
||||||
#define WORKER_USE_LENGTH_PREFIX_SERIALISER(TEMPLATE, T) \
|
#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); \
|
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); \
|
LengthPrefixedProtoHelper<WorkerProto, T >::write(store, conn, t); \
|
||||||
}
|
}
|
||||||
@ -41,12 +41,12 @@ WORKER_USE_LENGTH_PREFIX_SERIALISER(
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct WorkerProto::Serialise
|
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,
|
return CommonProto::Serialise<T>::read(store,
|
||||||
CommonProto::ReadConn { .from = conn.from });
|
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::Serialise<T>::write(store,
|
||||||
CommonProto::WriteConn { .to = conn.to },
|
CommonProto::WriteConn { .to = conn.to },
|
||||||
|
@ -13,7 +13,7 @@ namespace nix {
|
|||||||
|
|
||||||
/* protocol-specific definitions */
|
/* 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);
|
auto temp = readNum<uint8_t>(conn.from);
|
||||||
switch (temp) {
|
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)
|
if (!optTrusted)
|
||||||
conn.to << uint8_t{0};
|
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);
|
auto s = readString(conn.from);
|
||||||
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
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) {
|
if (GET_PROTOCOL_MINOR(conn.version) >= 30) {
|
||||||
conn.to << req.to_string_legacy(store);
|
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 path = WorkerProto::Serialise<DerivedPath>::read(store, conn);
|
||||||
auto br = WorkerProto::Serialise<BuildResult>::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, res.path);
|
||||||
WorkerProto::write(store, conn, static_cast<const BuildResult &>(res));
|
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;
|
BuildResult res;
|
||||||
res.status = static_cast<BuildResult::Status>(readInt(conn.from));
|
res.status = static_cast<BuildResult::Status>(readInt(conn.from));
|
||||||
@ -120,7 +120,7 @@ BuildResult WorkerProto::Serialise<BuildResult>::read(const Store & store, Worke
|
|||||||
return res;
|
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
|
conn.to
|
||||||
<< res.status
|
<< 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);
|
auto path = WorkerProto::Serialise<StorePath>::read(store, conn);
|
||||||
return ValidPathInfo {
|
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, pathInfo.path);
|
||||||
WorkerProto::write(store, conn, static_cast<const UnkeyedValidPathInfo &>(pathInfo));
|
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 deriver = readString(conn.from);
|
||||||
auto narHash = Hash::parseAny(readString(conn.from), htSHA256);
|
auto narHash = Hash::parseAny(readString(conn.from), htSHA256);
|
||||||
@ -173,7 +173,7 @@ UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const St
|
|||||||
return info;
|
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
|
conn.to
|
||||||
<< (pathInfo.deriver ? store.printStorePath(*pathInfo.deriver) : "")
|
<< (pathInfo.deriver ? store.printStorePath(*pathInfo.deriver) : "")
|
||||||
|
@ -24,7 +24,7 @@ namespace nix {
|
|||||||
#define STDERR_RESULT 0x52534c54
|
#define STDERR_RESULT 0x52534c54
|
||||||
|
|
||||||
|
|
||||||
class Store;
|
struct StoreDirConfig;
|
||||||
struct Source;
|
struct Source;
|
||||||
|
|
||||||
// items being serialised
|
// items being serialised
|
||||||
@ -100,8 +100,8 @@ struct WorkerProto
|
|||||||
// This makes for a quicker debug cycle, as desired.
|
// This makes for a quicker debug cycle, as desired.
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
static T read(const Store & store, ReadConn conn);
|
static T read(const StoreDirConfig & store, ReadConn conn);
|
||||||
static void write(const Store & store, WriteConn conn, const T & t);
|
static void write(const StoreDirConfig & store, WriteConn conn, const T & t);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ struct WorkerProto
|
|||||||
* infer the type instead of having to write it down explicitly.
|
* infer the type instead of having to write it down explicitly.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
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);
|
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) \
|
#define DECLARE_WORKER_SERIALISER(T) \
|
||||||
struct WorkerProto::Serialise< T > \
|
struct WorkerProto::Serialise< T > \
|
||||||
{ \
|
{ \
|
||||||
static T read(const Store & store, WorkerProto::ReadConn conn); \
|
static T read(const StoreDirConfig & store, WorkerProto::ReadConn conn); \
|
||||||
static void write(const Store & store, WorkerProto::WriteConn conn, const T & t); \
|
static void write(const StoreDirConfig & store, WorkerProto::WriteConn conn, const T & t); \
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
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});
|
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()) {
|
while (pos < contents.size()) {
|
||||||
std::string line;
|
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);
|
throw UsageError("illegal configuration line '%1%' in '%2%'", line, path);
|
||||||
auto p = absPath(tokens[1], dirOf(path));
|
auto p = absPath(tokens[1], dirOf(path));
|
||||||
if (pathExists(p)) {
|
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) {
|
} else if (!ignoreMissing) {
|
||||||
throw Error("file '%1%' included from '%2%' not found", p, path);
|
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())),
|
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
|
// First apply experimental-feature related settings
|
||||||
for (const auto & [name, value] : parsedContents)
|
for (const auto & [name, value] : parsedContents)
|
||||||
@ -154,14 +164,6 @@ void AbstractConfig::applyConfig(const std::string & contents, const std::string
|
|||||||
set(name, value);
|
set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractConfig::applyConfigFile(const Path & path)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
std::string contents = readFile(path);
|
|
||||||
applyConfig(contents, path);
|
|
||||||
} catch (SysError &) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
void Config::resetOverridden()
|
void Config::resetOverridden()
|
||||||
{
|
{
|
||||||
for (auto & s : _settings)
|
for (auto & s : _settings)
|
||||||
|
@ -82,12 +82,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void applyConfig(const std::string & contents, const std::string & path = "<unknown>");
|
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
|
* 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:
|
* 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
|
* 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.
|
* Print a position, if it is known.
|
||||||
|
@ -252,7 +252,7 @@ constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails
|
|||||||
.tag = Xp::ReadOnlyLocalStore,
|
.tag = Xp::ReadOnlyLocalStore,
|
||||||
.name = "read-only-local-store",
|
.name = "read-only-local-store",
|
||||||
.description = R"(
|
.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 "store-api.hh"
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "path-with-outputs.hh"
|
#include "path-with-outputs.hh"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
#include "realisation.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "legacy.hh"
|
#include "legacy.hh"
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ void checkInfo(const std::string & msg) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CmdDoctor : StoreCommand
|
struct CmdConfigCheck : StoreCommand
|
||||||
{
|
{
|
||||||
bool success = true;
|
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-base32", {"hash", "to-base32"}},
|
||||||
{"to-base64", {"hash", "to-base64"}},
|
{"to-base64", {"hash", "to-base64"}},
|
||||||
{"verify", {"store", "verify"}},
|
{"verify", {"store", "verify"}},
|
||||||
|
{"doctor", {"config", "check"}},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool aliasUsed = false;
|
bool aliasUsed = false;
|
||||||
|
@ -235,8 +235,12 @@ operate are determined as follows:
|
|||||||
|
|
||||||
# Nix stores
|
# Nix stores
|
||||||
|
|
||||||
Most `nix` subcommands operate on a *Nix store*. These are documented
|
Most `nix` subcommands operate on a *Nix store*.
|
||||||
in [`nix help-stores`](./nix3-help-stores.md).
|
The various store types are documented in the
|
||||||
|
[Store Types](@docroot@/store/types/index.md)
|
||||||
|
section of the manual.
|
||||||
|
|
||||||
|
The same information is also available from the [`nix help-stores`](./nix3-help-stores.md) command.
|
||||||
|
|
||||||
# Shebang interpreter
|
# Shebang interpreter
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "common-args.hh"
|
#include "common-args.hh"
|
||||||
|
#include "nar-info.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -25,6 +25,7 @@ std::string chrootHelperName = "__run_in_chroot";
|
|||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
void runProgramInStore(ref<Store> store,
|
void runProgramInStore(ref<Store> store,
|
||||||
|
UseSearchPath useSearchPath,
|
||||||
const std::string & program,
|
const std::string & program,
|
||||||
const Strings & args,
|
const Strings & args,
|
||||||
std::optional<std::string_view> system)
|
std::optional<std::string_view> system)
|
||||||
@ -58,7 +59,10 @@ void runProgramInStore(ref<Store> store,
|
|||||||
if (system)
|
if (system)
|
||||||
setPersonality(*system);
|
setPersonality(*system);
|
||||||
|
|
||||||
|
if (useSearchPath == UseSearchPath::Use)
|
||||||
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
execvp(program.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
else
|
||||||
|
execv(program.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
|
||||||
throw SysError("unable to execute '%s'", program);
|
throw SysError("unable to execute '%s'", program);
|
||||||
}
|
}
|
||||||
@ -132,7 +136,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment
|
|||||||
Strings args;
|
Strings args;
|
||||||
for (auto & arg : command) args.push_back(arg);
|
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};
|
Strings allArgs{app.program};
|
||||||
for (auto & i : args) allArgs.push_back(i);
|
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 {
|
namespace nix {
|
||||||
|
|
||||||
|
enum struct UseSearchPath {
|
||||||
|
Use,
|
||||||
|
DontUse
|
||||||
|
};
|
||||||
|
|
||||||
void runProgramInStore(ref<Store> store,
|
void runProgramInStore(ref<Store> store,
|
||||||
|
UseSearchPath useSearchPath,
|
||||||
const std::string & program,
|
const std::string & program,
|
||||||
const Strings & args,
|
const Strings & args,
|
||||||
std::optional<std::string_view> system = std::nullopt);
|
std::optional<std::string_view> system = std::nullopt);
|
||||||
|
@ -20,7 +20,7 @@ cat > "$NIX_CONF_DIR"/nix.conf <<EOF
|
|||||||
build-users-group =
|
build-users-group =
|
||||||
keep-derivations = false
|
keep-derivations = false
|
||||||
sandbox = false
|
sandbox = false
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command
|
||||||
gc-reserved-space = 0
|
gc-reserved-space = 0
|
||||||
substituters =
|
substituters =
|
||||||
flake-registry = $TEST_ROOT/registry.json
|
flake-registry = $TEST_ROOT/registry.json
|
||||||
@ -31,6 +31,7 @@ EOF
|
|||||||
|
|
||||||
cat > "$NIX_CONF_DIR"/nix.conf.extra <<EOF
|
cat > "$NIX_CONF_DIR"/nix.conf.extra <<EOF
|
||||||
fsync-metadata = false
|
fsync-metadata = false
|
||||||
|
extra-experimental-features = flakes
|
||||||
!include nix.conf.extra.not-there
|
!include nix.conf.extra.not-there
|
||||||
EOF
|
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 <rapidcheck/gen/Arbitrary.h>
|
||||||
|
|
||||||
#include <value/context.hh>
|
#include "value/context.hh"
|
||||||
|
|
||||||
namespace rc {
|
namespace rc {
|
||||||
using namespace nix;
|
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"));
|
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) {
|
TEST_F(PrimOpTest, attrNames) {
|
||||||
auto v = eval("builtins.attrNames { x = 1; y = 2; z = 3; a = 2; }");
|
auto v = eval("builtins.attrNames { x = 1; y = 2; z = 3; a = 2; }");
|
||||||
ASSERT_THAT(v, IsListOfSize(4));
|
ASSERT_THAT(v, IsListOfSize(4));
|
@ -117,36 +117,6 @@ TEST(NixStringContextElemTest, built_built_xp) {
|
|||||||
NixStringContextElem::parse("!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv"), MissingExperimentalFeature);
|
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
|
#ifndef COVERAGE
|
||||||
|
|
||||||
RC_GTEST_PROP(
|
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 <outputs-spec.hh>
|
||||||
|
|
||||||
#include <tests/path.hh>
|
#include "tests/path.hh"
|
||||||
|
|
||||||
namespace rc {
|
namespace rc {
|
||||||
using namespace nix;
|
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;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For rapidcheck
|
||||||
|
void showValue(const StorePath & p, std::ostream & os);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace rc {
|
namespace rc {
|
@ -12,7 +12,7 @@ namespace nix {
|
|||||||
template<class Proto, const char * protocolDir>
|
template<class Proto, const char * protocolDir>
|
||||||
class ProtoTest : public CharacterizationTest, public LibStoreTest
|
class ProtoTest : public CharacterizationTest, public LibStoreTest
|
||||||
{
|
{
|
||||||
Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir;
|
Path unitTestData = getUnitTestData() + "/" + protocolDir;
|
||||||
|
|
||||||
Path goldenMaster(std::string_view testStem) const override {
|
Path goldenMaster(std::string_view testStem) const override {
|
||||||
return unitTestData + "/" + testStem + ".bin";
|
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