diff --git a/flake.nix b/flake.nix index c9a5657..1556e14 100644 --- a/flake.nix +++ b/flake.nix @@ -51,9 +51,7 @@ package = name: path: let - pkg = (pkgs' pkgs).callPackage path { - original = pkgs.${name} or null; - }; + pkg = pkgs.lib.callPackageWith ((pkgs' pkgs) // { original = pkgs.${name} or null; }) path {}; patches = scan (name: type: if lib.strings.removeSuffix ".patch" name != name then name else null) ( name: path: path ) path; diff --git a/package/jellyfin/build-plugin.nix b/package/jellyfin/build-plugin.nix new file mode 100644 index 0000000..6e76c88 --- /dev/null +++ b/package/jellyfin/build-plugin.nix @@ -0,0 +1,110 @@ +let + capitalize = + upper: str: + let + length = builtins.stringLength str; + head = builtins.substring 0 1 str; + tail = builtins.substring 1 length str; + in "${upper head}${tail}"; + + buildJellyfinPlugin = { + lib, + name, + version, + + dotnetCorePackages, + buildDotnetModule, + fetchJellyfinPlugin, + jellyfin, + jprm, + unzip, + + ... + }@params: let + project = params.project or "Jellyfin.Plugin.${capitalize lib.strings.toUpper name}"; + src = params.src or (fetchJellyfinPlugin { name = name; tag = "v${builtins.head (builtins.splitVersion version)}"; hash = params.hash or ""; }); + + extraArgs = lib.attrsets.removeAttrs params (builtins.attrNames (lib.functionArgs buildJellyfinPlugin)); + + pluginLibraries = extraArgs.pluginLibraries or lib.attrsets.foldlAttrs ( + acc: name: value: + acc ++ lib.optional (value == "directory") name + ) [ ] (builtins.readDir "${src}/src"); + + args = { + pname = "jellyfin-plugin-${name}"; + version = version; + description = "${name} plugin for jellyfin"; + projectFile = "src/${project}/${project}.csproj"; + dotnet-sdk = dotnetCorePackages.sdk_9_0; + dotnet-runtime = jellyfin.dotnet-runtime; + dontDotnetBuild = true; + dontDontnetInstall = true; + } // extraArgs // { + inherit src; + meta = { inherit (jellyfin.meta) license homepage; + maintainer = [ "nonapode@fbs42.ddnss.de" ]; + } // (extraArgs.meta or {}); + + nativeBuildInputs = (extraArgs.nativeBuildInputs or []) ++ [ + jprm + unzip + ]; + outputs = (extraArgs.outputs or []) ++ [ "out" "zip" ]; + prePatch = '' + sed --sandbox --separate \ + -e 's:\(PackageReference Include="Jellyfin\..*" Version="\)[^"]\+":\1${jellyfin.version}":' \ + -e 's:<\(enerateDocumentationFile\|TreatWarningsAsErrors\)>true:<\1>false:' \ + -i ${ + lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") pluginLibraries) + } + + success=true + for x in ${ + lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") pluginLibraries) + } + do + diff -q $src/$x $x 2>/dev/null || continue + printf >&2 'no change: %s\n' $x + success=false + done + $success || exit 1 + '' + (extraArgs.prePatch or ""); + + postInstall = + let + dlls = builtins.map (name: "${name}.dll") pluginLibraries; + in + '' + tmp_output_dir="$(mktemp -d)" + jprm plugin build . --output="''${tmp_output_dir}" --version="${version}" --dotnet-configuration="''${dotnetBuildType-Release}" + mv "''${tmp_output_dir}/${name}_${version}.zip" $zip + mkdir -p $out + unzip $zip -d $out + + success=true + for file in $out/*; + do + case "''${file##*/}" in + meta.json) + ;; + ${builtins.concatStringsSep "|" (builtins.map lib.strings.escapeShellArg dlls)}) ;; + *) + printf 'unknown file: %s\n' ''${file@Q} + success=false + ;; + esac + done + + for file in meta.json ${lib.strings.escapeShellArgs dlls} + do + [[ -f "$out/$file" ]] && continue + printf 'missing file: %s\n' ''${file@Q} + success=false + done + + $success || exit 42 + ''; + }; + in buildDotnetModule args; +in buildJellyfinPlugin diff --git a/package/jellyfin/default.nix b/package/jellyfin/default.nix index 29532a8..af74e5c 100644 --- a/package/jellyfin/default.nix +++ b/package/jellyfin/default.nix @@ -1,18 +1,33 @@ { + pkgs, + lib, original, - callPackage, + fetchFromGitHub, + + gnused, + jprm, + unzip, + dotnetCorePackages, + buildDotnetModule, + ... }: let + context = pkgs // { + inherit callPackage fetchJellyfinPlugin buildJellyfinPlugin jellyfin; + }; + callPackage = lib.callPackageWith context; + + fetchJellyfinPlugin = callPackage ./fetch-plugin.nix; + buildJellyfinPlugin = callPackage ./build-plugin.nix; + jellyfin = original.overrideAttrs ( - final: prev: + final: { passthru ? {}, ... }@prev: assert !prev ? "plugin"; { - passthru.plugin = - base: - callPackage ./plugin.nix { - plugin = base; - jellyfin = jellyfin; - }; + passthru = passthru // { + plugin = + base: callPackage base; + }; } ); in diff --git a/package/jellyfin/fetch-plugin.nix b/package/jellyfin/fetch-plugin.nix new file mode 100644 index 0000000..23e87d3 --- /dev/null +++ b/package/jellyfin/fetch-plugin.nix @@ -0,0 +1,16 @@ +let + fetchJellyfinPlugin = { + lib, + fetchFromGitHub, + runCommandLocal, + ... + }@args: let + owner = args.owner or "jellyfin"; + repo = args.repo or "jellyfin-plugin-${args.name}"; + + extraArgs = lib.attrsets.removeAttrs args (builtins.attrNames (lib.functionArgs fetchJellyfinPlugin)); + git = fetchFromGitHub ({ + inherit owner repo; + } // extraArgs); + in git; +in fetchJellyfinPlugin diff --git a/package/jellyfin/plugin.nix b/package/jellyfin/plugin.nix index 2bc5f0c..4abf045 100644 --- a/package/jellyfin/plugin.nix +++ b/package/jellyfin/plugin.nix @@ -143,15 +143,18 @@ let ''; meta = meta jellyfin.meta // meta info; }; - info = helper // defaults // callPackage plugin ({ inherit info; } // args); + info = helper // defaults // { + inherit (callPackage plugin ({ inherit info; } // args)) + version hash rev; + }; in info.mkPlugin info (lib.attrsets.removeAttrs info info.ignore); functor = args: (drv args).overrideAttrs ( - final: prev: { - passthru = (prev.passthru or { }) // { + final: { passthru ? {}, ... }@prev: { + passthru = passthru // { in-version = { version, @@ -170,4 +173,5 @@ let } ); in -lib.trivial.mirrorFunctionArgs plugin functor +#lib.trivial.mirrorFunctionArgs plugin functor + drv diff --git a/package/jprm/default.nix b/package/jprm/default.nix index 49970c9..765a28c 100644 --- a/package/jprm/default.nix +++ b/package/jprm/default.nix @@ -2,7 +2,7 @@ let v."1.1.1" = "sha256-PWgZ9K81RX+AboU8/6IGEQ8Fv/e8d2I1KH3+jIQOyj4="; current = lib: - lib.lists.fold (acc: v: if lib.strings.versionOlder acc v then v else acc) "0.0.0" ( + lib.lists.foldl (acc: v: if lib.strings.versionOlder acc v then v else acc) "0.0.0" ( builtins.attrNames v ); in diff --git a/plugin/dlna/default.nix b/plugin/dlna/default.nix index 49e4842..afd626a 100644 --- a/plugin/dlna/default.nix +++ b/plugin/dlna/default.nix @@ -7,19 +7,26 @@ let hash = "sha256-pPhMmH17RKktIX16ozSxsigxo6tU8tlST4IAm3vpjrw="; rev = "v10"; }; - current = - lib: - lib.lists.fold (acc: v: if lib.strings.versionOlder acc v then v else acc) "0.0.0" ( - builtins.attrNames v - ); -in -{ - lib, - version ? current lib, - hash ? v.${version}.hash, - rev ? v.${version}.rev or "v${version}", - ... -}: -{ - inherit version hash rev; -} + + dlna = { + lib, + buildJellyfinPlugin, + fetchJellyfinPlugin, + ... + }@args: let + version = args.version or "10.0.0.0"; + hash = args.hash or v.${version}.hash or ""; + rev = args.rev or v.${version}.rev or "v${lib.versions.major version}"; + extra = lib.attrsets.removeAttrs args (builtins.attrNames (lib.functionArgs dlna)); + + plain = buildJellyfinPlugin { + name = "dlna"; + inherit version; + src = fetchJellyfinPlugin { + name = "dlna"; + inherit hash rev; + }; + nugetDeps = ./deps.json; + }; + in plain.override extra; +in dlna diff --git a/plugin/dlna/deps.json b/plugin/dlna/deps.json index e6de4d7..bd23349 100644 --- a/plugin/dlna/deps.json +++ b/plugin/dlna/deps.json @@ -1,8 +1,13 @@ [ + { + "pname": "BitFaster.Caching", + "version": "2.5.4", + "hash": "sha256-PWuVT1kKjL8ulMtv9hWmg0nMChFh8skr34xUl3mQ0Y8=" + }, { "pname": "Diacritics", - "version": "3.3.29", - "hash": "sha256-sIbdJ3yMthnmJHly3WheUdYjtwPakcczTJx9ycxtgrY=" + "version": "4.0.17", + "hash": "sha256-O1pOeOV7c+dfD/EjwiOmqYhP5RDZyosVOk0OjVuK5Eg=" }, { "pname": "ICU4N", @@ -21,33 +26,43 @@ }, { "pname": "Jellyfin.Common", - "version": "10.10.7", - "hash": "sha256-9EIigrDheob4vRP+UBAoIPHH4fyz6Cl27GUpelEGpBg=" + "version": "10.11.3", + "hash": "sha256-d0rIKccKSGqKUoXGT5N+/Wfq5M6eM06WQEzL6CA5eao=" }, { "pname": "Jellyfin.Controller", - "version": "10.10.7", - "hash": "sha256-/obWAuxWpSn+NlMES+fjyrf1g+qbxmSYQUBvgXQYltQ=" + "version": "10.11.3", + "hash": "sha256-Rudd5SwnQSwTkFATD7FCXIf3cdXmiHtQUXl8G+NW1k4=" }, { "pname": "Jellyfin.Data", - "version": "10.10.7", - "hash": "sha256-lRQjg/HkFAtCN0woL1gX6j5dMfVLP/fzQTKjFTcRth4=" + "version": "10.11.3", + "hash": "sha256-e0eWPDTh1zgitbeOmg/M1c/fYL5/OLKzAtQZg48IUYg=" + }, + { + "pname": "Jellyfin.Database.Implementations", + "version": "10.11.3", + "hash": "sha256-IP1jfyE/3Orzs1ZzIvv8V1qxfkfW9z7eRIZn5CE6WZQ=" }, { "pname": "Jellyfin.Extensions", - "version": "10.10.7", - "hash": "sha256-AOGJ2IoT2v+LnlEqnb2O4FnXapcQiH0V9ny8GUysNHg=" + "version": "10.11.3", + "hash": "sha256-dipmxz4qL4qo7i+ifrLBVMroUjzW5BkkGNrNwpDCVQw=" + }, + { + "pname": "Jellyfin.MediaEncoding.Keyframes", + "version": "10.11.3", + "hash": "sha256-w9BtlQMOeNKj7B+qFtn5oVzaGfRqsGNvISjF4cE4m8k=" }, { "pname": "Jellyfin.Model", - "version": "10.10.7", - "hash": "sha256-ubsClGTLq/aFnMiBCaHVUX2b88beuL07Yn5VXNbTCjQ=" + "version": "10.11.3", + "hash": "sha256-3+ScXU/pWj+Ru1b74v5aWlqg/+XSuKAmqeFbrVYrqRg=" }, { "pname": "Jellyfin.Naming", - "version": "10.10.7", - "hash": "sha256-/jlIS0X4FuBo6Ac1cjLGzgdJ3vR6VotBspxpNrqfMzo=" + "version": "10.11.3", + "hash": "sha256-oZ0qcARGOqAyvhdWMjdvuDVSuFYjyVd5TUpDdIMYRJs=" }, { "pname": "Microsoft.AspNetCore.Authorization", @@ -59,30 +74,60 @@ "version": "8.0.10", "hash": "sha256-SxnMOWJGgUUQyKaRezJQwMUt4eMfWjnhmfk8pldYGNA=" }, + { + "pname": "Microsoft.EntityFrameworkCore", + "version": "9.0.10", + "hash": "sha256-Zm4oMVeloK2WmPskzg4l3SXjJuC+sRg3O5aiTK5rHvw=" + }, + { + "pname": "Microsoft.EntityFrameworkCore.Abstractions", + "version": "9.0.10", + "hash": "sha256-FB+8WtFYKn1PH9R3pgKw7dNJiJDCcS78UkeRkxdOuCk=" + }, + { + "pname": "Microsoft.EntityFrameworkCore.Analyzers", + "version": "9.0.10", + "hash": "sha256-q6w0uQ4qMAe2EuA65a3rk18rhGXuGVYMrdrIzD5Z+tw=" + }, + { + "pname": "Microsoft.EntityFrameworkCore.Relational", + "version": "9.0.10", + "hash": "sha256-2XHQOKvs4mAXwl8vEZpdi6ZtDFhK2hPusRMFemu3Shw=" + }, { "pname": "Microsoft.Extensions.Caching.Abstractions", "version": "2.0.0", "hash": "sha256-Eg1MES40kzkGW9tZmjaKtbWI00Kbv7fLJQmjrigjxqk=" }, + { + "pname": "Microsoft.Extensions.Caching.Abstractions", + "version": "9.0.10", + "hash": "sha256-W/9WhAG5t/hWPZxIL5+ILMsPKO/DjprHRymZUmU5YOA=" + }, { "pname": "Microsoft.Extensions.Caching.Memory", "version": "2.0.0", "hash": "sha256-1fnNvp62KrviVwYlqVl1CbdaZVpCDah9eCZeNDGDbWM=" }, + { + "pname": "Microsoft.Extensions.Caching.Memory", + "version": "9.0.10", + "hash": "sha256-HIXNiUnBJaYN+QGzpTlHzkvkBwYmcU0QUlIgQDhVG5g=" + }, { "pname": "Microsoft.Extensions.Configuration.Abstractions", - "version": "8.0.0", - "hash": "sha256-4eBpDkf7MJozTZnOwQvwcfgRKQGcNXe0K/kF+h5Rl8o=" + "version": "9.0.10", + "hash": "sha256-sRv0yS2sbyli7eejtnpmd7UIAz4PwSt5/Po5Irc1j98=" }, { "pname": "Microsoft.Extensions.Configuration.Binder", - "version": "8.0.2", - "hash": "sha256-aGB0VuoC34YadAEqrwoaXLc5qla55pswDV2xLSmR7SE=" + "version": "9.0.10", + "hash": "sha256-4NEBx28byvjjIzo0wQPIUUymk9AzSgPS4fu5IRxkIt4=" }, { "pname": "Microsoft.Extensions.DependencyInjection", - "version": "8.0.1", - "hash": "sha256-O9g0jWS+jfGoT3yqKwZYJGL+jGSIeSbwmvomKDC3hTU=" + "version": "9.0.10", + "hash": "sha256-f3r2msA/oV9gGdFn9OEr5bPAfINR17P+sS6/2/NnCuk=" }, { "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", @@ -96,19 +141,24 @@ }, { "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", - "version": "8.0.2", - "hash": "sha256-UfLfEQAkXxDaVPC7foE/J3FVEXd31Pu6uQIhTic3JgY=" + "version": "9.0.10", + "hash": "sha256-5rwFXG+Wjbf+TkXeWrkGVKV4wfvOryTPadEkEyPyKj4=" }, { "pname": "Microsoft.Extensions.Logging", - "version": "8.0.1", - "hash": "sha256-vkfVw4tQEg86Xg18v6QO0Qb4Ysz0Njx57d1XcNuj6IU=" + "version": "9.0.10", + "hash": "sha256-/Et36NBhpMoxQzI+p/moW7knwYDfjI7Ma7DF7KIYn+Q=" }, { "pname": "Microsoft.Extensions.Logging.Abstractions", "version": "8.0.2", "hash": "sha256-cHpe8X2BgYa5DzulZfq24rg8O2K5Lmq2OiLhoyAVgJc=" }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "9.0.10", + "hash": "sha256-PtYXXHi+mbdQMh2QtA57NbWlt+JEpXiey36zLzbKTmo=" + }, { "pname": "Microsoft.Extensions.Options", "version": "2.0.0", @@ -119,6 +169,11 @@ "version": "8.0.2", "hash": "sha256-AjcldddddtN/9aH9pg7ClEZycWtFHLi9IPe1GGhNQys=" }, + { + "pname": "Microsoft.Extensions.Options", + "version": "9.0.10", + "hash": "sha256-QTNhi83xhjJuIQ/3QffzQs/KY7avNyBMvnkuuSr3pBo=" + }, { "pname": "Microsoft.Extensions.Primitives", "version": "2.0.0", @@ -129,6 +184,11 @@ "version": "8.0.0", "hash": "sha256-FU8qj3DR8bDdc1c+WeGZx/PCZeqqndweZM9epcpXjSo=" }, + { + "pname": "Microsoft.Extensions.Primitives", + "version": "9.0.10", + "hash": "sha256-It7NQ+Ap/hrqFX3LXDVJqVz1Xl3j8QIapYDcG2MQ/7w=" + }, { "pname": "Microsoft.NETCore.Platforms", "version": "1.1.0", @@ -139,6 +199,21 @@ "version": "1.1.0", "hash": "sha256-0AqQ2gMS8iNlYkrD+BxtIg7cXMnr9xZHtKAuN4bjfaQ=" }, + { + "pname": "NEbml", + "version": "1.1.0.5", + "hash": "sha256-MrQLekP6z5y6rfqnCbLefkYv4Fm8di4HqZ/AiYTzBQ4=" + }, + { + "pname": "Polly", + "version": "8.6.4", + "hash": "sha256-Z+ZbhnHWMu55qgQkxvw3yMiMd+zIMzzQiFhvn/PeQ3I=" + }, + { + "pname": "Polly.Core", + "version": "8.6.4", + "hash": "sha256-4Xrg/H481Y/WOHk1sGvFNEOfgaGrdKi+4U54PTXhh9I=" + }, { "pname": "runtime.any.System.Globalization", "version": "4.3.0", @@ -174,19 +249,14 @@ "version": "4.3.0", "hash": "sha256-51813WXpBIsuA6fUtE5XaRQjcWdQ2/lmEokJt97u0Rg=" }, - { - "pname": "System.Runtime.CompilerServices.Unsafe", - "version": "4.4.0", - "hash": "sha256-SeTI4+yVRO2SmAKgOrMni4070OD+Oo8L1YiEVeKDyig=" - }, { "pname": "System.Text.Json", - "version": "8.0.5", - "hash": "sha256-yKxo54w5odWT6nPruUVsaX53oPRe+gKzGvLnnxtwP68=" + "version": "9.0.10", + "hash": "sha256-wqeobpRw3PqOw21q8oGvauj5BkX1pS02Cm78E6c742w=" }, { "pname": "System.Threading.Tasks.Dataflow", - "version": "8.0.1", - "hash": "sha256-hgCfF91BDd/eOtLEd5jhjzgJdvwmVv4/b42fXRr3nvo=" + "version": "9.0.10", + "hash": "sha256-V3UjIEGn9Yrl/DQoKeEVg9pDpp4iNz8r9+WmQ09R1bg=" } ]