Commit 7ba46415 authored by Robert Hensing's avatar Robert Hensing
Browse files

lib: Introduce Cross Index concept

A Cross Index, short for Cross Platform Pair Index, is the essential
shape of a splice, without the invoking the more mind bending concept
of adding variations of for these 6 pairings to an existing thing so
that it can be switched out for something else.

So the purpose of a Cross Index is to contain the result of `f`\
(which may be reified in code, or just an abstract concept):
 - f "build" "build"
 - f "build" "host"
 - ...

Splicing on the other hand refers not just to these six variants, but
to the idea of tacking them onto one of the variants. (hostTarget,
I believe)

Cross Indexes are a necessity for making cross compilation work, but
splicing is more than necessary.
parent ca4beaaf
Loading
Loading
Loading
Loading
+38 −24
Original line number Diff line number Diff line
@@ -865,34 +865,37 @@ rec {
    };

  /**
    Removes a prefix from the attribute names of a set of splices.
    Removes a prefix from the attribute names of a cross index.

    A cross index (short for "Cross Platform Pair Index") is a 6-field structure
    organizing values by cross-compilation platform relationships.

    # Inputs

    `prefix`
    : The prefix to remove from splice attribute names
    : The prefix to remove from cross index attribute names

    `splices`
    : A set of splices with prefixed names
    `crossIndex`
    : A cross index with prefixed names

    # Type

    ```
    renameSplicesFrom :: String -> AttrSet -> AttrSet
    renameCrossIndexFrom :: String -> AttrSet -> AttrSet
    ```

    # Examples

    :::{.example}
    ## `lib.customisation.renameSplicesFrom` usage example
    ## `lib.customisation.renameCrossIndexFrom` usage example

    ```nix
    renameSplicesFrom "pkgs" { pkgsBuildBuild = ...; pkgsBuildHost = ...; ... }
    renameCrossIndexFrom "pkgs" { pkgsBuildBuild = ...; pkgsBuildHost = ...; ... }
    => { buildBuild = ...; buildHost = ...; ... }
    ```
    :::
  */
  renameSplicesFrom = prefix: x: {
  renameCrossIndexFrom = prefix: x: {
    buildBuild = x."${prefix}BuildBuild";
    buildHost = x."${prefix}BuildHost";
    buildTarget = x."${prefix}BuildTarget";
@@ -902,34 +905,37 @@ rec {
  };

  /**
    Adds a prefix to the attribute names of a set of splices.
    Adds a prefix to the attribute names of a cross index.

    A cross index (short for "Cross Platform Pair Index") is a 6-field structure
    organizing values by cross-compilation platform relationships.

    # Inputs

    `prefix`
    : The prefix to add to splice attribute names
    : The prefix to add to cross index attribute names

    `splices`
    : A set of splices to be prefixed
    `crossIndex`
    : A cross index to be prefixed

    # Type

    ```
    renameSplicesTo :: String -> AttrSet -> AttrSet
    renameCrossIndexTo :: String -> AttrSet -> AttrSet
    ```

    # Examples

    :::{.example}
    ## `lib.customisation.renameSplicesTo` usage example
    ## `lib.customisation.renameCrossIndexTo` usage example

    ```nix
    renameSplicesTo "self" { buildBuild = ...; buildHost = ...; ... }
    renameCrossIndexTo "self" { buildBuild = ...; buildHost = ...; ... }
    => { selfBuildBuild = ...; selfBuildHost = ...; ... }
    ```
    :::
  */
  renameSplicesTo = prefix: x: {
  renameCrossIndexTo = prefix: x: {
    "${prefix}BuildBuild" = x.buildBuild;
    "${prefix}BuildHost" = x.buildHost;
    "${prefix}BuildTarget" = x.buildTarget;
@@ -939,34 +945,42 @@ rec {
  };

  /**
    Takes a function and applies it pointwise to each splice.
    Takes a function and applies it pointwise to each field of a cross index.

    A cross index (short for "Cross Platform Pair Index") is a 6-field structure
    organizing values by cross-compilation platform relationships.

    # Inputs

    `f`
    : Function to apply to each splice value
    : Function to apply to each cross index value

    `splices`
    : A set of splices to transform
    `crossIndex`
    : A cross index to transform

    # Type

    ```
    mapSplices :: (a -> b) -> AttrSet -> AttrSet
    mapCrossIndex :: (a -> b) -> AttrSet -> AttrSet
    ```

    # Examples

    :::{.example}
    ## `lib.customisation.mapSplices` usage example
    ## `lib.customisation.mapCrossIndex` usage example

    ```nix
    mapSplices (x: x * 10) { buildBuild = 1; buildHost = 2; ... }
    mapCrossIndex (x: x * 10) { buildBuild = 1; buildHost = 2; ... }
    => { buildBuild = 10; buildHost = 20; ... }
    ```

    ```nix
    # Extract a package from package sets
    mapCrossIndex (pkgs: pkgs.hello) crossIndexedPackageSets
    ```
    :::
  */
  mapSplices =
  mapCrossIndex =
    f:
    {
      buildBuild,
+3 −3
Original line number Diff line number Diff line
@@ -398,9 +398,9 @@ let
        makeScopeWithSplicing
        makeScopeWithSplicing'
        extendMkDerivation
        renameSplicesFrom
        renameSplicesTo
        mapSplices
        renameCrossIndexFrom
        renameCrossIndexTo
        mapCrossIndex
        ;
      inherit (self.derivations) lazyDerivation optionalDrvAttr warnOnInstantiate;
      inherit (self.generators) mkLuaInline;
+9 −9
Original line number Diff line number Diff line
@@ -4432,10 +4432,10 @@ runTests {
    expected = "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs/default.nix";
  };

  # Tests for splicing utilities
  # Tests for cross index utilities

  testRenameSplicesFrom = {
    expr = lib.renameSplicesFrom "pkgs" {
  testRenameCrossIndexFrom = {
    expr = lib.renameCrossIndexFrom "pkgs" {
      pkgsBuildBuild = "dummy-build-build";
      pkgsBuildHost = "dummy-build-host";
      pkgsBuildTarget = "dummy-build-target";
@@ -4453,8 +4453,8 @@ runTests {
    };
  };

  testRenameSplicesTo = {
    expr = lib.renameSplicesTo "self" {
  testRenameCrossIndexTo = {
    expr = lib.renameCrossIndexTo "self" {
      buildBuild = "dummy-build-build";
      buildHost = "dummy-build-host";
      buildTarget = "dummy-build-target";
@@ -4472,8 +4472,8 @@ runTests {
    };
  };

  testMapSplices = {
    expr = lib.mapSplices (x: x * 10) {
  testMapCrossIndex = {
    expr = lib.mapCrossIndex (x: x * 10) {
      buildBuild = 1;
      buildHost = 2;
      buildTarget = 3;
@@ -4491,8 +4491,8 @@ runTests {
    };
  };

  testMapSplicesString = {
    expr = lib.mapSplices (x: "prefix-${x}") {
  testMapCrossIndexString = {
    expr = lib.mapCrossIndex (x: "prefix-${x}") {
      buildBuild = "bb";
      buildHost = "bh";
      buildTarget = "bt";