diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index bde64c2c14e8..625dd1516cd5 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -749,6 +749,15 @@ "module-services-davis-basic-usage": [ "index.html#module-services-davis-basic-usage" ], + "module-services-draupnir": [ + "index.html#module-services-draupnir" + ], + "module-services-draupnir-setup": [ + "index.html#module-services-draupnir-setup" + ], + "module-services-draupnir-setup-ems": [ + "index.html#module-services-draupnir-setup-ems" + ], "module-services-castopod": [ "index.html#module-services-castopod" ], diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md index 72c1ca24362c..f312d135cba2 100644 --- a/nixos/doc/manual/release-notes/rl-2511.section.md +++ b/nixos/doc/manual/release-notes/rl-2511.section.md @@ -22,6 +22,8 @@ - [Broadcast Box](https://github.com/Glimesh/broadcast-box), a WebRTC broadcast server. Available as [services.broadcast-box](options.html#opt-services.broadcast-box.enable). +- [Draupnir](https://github.com/the-draupnir-project/draupnir), a Matrix moderation bot. Available as [services.draupnir](#opt-services.draupnir.enable). + - [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable). [dwl](https://codeberg.org/dwl/dwl), a compact, hackable compositor for Wayland based on wlroots. Available as [programs.dwl](#opt-programs.dwl.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 57a164ea3935..34419e33f3f3 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -758,6 +758,7 @@ ./services/matrix/conduit.nix ./services/matrix/continuwuity.nix ./services/matrix/dendrite.nix + ./services/matrix/draupnir.nix ./services/matrix/hebbot.nix ./services/matrix/hookshot.nix ./services/matrix/lk-jwt-service.nix diff --git a/nixos/modules/services/matrix/draupnir.md b/nixos/modules/services/matrix/draupnir.md new file mode 100644 index 000000000000..1d6bce2c4e63 --- /dev/null +++ b/nixos/modules/services/matrix/draupnir.md @@ -0,0 +1,62 @@ +# Draupnir (Matrix Moderation Bot) {#module-services-draupnir} + +This chapter will show you how to set up your own, self-hosted +[Draupnir](https://github.com/the-draupnir-project/Draupnir) instance. + +As an all-in-one moderation tool, it can protect your server from +malicious invites, spam messages, and whatever else you don't want. +In addition to server-level protection, Draupnir is great for communities +wanting to protect their rooms without having to use their personal +accounts for moderation. + +The bot by default includes support for bans, redactions, anti-spam, +server ACLs, room directory changes, room alias transfers, account +deactivation, room shutdown, and more. (This depends on homeserver configuration and implementation.) + +See the [README](https://github.com/the-draupnir-project/draupnir#readme) +page and the [Moderator's guide](https://the-draupnir-project.github.io/draupnir-documentation/moderator/setting-up-and-configuring) +for additional instructions on how to setup and use Draupnir. + +For [additional settings](#opt-services.draupnir.settings) +see [the default configuration](https://github.com/the-draupnir-project/Draupnir/blob/main/config/default.yaml). + +## Draupnir Setup {#module-services-draupnir-setup} + +First create a new unencrypted, private room which will be used as the management room for Draupnir. +This is the room in which moderators will interact with Draupnir and where it will log possible errors and debugging information. +You'll need to set this room ID or alias in [services.draupnir.settings.managementRoom](#opt-services.draupnir.settings.managementRoom). + +Next, create a new user for Draupnir on your homeserver, if one does not already exist. + +The Draupnir Matrix user expects to be free of any rate limiting. +See [Synapse #6286](https://github.com/matrix-org/synapse/issues/6286) +for an example on how to achieve this. + +If you want Draupnir to be able to deactivate users, move room aliases, shut down rooms, etc. +you'll need to make the Draupnir user a Matrix server admin. + +Now invite the Draupnir user to the management room. +Draupnir will automatically try to join this room on startup. + +```nix +{ + services.draupnir = { + enable = true; + + settings = { + homeserverUrl = "https://matrix.org"; + managementRoom = "!yyy:example.org"; + }; + + secrets = { + accessToken = "/path/to/secret/containing/access-token"; + }; + }; +} +``` + +### Element Matrix Services (EMS) {#module-services-draupnir-setup-ems} + +If you are using a managed ["Element Matrix Services (EMS)"](https://ems.element.io/) +server, you will need to consent to the terms and conditions. Upon startup, an error +log entry with a URL to the consent page will be generated. diff --git a/nixos/modules/services/matrix/draupnir.nix b/nixos/modules/services/matrix/draupnir.nix new file mode 100644 index 000000000000..e4dfa5d2917b --- /dev/null +++ b/nixos/modules/services/matrix/draupnir.nix @@ -0,0 +1,257 @@ +{ + config, + options, + lib, + pkgs, + ... +}: + +let + cfg = config.services.draupnir; + opt = options.services.draupnir; + + format = pkgs.formats.yaml { }; + configFile = format.generate "draupnir.yaml" cfg.settings; + + inherit (lib) + literalExpression + mkEnableOption + mkOption + mkPackageOption + mkRemovedOptionModule + mkRenamedOptionModule + types + ; +in +{ + imports = [ + # Removed options for those migrating from the Mjolnir module + (mkRenamedOptionModule + [ "services" "draupnir" "dataPath" ] + [ "services" "draupnir" "settings" "dataPath" ] + ) + (mkRenamedOptionModule + [ "services" "draupnir" "homeserverUrl" ] + [ "services" "draupnir" "settings" "homeserverUrl" ] + ) + (mkRenamedOptionModule + [ "services" "draupnir" "managementRoom" ] + [ "services" "draupnir" "settings" "managementRoom" ] + ) + (mkRenamedOptionModule + [ "services" "draupnir" "accessTokenFile" ] + [ "services" "draupnir" "secrets" "accessToken" ] + ) + (mkRemovedOptionModule [ "services" "draupnir" "pantalaimon" ] '' + `services.draupnir.pantalaimon.*` has been removed because it depends on the deprecated and vulnerable + libolm library for end-to-end encryption and upstream support for Pantalaimon in Draupnir is limited. + See for details. + If you nontheless require E2EE via Pantalaimon, you can configure `services.pantalaimon-headless.instances` + yourself and use that with `services.draupnir.settings.pantalaimon` and `services.draupnir.secrets.pantalaimon.password`. + '') + ]; + + options.services.draupnir = { + enable = mkEnableOption "Draupnir, a moderations bot for Matrix"; + + package = mkPackageOption pkgs "draupnir" { }; + + settings = mkOption { + example = literalExpression '' + { + homeserverUrl = "https://matrix.org"; + managementRoom = "#moderators:example.org"; + + autojoinOnlyIfManager = true; + automaticallyRedactForReasons = [ "spam" "advertising" ]; + } + ''; + description = '' + Free-form settings written to Draupnir's configuration file. + See [Draupnir's default configuration](https://github.com/the-draupnir-project/Draupnir/blob/main/config/default.yaml) for available settings. + ''; + default = { }; + type = types.submodule { + freeformType = format.type; + options = { + homeserverUrl = mkOption { + type = types.str; + example = "https://matrix.org"; + description = '' + Base URL of the Matrix homeserver that provides the Client-Server API. + + ::: {.note} + When using Pantalaimon, set this to the Pantalaimon URL and + {option}`${opt.settings}.rawHomeserverUrl` to the public URL. + ::: + ''; + }; + + rawHomeserverUrl = mkOption { + type = types.str; + example = "https://matrix.org"; + default = cfg.settings.homeserverUrl; + defaultText = literalExpression "config.${opt.settings}.homeserverUrl"; + description = '' + Public base URL of the Matrix homeserver that provides the Client-Server API when using the Draupnir's + [Report forwarding feature](https://the-draupnir-project.github.io/draupnir-documentation/bot/homeserver-administration#report-forwarding). + + ::: {.warning} + When using Pantalaimon, do not set this to the Pantalaimon URL! + ::: + ''; + }; + + managementRoom = mkOption { + type = types.str; + example = "#moderators:example.org"; + description = '' + The room ID or alias where moderators can use the bot's functionality. + + The bot has no access controls, so anyone in this room can use the bot - secure this room! + Do not enable end-to-end encryption for this room, unless set up with Pantalaimon. + + ::: {.warning} + When using a room alias, make sure the alias used is on the local homeserver! + This prevents an issue where the control room becomes undefined when the alias can't be resolved. + ::: + ''; + }; + + dataPath = mkOption { + type = types.path; + readOnly = true; + default = "/var/lib/draupnir"; + description = '' + The path Draupnir will store its state/data in. + + ::: {.warning} + This option is read-only. + ::: + + ::: {.note} + If you want to customize where this data is stored, use a bind mount. + ::: + ''; + }; + }; + }; + }; + + secrets = { + accessToken = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing the access token for Draupnir's Matrix account + to be used in place of {option}`${opt.settings}.accessToken`. + ''; + }; + + pantalaimon.password = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing the password for Draupnir's Matrix account when used in + conjunction with Pantalaimon to be used in place of + {option}`${opt.settings}.pantalaimon.password`. + + ::: {.warning} + Take note that upstream has limited Pantalaimon and E2EE support: + and + . + ::: + ''; + }; + + web.synapseHTTPAntispam.authorization = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing the secret token when using the Synapse HTTP Antispam module + to be used in place of + {option}`${opt.settings}.web.synapseHTTPAntispam.authorization`. + + See for details. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + # Removed option for those migrating from the Mjolnir module - mkRemovedOption module does *not* work with submodules. + assertion = !(cfg.settings ? protectedRooms); + message = "Unset ${opt.settings}.protectedRooms, as it is unsupported on Draupnir. Add these rooms via `!draupnir rooms add` instead."; + } + ]; + + systemd.services.draupnir = { + description = "Draupnir - a moderation bot for Matrix"; + wants = [ + "network-online.target" + "matrix-synapse.service" + "conduit.service" + "dendrite.service" + ]; + after = [ + "network-online.target" + "matrix-synapse.service" + "conduit.service" + "dendrite.service" + ]; + wantedBy = [ "multi-user.target" ]; + + startLimitIntervalSec = 0; + serviceConfig = { + ExecStart = toString ( + [ + (lib.getExe cfg.package) + "--draupnir-config" + configFile + ] + ++ lib.optionals (cfg.secrets.accessToken != null) [ + "--access-token-path" + "%d/access_token" + ] + ++ lib.optionals (cfg.secrets.pantalaimon.password != null) [ + "--pantalaimon-password-path" + "%d/pantalaimon_password" + ] + ++ lib.optionals (cfg.secrets.web.synapseHTTPAntispam.authorization != null) [ + "--http-antispam-authorization-path" + "%d/http_antispam_authorization" + ] + ); + + WorkingDirectory = "/var/lib/draupnir"; + StateDirectory = "draupnir"; + StateDirectoryMode = "0700"; + ProtectHome = true; + PrivateDevices = true; + Restart = "on-failure"; + RestartSec = "5s"; + DynamicUser = true; + LoadCredential = + lib.optionals (cfg.secrets.accessToken != null) [ + "access_token:${cfg.secrets.accessToken}" + ] + ++ lib.optionals (cfg.secrets.pantalaimon.password != null) [ + "pantalaimon_password:${cfg.secrets.pantalaimon.password}" + ] + ++ lib.optionals (cfg.secrets.web.synapseHTTPAntispam.authorization != null) [ + "http_antispam_authorization:${cfg.secrets.web.synapseHTTPAntispam.authorization}" + ]; + }; + }; + }; + + meta = { + doc = ./draupnir.md; + maintainers = with lib.maintainers; [ + RorySys + emilylange + ]; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index c19fea0695ff..3000afe32253 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -409,6 +409,7 @@ in domination = runTest ./domination.nix; dovecot = handleTest ./dovecot.nix { }; drawterm = discoverTests (import ./drawterm.nix); + draupnir = runTest ./matrix/draupnir.nix; drbd = runTest ./drbd.nix; druid = handleTestOn [ "x86_64-linux" ] ./druid { }; drupal = runTest ./drupal.nix; diff --git a/nixos/tests/matrix/draupnir.nix b/nixos/tests/matrix/draupnir.nix new file mode 100644 index 000000000000..18dae8b2fffb --- /dev/null +++ b/nixos/tests/matrix/draupnir.nix @@ -0,0 +1,150 @@ +{ + lib, + ... +}: + +{ + name = "draupnir"; + meta.maintainers = with lib.maintainers; [ + RorySys + emilylange + ]; + + nodes = { + homeserver = + { pkgs, ... }: + { + services.matrix-synapse = { + enable = true; + log.root.level = "WARNING"; + settings = { + database.name = "sqlite3"; + registration_shared_secret = "supersecret-registration"; + + listeners = [ + { + bind_addresses = [ + "::" + ]; + port = 8008; + resources = [ + { + compress = true; + names = [ "client" ]; + } + { + compress = false; + names = [ "federation" ]; + } + ]; + tls = false; + type = "http"; + x_forwarded = false; + } + ]; + }; + }; + + specialisation.draupnir = { + inheritParentConfig = true; + + configuration.services.draupnir = { + enable = true; + settings = { + homeserverUrl = "http://localhost:8008"; + managementRoom = "#moderators:homeserver"; + }; + secrets = { + accessToken = "/tmp/draupnir-access-token"; + }; + }; + }; + + environment.systemPackages = with pkgs; [ + curl + jq + (writers.writePython3Bin "test_draupnir_in_matrix" + { + libraries = [ python3Packages.matrix-nio ]; + flakeIgnore = [ "E501" ]; + } + '' + import asyncio + from nio import AsyncClient, MatrixRoom, RoomMemberEvent, RoomMessageNotice + + + async def main() -> None: + client = AsyncClient("http://localhost:8008", "moderator") + + async def member_callback(room: MatrixRoom, event: RoomMemberEvent) -> None: + if event.membership == "join" and event.sender == "@draupnir:homeserver": + await client.room_send( + room_id=room.room_id, + message_type="m.room.message", + content={ + "msgtype": "m.text", + "body": "!draupnir status" + } + ) + + async def message_callback(room: MatrixRoom, event: RoomMessageNotice) -> None: + print(f"{event.sender}: {event.body}") + if event.sender == "@draupnir:homeserver": + await client.close() + exit(0) + + client.add_event_callback(member_callback, RoomMemberEvent) + client.add_event_callback(message_callback, RoomMessageNotice) + + print(await client.login("password")) + + room = await client.room_create( + name="Moderators", + alias="moderators", + invite=["@draupnir:homeserver"], + power_level_override={ + "users": { + "@draupnir:homeserver": 100, + "@moderator:homeserver": 100, + } + } + ) + print(room) + + print(await client.join(room.room_id)) + + await client.sync_forever(timeout=30000) + + + asyncio.run(main()) + '' + ) + ]; + }; + }; + + testScript = + { nodes, ... }: + '' + import json + + homeserver.wait_for_unit("matrix-synapse.service") + homeserver.wait_until_succeeds("curl --fail -L http://localhost:8008/") + + homeserver.succeed("matrix-synapse-register_new_matrix_user -u draupnir -p password --no-admin") + homeserver.succeed("matrix-synapse-register_new_matrix_user -u moderator -p password --no-admin") + + # get draupnir access token + payload = json.dumps({ "type": "m.login.password", "user": "draupnir", "password": "password" }) + homeserver.succeed( + f"curl --fail --json '{payload}' http://localhost:8008/_matrix/client/v3/login" + + " | jq -r .access_token" + + " | tee /tmp/draupnir-access-token" + ) + + homeserver.succeed("${nodes.homeserver.system.build.toplevel}/specialisation/draupnir/bin/switch-to-configuration test") + homeserver.wait_for_unit("draupnir.service") + + print(homeserver.succeed("test_draupnir_in_matrix >&2", timeout=60)) + ''; +} diff --git a/pkgs/by-name/dr/draupnir/package.nix b/pkgs/by-name/dr/draupnir/package.nix index 979e59b6f8bf..2b1bf4742def 100644 --- a/pkgs/by-name/dr/draupnir/package.nix +++ b/pkgs/by-name/dr/draupnir/package.nix @@ -12,6 +12,7 @@ fetchYarnDeps, stdenv, cctools, + nixosTests, }: # docs: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/javascript.section.md#yarn2nix-javascript-yarn2nix @@ -95,7 +96,10 @@ mkYarnPackage rec { distPhase = "true"; - passthru.updateScript = ./update.sh; + passthru = { + tests = { inherit (nixosTests) draupnir; }; + updateScript = ./update.sh; + }; meta = with lib; { description = "Moderation tool for Matrix"; diff --git a/pkgs/by-name/ex/exploitdb/package.nix b/pkgs/by-name/ex/exploitdb/package.nix index 67585f1d7c39..069a9f644a54 100644 --- a/pkgs/by-name/ex/exploitdb/package.nix +++ b/pkgs/by-name/ex/exploitdb/package.nix @@ -7,13 +7,13 @@ stdenv.mkDerivation rec { pname = "exploitdb"; - version = "2025-05-30"; + version = "2025-06-06"; src = fetchFromGitLab { owner = "exploit-database"; repo = "exploitdb"; rev = "refs/tags/${version}"; - hash = "sha256-X90stp4BiHOHoh030eqGeUGiWytF5ryY08/VYEsbnIw="; + hash = "sha256-DOzhxZZ66p49tECn0z1lGSNHq3GEpEbayhwsiJ6IGG4="; }; nativeBuildInputs = [ makeWrapper ]; diff --git a/pkgs/by-name/so/solarus-launcher/github-fetches.patch b/pkgs/by-name/so/solarus-launcher/github-fetches.patch new file mode 100644 index 000000000000..181acbd56123 --- /dev/null +++ b/pkgs/by-name/so/solarus-launcher/github-fetches.patch @@ -0,0 +1,34 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 80b9aab..e56ca84 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -88,8 +88,7 @@ include(FetchContent) + + # Qlementine Icons: an SVG icon library made for Qt. + FetchContent_Declare(qlementine-icons +- GIT_REPOSITORY "https://github.com/oclero/qlementine-icons.git" +- GIT_TAG v1.8.0 ++ SOURCE_DIR "@qlementine-icons-src@" + ) + FetchContent_MakeAvailable(qlementine-icons) + set_target_properties(qlementine-icons +@@ -99,8 +98,7 @@ set_target_properties(qlementine-icons + + # Qlementine: the QStyle library to have a modern look n' feel. + FetchContent_Declare(qlementine +- GIT_REPOSITORY "https://github.com/oclero/qlementine.git" +- GIT_TAG v1.2.0 ++ SOURCE_DIR "@qlementine-src@" + ) + FetchContent_MakeAvailable(qlementine) + set_target_properties(qlementine +@@ -109,8 +107,7 @@ set_target_properties(qlementine + ) + + FetchContent_Declare(QtAppInstanceManager +- GIT_REPOSITORY "https://github.com/oclero/qtappinstancemanager.git" +- GIT_TAG v1.3.0 ++ SOURCE_DIR "@qtappinstancemanager-src@" + ) + FetchContent_MakeAvailable(QtAppInstanceManager) + set_target_properties(QtAppInstanceManager diff --git a/pkgs/by-name/so/solarus-launcher/package.nix b/pkgs/by-name/so/solarus-launcher/package.nix new file mode 100644 index 000000000000..ce8cd109a307 --- /dev/null +++ b/pkgs/by-name/so/solarus-launcher/package.nix @@ -0,0 +1,109 @@ +{ + lib, + stdenv, + fetchFromGitLab, + fetchFromGitHub, + replaceVars, + cmake, + ninja, + luajit, + SDL2, + SDL2_image, + SDL2_ttf, + physfs, + openal, + libmodplug, + libvorbis, + solarus, + glm, + qt6Packages, + kdePackages, +}: + +let + qlementine-icons-src = fetchFromGitHub { + owner = "oclero"; + repo = "qlementine-icons"; + tag = "v1.8.0"; + hash = "sha256-FPndzMEOQvYNYUbT2V6iDlwoYqOww38GW/T3zUID3g0="; + }; + + qlementine-src = fetchFromGitHub { + owner = "oclero"; + repo = "qlementine"; + tag = "v1.2.1"; + hash = "sha256-CPQMmTXyUW+CyLjHYx+IdXY4I2mVPudOmAksjd+izPA="; + }; + + qtappinstancemanager-src = fetchFromGitHub { + owner = "oclero"; + repo = "qtappinstancemanager"; + tag = "v1.3.0"; + hash = "sha256-/zvNR/RHNV19ZI8d+58sotWxY16q2a7wWIBuKO52H5M="; + }; + + inherit (qt6Packages) + qtbase + qttools + wrapQtAppsHook + ; +in +stdenv.mkDerivation (finalAttrs: { + pname = "solarus-launcher"; + version = "2.0.0"; + + src = fetchFromGitLab { + owner = "solarus-games"; + repo = "solarus-launcher"; + tag = "v${finalAttrs.version}"; + hash = "sha256-zBJnHzYJyhfzP1m6TgMkDLRA3EXC1oG8PC0Jq/fC2+Q="; + }; + + patches = [ + (replaceVars ./github-fetches.patch { + inherit qlementine-src qlementine-icons-src qtappinstancemanager-src; + }) + ]; + + strictDeps = true; + nativeBuildInputs = [ + cmake + ninja + qttools + wrapQtAppsHook + ]; + + buildInputs = [ + luajit + SDL2 + SDL2_image + SDL2_ttf + physfs + openal + libmodplug + libvorbis + solarus + qtbase + kdePackages.qtsvg + glm + ]; + + meta = { + description = "Launcher for the Zelda-like ARPG game engine, Solarus"; + longDescription = '' + Solarus is a game engine for Zelda-like ARPG games written in lua. + Many full-fledged games have been writen for the engine. + Games can be created easily using the editor. + ''; + homepage = "https://www.solarus-games.org"; + mainProgram = "solarus-launcher"; + license = with lib.licenses; [ + # code + gpl3Plus + # assets + cc-by-sa-40 + ]; + maintainers = with lib.maintainers; [ marcin-serwin ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/pkgs/by-name/so/solarus-quest-editor/package.nix b/pkgs/by-name/so/solarus-quest-editor/package.nix new file mode 100644 index 000000000000..124e26d348f2 --- /dev/null +++ b/pkgs/by-name/so/solarus-quest-editor/package.nix @@ -0,0 +1,88 @@ +{ + lib, + stdenv, + fetchFromGitLab, + fetchFromGitHub, + replaceVars, + cmake, + ninja, + luajit, + SDL2, + SDL2_image, + SDL2_ttf, + physfs, + openal, + libmodplug, + libvorbis, + solarus, + glm, + qt6Packages, + kdePackages, +}: + +let + qlementine-src = fetchFromGitHub { + owner = "oclero"; + repo = "qlementine"; + tag = "v1.2.0"; + hash = "sha256-25PKOpQl3IkBXX14gt8KKYXXJKeutQ75O7BftEqCAxk="; + }; + + inherit (qt6Packages) + qtbase + qttools + wrapQtAppsHook + ; +in +stdenv.mkDerivation (finalAttrs: { + pname = "solarus-quest-editor"; + version = "2.0.0"; + + src = fetchFromGitLab { + owner = "solarus-games"; + repo = "solarus-quest-editor"; + tag = "v${finalAttrs.version}"; + hash = "sha256-GTslxValldReWGb3x67zRPrvQUuCO/HQSXOEQlJfAmw="; + }; + + patches = [ + (replaceVars ./qlementine-src.patch { inherit qlementine-src; }) + ]; + + strictDeps = true; + nativeBuildInputs = [ + cmake + ninja + qttools + wrapQtAppsHook + ]; + + buildInputs = [ + luajit + SDL2 + SDL2_image + SDL2_ttf + physfs + openal + libmodplug + libvorbis + solarus + qtbase + kdePackages.qtsvg + glm + ]; + + meta = { + description = "Editor for the Zelda-like ARPG game engine, Solarus"; + mainProgram = "solarus-editor"; + longDescription = '' + Solarus is a game engine for Zelda-like ARPG games written in lua. + Many full-fledged games have been writen for the engine. + Games can be created easily using the editor. + ''; + homepage = "https://www.solarus-games.org"; + license = lib.licenses.gpl3; + maintainers = with lib.maintainers; [ marcin-serwin ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/pkgs/by-name/so/solarus-quest-editor/qlementine-src.patch b/pkgs/by-name/so/solarus-quest-editor/qlementine-src.patch new file mode 100644 index 000000000000..a19cc2538f9d --- /dev/null +++ b/pkgs/by-name/so/solarus-quest-editor/qlementine-src.patch @@ -0,0 +1,13 @@ +diff --git a/cmake/AddDependencies.cmake b/cmake/AddDependencies.cmake +index 8272d14..054c079 100644 +--- a/cmake/AddDependencies.cmake ++++ b/cmake/AddDependencies.cmake +@@ -51,7 +51,6 @@ endif() + include(FetchContent) + FetchContent_Declare( + qlementine +- GIT_REPOSITORY https://github.com/oclero/qlementine.git +- GIT_TAG v1.2.0 ++ SOURCE_DIR "@qlementine-src@" + ) + FetchContent_MakeAvailable(qlementine) diff --git a/pkgs/by-name/so/solarus/package.nix b/pkgs/by-name/so/solarus/package.nix new file mode 100644 index 000000000000..34db918dc2d4 --- /dev/null +++ b/pkgs/by-name/so/solarus/package.nix @@ -0,0 +1,92 @@ +{ + lib, + stdenv, + fetchFromGitLab, + fetchpatch, + cmake, + ninja, + luajit, + SDL2, + SDL2_image, + SDL2_ttf, + physfs, + glm, + openal, + libmodplug, + libvorbis, + + # tests + solarus-quest-editor, + solarus-launcher, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "solarus"; + version = "2.0.0"; + + src = fetchFromGitLab { + owner = "solarus-games"; + repo = "solarus"; + tag = "v${finalAttrs.version}"; + hash = "sha256-Kfg4pFZrEhsIU4RQlOox3hMpk2PXbOzrkwDElPGnDjA="; + }; + + patches = [ + # https://gitlab.com/solarus-games/solarus/-/merge_requests/1570 + (fetchpatch { + url = "https://gitlab.com/solarus-games/solarus/-/commit/8e1eee51cbfa5acf2511b059739153065b0ba21d.patch"; + hash = "sha256-KevGavtUhpHRt85WLh9ApmZ8a+NeWB1zDDHKGT08yhQ="; + }) + ]; + + outputs = [ + "out" + "lib" + "dev" + ]; + + strictDeps = true; + nativeBuildInputs = [ + cmake + ninja + ]; + buildInputs = [ + luajit + SDL2 + SDL2_image + SDL2_ttf + physfs + openal + libmodplug + libvorbis + glm + ]; + + cmakeFlags = [ + (lib.cmakeFeature "CMAKE_CXX_FLAGS" "-DGLM_ENABLE_EXPERIMENTAL") + (lib.cmakeFeature "CMAKE_INSTALL_DATADIR" "${placeholder "lib"}/share") + ]; + + passthru.tests = { + inherit solarus-quest-editor solarus-launcher; + }; + + meta = { + description = "Zelda-like ARPG game engine"; + longDescription = '' + Solarus is a game engine for Zelda-like ARPG games written in lua. + Many full-fledged games have been writen for the engine. + ''; + homepage = "https://www.solarus-games.org"; + mainProgram = "solarus-run"; + license = with lib.licenses; [ + # code + gpl3Plus + # assets + cc-by-sa-30 + cc-by-sa-40 + ]; + maintainers = with lib.maintainers; [ marcin-serwin ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/pkgs/by-name/zi/zipline/package.nix b/pkgs/by-name/zi/zipline/package.nix index f31096bfe0a7..46186f60ea81 100644 --- a/pkgs/by-name/zi/zipline/package.nix +++ b/pkgs/by-name/zi/zipline/package.nix @@ -29,18 +29,18 @@ in stdenv.mkDerivation (finalAttrs: { pname = "zipline"; - version = "4.1.1"; + version = "4.1.2"; src = fetchFromGitHub { owner = "diced"; repo = "zipline"; tag = "v${finalAttrs.version}"; - hash = "sha256-5/qVczCypQ2HybpBzEJe9THsrT5Iu3md+IXffLJnVmQ="; + hash = "sha256-xxe64tGxZ2Udr+p21CKTZCHJ19ZOsdgPLlil+v+j5j4="; }; pnpmDeps = pnpm_10.fetchDeps { inherit (finalAttrs) pname version src; - hash = "sha256-zpNl6Ua4xRvBa62IHf+frnk4tWQHHF/HyEYGuUF2a78="; + hash = "sha256-O8RLaKff4Dj/JDeUOyf7GtcFcOu/aOuclyaZmVqVi5s="; }; buildInputs = [ vips ]; diff --git a/pkgs/development/compilers/llvm/common/llvm/default.nix b/pkgs/development/compilers/llvm/common/llvm/default.nix index 3e85b13e0c96..6051243f6668 100644 --- a/pkgs/development/compilers/llvm/common/llvm/default.nix +++ b/pkgs/development/compilers/llvm/common/llvm/default.nix @@ -294,7 +294,17 @@ stdenv.mkDerivation ( ++ lib.optional (lib.versionAtLeast release_version "15") # Just like the `llvm-lit-cfg` patch, but for `polly`. - (getVersionFile "llvm/polly-lit-cfg-add-libs-to-dylib-path.patch"); + (getVersionFile "llvm/polly-lit-cfg-add-libs-to-dylib-path.patch") + ++ + lib.optional (lib.versions.major release_version == "20") + # https://github.com/llvm/llvm-project/pull/139822 adds a commit which didn't get backported but is necessary for tests. + ( + fetchpatch { + url = "https://github.com/llvm/llvm-project/commit/ff2e8f93f6090965e82d799af43f6dfef52baa66.patch"; + stripLen = 1; + hash = "sha256-CZBTZKzi4cYkZhgTB5oXIo1UdEAArg9I4vR/m0upSRk="; + } + ); nativeBuildInputs = [ diff --git a/pkgs/development/compilers/llvm/default.nix b/pkgs/development/compilers/llvm/default.nix index 9fc862c71751..1762da6b16a8 100644 --- a/pkgs/development/compilers/llvm/default.nix +++ b/pkgs/development/compilers/llvm/default.nix @@ -31,7 +31,7 @@ let "17.0.6".officialRelease.sha256 = "sha256-8MEDLLhocshmxoEBRSKlJ/GzJ8nfuzQ8qn0X/vLA+ag="; "18.1.8".officialRelease.sha256 = "sha256-iiZKMRo/WxJaBXct9GdAcAT3cz9d9pnAcO1mmR6oPNE="; "19.1.7".officialRelease.sha256 = "sha256-cZAB5vZjeTsXt9QHbP5xluWNQnAHByHtHnAhVDV0E6I="; - "20.1.6".officialRelease.sha256 = "sha256-PfCzECiCM+k0hHqEUSr1TSpnII5nqIxg+Z8ICjmMj0Y="; + "20.1.5".officialRelease.sha256 = "sha256-WKfY+VvAsZEEc0xYgF6+MsXDXZz7haMU6bxqmUpaHuQ="; "21.0.0-git".gitRelease = { rev = "9e2684e4cfb0a7e30d5e49f812127d07cdda600d"; rev-version = "21.0.0-unstable-2025-06-06"; diff --git a/pkgs/development/tools/solarus-quest-editor/default.nix b/pkgs/development/tools/solarus-quest-editor/default.nix deleted file mode 100644 index 873314138265..000000000000 --- a/pkgs/development/tools/solarus-quest-editor/default.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ - lib, - mkDerivation, - fetchFromGitLab, - cmake, - luajit, - SDL2, - SDL2_image, - SDL2_ttf, - physfs, - fetchpatch, - openal, - libmodplug, - libvorbis, - solarus, - qtbase, - qttools, - glm, -}: - -mkDerivation rec { - pname = "solarus-quest-editor"; - version = "1.6.4"; - - src = fetchFromGitLab { - owner = "solarus-games"; - repo = pname; - rev = "v${version}"; - sha256 = "1qbc2j9kalk7xqk9j27s7wnm5zawiyjs47xqkqphw683idmzmjzn"; - }; - - patches = [ - (fetchpatch { - url = "https://gitlab.com/solarus-games/solarus-quest-editor/-/commit/81d5c7f1602cf355684d70a5e3449fefccfc44b8.patch"; - sha256 = "tVUxkkDp2PcOHGy4dGvUcYj9gF7k4LN21VuxohCw9NE="; - }) - ]; - - nativeBuildInputs = [ cmake ]; - - buildInputs = [ - luajit - SDL2 - SDL2_image - SDL2_ttf - physfs - openal - libmodplug - libvorbis - solarus - qtbase - qttools - glm - ]; - - meta = with lib; { - description = "Editor for the Zelda-like ARPG game engine, Solarus"; - mainProgram = "solarus-quest-editor"; - longDescription = '' - Solarus is a game engine for Zelda-like ARPG games written in lua. - Many full-fledged games have been writen for the engine. - Games can be created easily using the editor. - ''; - homepage = "https://www.solarus-games.org"; - license = licenses.gpl3; - maintainers = [ ]; - platforms = platforms.linux; - }; - -} diff --git a/pkgs/games/solarus/default.nix b/pkgs/games/solarus/default.nix deleted file mode 100644 index 90b988de4796..000000000000 --- a/pkgs/games/solarus/default.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - lib, - mkDerivation, - fetchFromGitLab, - cmake, - luajit, - SDL2, - SDL2_image, - SDL2_ttf, - physfs, - glm, - openal, - libmodplug, - libvorbis, - qtbase, - qttools, -}: - -mkDerivation rec { - pname = "solarus"; - version = "1.6.4"; - - src = fetchFromGitLab { - owner = "solarus-games"; - repo = pname; - rev = "v${version}"; - sha256 = "sbdlf+R9OskDQ5U5rqUX2gF8l/fj0sDJv6BL7H1I1Ng="; - }; - - outputs = [ - "out" - "lib" - "dev" - ]; - - nativeBuildInputs = [ - cmake - qttools - ]; - buildInputs = [ - luajit - SDL2 - SDL2_image - SDL2_ttf - physfs - openal - libmodplug - libvorbis - qtbase - glm - ]; - - cmakeFlags = [ - (lib.cmakeFeature "CMAKE_CXX_FLAGS" "-DGLM_ENABLE_EXPERIMENTAL") - ]; - - preFixup = '' - mkdir $lib/ - mv $out/lib $lib - ''; - - meta = with lib; { - description = "Zelda-like ARPG game engine"; - longDescription = '' - Solarus is a game engine for Zelda-like ARPG games written in lua. - Many full-fledged games have been writen for the engine. - ''; - homepage = "https://www.solarus-games.org"; - license = licenses.gpl3; - maintainers = [ ]; - platforms = platforms.linux; - }; - -} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 9193faed007b..30d59065e2ee 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -15229,10 +15229,6 @@ with pkgs; lua = lua5_1; }; - # solarus and solarus-quest-editor must use the same version of Qt. - solarus = libsForQt5.callPackage ../games/solarus { }; - solarus-quest-editor = libsForQt5.callPackage ../development/tools/solarus-quest-editor { }; - # You still can override by passing more arguments. spring = callPackage ../games/spring { asciidoc = asciidoc-full; };