diff --git a/doc/release-notes/rl-2611.section.md b/doc/release-notes/rl-2611.section.md index 0de5d13ed18a..20e2411b4ffd 100644 --- a/doc/release-notes/rl-2611.section.md +++ b/doc/release-notes/rl-2611.section.md @@ -274,6 +274,10 @@ - `typescript` 7.0.2 now uses the Golang implementation. The [announcement document](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) has information on what was changed. +- `navidrome`'s plugin infrastructure has significantly changed. `buildNavidromePlugin` is renamed to `buildNavidromeGoPlugin` to allow for other language types. Plugins must now be sourced from `pkgsCross.wasi32.navidromePlugins.`. + +- `navidromePlugins.apple-music` now uses a `bundleName` attribute which sets the plugin's name to match the plugin's documentation for easier use. You will need to update your Agent from `apple-music-plugin` to `apple-music` as noted in [their docs](https://github.com/navidrome/apple-music-plugin#installation). + ### Deprecations {#sec-nixpkgs-release-26.11-lib-deprecations} - Setting `config.allowBrokenPredicate` is deprecated in favor of diff --git a/nixos/modules/services/audio/navidrome.nix b/nixos/modules/services/audio/navidrome.nix index a57fa2e159c6..3f184dc1dd82 100644 --- a/nixos/modules/services/audio/navidrome.nix +++ b/nixos/modules/services/audio/navidrome.nix @@ -45,7 +45,7 @@ in default = [ ]; description = "List of Navidrome plugins"; example = literalExpression '' - with pkgs.navidromePlugins; [ + with pkgs.pkgsCross.wasi32.navidromePlugins; [ listenbrainz-daily-playlist ]; ''; diff --git a/nixos/tests/navidrome.nix b/nixos/tests/navidrome.nix index 286fec66da2e..133ad83fa213 100644 --- a/nixos/tests/navidrome.nix +++ b/nixos/tests/navidrome.nix @@ -1,15 +1,21 @@ -{ pkgs, ... }: +{ ... }: { name = "navidrome"; nodes.machine = - { ... }: + { pkgs, ... }: { services.navidrome = { enable = true; - plugins = with pkgs.navidromePlugins; [ + plugins = with pkgs.pkgsCross.wasi32.navidromePlugins; [ listenbrainz-daily-playlist + # uses bundleName instead of pname + apple-music ]; + settings = { + # Disables all external network connections + EnableExternalServices = "false"; + }; }; }; diff --git a/pkgs/by-name/na/navidrome/package.nix b/pkgs/by-name/na/navidrome/package.nix index e8df91c2dd33..ce5653b2e7b1 100644 --- a/pkgs/by-name/na/navidrome/package.nix +++ b/pkgs/by-name/na/navidrome/package.nix @@ -82,7 +82,10 @@ buildGo127Module (finalAttrs: { postInstall = '' mkdir -p $out/share/plugins/ ${lib.concatMapStringsSep "\n" (plugin: '' - ln -s ${plugin}/share/${plugin.pname}.ndp $out/share/plugins/ + find ${plugin}/share/ \ + -type f \ + -name "*.ndp" \ + -exec ln -s {} $out/share/plugins/${plugin.bundleName or plugin.pname}.ndp \; '') plugins} ''; diff --git a/pkgs/by-name/na/navidrome/plugins/README.md b/pkgs/by-name/na/navidrome/plugins/README.md index a59ba3caa74a..9928ad3771d9 100644 --- a/pkgs/by-name/na/navidrome/plugins/README.md +++ b/pkgs/by-name/na/navidrome/plugins/README.md @@ -6,3 +6,21 @@ Each navidrome plugin is a `.zip` file named `${pname}.ndp`. Inside this zip is two files named exactly: - `manifest.json` which defines permissions and configuration - `plugin.wasm` which is the output of the plugin build + +## Builders + +The builders all currently have their platforms set to `wasi` and are +accessed/built through `pkgs.pkgsCross.wasi32.navidromePlugins.`. This is +the most efficient way to cross-compile the plugins under wasip1-wasm. + +### `bundleName` + +This property allows you to specify the name of the ndp file that is symlinked +within Navidrome. Navidrome keys off of the file name for plugins and the output +name may differ from the documentation, so we allow setting `bundleName` which +makes the documentation of a particular plugin easier to follow. + +### `buildNavidromeGoPlugin` + +This builder uses the standard `buildGoModule` under the hood (from within the +wasi arch's `callPackage`). diff --git a/pkgs/by-name/na/navidrome/plugins/apple-music/package.nix b/pkgs/by-name/na/navidrome/plugins/apple-music/package.nix index 0796270459da..0f0d1bab4efa 100644 --- a/pkgs/by-name/na/navidrome/plugins/apple-music/package.nix +++ b/pkgs/by-name/na/navidrome/plugins/apple-music/package.nix @@ -1,26 +1,28 @@ { lib, - pkgs, - buildNavidromePlugin, + fetchFromGitHub, + buildNavidromeGoPlugin, }: -buildNavidromePlugin rec { +buildNavidromeGoPlugin (finalAttrs: { pname = "apple-music-plugin"; + bundleName = "apple-music"; version = "0.2.0"; - src = pkgs.fetchFromGitHub { + src = fetchFromGitHub { owner = "navidrome"; repo = "apple-music-plugin"; - tag = "v${version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-45nUrIDXCtkh08TeZoc6j2BcGLQnpVJu23L56nIBN1s="; }; vendorHash = "sha256-G1B6W8ZKoLuNwvOt3z5vSKcQmF2574j41A0lC+u39uI="; meta = { + changelog = "https://github.com/navidrome/apple-music-plugin/releases/tag/v${finalAttrs.version}"; description = "Fetches artist metadata from Apple Music using free iTunes/Apple Music endpoints"; homepage = "https://github.com/navidrome/apple-music-plugin"; license = lib.licenses.gpl3Only; sourceProvenance = with lib.sourceTypes; [ fromSource ]; }; -} +}) diff --git a/pkgs/by-name/na/navidrome/plugins/audiomuseai/package.nix b/pkgs/by-name/na/navidrome/plugins/audiomuseai/package.nix index 31bf49bff008..0cfc6385ba3e 100644 --- a/pkgs/by-name/na/navidrome/plugins/audiomuseai/package.nix +++ b/pkgs/by-name/na/navidrome/plugins/audiomuseai/package.nix @@ -1,25 +1,26 @@ { lib, - pkgs, - buildNavidromePlugin, + fetchFromGitHub, + buildNavidromeGoPlugin, }: -buildNavidromePlugin rec { +buildNavidromeGoPlugin (finalAttrs: { pname = "audiomuseai"; version = "8"; - src = pkgs.fetchFromGitHub { + src = fetchFromGitHub { owner = "NeptuneHub"; repo = "AudioMuse-AI-NV-plugin"; - tag = "v${version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-WyobjyadD9IcY6mFYhCmuQgLbnoHpDoiLfINNfKmQM8="; }; vendorHash = "sha256-mXes+doBSa5kcfHp1cuzTz30wnyyPN7NLC0iOSL8FDo="; meta = { + changelog = "https://github.com/NeptuneHub/AudioMuse-AI-NV-plugin/releases/tag/v${finalAttrs.version}"; description = "Navidrome plugin that integrates core AudioMuse-AI features into the Navidrome frontend."; homepage = "https://github.com/NeptuneHub/AudioMuse-AI-NV-plugin"; license = lib.licenses.agpl3Only; sourceProvenance = with lib.sourceTypes; [ fromSource ]; }; -} +}) diff --git a/pkgs/by-name/na/navidrome/plugins/build-go-plugin.nix b/pkgs/by-name/na/navidrome/plugins/build-go-plugin.nix new file mode 100644 index 000000000000..641c54d23bdc --- /dev/null +++ b/pkgs/by-name/na/navidrome/plugins/build-go-plugin.nix @@ -0,0 +1,61 @@ +{ + buildGoModule, + lib, + navidrome, + navidromePluginInstallHook, + go, + gitMinimal, + cacert, +}: +lib.extendMkDerivation { + constructDrv = buildGoModule; + + excludeDrvArgNames = [ + "meta" + "passthru" + ]; + extendDrvArgs = + finalAttrs: + { + pname, + version, + src, + vendorHash, + meta, + passthru ? { }, + ... + }@args: + { + __structuredAttrs = true; + + nativeBuildInputs = [ + navidromePluginInstallHook + ]; + + ldflags = [ "-buildmode=c-shared" ]; + + overrideModAttrs = { + nativeBuildInputs = [ + go + gitMinimal + cacert + ]; + }; + + # Go plugins are built using go install which lands in $GOPATH/bin without + # .wasm extension + preInstall = '' + find "$GOPATH"/bin/ -type f -exec cp {} "./plugin.wasm" \; + ''; + + passthru = { + isNavidromePlugin = true; + } + // passthru; + + meta = meta // { + platforms = lib.platforms.wasi; + maintainers = navidrome.meta.maintainers ++ meta.maintainers or [ ]; + }; + }; +} diff --git a/pkgs/by-name/na/navidrome/plugins/build-plugin.nix b/pkgs/by-name/na/navidrome/plugins/build-plugin.nix deleted file mode 100644 index ae91384401c5..000000000000 --- a/pkgs/by-name/na/navidrome/plugins/build-plugin.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ - buildGoModule, - lib, - navidrome, - zip, -}: - -{ - pname, - src, - version, - vendorHash, - meta, - ... -}@args: - -buildGoModule ( - finalAttrs: - { - inherit - pname - version - src - vendorHash - ; - - env = { - CGO_ENABLED = "0"; - } - // (args.env or { }); - - postBuild = '' - GOOS=wasip1 \ - GOARCH=wasm \ - go build \ - -buildmode=c-shared \ - -o $GOPATH/bin/plugin.wasm . - ''; - - postInstall = '' - mkdir $out/share - pushd $(mktemp -d) - cp $GOPATH/bin/plugin.wasm . - cp ${finalAttrs.src}/manifest.json . - ${lib.getExe zip} \ - $out/share/${finalAttrs.pname}.ndp \ - plugin.wasm \ - manifest.json - popd - rm -r $out/bin - ''; - - passthru = { - isNavidromePlugin = true; - } - // args.passthru or { }; - - meta = { - inherit (navidrome.meta) platforms maintainers; - } - // args.meta or { }; - } - // removeAttrs args [ - "meta" - "passthru" - ] -) diff --git a/pkgs/by-name/na/navidrome/plugins/discord-rich-presence/package.nix b/pkgs/by-name/na/navidrome/plugins/discord-rich-presence/package.nix index 1aee85c00051..1b0ccf9b7547 100644 --- a/pkgs/by-name/na/navidrome/plugins/discord-rich-presence/package.nix +++ b/pkgs/by-name/na/navidrome/plugins/discord-rich-presence/package.nix @@ -1,25 +1,26 @@ { lib, - pkgs, - buildNavidromePlugin, + fetchFromGitHub, + buildNavidromeGoPlugin, }: -buildNavidromePlugin rec { +buildNavidromeGoPlugin (finalAttrs: { pname = "discord-rich-presence-plugin"; version = "2.0.0"; - src = pkgs.fetchFromGitHub { + src = fetchFromGitHub { owner = "navidrome"; repo = "discord-rich-presence-plugin"; - tag = "v${version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-j4iGymXH9JstPGdpPl5TFLiH8ShfE46U+BZk1n7a2yQ="; }; vendorHash = "sha256-5ZlqyUa+UcLCBdLQaYAlb818Y8sOENjIFfb2hpRsbpQ="; meta = { + changelog = "https://github.com/navidrome/discord-rich-presence-plugin/releases/tag/v${finalAttrs.version}"; description = "Displays your currently playing track in your Discord status"; homepage = "https://github.com/navidrome/discord-rich-presence-plugin"; license = lib.licenses.gpl3Only; sourceProvenance = with lib.sourceTypes; [ fromSource ]; }; -} +}) diff --git a/pkgs/by-name/na/navidrome/plugins/listenbrainz-daily-playlist/package.nix b/pkgs/by-name/na/navidrome/plugins/listenbrainz-daily-playlist/package.nix index 9023735ac6f3..4ccb07d0f8c9 100644 --- a/pkgs/by-name/na/navidrome/plugins/listenbrainz-daily-playlist/package.nix +++ b/pkgs/by-name/na/navidrome/plugins/listenbrainz-daily-playlist/package.nix @@ -1,25 +1,26 @@ { lib, pkgs, - buildNavidromePlugin, + buildNavidromeGoPlugin, }: -buildNavidromePlugin rec { +buildNavidromeGoPlugin (finalAttrs: { pname = "listenbrainz-daily-playlist"; version = "6.0.0"; src = pkgs.fetchFromGitHub { owner = "kgarner7"; repo = "navidrome-listenbrainz-daily-playlist"; - tag = "v${version}"; + tag = "v${finalAttrs.version}"; hash = "sha256-Pzn6KwYzaCNGRH93lR4wfVnTiFr2zo8J2DAAZd41oas="; }; vendorHash = "sha256-wvRQjLom1ZmDabsPwin5uiR8ggSDWBrEvaFljuUd/bo="; meta = { + changelog = "https://github.com/kgarner7/navidrome-listenbrainz-daily-playlist/releases/tag/v${finalAttrs.version}"; description = "fetch daily/weekly playlists from ListenBrainz"; homepage = "https://github.com/kgarner7/navidrome-listenbrainz-daily-playlist"; license = lib.licenses.mit; sourceProvenance = with lib.sourceTypes; [ fromSource ]; }; -} +}) diff --git a/pkgs/by-name/na/navidromePluginInstallHook/install-phase.sh b/pkgs/by-name/na/navidromePluginInstallHook/install-phase.sh new file mode 100644 index 000000000000..91cb9f2eb354 --- /dev/null +++ b/pkgs/by-name/na/navidromePluginInstallHook/install-phase.sh @@ -0,0 +1,27 @@ +# shellcheck shell=bash disable=SC2154,SC2164 + +naviPluginInstall() { + echo "Executing installPhase" + + runHook preInstall + + mkdir -p "$out"/share + buildDir="$(mktemp -d)" + + find . -type f -name "*.wasm" -exec cp {} "$buildDir/plugin.wasm" \; + + cp manifest.json "$buildDir" + + pushd "$buildDir" + + zip --must-match \ + "$out/share/$pname.ndp" \ + plugin.wasm \ + manifest.json + + popd + + runHook postInstall +} + +installPhase=naviPluginInstall diff --git a/pkgs/by-name/na/navidromePluginInstallHook/package.nix b/pkgs/by-name/na/navidromePluginInstallHook/package.nix new file mode 100644 index 000000000000..bef94fc95f69 --- /dev/null +++ b/pkgs/by-name/na/navidromePluginInstallHook/package.nix @@ -0,0 +1,11 @@ +{ + makeSetupHook, + zip, +}: +makeSetupHook { + name = "navidrome-plugin-install-hook"; + + propagatedBuildInputs = [ + zip + ]; +} ./install-phase.sh diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 16da8d14a411..adcd9e5a93a3 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2310,7 +2310,8 @@ with pkgs; nanoemoji = with python3Packages; toPythonApplication nanoemoji; - buildNavidromePlugin = callPackage ../by-name/na/navidrome/plugins/build-plugin.nix { }; + buildNavidromeGoPlugin = callPackage ../by-name/na/navidrome/plugins/build-go-plugin.nix { }; + navidromePlugins = recurseIntoAttrs ( lib.makeExtensible ( self: diff --git a/pkgs/top-level/release-cross.nix b/pkgs/top-level/release-cross.nix index 52b383d9a8ef..83545228065e 100644 --- a/pkgs/top-level/release-cross.nix +++ b/pkgs/top-level/release-cross.nix @@ -121,6 +121,9 @@ let gmp = nativePlatforms; boehmgc = nativePlatforms; hello = nativePlatforms; + navidromePlugins = + mapAttrs (_: _: nativePlatforms) + (pkgsForCross systems.examples.wasi32 (builtins.head supportedSystems)).navidromePlugins; tree-sitter.builtGrammars = mapAttrs (_: _: nativePlatforms) (pkgsForCross systems.examples.wasm32-wasip1 (builtins.head supportedSystems))