joplin-desktop: simplify plugin build

Fetching plugins as npm dependencies seems to be the default now, while
joplin-plugin-backup is an edge case (is patched and built from source).
This commit is contained in:
Lyn
2026-01-25 22:20:48 +01:00
parent 42ed8edc8f
commit fda07bac84
4 changed files with 42 additions and 88 deletions
@@ -2,36 +2,30 @@
lib,
stdenv,
fetchzip,
npm-lockfile-fix,
buildNpmPackage,
clang_20,
name,
url,
hash,
npmDepsHash,
patches ? [ ],
}:
let
releaseData = (lib.importJSON ./release-data.json).plugins."io.github.jackgruber.backup";
in
buildNpmPackage {
inherit name npmDepsHash patches;
name = "joplin-plugin-backup";
inherit (releaseData) npmDepsHash;
inherit patches;
src = fetchzip {
inherit url hash;
postFetch = ''
# Add missing integrity and resolved fields
${lib.getExe npm-lockfile-fix} $out/package-lock.json
'';
inherit (releaseData) url hash;
};
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isDarwin [
clang_20 # clang_21 breaks keytar
];
postPatch = ''
sed -i '/preinstall/d' package.json
'';
npmBuildScript = "dist";
installPhase = ''
+19 -35
View File
@@ -17,32 +17,15 @@
xcbuild,
buildPackages,
callPackage,
runCommand,
libGL,
clang_20,
jq,
}:
let
yarn-berry = yarn-berry_4;
releaseData = lib.importJSON ./release-data.json;
buildPlugin = import ./buildPlugin.nix;
getPluginPatch =
src: id:
runCommand "${id}.diff" { } ''
patch="${src}/packages/default-plugins/plugin-patches/${id}.diff"
if [ -f "$patch" ]; then
cp "$patch" "$out"
else
# create an empty patch file if it doesn't exist can't check this from Nix code without IFD
touch "$out"
fi
'';
getDefaultPlugins = map (callPackage buildPlugin);
in
stdenv.mkDerivation (finalAttrs: {
@@ -69,16 +52,14 @@ stdenv.mkDerivation (finalAttrs: {
hash = releaseData.deps_hash;
};
# allows overriding to disable building the plugins
defaultPlugins = getDefaultPlugins (
lib.mapAttrsToList (
id: plugin:
plugin
// {
patches = [ (getPluginPatch finalAttrs.src id) ];
}
) releaseData.plugins
);
# allows overriding to disable building these plugins or add other ones
defaultPlugins = [
(callPackage ./joplin-plugin-backup.nix {
patches = [
(finalAttrs.src + "/packages/default-plugins/plugin-patches/io.github.jackgruber.backup.diff")
];
})
];
buildInputs = [
libGL
@@ -95,6 +76,7 @@ stdenv.mkDerivation (finalAttrs: {
pixman
libsecret
makeWrapper
jq
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
xcbuild
@@ -119,24 +101,26 @@ stdenv.mkDerivation (finalAttrs: {
sed -i '/postinstall/d' package.json
# Don't install onenote-converter subpackage deps
sed -i '/onenote-converter/d' packages/{lib,app-desktop}/package.json
# Don't build the default plugins, would require networking. We build them separately.
sed -i "/'buildDefaultPlugins',/d" packages/app-desktop/gulpfile.ts
'';
buildPhase = ''
runHook preBuild
# fails otherwise because it tries to set up git hooks, not needed here
sed -i 's/"preinstall": ".*"/"preinstall": "echo skipped preinstall"/' packages/default-plugins/node_modules/joplin-plugin-freehand-drawing/package.json
unset YARN_ENABLE_SCRIPTS
for node_modules in packages/*/node_modules; do
patchShebangs $node_modules
done
unset YARN_ENABLE_SCRIPTS
yarn config set enableInlineBuilds true
# fails otherwise because it tries to set up git hooks, not needed here
sed -i 's/"preinstall": ".*"/"preinstall": "echo skipped preinstall"/' packages/default-plugins/node_modules/joplin-plugin-freehand-drawing/package.json
# Don't let joplin build plugins from source, would require networking. We build them separately.
pluginRepositories=packages/default-plugins/pluginRepositories.json
jq 'with_entries(select(.value | has("package")))' <<< "$(cat $pluginRepositories)" > $pluginRepositories
echo "installing yarn dependencies..."
yarn workspaces focus \
root \
@@ -5,14 +5,8 @@
"io.github.jackgruber.backup": {
"name": "joplin-plugin-backup",
"url": "https://github.com/JackGruber/joplin-plugin-backup/archive/2c3da7056e7ac39c86c2051a4fdb99d9534dd0a1.tar.gz",
"hash": "sha256-fivuaggp8WX9aEjt+ga4Pz/Tx+JHrQWla8Ef2rpoOzs=",
"npmDepsHash": "sha256-xpE3YJBZu+Uv17cNLYYxQOFiZVe1tqReGYJRSAG6rYk="
},
"io.github.personalizedrefrigerator.js-draw": {
"name": "joplin-plugin-freehand-drawing",
"url": "https://github.com/personalizedrefrigerator/joplin-plugin-freehand-drawing/archive/refs/tags/v4.2.0.tar.gz",
"hash": "sha256-PVpwcy0uDwmOsnzmeKfFNTniePddA2rrqfufaQEi/X4=",
"npmDepsHash": "sha256-B1deBNProLghMTjlV6AX258YQJyr1GIjlUO8f6h1nek="
"hash": "sha256-rPmBg/+mJH7Fp26gVzuSGFxi1Y4MtfRT+hqppk3tHdY=",
"npmDepsHash": "sha256-xZJ0Oir1A6sLe0ztIyBu39Yy3D6sNrVaciOYG0k85l0="
}
},
"deps_hash": "sha256-9xJmudcpUw1xmTvJD3TFrfzYEi+LupZGSzsA5zUOemI="
+12 -30
View File
@@ -7,7 +7,7 @@ import shutil
from pathlib import Path
from plumbum.cmd import nurl, nix_build, yarn, chmod, yarn_berry_fetcher, prefetch_npm_deps, diff, git
from plumbum.cmd import nurl, nix_build, yarn, chmod, yarn_berry_fetcher, prefetch_npm_deps, diff, git, nix
HERE = Path(__file__).parent
NIXPKGS_ROOT = git.with_cwd(HERE)["rev-parse", "--show-toplevel"]().strip()
@@ -70,44 +70,26 @@ default_plugins_dir = Path(src_dir).joinpath("packages/default-plugins")
with default_plugins_dir.joinpath("pluginRepositories.json").open() as fd:
plugin_repositories = json.load(fd)
with default_plugins_dir.joinpath("package.json").open() as fd:
plugins_packagejson = json.load(fd)
release["plugins"] = dict()
for key, value in plugin_repositories.items():
if "package" in value:
print("skipping npm-packaged plugin", key)
continue
print(key)
plugin = {
"name": "",
"url": "",
"hash": "",
"npmDepsHash": "",
"name": value["cloneUrl"].split("/")[-1].removesuffix(".git"),
"url": f"{value["cloneUrl"].removesuffix('.git')}/archive/{value["commit"]}.tar.gz",
}
plugin["name"] = value["cloneUrl"].split("/")[-1].removesuffix(".git")
fetched_src = json.loads(
nix["store", "prefetch-file", "--json", "--unpack", plugin["url"]]()
)
plugin["hash"] = fetched_src["hash"]
if "package" in value:
ref = "refs/tags/v" + plugins_packagejson["devDependencies"][value["package"]]
else:
ref = value["commit"]
plugin["url"] = f"{value["cloneUrl"].removesuffix('.git')}/archive/{ref}.tar.gz"
plugin_src = lambda plugin : f"((import {NIXPKGS_ROOT}/. {{}}).callPackage ./buildPlugin.nix {dict_to_argstr(plugin)}).src"
plugin["hash"] = nurl.with_cwd(HERE)[
"-e",
plugin_src(plugin)
]().strip()
print(plugin["hash"])
plugin_src = nix_build.with_cwd(HERE)[
"--no-out-link",
"-E",
plugin_src(plugin)
]().strip()
plugin["npmDepsHash"] = prefetch_npm_deps(Path(plugin_src).joinpath("package-lock.json")).strip()
plugin["npmDepsHash"] = prefetch_npm_deps(Path(fetched_src["storePath"]).joinpath("package-lock.json")).strip()
release["plugins"][key] = plugin