Commit e7b611e5 authored by K900's avatar K900
Browse files

Merge remote-tracking branch 'origin/master' into staging-next

parents 9490738b 96478c43
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -66,6 +66,10 @@
/doc/build-helpers/images/makediskimage.section.md  @raitobezarius
/nixos/lib/make-disk-image.nix                 @raitobezarius

# Nix, the package manager
pkgs/tools/package-management/nix/                    @raitobezarius
nixos/modules/installer/tools/nix-fallback-paths.nix  @raitobezarius

# Nixpkgs documentation
/maintainers/scripts/db-to-md.sh @jtojnar @ryantm
/maintainers/scripts/doc @jtojnar @ryantm
+136 −23
Original line number Diff line number Diff line
@@ -103,42 +103,155 @@ rec {
      else converge f x';

  /*
    Modify the contents of an explicitly recursive attribute set in a way that
    honors `self`-references. This is accomplished with a function
    Extend a function using an overlay.

    Overlays allow modifying and extending fixed-point functions, specifically ones returning attribute sets.
    A fixed-point function is a function which is intended to be evaluated by passing the result of itself as the argument.
    This is possible due to Nix's lazy evaluation.


    A fixed-point function returning an attribute set has the form

    ```nix
    final: { # attributes }
    ```

    where `final` refers to the lazily evaluated attribute set returned by the fixed-point function.

    An overlay to such a fixed-point function has the form

    ```nix
    final: prev: { # attributes }
    ```

    where `prev` refers to the result of the original function to `final`, and `final` is the result of the composition of the overlay and the original function.

    Applying an overlay is done with `extends`:

    ```nix
    let
      f = final: { # attributes };
      overlay = final: prev: { # attributes };
    in extends overlay f;
    ```

    To get the value of `final`, use `lib.fix`:

    ```nix
    g = self: super: { foo = super.foo + " + "; }
    let
      f = final: { # attributes };
      overlay = final: prev: { # attributes };
      g = extends overlay f;
    in fix g
    ```

    :::{.example}

    # Extend a fixed-point function with an overlay

    Define a fixed-point function `f` that expects its own output as the argument `final`:

    ```nix-repl
    f = final: {
      # Constant value a
      a = 1;

      # b depends on the final value of a, available as final.a
      b = final.a + 2;
    }
    ```

    Evaluate this using [`lib.fix`](#function-library-lib.fixedPoints.fix) to get the final result:

    ```nix-repl
    fix f
    => { a = 1; b = 3; }
    ```

    that has access to the unmodified input (`super`) as well as the final
    non-recursive representation of the attribute set (`self`). `extends`
    differs from the native `//` operator insofar as that it's applied *before*
    references to `self` are resolved:
    An overlay represents a modification or extension of such a fixed-point function.
    Here's an example of an overlay:

    ```nix-repl
    overlay = final: prev: {
      # Modify the previous value of a, available as prev.a
      a = prev.a + 10;

      # Extend the attribute set with c, letting it depend on the final values of a and b
      c = final.a + final.b;
    }
    ```
    nix-repl> fix (extends g f)
    { bar = "bar"; foo = "foo + "; foobar = "foo + bar"; }

    Use `extends overlay f` to apply the overlay to the fixed-point function `f`.
    This produces a new fixed-point function `g` with the combined behavior of `f` and `overlay`:

    ```nix-repl
    g = extends overlay f
    ```

    The name of the function is inspired by object-oriented inheritance, i.e.
    think of it as an infix operator `g extends f` that mimics the syntax from
    Java. It may seem counter-intuitive to have the "base class" as the second
    argument, but it's nice this way if several uses of `extends` are cascaded.
    The result is a function, so we can't print it directly, but it's the same as:

    To get a better understanding how `extends` turns a function with a fix
    point (the package set we start with) into a new function with a different fix
    point (the desired packages set) lets just see, how `extends g f`
    unfolds with `g` and `f` defined above:
    ```nix-repl
    g' = final: {
      # The constant from f, but changed with the overlay
      a = 1 + 10;

      # Unchanged from f
      b = final.a + 2;

      # Extended in the overlay
      c = final.a + final.b;
    }
    ```
    extends g f = self: let super = f self; in super // g self super;
                = self: let super = { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }; in super // g self super
                = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // g self { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
                = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // { foo = "foo" + " + "; }
                = self: { foo = "foo + "; bar = "bar"; foobar = self.foo + self.bar; }

    Evaluate this using [`lib.fix`](#function-library-lib.fixedPoints.fix) again to get the final result:

    ```nix-repl
    fix g
    => { a = 11; b = 13; c = 24; }
    ```
    :::

    Type:
      extends :: (Attrs -> Attrs -> Attrs) # The overlay to apply to the fixed-point function
              -> (Attrs -> Attrs) # A fixed-point function
              -> (Attrs -> Attrs) # The resulting fixed-point function

    Example:
      f = final: { a = 1; b = final.a + 2; }

      fix f
      => { a = 1; b = 3; }

      fix (extends (final: prev: { a = prev.a + 10; }) f)
      => { a = 11; b = 13; }

      fix (extends (final: prev: { b = final.a + 5; }) f)
      => { a = 1; b = 6; }

      fix (extends (final: prev: { c = final.a + final.b; }) f)
      => { a = 1; b = 3; c = 4; }

    :::{.note}
    The argument to the given fixed-point function after applying an overlay will *not* refer to its own return value, but rather to the value after evaluating the overlay function.

    The given fixed-point function is called with a separate argument than if it was evaluated with `lib.fix`.
    The new argument
    :::
  */
  extends = f: rattrs: self: let super = rattrs self; in super // f self super;
  extends =
    # The overlay to apply to the fixed-point function
    overlay:
    # The fixed-point function
    f:
    # Wrap with parenthesis to prevent nixdoc from rendering the `final` argument in the documentation
    # The result should be thought of as a function, the argument of that function is not an argument to `extends` itself
    (
      final:
      let
        prev = f final;
      in
      prev // overlay final prev
    );

  /*
    Compose two extending functions of the type expected by 'extends'
+5 −5
Original line number Diff line number Diff line
{
  x86_64-linux = "/nix/store/smfmnz0ylx80wkbqbjibj7zcw4q668xp-nix-2.19.2";
  i686-linux = "/nix/store/knp0akbpj2k0rf26fmysmxdysmayihax-nix-2.19.2";
  aarch64-linux = "/nix/store/761hq0abn07nrydrf6mls61bscx2vz2i-nix-2.19.2";
  x86_64-darwin = "/nix/store/zlqvxis1dfcfgmy5fza4hllg6h03vhpb-nix-2.19.2";
  aarch64-darwin = "/nix/store/53r8ay20mygy2sifn7j2p8wjqlx2kxik-nix-2.19.2";
  x86_64-linux = "/nix/store/azvn85cras6xv4z5j85fiy406f24r1q0-nix-2.18.1";
  i686-linux = "/nix/store/9bnwy7f9h0kzdzmcnjjsjg0aak5waj40-nix-2.18.1";
  aarch64-linux = "/nix/store/hh65xwqm9s040s3cgn9vzcmrxj0sf5ij-nix-2.18.1";
  x86_64-darwin = "/nix/store/6zi5fqzn9n17wrk8r41rhdw4j7jqqsi3-nix-2.18.1";
  aarch64-darwin = "/nix/store/0pbq6wzr2f1jgpn5212knyxpwmkjgjah-nix-2.18.1";
}
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ in
    services.pgadmin.settings = {
      DEFAULT_SERVER_PORT = cfg.port;
      SERVER_MODE = true;
      UPGRADE_CHECK_ENABLED = false;
    } // (optionalAttrs cfg.openFirewall {
      DEFAULT_SERVER = mkDefault "::";
    }) // (optionalAttrs cfg.emailServer.enable {
+2 −9
Original line number Diff line number Diff line
@@ -27,13 +27,7 @@ let
      encoding = "utf8";
      pool = cfg.databasePool;
    } // cfg.extraDatabaseConfig;
  in if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.9" then {
    production.main = val;
    # Starting with GitLab 15.9, single connections were deprecated and will be
    # removed in GitLab 17.0. The CI connection however requires database_tasks set
    # to false.
    production.ci = val // { database_tasks = false; };
  } else if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then {
  in if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then {
    production.main = val;
  } else {
    production = val;
@@ -1354,12 +1348,11 @@ in {
                fi

                jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
                   '.${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then "production.main" else "production"}.password = $ENV.db_password ${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.9" then "| .production.ci.password = $ENV.db_password | .production.main as $main | del(.production.main) | .production |= {main: $main} + ." else ""}' \
                   '.${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then "production.main" else "production"}.password = $ENV.db_password' \
                   >'${cfg.statePath}/config/database.yml'
              ''
              else ''
                jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \
                   '${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.9" then ".production.main as $main | del(.production.main) | .production |= {main: $main} + ." else ""}' \
                   >'${cfg.statePath}/config/database.yml'
              ''
            }
Loading