···11# Nim {#nim}
2233-## Overview {#nim-overview}
44-55-The Nim compiler, a builder function, and some packaged libraries are available
66-in Nixpkgs. Until now each compiler release has been effectively backwards
77-compatible so only the latest version is available.
88-99-## Nim program packages in Nixpkgs {#nim-program-packages-in-nixpkgs}
1010-1111-Nim programs can be built using `nimPackages.buildNimPackage`. In the
1212-case of packages not containing exported library code the attribute
1313-`nimBinOnly` should be set to `true`.
33+The Nim compiler and a builder function is available.
44+Nim programs are built using `buildNimPackage` and a lockfile containing Nim dependencies.
145156The following example shows a Nim program that depends only on Nim libraries:
1616-177```nix
1818-{ lib, nimPackages, fetchFromGitHub }:
88+{ lib, buildNimPackage, fetchFromGitHub }:
1992020-nimPackages.buildNimPackage (finalAttrs: {
1010+buildNimPackage { } (finalAttrs: {
2111 pname = "ttop";
2222- version = "1.0.1";
2323- nimBinOnly = true;
1212+ version = "1.2.7";
24132514 src = fetchFromGitHub {
2615 owner = "inv2004";
2716 repo = "ttop";
2817 rev = "v${finalAttrs.version}";
2929- hash = "sha256-x4Uczksh6p3XX/IMrOFtBxIleVHdAPX9e8n32VAUTC4=";
1818+ hash = "sha256-oPdaUqh6eN1X5kAYVvevOndkB/xnQng9QVLX9bu5P5E=";
3019 };
31203232- buildInputs = with nimPackages; [ asciigraph illwill parsetoml zippy ];
3333-3434-})
3535-```
3636-3737-## Nim library packages in Nixpkgs {#nim-library-packages-in-nixpkgs}
3838-3939-4040-Nim libraries can also be built using `nimPackages.buildNimPackage`, but
4141-often the product of a fetcher is sufficient to satisfy a dependency.
4242-The `fetchgit`, `fetchFromGitHub`, and `fetchNimble` functions yield an
4343-output that can be discovered during the `configurePhase` of `buildNimPackage`.
2121+ lockFile = ./lock.json;
44224545-Nim library packages are listed in
4646-[pkgs/top-level/nim-packages.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/nim-packages.nix) and implemented at
4747-[pkgs/development/nim-packages](https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/nim-packages).
4848-4949-The following example shows a Nim library that propagates a dependency on a
5050-non-Nim package:
5151-```nix
5252-{ lib, buildNimPackage, fetchNimble, SDL2 }:
5353-5454-buildNimPackage (finalAttrs: {
5555- pname = "sdl2";
5656- version = "2.0.4";
5757- src = fetchNimble {
5858- inherit (finalAttrs) pname version;
5959- hash = "sha256-Vtcj8goI4zZPQs2TbFoBFlcR5UqDtOldaXSH/+/xULk=";
6060- };
6161- propagatedBuildInputs = [ SDL2 ];
2323+ nimFlags = [
2424+ "-d:NimblePkgVersion=${finalAttrs.version}"
2525+ ];
6226})
6327```
64286529## `buildNimPackage` parameters {#buildnimpackage-parameters}
66306767-All parameters from `stdenv.mkDerivation` function are still supported. The
6868-following are specific to `buildNimPackage`:
3131+The `buildNimPackage` function takes an attrset of parameters that are passed on to `stdenv.mkDerivation`.
3232+3333+The following parameters are specific to `buildNimPackage`:
69347070-* `nimBinOnly ? false`: If `true` then build only the programs listed in
7171- the Nimble file in the packages sources.
3535+* `lockFile`: JSON formatted lockfile.
7236* `nimbleFile`: Specify the Nimble file location of the package being built
7337 rather than discover the file at build-time.
7438* `nimRelease ? true`: Build the package in *release* mode.
···7741 Use this to specify defines with arguments in the form of `-d:${name}=${value}`.
7842* `nimDoc` ? false`: Build and install HTML documentation.
79438080-* `buildInputs` ? []: The packages listed here will be searched for `*.nimble`
8181- files which are used to populate the Nim library path. Otherwise the standard
8282- behavior is in effect.
4444+## Lockfiles {#nim-lockfiles}
4545+Nim lockfiles are created with the `nim_lk` utility.
4646+Run `nim_lk` with the source directory as an argument and it will print a lockfile to stdout.
4747+```sh
4848+$ cd nixpkgs
4949+$ nix build -f . ttop.src
5050+$ nix run -f . nim_lk ./result | jq --sort-keys > pkgs/by-name/tt/ttop/lock.json
5151+```
5252+5353+## Lockfile dependency overrides {#nimoverrides}
5454+5555+The `buildNimPackage` function matches the libraries specified by `lockFile` to attrset of override functions that are then applied to the package derivation.
5656+The default overrides are maintained as the top-level `nimOverrides` attrset at `pkgs/top-level/nim-overrides.nix`.
5757+5858+For example, to propagate a dependency on SDL2 for lockfiles that select the Nim `sdl2` library, an overlay is added to the set in the `nim-overrides.nix` file:
5959+```nix
6060+{ lib
6161+/* … */
6262+, SDL2
6363+/* … */
6464+}:
6565+6666+{
6767+ /* … */
6868+ sdl2 =
6969+ lockAttrs:
7070+ finalAttrs:
7171+ { buildInputs ? [ ], ... }:
7272+ {
7373+ buildInputs = buildInputs ++ [ SDL2 ];
7474+ };
7575+ /* … */
7676+}
7777+```
7878+7979+The annotations in the `nim-overrides.nix` set are functions that take three arguments and return a new attrset to be overlayed on the package being built.
8080+- lockAttrs: the attrset for this library from within a lockfile. This can be used to implement library version constraints, such as marking libraries as broken or insecure.
8181+- finalAttrs: the final attrset passed by `buildNimPackage` to `stdenv.mkDerivation`.
8282+- prevAttrs: the attrset produced by initial arguments to `buildNimPackage` and any preceding lockfile overlays.
8383+8484+### Overriding an Nim library override {#nimoverrides-overrides}
8585+8686+The `nimOverrides` attrset makes it possible to modify overrides in a few different ways.
8787+8888+Override a package internal to its definition:
8989+```nix
9090+{ lib, buildNimPackage, nimOverrides, libressl }:
9191+9292+let
9393+ buildNimPackage' = buildNimPackage.override {
9494+ nimOverrides = nimOverrides.override { openssl = libressl; };
9595+ };
9696+in buildNimPackage' (finalAttrs: {
9797+ pname = "foo";
9898+ # …
9999+})
100100+101101+```
102102+103103+Override a package externally:
104104+```nix
105105+{ pkgs }: {
106106+ foo = pkgs.foo.override {
107107+ buildNimPackage = pkgs.buildNimPackage.override {
108108+ nimOverrides = pkgs.nimOverrides.override { openssl = libressl; };
109109+ };
110110+ };
111111+}
112112+```
+2-1
nixos/doc/manual/release-notes/rl-2311.section.md
···665665 designed to be easy and safe to use.
666666667667 This aims to be a replacement for `lib.sources`-based filtering.
668668- To learn more about it, see [the tutorial](https://nix.dev/tutorials/file-sets).
668668+ To learn more about it, see [the blog post](https://www.tweag.io/blog/2023-11-28-file-sets/)
669669+ or [the tutorial](https://nix.dev/tutorials/file-sets).
669670670671- [`lib.gvariant`](https://nixos.org/manual/nixpkgs/unstable#sec-functions-library-gvariant):
671672 A partial and basic implementation of GVariant formatted strings.
+4-2
nixos/doc/manual/release-notes/rl-2405.section.md
···14141515<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
16161717-- Create the first release note entry in this section!
1717+- [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable).
18181919## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
2020···26262727<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
28282929-- Create the first release note entry in this section!
2929+- Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles.
3030+ The `nimPackages` and `nim2Packages` sets have been removed.
3131+ See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
+6-3
nixos/modules/installer/tools/tools.nix
···130130 '';
131131 };
132132133133- config = lib.mkIf (config.nix.enable && !config.system.disableInstallerTools) {
133133+ config = lib.mkMerge [ (lib.mkIf (config.nix.enable && !config.system.disableInstallerTools) {
134134135135 system.nixos-generate-config.configuration = mkDefault ''
136136 # Edit this configuration file to define what should be installed on
···257257258258 documentation.man.man-db.skipPackages = [ nixos-version ];
259259260260+ })
261261+262262+ # These may be used in auxiliary scripts (ie not part of toplevel), so they are defined unconditionally.
263263+ ({
260264 system.build = {
261265 inherit nixos-install nixos-generate-config nixos-option nixos-rebuild nixos-enter;
262266 };
263263-264264- };
267267+ })];
265268266269}
···11+# Maubot {#module-services-maubot}
22+33+[Maubot](https://github.com/maubot/maubot) is a plugin-based bot
44+framework for Matrix.
55+66+## Configuration {#module-services-maubot-configuration}
77+88+1. Set [](#opt-services.maubot.enable) to `true`. The service will use
99+ SQLite by default.
1010+2. If you want to use PostgreSQL instead of SQLite, do this:
1111+1212+ ```nix
1313+ services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
1414+ ```
1515+1616+ If the PostgreSQL connection requires a password, you will have to
1717+ add it later on step 8.
1818+3. If you plan to expose your Maubot interface to the web, do something
1919+ like this:
2020+ ```nix
2121+ services.nginx.virtualHosts."matrix.example.org".locations = {
2222+ "/_matrix/maubot/" = {
2323+ proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
2424+ proxyWebsockets = true;
2525+ };
2626+ };
2727+ services.maubot.settings.server.public_url = "matrix.example.org";
2828+ # do the following only if you want to use something other than /_matrix/maubot...
2929+ services.maubot.settings.server.ui_base_path = "/another/base/path";
3030+ ```
3131+4. Optionally, set `services.maubot.pythonPackages` to a list of python3
3232+ packages to make available for Maubot plugins.
3333+5. Optionally, set `services.maubot.plugins` to a list of Maubot
3434+ plugins (full list available at https://plugins.maubot.xyz/):
3535+ ```nix
3636+ services.maubot.plugins = with config.services.maubot.package.plugins; [
3737+ reactbot
3838+ # This will only change the default config! After you create a
3939+ # plugin instance, the default config will be copied into that
4040+ # instance's config in Maubot's database, and further base config
4141+ # changes won't affect the running plugin.
4242+ (rss.override {
4343+ base_config = {
4444+ update_interval = 60;
4545+ max_backoff = 7200;
4646+ spam_sleep = 2;
4747+ command_prefix = "rss";
4848+ admins = [ "@chayleaf:pavluk.org" ];
4949+ };
5050+ })
5151+ ];
5252+ # ...or...
5353+ services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
5454+ # ...or...
5555+ services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
5656+ # ...or...
5757+ services.maubot.plugins = with config.services.maubot.package.plugins; [
5858+ (weather.override {
5959+ # you can pass base_config as a string
6060+ base_config = ''
6161+ default_location: New York
6262+ default_units: M
6363+ default_language:
6464+ show_link: true
6565+ show_image: false
6666+ '';
6767+ })
6868+ ];
6969+ ```
7070+6. Start Maubot at least once before doing the following steps (it's
7171+ necessary to generate the initial config).
7272+7. If your PostgreSQL connection requires a password, add
7373+ `database: postgresql://user:password@localhost/maubot`
7474+ to `/var/lib/maubot/config.yaml`. This overrides the Nix-provided
7575+ config. Even then, don't remove the `database` line from Nix config
7676+ so the module knows you use PostgreSQL!
7777+8. To create a user account for logging into Maubot web UI and
7878+ configuring it, generate a password using the shell command
7979+ `mkpasswd -R 12 -m bcrypt`, and edit `/var/lib/maubot/config.yaml`
8080+ with the following:
8181+8282+ ```yaml
8383+ admins:
8484+ admin_username: $2b$12$g.oIStUeUCvI58ebYoVMtO/vb9QZJo81PsmVOomHiNCFbh0dJpZVa
8585+ ```
8686+8787+ Where `admin_username` is your username, and `$2b...` is the bcrypted
8888+ password.
8989+9. Optional: if you want to be able to register new users with the
9090+ Maubot CLI (`mbc`), and your homeserver is private, add your
9191+ homeserver's registration key to `/var/lib/maubot/config.yaml`:
9292+9393+ ```yaml
9494+ homeservers:
9595+ matrix.example.org:
9696+ url: https://matrix.example.org
9797+ secret: your-very-secret-key
9898+ ```
9999+10. Restart Maubot after editing `/var/lib/maubot/config.yaml`,and
100100+ Maubot will be available at
101101+ `https://matrix.example.org/_matrix/maubot`. If you want to use the
102102+ `mbc` CLI, it's available using the `maubot` package (`nix-shell -p
103103+ maubot`).
+459
nixos/modules/services/matrix/maubot.nix
···11+{ lib
22+, config
33+, pkgs
44+, ...
55+}:
66+77+let
88+ cfg = config.services.maubot;
99+1010+ wrapper1 =
1111+ if cfg.plugins == [ ]
1212+ then cfg.package
1313+ else cfg.package.withPlugins (_: cfg.plugins);
1414+1515+ wrapper2 =
1616+ if cfg.pythonPackages == [ ]
1717+ then wrapper1
1818+ else wrapper1.withPythonPackages (_: cfg.pythonPackages);
1919+2020+ settings = lib.recursiveUpdate cfg.settings {
2121+ plugin_directories.trash =
2222+ if cfg.settings.plugin_directories.trash == null
2323+ then "delete"
2424+ else cfg.settings.plugin_directories.trash;
2525+ server.unshared_secret = "generate";
2626+ };
2727+2828+ finalPackage = wrapper2.withBaseConfig settings;
2929+3030+ isPostgresql = db: builtins.isString db && lib.hasPrefix "postgresql://" db;
3131+ isLocalPostgresDB = db: isPostgresql db && builtins.any (x: lib.hasInfix x db) [
3232+ "@127.0.0.1/"
3333+ "@::1/"
3434+ "@[::1]/"
3535+ "@localhost/"
3636+ ];
3737+ parsePostgresDB = db:
3838+ let
3939+ noSchema = lib.removePrefix "postgresql://" db;
4040+ in {
4141+ username = builtins.head (lib.splitString "@" noSchema);
4242+ database = lib.last (lib.splitString "/" noSchema);
4343+ };
4444+4545+ postgresDBs = [
4646+ cfg.settings.database
4747+ cfg.settings.crypto_database
4848+ cfg.settings.plugin_databases.postgres
4949+ ];
5050+5151+ localPostgresDBs = builtins.filter isLocalPostgresDB postgresDBs;
5252+5353+ parsedLocalPostgresDBs = map parsePostgresDB localPostgresDBs;
5454+ parsedPostgresDBs = map parsePostgresDB postgresDBs;
5555+5656+ hasLocalPostgresDB = localPostgresDBs != [ ];
5757+in
5858+{
5959+ options.services.maubot = with lib; {
6060+ enable = mkEnableOption (mdDoc "maubot");
6161+6262+ package = lib.mkPackageOptionMD pkgs "maubot" { };
6363+6464+ plugins = mkOption {
6565+ type = types.listOf types.package;
6666+ default = [ ];
6767+ example = literalExpression ''
6868+ with config.services.maubot.package.plugins; [
6969+ xyz.maubot.reactbot
7070+ xyz.maubot.rss
7171+ ];
7272+ '';
7373+ description = mdDoc ''
7474+ List of additional maubot plugins to make available.
7575+ '';
7676+ };
7777+7878+ pythonPackages = mkOption {
7979+ type = types.listOf types.package;
8080+ default = [ ];
8181+ example = literalExpression ''
8282+ with pkgs.python3Packages; [
8383+ aiohttp
8484+ ];
8585+ '';
8686+ description = mdDoc ''
8787+ List of additional Python packages to make available for maubot.
8888+ '';
8989+ };
9090+9191+ dataDir = mkOption {
9292+ type = types.str;
9393+ default = "/var/lib/maubot";
9494+ description = mdDoc ''
9595+ The directory where maubot stores its stateful data.
9696+ '';
9797+ };
9898+9999+ extraConfigFile = mkOption {
100100+ type = types.str;
101101+ default = "./config.yaml";
102102+ defaultText = literalExpression ''"''${config.services.maubot.dataDir}/config.yaml"'';
103103+ description = mdDoc ''
104104+ A file for storing secrets. You can pass homeserver registration keys here.
105105+ If it already exists, **it must contain `server.unshared_secret`** which is used for signing API keys.
106106+ If `configMutable` is not set to true, **maubot user must have write access to this file**.
107107+ '';
108108+ };
109109+110110+ configMutable = mkOption {
111111+ type = types.bool;
112112+ default = false;
113113+ description = mdDoc ''
114114+ Whether maubot should write updated config into `extraConfigFile`. **This will make your Nix module settings have no effect besides the initial config, as extraConfigFile takes precedence over NixOS settings!**
115115+ '';
116116+ };
117117+118118+ settings = mkOption {
119119+ default = { };
120120+ description = mdDoc ''
121121+ YAML settings for maubot. See the
122122+ [example configuration](https://github.com/maubot/maubot/blob/master/maubot/example-config.yaml)
123123+ for more info.
124124+125125+ Secrets should be passed in by using `extraConfigFile`.
126126+ '';
127127+ type = with types; submodule {
128128+ options = {
129129+ database = mkOption {
130130+ type = str;
131131+ default = "sqlite:maubot.db";
132132+ example = "postgresql://username:password@hostname/dbname";
133133+ description = mdDoc ''
134134+ The full URI to the database. SQLite and Postgres are fully supported.
135135+ Other DBMSes supported by SQLAlchemy may or may not work.
136136+ '';
137137+ };
138138+139139+ crypto_database = mkOption {
140140+ type = str;
141141+ default = "default";
142142+ example = "postgresql://username:password@hostname/dbname";
143143+ description = mdDoc ''
144144+ Separate database URL for the crypto database. By default, the regular database is also used for crypto.
145145+ '';
146146+ };
147147+148148+ database_opts = mkOption {
149149+ type = types.attrs;
150150+ default = { };
151151+ description = mdDoc ''
152152+ Additional arguments for asyncpg.create_pool() or sqlite3.connect()
153153+ '';
154154+ };
155155+156156+ plugin_directories = mkOption {
157157+ default = { };
158158+ description = mdDoc "Plugin directory paths";
159159+ type = submodule {
160160+ options = {
161161+ upload = mkOption {
162162+ type = types.str;
163163+ default = "./plugins";
164164+ defaultText = literalExpression ''"''${config.services.maubot.dataDir}/plugins"'';
165165+ description = mdDoc ''
166166+ The directory where uploaded new plugins should be stored.
167167+ '';
168168+ };
169169+ load = mkOption {
170170+ type = types.listOf types.str;
171171+ default = [ "./plugins" ];
172172+ defaultText = literalExpression ''[ "''${config.services.maubot.dataDir}/plugins" ]'';
173173+ description = mdDoc ''
174174+ The directories from which plugins should be loaded. Duplicate plugin IDs will be moved to the trash.
175175+ '';
176176+ };
177177+ trash = mkOption {
178178+ type = with types; nullOr str;
179179+ default = "./trash";
180180+ defaultText = literalExpression ''"''${config.services.maubot.dataDir}/trash"'';
181181+ description = mdDoc ''
182182+ The directory where old plugin versions and conflicting plugins should be moved. Set to null to delete files immediately.
183183+ '';
184184+ };
185185+ };
186186+ };
187187+ };
188188+189189+ plugin_databases = mkOption {
190190+ description = mdDoc "Plugin database settings";
191191+ default = { };
192192+ type = submodule {
193193+ options = {
194194+ sqlite = mkOption {
195195+ type = types.str;
196196+ default = "./plugins";
197197+ defaultText = literalExpression ''"''${config.services.maubot.dataDir}/plugins"'';
198198+ description = mdDoc ''
199199+ The directory where SQLite plugin databases should be stored.
200200+ '';
201201+ };
202202+203203+ postgres = mkOption {
204204+ type = types.nullOr types.str;
205205+ default = if isPostgresql cfg.settings.database then "default" else null;
206206+ defaultText = literalExpression ''if isPostgresql config.services.maubot.settings.database then "default" else null'';
207207+ description = mdDoc ''
208208+ The connection URL for plugin database. See [example config](https://github.com/maubot/maubot/blob/master/maubot/example-config.yaml) for exact format.
209209+ '';
210210+ };
211211+212212+ postgres_max_conns_per_plugin = mkOption {
213213+ type = types.nullOr types.int;
214214+ default = 3;
215215+ description = mdDoc ''
216216+ Maximum number of connections per plugin instance.
217217+ '';
218218+ };
219219+220220+ postgres_opts = mkOption {
221221+ type = types.attrs;
222222+ default = { };
223223+ description = mdDoc ''
224224+ Overrides for the default database_opts when using a non-default postgres connection URL.
225225+ '';
226226+ };
227227+ };
228228+ };
229229+ };
230230+231231+ server = mkOption {
232232+ default = { };
233233+ description = mdDoc "Listener config";
234234+ type = submodule {
235235+ options = {
236236+ hostname = mkOption {
237237+ type = types.str;
238238+ default = "127.0.0.1";
239239+ description = mdDoc ''
240240+ The IP to listen on
241241+ '';
242242+ };
243243+ port = mkOption {
244244+ type = types.port;
245245+ default = 29316;
246246+ description = mdDoc ''
247247+ The port to listen on
248248+ '';
249249+ };
250250+ public_url = mkOption {
251251+ type = types.str;
252252+ default = "http://${cfg.settings.server.hostname}:${toString cfg.settings.server.port}";
253253+ defaultText = literalExpression ''"http://''${config.services.maubot.settings.server.hostname}:''${toString config.services.maubot.settings.server.port}"'';
254254+ description = mdDoc ''
255255+ Public base URL where the server is visible.
256256+ '';
257257+ };
258258+ ui_base_path = mkOption {
259259+ type = types.str;
260260+ default = "/_matrix/maubot";
261261+ description = mdDoc ''
262262+ The base path for the UI.
263263+ '';
264264+ };
265265+ plugin_base_path = mkOption {
266266+ type = types.str;
267267+ default = "${config.services.maubot.settings.server.ui_base_path}/plugin/";
268268+ defaultText = literalExpression ''
269269+ "''${config.services.maubot.settings.server.ui_base_path}/plugin/"
270270+ '';
271271+ description = mdDoc ''
272272+ The base path for plugin endpoints. The instance ID will be appended directly.
273273+ '';
274274+ };
275275+ override_resource_path = mkOption {
276276+ type = types.nullOr types.str;
277277+ default = null;
278278+ description = mdDoc ''
279279+ Override path from where to load UI resources.
280280+ '';
281281+ };
282282+ };
283283+ };
284284+ };
285285+286286+ homeservers = mkOption {
287287+ type = types.attrsOf (types.submodule {
288288+ options = {
289289+ url = mkOption {
290290+ type = types.str;
291291+ description = mdDoc ''
292292+ Client-server API URL
293293+ '';
294294+ };
295295+ };
296296+ });
297297+ default = {
298298+ "matrix.org" = {
299299+ url = "https://matrix-client.matrix.org";
300300+ };
301301+ };
302302+ description = mdDoc ''
303303+ Known homeservers. This is required for the `mbc auth` command and also allows more convenient access from the management UI.
304304+ If you want to specify registration secrets, pass this via extraConfigFile instead.
305305+ '';
306306+ };
307307+308308+ admins = mkOption {
309309+ type = types.attrsOf types.str;
310310+ default = { root = ""; };
311311+ description = mdDoc ''
312312+ List of administrator users. Plaintext passwords will be bcrypted on startup. Set empty password
313313+ to prevent normal login. Root is a special user that can't have a password and will always exist.
314314+ '';
315315+ };
316316+317317+ api_features = mkOption {
318318+ type = types.attrsOf bool;
319319+ default = {
320320+ login = true;
321321+ plugin = true;
322322+ plugin_upload = true;
323323+ instance = true;
324324+ instance_database = true;
325325+ client = true;
326326+ client_proxy = true;
327327+ client_auth = true;
328328+ dev_open = true;
329329+ log = true;
330330+ };
331331+ description = mdDoc ''
332332+ API feature switches.
333333+ '';
334334+ };
335335+336336+ logging = mkOption {
337337+ type = types.attrs;
338338+ description = mdDoc ''
339339+ Python logging configuration. See [section 16.7.2 of the Python
340340+ documentation](https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema)
341341+ for more info.
342342+ '';
343343+ default = {
344344+ version = 1;
345345+ formatters = {
346346+ colored = {
347347+ "()" = "maubot.lib.color_log.ColorFormatter";
348348+ format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
349349+ };
350350+ normal = {
351351+ format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
352352+ };
353353+ };
354354+ handlers = {
355355+ file = {
356356+ class = "logging.handlers.RotatingFileHandler";
357357+ formatter = "normal";
358358+ filename = "./maubot.log";
359359+ maxBytes = 10485760;
360360+ backupCount = 10;
361361+ };
362362+ console = {
363363+ class = "logging.StreamHandler";
364364+ formatter = "colored";
365365+ };
366366+ };
367367+ loggers = {
368368+ maubot = {
369369+ level = "DEBUG";
370370+ };
371371+ mau = {
372372+ level = "DEBUG";
373373+ };
374374+ aiohttp = {
375375+ level = "INFO";
376376+ };
377377+ };
378378+ root = {
379379+ level = "DEBUG";
380380+ handlers = [ "file" "console" ];
381381+ };
382382+ };
383383+ };
384384+ };
385385+ };
386386+ };
387387+ };
388388+389389+ config = lib.mkIf cfg.enable {
390390+ warnings = lib.optional (builtins.any (x: x.username != x.database) parsedLocalPostgresDBs) ''
391391+ The Maubot database username doesn't match the database name! This means the user won't be automatically
392392+ granted ownership of the database. Consider changing either the username or the database name.
393393+ '';
394394+ assertions = [
395395+ {
396396+ assertion = builtins.all (x: !lib.hasInfix ":" x.username) parsedPostgresDBs;
397397+ message = ''
398398+ Putting database passwords in your Nix config makes them world-readable. To securely put passwords
399399+ in your Maubot config, change /var/lib/maubot/config.yaml after running Maubot at least once as
400400+ described in the NixOS manual.
401401+ '';
402402+ }
403403+ {
404404+ assertion = hasLocalPostgresDB -> config.services.postgresql.enable;
405405+ message = ''
406406+ Cannot deploy maubot with a configuration for a local postgresql database and a missing postgresql service.
407407+ '';
408408+ }
409409+ ];
410410+411411+ services.postgresql = lib.mkIf hasLocalPostgresDB {
412412+ enable = true;
413413+ ensureDatabases = map (x: x.database) parsedLocalPostgresDBs;
414414+ ensureUsers = lib.flip map parsedLocalPostgresDBs (x: {
415415+ name = x.username;
416416+ ensureDBOwnership = lib.mkIf (x.username == x.database) true;
417417+ });
418418+ };
419419+420420+ users.users.maubot = {
421421+ group = "maubot";
422422+ home = cfg.dataDir;
423423+ # otherwise StateDirectory is enough
424424+ createHome = lib.mkIf (cfg.dataDir != "/var/lib/maubot") true;
425425+ isSystemUser = true;
426426+ };
427427+428428+ users.groups.maubot = { };
429429+430430+ systemd.services.maubot = rec {
431431+ description = "maubot - a plugin-based Matrix bot system written in Python";
432432+ after = [ "network.target" ] ++ wants ++ lib.optional hasLocalPostgresDB "postgresql.service";
433433+ # all plugins get automatically disabled if maubot starts before synapse
434434+ wants = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
435435+ wantedBy = [ "multi-user.target" ];
436436+437437+ preStart = ''
438438+ if [ ! -f "${cfg.extraConfigFile}" ]; then
439439+ echo "server:" > "${cfg.extraConfigFile}"
440440+ echo " unshared_secret: $(head -c40 /dev/random | base32 | ${pkgs.gawk}/bin/awk '{print tolower($0)}')" > "${cfg.extraConfigFile}"
441441+ chmod 640 "${cfg.extraConfigFile}"
442442+ fi
443443+ '';
444444+445445+ serviceConfig = {
446446+ ExecStart = "${finalPackage}/bin/maubot --config ${cfg.extraConfigFile}" + lib.optionalString (!cfg.configMutable) " --no-update";
447447+ User = "maubot";
448448+ Group = "maubot";
449449+ Restart = "on-failure";
450450+ RestartSec = "10s";
451451+ StateDirectory = lib.mkIf (cfg.dataDir == "/var/lib/maubot") "maubot";
452452+ WorkingDirectory = cfg.dataDir;
453453+ };
454454+ };
455455+ };
456456+457457+ meta.maintainers = with lib.maintainers; [ chayleaf ];
458458+ meta.doc = ./maubot.md;
459459+}
···3030 meta = with lib; {
3131 description = "A program that reformats Kotlin source code to comply with the common community standard for Kotlin code conventions.";
3232 homepage = "https://github.com/facebook/ktfmt";
3333- license = licenses.apsl20;
3333+ license = licenses.asl20;
3434 mainProgram = "ktfmt";
3535 maintainers = with maintainers; [ ghostbuster91 ];
3636 inherit (jre_headless.meta) platforms;
···120120 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 # Dont try to expand NuGetFallbackFolder to disk
121121 export DOTNET_NOLOGO=1 # Disables the welcome message
122122 export DOTNET_CLI_TELEMETRY_OPTOUT=1
123123+ export DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK=1 # Skip integrity check on first run, which fails due to read-only directory
123124 '';
124125125126 passthru = {
···147148 nativeBuildInputs = [ finalAttrs.finalPackage ];
148149 } ''
149150 HOME=$(pwd)/fake-home
150150- dotnet new console
151151- dotnet build
152152- output="$(dotnet run)"
151151+ dotnet new console --no-restore
152152+ dotnet restore --source "$(mktemp -d)"
153153+ dotnet build --no-restore
154154+ output="$(dotnet run --no-build)"
153155 # yes, older SDKs omit the comma
154156 [[ "$output" =~ Hello,?\ World! ]] && touch "$out"
155157 '';
+1-2
pkgs/development/compilers/dotnet/update.sh
···255255 "Microsoft.NETCore.App.Crossgen2.osx-arm64"
256256 )
257257258258- # These packages are currently broken on .NET 8
259259- # When .NET 8 officialy launches, these should be checked and added back if fixed
258258+ # These packages were removed on .NET 8
260259 if version_older "$version" "8"; then
261260 pkgs+=( \
262261 "Microsoft.NETCore.App.Host.win-arm" \
···11-WGET_ARGS=( https://download.qt.io/official_releases/qt/6.6/6.6.0/submodules/ -A '*.tar.xz' )
11+WGET_ARGS=( https://download.qt.io/official_releases/qt/6.6/6.6.1/submodules/ -A '*.tar.xz' )
···11-From 880fe5653a86d8091f3f577977f8af93552c48fd Mon Sep 17 00:00:00 2001
11+From 82e243f326aea40e7f3da935d8166979b11e8063 Mon Sep 17 00:00:00 2001
22From: Nick Cao <nickcao@nichi.co>
33Date: Tue, 21 Mar 2023 15:48:49 +0800
44-Subject: [PATCH 05/11] qtbase: deal with a font face at index 0 as Regular for
44+Subject: [PATCH 04/11] qtbase: deal with a font face at index 0 as Regular for
55 Variable fonts
6677Reference: https://bugreports.qt.io/browse/QTBUG-111994
···2233stdenv.mkDerivation rec {
44 pname = "tdlib";
55- version = "1.8.19";
55+ version = "1.8.21";
6677 src = fetchFromGitHub {
88 owner = "tdlib";
···1111 # The tdlib authors do not set tags for minor versions, but
1212 # external programs depending on tdlib constrain the minor
1313 # version, hence we set a specific commit with a known version.
1414- rev = "2589c3fd46925f5d57e4ec79233cd1bd0f5d0c09";
1515- hash = "sha256-mbhxuJjrV3nC8Ja7N0WWF9ByHovJLmoLLuuzoU4khjU=";
1414+ rev = "3870c29b158b75ca5e48e0eebd6b5c3a7994a000";
1515+ hash = "sha256-MCzgovcEZa34ZkwbbwfXHm2qitHwL2Tpr8p7+PxNhYk=";
1616 };
17171818 buildInputs = [ gperf openssl readline zlib ];
···133133 if err != 0: quit("build phase failed", err)
134134135135proc installPhase*() =
136136- ## Install the Nim sources if ``nimBinOnly`` is not
136136+ ## Install the Nim sources if ``nimCopySources`` is
137137 ## set in the environment.
138138- if not getEnvBool"nimBinOnly":
138138+ if getEnvBool"nimCopySources":
139139 let
140140 nf = getNimbleFilePath()
141141 srcDir = nf.getNimbleValue("srcDir", ".")
···11+Do not use vendored libraries
22+33+--- a/vendor/CMakeLists.txt
44++++ b/vendor/CMakeLists.txt
55+@@ -14,10 +14,7 @@
66+ # License along with this library; if not, write to the Free Software
77+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
88+99+ add_subdirectory(onigmo)
1010+-add_subdirectory(mruby)
1111+-add_subdirectory(mecab)
1212+-add_subdirectory(message_pack)
1313+ if(GRN_WITH_MRUBY)
1414+ add_subdirectory(groonga-log)
1515+ endif()
···589589 monero = monero-cli; # Added 2021-11-28
590590 mongodb-4_0 = throw "mongodb-4_0 has been removed, it's end of life since April 2022"; # Added 2023-01-05
591591 mongodb-4_2 = throw "mongodb-4_2 has been removed, it's end of life since April 2023"; # Added 2023-06-06
592592-592592+ moonlander = throw "'moonlander' has been removed due to it being broken and unmaintained"; # Added 2023-11-26
593593 moz-phab = mozphab; # Added 2022-08-09
594594 mozart-binary = throw "'mozart-binary' has been renamed to/replaced by 'mozart2-binary'"; # Converted to throw 2023-09-10
595595 mozart = throw "'mozart' has been renamed to/replaced by 'mozart2-binary'"; # Converted to throw 2023-09-10