diff options
author | Silvan Mosberger <silvan.mosberger@tweag.io> | 2023-09-13 18:50:45 +0200 |
---|---|---|
committer | Silvan Mosberger <silvan.mosberger@tweag.io> | 2023-09-13 18:53:53 +0200 |
commit | 19b39dcc934aba37e39b5f492c2919dd93b74870 (patch) | |
tree | 35184a186a01641a4ee0ec6e9acda5d043e1b721 /lib/fileset | |
parent | 48abfde844547c1b62c8a082ccccd9caf2d650bd (diff) |
lib.fileset: Internal representation v1
Diffstat (limited to 'lib/fileset')
-rw-r--r-- | lib/fileset/README.md | 12 | ||||
-rw-r--r-- | lib/fileset/internal.nix | 64 | ||||
-rwxr-xr-x | lib/fileset/tests.sh | 12 |
3 files changed, 64 insertions, 24 deletions
diff --git a/lib/fileset/README.md b/lib/fileset/README.md index dbb591a4c8c83..306dcdaa421d8 100644 --- a/lib/fileset/README.md +++ b/lib/fileset/README.md @@ -41,13 +41,21 @@ An attribute set with these values: - `_type` (constant string `"fileset"`): Tag to indicate this value is a file set. -- `_internalVersion` (constant string equal to the current version): - Version of the representation +- `_internalVersion` (constant `1`, the current version): + Version of the representation. - `_internalBase` (path): Any files outside of this path cannot influence the set of files. 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)): A tree representation of all included files under `_internalBase`. diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix index eeaa7d96875e0..ae8eb20e3ed29 100644 --- a/lib/fileset/internal.nix +++ b/lib/fileset/internal.nix @@ -23,7 +23,9 @@ let inherit (lib.lists) all elemAt + foldl' length + sublist ; inherit (lib.path) @@ -50,24 +52,48 @@ in rec { # If you change the internal representation, make sure to: - # - Update this version - # - Adjust _coerce to also accept and coerce older versions + # - Increment this version + # - Add an additional migration function below # - 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 # Type: path -> filesetTree -> fileset - _create = base: tree: { - _type = "fileset"; + _create = base: tree: + 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; - _internalBase = base; - _internalTree = tree; + _internalVersion = _currentVersion; + _internalBase = base; + _internalBaseRoot = parts.root; + _internalBaseComponents = components parts.subpath; + _internalTree = tree; - # Double __ to make it be evaluated and ordered first - __noEval = throw '' - lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.''; - }; + # Double __ to make it be evaluated and ordered first + __noEval = throw '' + 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. # 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 library: ${toString _currentVersion} 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 value else if ! isPath value then @@ -193,17 +225,13 @@ rec { # which has the effect that they aren't included in the result 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 baseString = - if baseComponents == [] then + if fileset._internalBaseComponents == [] then # Need to handle the filesystem root specially "/" else - "/" + concatStringsSep "/" baseComponents + "/"; + "/" + concatStringsSep "/" fileset._internalBaseComponents + "/"; baseLength = stringLength baseString; diff --git a/lib/fileset/tests.sh b/lib/fileset/tests.sh index 88cd4bcc47c9c..e27610573a86e 100755 --- a/lib/fileset/tests.sh +++ b/lib/fileset/tests.sh @@ -264,17 +264,21 @@ expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: ` # 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.' +# 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 -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: -\s*- Internal version of the file set: 1 -\s*- Internal version of the library: 0 +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: 2 +\s*- Internal version of the library: 1 \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 expectEqual '{ inherit (_coerce "<test>" (_create ./. "directory")) _internalVersion _internalBase _internalTree; -}' '{ _internalBase = ./.; _internalTree = "directory"; _internalVersion = 0; }' +}' '{ _internalBase = ./.; _internalTree = "directory"; _internalVersion = 1; }' #### Resulting store path #### |