mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-12 04:35:41 +03:00
lib.fileset: Internal representation v1
This commit is contained in:
parent
48abfde844
commit
19b39dcc93
3 changed files with 64 additions and 24 deletions
|
@ -41,13 +41,21 @@ An attribute set with these values:
|
||||||
- `_type` (constant string `"fileset"`):
|
- `_type` (constant string `"fileset"`):
|
||||||
Tag to indicate this value is a file set.
|
Tag to indicate this value is a file set.
|
||||||
|
|
||||||
- `_internalVersion` (constant string equal to the current version):
|
- `_internalVersion` (constant `1`, the current version):
|
||||||
Version of the representation
|
Version of the representation.
|
||||||
|
|
||||||
- `_internalBase` (path):
|
- `_internalBase` (path):
|
||||||
Any files outside of this path cannot influence the set of files.
|
Any files outside of this path cannot influence the set of files.
|
||||||
This is always a directory.
|
This is always a directory.
|
||||||
|
|
||||||
|
- `_internalBaseRoot` (path):
|
||||||
|
The filesystem root of `_internalBase`, same as `(lib.path.splitRoot _internalBase).root`.
|
||||||
|
This is here because this needs to be computed anyways, and this computation shouldn't be duplicated.
|
||||||
|
|
||||||
|
- `_internalBaseComponents` (list of strings):
|
||||||
|
The path components of `_internalBase`, same as `lib.path.subpath.components (lib.path.splitRoot _internalBase).subpath`.
|
||||||
|
This is here because this needs to be computed anyways, and this computation shouldn't be duplicated.
|
||||||
|
|
||||||
- `_internalTree` ([filesetTree](#filesettree)):
|
- `_internalTree` ([filesetTree](#filesettree)):
|
||||||
A tree representation of all included files under `_internalBase`.
|
A tree representation of all included files under `_internalBase`.
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ let
|
||||||
inherit (lib.lists)
|
inherit (lib.lists)
|
||||||
all
|
all
|
||||||
elemAt
|
elemAt
|
||||||
|
foldl'
|
||||||
length
|
length
|
||||||
|
sublist
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (lib.path)
|
inherit (lib.path)
|
||||||
|
@ -50,24 +52,48 @@ in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
# If you change the internal representation, make sure to:
|
# If you change the internal representation, make sure to:
|
||||||
# - Update this version
|
# - Increment this version
|
||||||
# - Adjust _coerce to also accept and coerce older versions
|
# - Add an additional migration function below
|
||||||
# - Update the description of the internal representation in ./README.md
|
# - Update the description of the internal representation in ./README.md
|
||||||
_currentVersion = 0;
|
_currentVersion = 1;
|
||||||
|
|
||||||
|
# Migrations between versions. The 0th element converts from v0 to v1, and so on
|
||||||
|
migrations = [
|
||||||
|
# Convert v0 into v1: Add the _internalBase{Root,Components} attributes
|
||||||
|
(
|
||||||
|
filesetV0:
|
||||||
|
let
|
||||||
|
parts = splitRoot filesetV0._internalBase;
|
||||||
|
in
|
||||||
|
filesetV0 // {
|
||||||
|
_internalVersion = 1;
|
||||||
|
_internalBaseRoot = parts.root;
|
||||||
|
_internalBaseComponents = components parts.subpath;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
# Create a fileset, see ./README.md#fileset
|
# Create a fileset, see ./README.md#fileset
|
||||||
# Type: path -> filesetTree -> fileset
|
# Type: path -> filesetTree -> fileset
|
||||||
_create = base: tree: {
|
_create = base: tree:
|
||||||
_type = "fileset";
|
let
|
||||||
|
# Decompose the base into its components
|
||||||
|
# See ../path/README.md for why we're not just using `toString`
|
||||||
|
parts = splitRoot base;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
_type = "fileset";
|
||||||
|
|
||||||
_internalVersion = _currentVersion;
|
_internalVersion = _currentVersion;
|
||||||
_internalBase = base;
|
_internalBase = base;
|
||||||
_internalTree = tree;
|
_internalBaseRoot = parts.root;
|
||||||
|
_internalBaseComponents = components parts.subpath;
|
||||||
|
_internalTree = tree;
|
||||||
|
|
||||||
# Double __ to make it be evaluated and ordered first
|
# Double __ to make it be evaluated and ordered first
|
||||||
__noEval = throw ''
|
__noEval = throw ''
|
||||||
lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.'';
|
lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Coerce a value to a fileset, erroring when the value cannot be coerced.
|
# Coerce a value to a fileset, erroring when the value cannot be coerced.
|
||||||
# The string gives the context for error messages.
|
# The string gives the context for error messages.
|
||||||
|
@ -80,6 +106,12 @@ rec {
|
||||||
- Internal version of the file set: ${toString value._internalVersion}
|
- Internal version of the file set: ${toString value._internalVersion}
|
||||||
- Internal version of the library: ${toString _currentVersion}
|
- Internal version of the library: ${toString _currentVersion}
|
||||||
Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.''
|
Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.''
|
||||||
|
else if value._internalVersion < _currentVersion then
|
||||||
|
let
|
||||||
|
# Get all the migration functions necessary to convert from the old to the current version
|
||||||
|
migrationsToApply = sublist value._internalVersion (_currentVersion - value._internalVersion) migrations;
|
||||||
|
in
|
||||||
|
foldl' (value: migration: migration value) value migrationsToApply
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
else if ! isPath value then
|
else if ! isPath value then
|
||||||
|
@ -193,17 +225,13 @@ rec {
|
||||||
# which has the effect that they aren't included in the result
|
# which has the effect that they aren't included in the result
|
||||||
tree = _simplifyTree fileset._internalBase fileset._internalTree;
|
tree = _simplifyTree fileset._internalBase fileset._internalTree;
|
||||||
|
|
||||||
# Decompose the base into its components
|
|
||||||
# See ../path/README.md for why we're not just using `toString`
|
|
||||||
baseComponents = components (splitRoot fileset._internalBase).subpath;
|
|
||||||
|
|
||||||
# The base path as a string with a single trailing slash
|
# The base path as a string with a single trailing slash
|
||||||
baseString =
|
baseString =
|
||||||
if baseComponents == [] then
|
if fileset._internalBaseComponents == [] then
|
||||||
# Need to handle the filesystem root specially
|
# Need to handle the filesystem root specially
|
||||||
"/"
|
"/"
|
||||||
else
|
else
|
||||||
"/" + concatStringsSep "/" baseComponents + "/";
|
"/" + concatStringsSep "/" fileset._internalBaseComponents + "/";
|
||||||
|
|
||||||
baseLength = stringLength baseString;
|
baseLength = stringLength baseString;
|
||||||
|
|
||||||
|
|
|
@ -264,17 +264,21 @@ expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `
|
||||||
# File sets cannot be evaluated directly
|
# File sets cannot be evaluated directly
|
||||||
expectFailure '_create ./. null' 'lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.'
|
expectFailure '_create ./. null' 'lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.'
|
||||||
|
|
||||||
|
# Past versions of the internal representation are supported
|
||||||
|
expectEqual '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 0; _internalBase = ./.; }' \
|
||||||
|
'{ _internalBase = ./.; _internalBaseComponents = path.subpath.components (path.splitRoot ./.).subpath; _internalBaseRoot = /.; _internalVersion = 1; _type = "fileset"; }'
|
||||||
|
|
||||||
# Future versions of the internal representation are unsupported
|
# Future versions of the internal representation are unsupported
|
||||||
expectFailure '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 1; }' '<tests>: value is a file set created from a future version of the file set library with a different internal representation:
|
expectFailure '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 2; }' '<tests>: value is a file set created from a future version of the file set library with a different internal representation:
|
||||||
\s*- Internal version of the file set: 1
|
\s*- Internal version of the file set: 2
|
||||||
\s*- Internal version of the library: 0
|
\s*- Internal version of the library: 1
|
||||||
\s*Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.'
|
\s*Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.'
|
||||||
|
|
||||||
# _create followed by _coerce should give the inputs back without any validation
|
# _create followed by _coerce should give the inputs back without any validation
|
||||||
expectEqual '{
|
expectEqual '{
|
||||||
inherit (_coerce "<test>" (_create ./. "directory"))
|
inherit (_coerce "<test>" (_create ./. "directory"))
|
||||||
_internalVersion _internalBase _internalTree;
|
_internalVersion _internalBase _internalTree;
|
||||||
}' '{ _internalBase = ./.; _internalTree = "directory"; _internalVersion = 0; }'
|
}' '{ _internalBase = ./.; _internalTree = "directory"; _internalVersion = 1; }'
|
||||||
|
|
||||||
#### Resulting store path ####
|
#### Resulting store path ####
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue