jetbrains.*: move pkgs to by-name (#564934)

This commit is contained in:
Matt Sturgeon
2026-09-25 16:13:22 +02:00
committed by GitHub
27 changed files with 143 additions and 90 deletions

View File

@@ -136,6 +136,13 @@
Additionally, the kernel module tree used inside the VM has been split out of the `kernel` argument into a new `kernelModules` argument (defaulting to `kernel`).
Callers that overrode `kernel` with a module tree (e.g. from `pkgs.aggregateModules`) to make extra modules available must now pass it via `kernelModules` instead, keeping `kernel` pointing at a bootable kernel derivation.
- The JetBrains IDEs have all been moved to the top-level:
- `jetbrains.idea` and `jetbrains.idea-oss` have been renamed to `intellij-idea` and `intellij-idea-oss` respectively.
- `jetbrains.mps` has been renamed to `jetbrains-mps`.
- `jetbrains.gateway` has been renamed to `jetbrains-gateway`.
- All other IDEs have directly moved to the top-level with no prefix (e.g. `jetbrains.pycharm` -> `pycharm`).
- `jetbrains.plugins` remains unchanged for now.
- The ARMv5 Linux kernel build now uses a standard configuration and generates a standard compressed image instead of the deprecated legacy U‐Boot image format.
`lib.systems.{examples,platforms}.{sheevaplug,pogoplug4}` have been unified into `lib.systems.examples.armv5tel-multiplatform`.
Note that there is no official support for ARMv5 and it is not possible to build even a simple NixOS configuration out of the box.

View File

@@ -1,9 +1,25 @@
{
# keep-sorted start
callPackage,
clion,
config,
datagrip,
dataspell,
goland,
intellij-idea,
intellij-idea-oss,
jetbrains,
jetbrains-gateway,
jetbrains-mps,
lib,
phpstorm,
pycharm,
pycharm-oss,
rider,
ruby-mine,
rust-rover,
stdenv,
webstorm,
# keep-sorted end
vmopts ? null,
@@ -19,48 +35,40 @@
cythonDebugSpeedupsHook = callPackage ./hooks/cython-debug-speedups.nix { };
sharedLibsHook = callPackage ./hooks/shared-libs.nix { };
# Sorted alphabetically. Deprecated products and aliases are at the very end.
clion = callPackage ./ides/clion.nix { };
datagrip = callPackage ./ides/datagrip.nix { };
dataspell = callPackage ./ides/dataspell.nix { };
gateway = callPackage ./ides/gateway.nix { };
goland = callPackage ./ides/goland.nix { };
idea = callPackage ./ides/idea.nix { };
idea-oss = callPackage ./ides/idea-oss.nix { };
mps = callPackage ./ides/mps.nix { };
phpstorm = callPackage ./ides/phpstorm.nix { };
pycharm = callPackage ./ides/pycharm.nix { };
pycharm-oss = callPackage ./ides/pycharm-oss.nix { };
rider = callPackage ./ides/rider.nix { };
ruby-mine = callPackage ./ides/ruby-mine.nix { };
rust-rover = callPackage ./ides/rust-rover.nix { };
webstorm = callPackage ./ides/webstorm.nix { };
# Plugins
plugins = callPackage ./plugins { };
}
// lib.optionalAttrs config.allowAliases {
# These now all live in by-name.
# This is managed by the maintainers/scripts/remove-old-aliases.py script, please run it to update these,
# but make sure the warning/throw text says "'jetbrains.xyz' has been..." (add the jetbrains prefix).
# Also update the names in the old aliases at the bottom then!
clion = clion; # Added 2026-08-15
datagrip = datagrip; # Added 2026-08-15
dataspell = dataspell; # Added 2026-08-15
gateway = jetbrains-gateway; # Added 2026-08-15
goland = goland; # Added 2026-08-15
idea = intellij-idea; # Added 2026-08-15
idea-oss = intellij-idea-oss; # Added 2026-08-15
mps = jetbrains-mps; # Added 2026-08-15
phpstorm = phpstorm; # Added 2026-08-15
pycharm = pycharm; # Added 2026-08-15
pycharm-oss = pycharm-oss; # Added 2026-08-15
rider = rider; # Added 2026-08-15
ruby-mine = ruby-mine; # Added 2026-08-15
rust-rover = rust-rover; # Added 2026-08-15
webstorm = webstorm; # Added 2026-08-15
# Deprecated products and aliases.
aqua = throw "jetbrains.aqua: Aqua has been removed as it has been discontinued by JetBrains";
idea-community = throw "jetbrains.idea-community: IntelliJ IDEA Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.idea-oss' or 'jetbrains.idea'. See: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/";
idea-community-bin = throw "jetbrains.idea-community-bin: IntelliJ IDEA Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.idea-oss' or 'jetbrains.idea'. See: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/";
idea-community-src = throw "jetbrains.idea-community-src: IntelliJ IDEA Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.idea-oss' or 'jetbrains.idea'. See: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/";
idea-ultimate = throw "'jetbrains.idea-ultimate' has been renamed to/replaced by 'jetbrains.idea'";
pycharm-community = throw "jetbrains.pycharm-community: PyCharm Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.pycharm-oss' or 'jetbrains.pycharm'. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025";
pycharm-community-bin = throw "jetbrains.pycharm-community-bin: PyCharm Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.pycharm-oss' or 'jetbrains.pycharm'. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025";
pycharm-community-src = throw "jetbrains.pycharm-community-src: PyCharm Community has been removed as it has been discontinued by JetBrains. Either switch to 'jetbrains.pycharm-oss' or 'jetbrains.pycharm'. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025";
pycharm-professional = throw "'jetbrains.pycharm-professional' has been renamed to/replaced by 'jetbrains.pycharm'";
writerside = throw "jetbrains.writerside: Writerside has been removed as it has been discontinued by JetBrains";
}

View File

@@ -1,11 +1,26 @@
{
# keep-sorted start
clion,
datagrip,
dataspell,
fetchurl,
fetchzip,
goland,
intellij-idea,
intellij-idea-oss,
jetbrains,
jetbrains-gateway,
jetbrains-mps,
lib,
phpstorm,
pycharm,
pycharm-oss,
rider,
ruby-mine,
runCommand,
rust-rover,
symlinkJoin,
webstorm,
# keep-sorted end
# If not set, all IDEs are tested.
@@ -15,17 +30,16 @@
let
ides =
if ide == null then
with jetbrains;
[
# keep-sorted start
clion
datagrip
dataspell
gateway
goland
idea
idea-oss
mps
intellij-idea
intellij-idea-oss
jetbrains-gateway
jetbrains-mps
phpstorm
pycharm
pycharm-oss

View File

@@ -1,13 +1,35 @@
This directory contains the build expressions needed to build any of the JetBrains IDEs.
The jdk is in `pkgs/development/compilers/jetbrains-jdk`.
## IDE packages
The IDEs live in by-name/:
| IDE Name | Package Location |
|--------------------------------|-----------------------------------------------|
| Clion | pkgs/by-name/cl/clion/package.nix |
| DataGrip | pkgs/by-name/da/datagrip/package.nix |
| DataSpell | pkgs/by-name/da/dataspell/package.nix |
| Gateway | pkgs/by-name/je/jetbrains-gateway/package.nix |
| Goland | pkgs/by-name/go/goland/package.nix |
| IntelliJ IDEA | pkgs/by-name/in/intellij-idea/package.nix |
| IntelliJ IDEA (Open Source) | pkgs/by-name/in/intellij-idea-oss/package.nix |
| MPS | pkgs/by-name/je/jetbrains-mps/package.nix |
| PhpStorm | pkgs/by-name/ph/phpstorm/package.nix |
| PyCharm | pkgs/by-name/py/pycharm/package.nix |
| PyCharm (Open Source) | pkgs/by-name/py/pycharm-oss/package.nix |
| Rider | pkgs/by-name/ri/rider/package.nix |
| RubyMine | pkgs/by-name/ru/ruby-mine/package.nix |
| RustRover | pkgs/by-name/ru/rust-rover/package.nix |
| WebStorm | pkgs/by-name/we/webstorm/package.nix |
## Tests:
- To test the build process of every IDE (as well as the process for adding plugins), build `jetbrains.plugins.tests.empty`.
- To test that plugins are correctly stored in the plugins directory, build `jetbrains.plugins.tests.stored-correctly`.
## How to use plugins:
- Pass your IDE package and a list of plugin packages to `jetbrains.plugins.addPlugins`.
E.g. `pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea [ ideavim ]`
E.g. `pkgs.jetbrains.plugins.addPlugins pkgs.intellij-idea [ ideavim ]`
- The list has to contain drvs giving the directory contents of the plugin or a single `.jar` (executable).
Nixpkgs does not package JetBrains plugins, however you can use third-party sources, such as
@@ -51,9 +73,9 @@ To keep things simple, the update script will search for the following markers a
Any comments or other manual changes between these markers will be removed when the script runs.
## How to add an IDE:
- Add a new derivation in `ides/`
- Add a new derivation in `/pkgs/by-name/...`
- Add an entry to the URL templates in `updater/updateInfo.json`
- Add it to `default.nix`
- Add it to the table at the top ("IDE packages")
### TODO:
- get rid of remaining `overrideAttrs` in IDE drvs:

View File

@@ -24,6 +24,7 @@ class UpdaterConfig:
no_bin: bool
no_src: bool
no_maven_deps: bool
dry_run: bool
def __init__(self, argparse_result):
self.nixpkgs_root = (
@@ -47,3 +48,4 @@ class UpdaterConfig:
self.no_bin = argparse_result.no_bin
self.no_src = argparse_result.no_src
self.no_maven_deps = argparse_result.no_maven_deps
self.dry_run = argparse_result.dry_run

View File

@@ -22,43 +22,33 @@ class Ide:
update_info: UpdateInfo | None
def is_source_ide(drv_path: Path):
assert " " not in str(drv_path)
try:
return (
run_command(
[
"nix-instantiate",
"--eval",
"-E",
f'builtins.hasAttr "mkJetBrainsSource" (builtins.functionArgs (import {drv_path}))',
]
)
== "true"
)
except CalledProcessError as ex:
print(f"Failed to eval {drv_path}: {ex.stderr}", file=sys.stderr)
exit(1)
def by_name_path(ide_name: str, nixpkgs_root: Path) -> Path:
by_name_stem = ide_name[0:2]
return nixpkgs_root / "pkgs" / "by-name" / by_name_stem / ide_name
def get_single_ide(update_info: dict[str, UpdateInfo], jb_root: Path, name: str) -> Ide:
drv_path = jb_root / "ides" / f"{name}.nix"
def is_source_ide(ide_name: str):
return ide_name.endswith("-oss")
def get_single_ide(update_info: dict[str, UpdateInfo], nixpkgs_root: Path, name: str) -> Ide:
drv_path = by_name_path(name, nixpkgs_root) / "package.nix"
if not drv_path.exists():
raise Exception(f"IDE not found at {drv_path}")
return Ide(
name=name,
drv_path=drv_path,
is_source=is_source_ide(drv_path),
is_source=is_source_ide(name),
update_info=update_info.get(name),
)
def get_all_ides(update_info: dict[str, UpdateInfo], jb_root: Path) -> Iterable[Ide]:
for file in sorted((jb_root / "ides").iterdir()):
if file.suffix == ".nix":
yield Ide(
name=file.stem,
drv_path=file,
is_source=is_source_ide(file),
update_info=update_info.get(file.stem),
)
def get_all_ides(update_info: dict[str, UpdateInfo], nixpkgs_root: Path) -> Iterable[Ide]:
for name, update_info in update_info.items():
drv_path = by_name_path(name, nixpkgs_root) / "package.nix"
yield Ide(
name=name,
drv_path=drv_path,
is_source=is_source_ide(name),
update_info=update_info,
)

View File

@@ -1,3 +1,4 @@
import os.path
import sys
import json
@@ -8,7 +9,7 @@ from subprocess import CalledProcessError
from jetbrains_nix_updater.config import UpdaterConfig
from jetbrains_nix_updater.fetcher import VersionInfo
from jetbrains_nix_updater.ides import Ide
from jetbrains_nix_updater.ides import Ide, by_name_path
from jetbrains_nix_updater.update_src_maven import (
get_maven_deps_for_ide,
ensure_is_list,
@@ -148,10 +149,6 @@ def generate_jps_hash(config: UpdaterConfig, root_path: Path) -> str:
)
def maven_out_path(jb_root: Path, name: str) -> Path:
return jb_root / "source" / f"{name}_maven_artefacts.json"
def run_src_update(ide: Ide, info: VersionInfo, config: UpdaterConfig) -> bool:
variant = ide.name.removesuffix("-oss")
try:
@@ -194,7 +191,7 @@ def run_src_update(ide: Ide, info: VersionInfo, config: UpdaterConfig) -> bool:
androidHash = "{android_hash}";
jpsHash = "{jps_hash}";
restarterHash = "{restarter_hash}";
mvnDeps = ../source/{variant}_maven_artefacts.json;
mvnDeps = ./maven_artefacts.json;
repositories = [
{repositories_nix}
];
@@ -213,7 +210,12 @@ def run_src_update(ide: Ide, info: VersionInfo, config: UpdaterConfig) -> bool:
if not config.no_maven_deps:
print("[*] Collecting maven hashes")
maven_hashes = get_maven_deps_for_ide(config, ide)
with open(maven_out_path(config.jetbrains_root, variant), "w") as f:
json.dump(maven_hashes, f, indent=4)
f.write("\n")
maven_out_path = by_name_path(ide.name, config.nixpkgs_root) / "maven_artefacts.json"
if config.dry_run:
assert maven_out_path.parent.exists()
print(f"[D] --dry-run: {maven_out_path} not modified", file=sys.stderr)
else:
with open(maven_out_path, "w") as f:
json.dump(maven_hashes, f, indent=4)
f.write("\n")
return True

View File

@@ -1,3 +1,4 @@
import sys
from typing import Iterable
import subprocess
@@ -45,6 +46,10 @@ def replace_blocks(
with open(file, "r") as f:
lines = f.readlines()
if config.dry_run:
print(f"[D] --dry-run: {file} not modified", file=sys.stderr)
return
for name, block in blocks:
old_lines = lines
lines = []

View File

@@ -34,6 +34,9 @@ def main():
action="store_true",
help="do not update maven dependencies for source IDEs",
)
parser.add_argument(
"--dry-run", action="store_true", help="do not change any files"
)
parser.add_argument(
"--old-version",
type=str,
@@ -50,9 +53,9 @@ def main():
version_fetcher = VersionFetcher()
ides_to_run_for = (
[get_single_ide(update_info, config.jetbrains_root, config.ide)]
[get_single_ide(update_info, config.nixpkgs_root, config.ide)]
if config.ide is not None
else list(get_all_ides(update_info, config.jetbrains_root))
else list(get_all_ides(update_info, config.nixpkgs_root))
)
print(f"[.] found IDEs to update: {', '.join(ide.name for ide in ides_to_run_for)}")

View File

@@ -23,14 +23,6 @@
"aarch64-darwin": "https://download.jetbrains.com/python/dataspell-{version}-aarch64.dmg"
}
},
"gateway": {
"channel": "GW-RELEASE-licensing-RELEASE",
"urls": {
"x86_64-linux": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.tar.gz",
"aarch64-linux": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.tar.gz",
"aarch64-darwin": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.dmg"
}
},
"goland": {
"channel": "GO-RELEASE-licensing-RELEASE",
"urls": {
@@ -39,7 +31,7 @@
"aarch64-darwin": "https://download.jetbrains.com/go/goland-{version}-aarch64.dmg"
}
},
"idea": {
"intellij-idea": {
"channel": "IU-RELEASE-licensing-RELEASE",
"urls": {
"x86_64-linux": "https://download.jetbrains.com/idea/ideaIU-{version}.tar.gz",
@@ -47,11 +39,19 @@
"aarch64-darwin": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.dmg"
}
},
"idea-oss": {
"intellij-dea-oss": {
"channel": "IU-RELEASE-licensing-RELEASE",
"urls": {}
},
"mps": {
"jetbrains-gateway": {
"channel": "GW-RELEASE-licensing-RELEASE",
"urls": {
"x86_64-linux": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.tar.gz",
"aarch64-linux": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.tar.gz",
"aarch64-darwin": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.dmg"
}
},
"jetbrains-mps": {
"channel": "MPS-RELEASE-licensing-RELEASE",
"urls": {
"x86_64-linux": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}.tar.gz",

View File

@@ -18,7 +18,7 @@ let
androidHash = "sha256-uvoDTv/7RlyxRp1d9v2tN9IJkv9d1QEkZpp23hae84k=";
jpsHash = "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk=";
restarterHash = "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag=";
mvnDeps = ../source/idea_maven_artefacts.json;
mvnDeps = ./maven_artefacts.json;
repositories = [
"repo1.maven.org/maven2"
"packages.jetbrains.team/maven/p/ij/intellij-dependencies"
@@ -50,7 +50,7 @@ jetbrains.mkJetBrainsProduct {
# the jdk is bundled on Darwin.
jdk = if lib.meta.availableOn stdenv.hostPlatform jetbrains.jdk then jetbrains.jdk else null;
pname = "idea-oss";
pname = "intellij-idea-oss";
wmClass = "jetbrains-idea-ce";
product = "IntelliJ IDEA Open Source";

View File

@@ -34,7 +34,7 @@ in
jetbrains.mkJetBrainsProduct {
inherit jetbrains-libdbm fsnotifier;
pname = "idea";
pname = "intellij-idea";
wmClass = "jetbrains-idea";
product = "IntelliJ IDEA";

View File

@@ -17,7 +17,7 @@ let
androidHash = "sha256-FA/6ry1M7+RISJL+2SR9QkDvAGJAkXhFMh9YoOEU5nk=";
jpsHash = "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk=";
restarterHash = "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag=";
mvnDeps = ../source/pycharm_maven_artefacts.json;
mvnDeps = ./maven_artefacts.json;
repositories = [
"repo1.maven.org/maven2"
"packages.jetbrains.team/maven/p/ij/intellij-dependencies"