From c062264d744cdf38cdc932476d09d74751ed5e7e Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 16:56:49 +0000 Subject: [PATCH 1/6] jetbrains.plugins: fix darwin builds There were 2 issues for usage of `jetbrains.plugins.addPlugins` in darwin: - Some IDE products have spaces in name (e.g.: "IntelliJ IDEA CE"). The current code didn't escape or quoted the strings together, so it failed during build - After fixing the issue above, opening the resulting app bundle (e.g.: `open result/Applications/IntelliJ IDEA CE`) would result in an error because we modified the bundle but kept the old signature This commit fixes both those issues, the first one by quoting the IDE name using `lib.escapeShellArg` and the second one by using `darwin.autoSignDarwinBinariesHook`. --- .../editors/jetbrains/plugins/default.nix | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pkgs/applications/editors/jetbrains/plugins/default.nix b/pkgs/applications/editors/jetbrains/plugins/default.nix index 11997430f556..a432a4577521 100644 --- a/pkgs/applications/editors/jetbrains/plugins/default.nix +++ b/pkgs/applications/editors/jetbrains/plugins/default.nix @@ -5,6 +5,7 @@ , callPackage , autoPatchelfHook , glib +, darwin }: let @@ -86,18 +87,24 @@ in { 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; + 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 From 89d7d9b6dca4dc9cec101887ffef87a0a1dfce85 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 18:03:38 +0000 Subject: [PATCH 2/6] jetbrains.plugins: fix JAR plugins While #321247 technically "fixed" JAR plugins, it fixed by creating a broken symlink. The reason it wasn't causing issues before is because the derivation before set `donFixup = true`, skipping the checks for broken symlinks in the derivation. Now that the fixup phase is re-enabled, this is causing the build to fail if you have a JAR plugin like `wakatime`. Now the symbolic links are correct, but I am not sure if this is working correctly or not. --- .../editors/jetbrains/plugins/default.nix | 50 ++++++++++++------- .../editors/jetbrains/plugins/tests.nix | 6 ++- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/pkgs/applications/editors/jetbrains/plugins/default.nix b/pkgs/applications/editors/jetbrains/plugins/default.nix index a432a4577521..e1868da0efe6 100644 --- a/pkgs/applications/editors/jetbrains/plugins/default.nix +++ b/pkgs/applications/editors/jetbrains/plugins/default.nix @@ -110,26 +110,40 @@ 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}) - 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) + ( + IFS=' ' read -ra pluginArray <<< "$newPlugins" + shopt -s nullglob + for plugin in "''${pluginArray[@]}"; do + pluginfiles=($plugin) + if [[ ''${#pluginfiles[@]} -eq 1 ]] && [[ "$pluginfiles" == *.jar ]]; then + # if the plugin contains a single jar file, link it directly into the plugins folder + ln -s "$pluginfiles" $out/${rootDir}/plugins/ + else + # otherwise link the plugin directory itself + ln -s "$plugin" -t $out/${rootDir}/plugins/ + fi + done + ) + + substituteInPlace $(realpath "$out/bin/${meta.mainProgram}") \ + --replace-warn '${ide.outPath}' $out + IFS=' ' read -ra pluginArray <<< "$newPlugins" + for plugin in "''${pluginArray[@]}"; do + 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 + + remote_dev="$out/bin/${meta.mainProgram}-remote-dev-server" + if [[ -f "$remote_dev" ]]; then + substituteInPlace $(realpath "$remote_dev") \ + --replace-warn '${ide.outPath}' $out fi - '' + lib.optionalString stdenv.hostPlatform.isLinux '' autoPatchelf $out ''; diff --git a/pkgs/applications/editors/jetbrains/plugins/tests.nix b/pkgs/applications/editors/jetbrains/plugins/tests.nix index 2c9be7479368..975f12df8b9e 100644 --- a/pkgs/applications/editors/jetbrains/plugins/tests.nix +++ b/pkgs/applications/editors/jetbrains/plugins/tests.nix @@ -27,5 +27,9 @@ in writeText "jb-ides" paths; - clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ "ideavim" ]; + clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ + "ideavim" + # test JAR plugins + "wakatime" + ]; } From 7d049ce0d65d43f9e0aef6d97216931b992d37fd Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 21:43:13 +0000 Subject: [PATCH 3/6] jetbrains.plugins: clean-up --- .../editors/jetbrains/plugins/default.nix | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/pkgs/applications/editors/jetbrains/plugins/default.nix b/pkgs/applications/editors/jetbrains/plugins/default.nix index e1868da0efe6..af86b016b5a7 100644 --- a/pkgs/applications/editors/jetbrains/plugins/default.nix +++ b/pkgs/applications/editors/jetbrains/plugins/default.nix @@ -112,40 +112,25 @@ in { rm -f $out/${rootDir}/plugins/plugin-classpath.txt ( - IFS=' ' read -ra pluginArray <<< "$newPlugins" shopt -s nullglob + + IFS=' ' read -ra pluginArray <<< "$newPlugins" for plugin in "''${pluginArray[@]}"; do - pluginfiles=($plugin) - if [[ ''${#pluginfiles[@]} -eq 1 ]] && [[ "$pluginfiles" == *.jar ]]; then + if [[ "$plugin" == *.jar ]]; then # if the plugin contains a single jar file, link it directly into the plugins folder - ln -s "$pluginfiles" $out/${rootDir}/plugins/ + 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 ) - - substituteInPlace $(realpath "$out/bin/${meta.mainProgram}") \ - --replace-warn '${ide.outPath}' $out - IFS=' ' read -ra pluginArray <<< "$newPlugins" - for plugin in "''${pluginArray[@]}"; do - 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 - - remote_dev="$out/bin/${meta.mainProgram}-remote-dev-server" - if [[ -f "$remote_dev" ]]; then - substituteInPlace $(realpath "$remote_dev") \ - --replace-warn '${ide.outPath}' $out - fi - '' + lib.optionalString stdenv.hostPlatform.isLinux '' - autoPatchelf $out ''; }; } From 329b675005751a161a1fbac8694243e99e139be8 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 22:30:00 +0000 Subject: [PATCH 4/6] jetbrains.plugins: format with rfc style --- .../editors/jetbrains/plugins/default.nix | 159 +++++++++--------- .../editors/jetbrains/plugins/tests.nix | 10 +- 2 files changed, 89 insertions(+), 80 deletions(-) diff --git a/pkgs/applications/editors/jetbrains/plugins/default.nix b/pkgs/applications/editors/jetbrains/plugins/default.nix index af86b016b5a7..6a369768fd1d 100644 --- a/pkgs/applications/editors/jetbrains/plugins/default.nix +++ b/pkgs/applications/editors/jetbrains/plugins/default.nix @@ -1,17 +1,19 @@ -{ fetchurl -, fetchzip -, lib -, stdenv -, callPackage -, autoPatchelfHook -, glib -, darwin +{ + 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; @@ -23,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 @@ -47,40 +54,41 @@ 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"; @@ -102,35 +110,36 @@ in { inherit (ide) meta; buildPhase = - 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 + 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 - ( - shopt -s nullglob + ( + shopt -s nullglob - IFS=' ' read -ra pluginArray <<< "$newPlugins" - for plugin in "''${pluginArray[@]}"; do - 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 + 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 - ) - ''; + for exe in $out/bin/${meta.mainProgram}*; do + if [[ -x "$exe" ]]; then + substituteInPlace $(realpath "$exe") --replace-warn '${ide.outPath}' $out + fi + done + ) + ''; }; } diff --git a/pkgs/applications/editors/jetbrains/plugins/tests.nix b/pkgs/applications/editors/jetbrains/plugins/tests.nix index 975f12df8b9e..bd1ca3199138 100644 --- a/pkgs/applications/editors/jetbrains/plugins/tests.nix +++ b/pkgs/applications/editors/jetbrains/plugins/tests.nix @@ -27,9 +27,9 @@ in writeText "jb-ides" paths; - clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ - "ideavim" - # test JAR plugins - "wakatime" - ]; + clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ + "ideavim" + # test JAR plugins + "wakatime" + ]; } From 081d35d92bfeb1688faf29570f8b70e7be5d9f07 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 21:46:21 +0000 Subject: [PATCH 5/6] maintainers/team-list: add thiagokokada as Jetbrains maintainer --- maintainers/team-list.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/maintainers/team-list.nix b/maintainers/team-list.nix index 6fce487c6ed5..364ffc1f1e3c 100644 --- a/maintainers/team-list.nix +++ b/maintainers/team-list.nix @@ -569,6 +569,7 @@ with lib.maintainers; edwtjo leona theCapypara + thiagokokada ]; shortName = "Jetbrains"; scope = "Maintainers of the Jetbrains IDEs in nixpkgs"; From 9a39cbb755baaa0bbef91a0fc95f39d36d376df3 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Mon, 24 Feb 2025 22:47:36 +0000 Subject: [PATCH 6/6] jetbrains.plugins: change tests to run in idea-community So we can build it in OfBorg. --- pkgs/applications/editors/jetbrains/plugins/tests.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/applications/editors/jetbrains/plugins/tests.nix b/pkgs/applications/editors/jetbrains/plugins/tests.nix index bd1ca3199138..b80e190fc6d5 100644 --- a/pkgs/applications/editors/jetbrains/plugins/tests.nix +++ b/pkgs/applications/editors/jetbrains/plugins/tests.nix @@ -27,8 +27,9 @@ in writeText "jb-ides" paths; - clion-with-vim = jetbrains.plugins.addPlugins jetbrains.clion [ + idea-ce-with-plugins = jetbrains.plugins.addPlugins jetbrains.idea-community [ "ideavim" + "nixidea" # test JAR plugins "wakatime" ];