jetbrains.plugins: fix darwin builds (#384811)

This commit is contained in:
Thiago Kenji Okada
2025-02-25 22:09:56 +00:00
committed by GitHub
3 changed files with 99 additions and 78 deletions
+1
View File
@@ -568,6 +568,7 @@ with lib.maintainers;
edwtjo
leona
theCapypara
thiagokokada
];
shortName = "Jetbrains";
scope = "Maintainers of the Jetbrains IDEs in nixpkgs";
@@ -1,16 +1,19 @@
{ fetchurl
, fetchzip
, lib
, stdenv
, callPackage
, autoPatchelfHook
, glib
{
fetchurl,
fetchzip,
lib,
stdenv,
callPackage,
autoPatchelfHook,
glib,
darwin,
}:
let
pluginsJson = builtins.fromJSON (builtins.readFile ./plugins.json);
specialPluginsInfo = callPackage ./specialPlugins.nix { };
fetchPluginSrc = url: hash:
fetchPluginSrc =
url: hash:
let
isJar = lib.hasSuffix ".jar" url;
fetcher = if isJar then fetchurl else fetchzip;
@@ -22,21 +25,26 @@ let
files = builtins.mapAttrs (key: value: fetchPluginSrc key value) pluginsJson.files;
ids = builtins.attrNames pluginsJson.plugins;
mkPlugin = id: file:
if !specialPluginsInfo ? "${id}"
then files."${file}"
mkPlugin =
id: file:
if !specialPluginsInfo ? "${id}" then
files."${file}"
else
stdenv.mkDerivation ({
name = "jetbrains-plugin-${id}";
installPhase = ''
runHook preInstall
mkdir -p $out && cp -r . $out
runHook postInstall
'';
src = files."${file}";
} // specialPluginsInfo."${id}");
stdenv.mkDerivation (
{
name = "jetbrains-plugin-${id}";
installPhase = ''
runHook preInstall
mkdir -p $out && cp -r . $out
runHook postInstall
'';
src = files."${file}";
}
// specialPluginsInfo."${id}"
);
selectFile = id: ide: build:
selectFile =
id: ide: build:
if !builtins.elem ide pluginsJson.plugins."${id}".compatible then
throw "Plugin with id ${id} does not support IDE ${ide}"
else if !pluginsJson.plugins."${id}".builds ? "${build}" then
@@ -46,85 +54,92 @@ let
else
pluginsJson.plugins."${id}".builds."${build}";
byId = builtins.listToAttrs
(map
(id: {
name = id;
value = ide: build: mkPlugin id (selectFile id ide build);
})
ids);
byId = builtins.listToAttrs (
map (id: {
name = id;
value = ide: build: mkPlugin id (selectFile id ide build);
}) ids
);
byName = builtins.listToAttrs
(map
(id: {
name = pluginsJson.plugins."${id}".name;
value = byId."${id}";
})
ids);
in {
byName = builtins.listToAttrs (
map (id: {
name = pluginsJson.plugins."${id}".name;
value = byId."${id}";
}) ids
);
in
{
# Only use if you know what youre doing
raw = { inherit files byId byName; };
tests = callPackage ./tests.nix {};
tests = callPackage ./tests.nix { };
addPlugins = ide: unprocessedPlugins:
addPlugins =
ide: unprocessedPlugins:
let
processPlugin = plugin:
if lib.isDerivation plugin then plugin else
if byId ? "${plugin}" then byId."${plugin}" ide.pname ide.buildNumber else
if byName ? "${plugin}" then byName."${plugin}" ide.pname ide.buildNumber else
throw "Could not resolve plugin ${plugin}";
processPlugin =
plugin:
if lib.isDerivation plugin then
plugin
else if byId ? "${plugin}" then
byId."${plugin}" ide.pname ide.buildNumber
else if byName ? "${plugin}" then
byName."${plugin}" ide.pname ide.buildNumber
else
throw "Could not resolve plugin ${plugin}";
plugins = map processPlugin unprocessedPlugins;
in
stdenv.mkDerivation rec {
pname = meta.mainProgram + "-with-plugins";
version = ide.version;
src = ide;
dontInstall = true;
dontFixup = true;
dontStrip = true;
passthru.plugins = plugins ++ (ide.plugins or [ ]);
newPlugins = plugins;
disallowedReferences = [ ide ];
nativeBuildInputs = (lib.optional stdenv.hostPlatform.isLinux autoPatchelfHook) ++ (ide.nativeBuildInputs or [ ]);
nativeBuildInputs =
(lib.optional stdenv.hostPlatform.isLinux autoPatchelfHook)
# The buildPhase hook rewrites the binary, which invaliates the code
# signature. Add the fixup hook to sign the output.
++ (lib.optional stdenv.hostPlatform.isDarwin darwin.autoSignDarwinBinariesHook)
++ (ide.nativeBuildInputs or [ ]);
buildInputs = lib.unique ((ide.buildInputs or [ ]) ++ [ glib ]);
inherit (ide) meta;
buildPhase =
let
rootDir = if stdenv.hostPlatform.isDarwin then "Applications/${ide.product}.app/Contents" else meta.mainProgram;
in
''
cp -r ${ide} $out
chmod +w -R $out
rm -f $out/${rootDir}/plugins/plugin-classpath.txt
IFS=' ' read -ra pluginArray <<< "$newPlugins"
for plugin in "''${pluginArray[@]}"
do
pluginfiles=$(ls $plugin);
if [ $(echo $pluginfiles | wc -l) -eq 1 ] && echo $pluginfiles | grep -E "\.jar" 1> /dev/null; then
# if the plugin contains a single jar file, link it directly into the plugins folder
ln -s "$plugin/$(echo $pluginfiles | head -1)" $out/${rootDir}/plugins/
else
# otherwise link the plugin directory itself
ln -s "$plugin" -t $out/${rootDir}/plugins/
fi
done
sed "s|${ide.outPath}|$out|" \
-i $(realpath $out/bin/${meta.mainProgram})
let
appDir = lib.optionalString stdenv.hostPlatform.isDarwin "Applications/${lib.escapeShellArg ide.product}.app";
rootDir = if stdenv.hostPlatform.isDarwin then "${appDir}/Contents" else meta.mainProgram;
in
''
cp -r ${ide} $out
chmod +w -R $out
rm -f $out/${rootDir}/plugins/plugin-classpath.txt
if test -f "$out/bin/${meta.mainProgram}-remote-dev-server"; then
sed "s|${ide.outPath}|$out|" \
-i $(realpath $out/bin/${meta.mainProgram}-remote-dev-server)
fi
(
shopt -s nullglob
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
autoPatchelf $out
'';
IFS=' ' read -ra pluginArray <<< "$newPlugins"
for plugin in "''${pluginArray[@]}"; do
pluginfiles=($plugin)
if [[ "$plugin" == *.jar ]]; then
# if the plugin contains a single jar file, link it directly into the plugins folder
ln -s "$plugin" $out/${rootDir}/plugins/
else
# otherwise link the plugin directory itself
ln -s "$plugin" -t $out/${rootDir}/plugins/
fi
done
for exe in $out/bin/${meta.mainProgram}*; do
if [[ -x "$exe" ]]; then
substituteInPlace $(realpath "$exe") --replace-warn '${ide.outPath}' $out
fi
done
)
'';
};
}
@@ -27,5 +27,10 @@
in
writeText "jb-ides" paths;
clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ "ideavim" ];
idea-ce-with-plugins = jetbrains.plugins.addPlugins jetbrains.idea-community [
"ideavim"
"nixidea"
# test JAR plugins
"wakatime"
];
}