Skip to content

jetbrains: split IDEs into separate nix files & reimplement update scripts#475183

Merged
MattSturgeon merged 3 commits intoNixOS:masterfrom
theCapypara:jetbrains/auto-updates-v2
Jan 8, 2026
Merged

jetbrains: split IDEs into separate nix files & reimplement update scripts#475183
MattSturgeon merged 3 commits intoNixOS:masterfrom
theCapypara:jetbrains/auto-updates-v2

Conversation

@theCapypara
Copy link
Member

@theCapypara theCapypara commented Dec 30, 2025

This PR majorly changes how Jetbrains IDEs are organized, maintained and updated. To explain my rationale behind this, I'll go through the changes commit-by-commit. It is not possible to split this into multiple PRs (at least not without making IDEs un-updatable in the meantime).

This PRcontains no actual changes to the IDEs or even the core mechanics of the build scripts. It refactors almost all of it, without changing the actual contents of the built packages or the inner logic of the old updater scripts. So there are no rebuilds.

I also added the comments below to the commit descriptions.

jetbrains: split IDEs into separate nix files

This splits each IDE into its own .nix file and refactors all related build machinery to support this.

Motivations (in order of priority):

  • Fixing reviews for update PRs: Currently update PRs get no maintainers assigned, since the versions.json was changed. Due to the way CI works, packages outside of by-name only have their maintainers added to PRs if the file that contains the derivation (meta.position) is changed.
  • Reducing the size of default.nix and making the differences & patches required for each IDE more clear and with that also actually cutting the code into separately maintainable chunks
  • Overall improving readability and code structure

This commit was half-automatically generated by a script I wrote: https://gist.github.com/theCapypara/2939ff9f83a5f30f1d3dff74d725a9bf

Note that this commit itself does not cause any rebuilds. This is important. It is just a refactoring without any functional changes.

jetbrains: reduce some usage of overrideAttrs

ℹ️ Note: I removed this commit, see comments, it's here for reference: 9e82055

This further improves the previous commit to remove some usage of overrideAttrs by just adding post* and pre* attributes to mkJetBrainsProduct. This causes some rebuilds without any actual changes aside from store paths.

This is the only commit that should cause some rebuilds (only CLion, Goland, Rider, Rust Rover)

jetbrains: reimplement update scripts

This adds passthru.updateScript to the IDEs for automatic updates and rewrites all existing update scripts into one Python CLI app. This app is re-using most of the existing scripts in some way:

  • Most of bin/update_bin.py has been moved to updater/jetbrains_nix_updater/fetcher.py
  • Most of source/update.py has been moved to updater/jetbrains_nix_updater/update_src.py
  • source/build_maven.py has been moved almost as-is to updater/jetbrains_nix_updater/update_src_maven.py

Since we are now no longer using JSON files but Nix files directly, I opted to use a simple "marker" approach for replacing things like versions and URLs in the files. I didn't want to implement complicated regex patterns like the update-source-version script does, it seemed overkill and I wanted to keep things as simple as possible.

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. 11.by: package-maintainer This PR was created by a maintainer of all the package it changes. labels Dec 30, 2025
@theCapypara

This comment has been minimized.

@MattSturgeon
Copy link
Contributor

MattSturgeon commented Dec 30, 2025

I've not looked too closely, but it seems like most of the overrideAttrs removed by 9e82055 existed just to get access to finalAttrs and/or prevAttrs.

Would making mkJetbrainsProduct fix-point args compatible solve this more cleanly (e.g. using lib.extendMkDerivation)?

I'm also not convinced that refactor needs to be part of this PR. It'd be great if the restructure and update-script changes could be a zero-rebuild PR, either by postponing unrelated refactors or by doing them separately first if they truly are needed.

@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Dec 30, 2025
@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from 69e9f3c to bcec23b Compare December 30, 2025 23:58
@theCapypara
Copy link
Member Author

theCapypara commented Dec 30, 2025

Good point! I rebased and removed that commit for now, for reference it is backed up here: 9e82055

Edit: Rebuilds are now 0!

@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from bcec23b to cf555d4 Compare December 31, 2025 00:00
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. and removed 2.status: merge conflict This PR has merge conflicts with the target branch 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. 11.by: package-maintainer This PR was created by a maintainer of all the package it changes. labels Dec 31, 2025
@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from cf555d4 to 51e668f Compare December 31, 2025 10:51
Copy link
Contributor

@MattSturgeon MattSturgeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to review the update scripts in detail. I trust they are mostly copied as-is from the old location(s).

Comment on lines +40 to +52
inherit
pname
extraLdPath
jdk
src
version
buildNumber
wmClass
product
productShort
libdbm
fsnotifier
;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off-topic refactoring suggestion:

Instead of explicitly inheriting everything, use the @args and removeAttrs args excludeDrvArgNames // pattern. This will work well when migrating to lib.extendMkDerivation.

This will:

  1. preserve attr position information (inherit counts as defining a new attribute, // counts as re-using the original attribute)
  2. reframe the args from "explicit inclusion" to "explicit exclusion", which usually makes more sense; most things should be passed through implicitly to mkDerivation. The excludeDrvArgNames list highlights any that are not.

(same applies in the base builders)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll keep this and your other comments (notably this one) in mind and open a follow-up PR to optimize this further, including switching to lib.extendMkDerivation!

Comment on lines +35 to +37
# Common build overrides, fixes, etc.
# TODO: These should eventually be moved outside of this file
pyCharmCommonOverrides = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a pycharm-overrides.nix file with a:

TODO: integrate into pycharm.nix once pycharm-community.nix is dropped?

Or will it also apply to pycharm-oss.nix even then?

Either way, I agree it makes more sense for the pycharm package files to import this themselves from a shared location, rather than have it passed in via package args.

An alternative would be for pycharm to define passthru.common-overrides. The others can then access it as jetbrains.pycharm.common-overrides. Pros: you don't need a loose file, cons: you need to add an internal passthru attr.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! If it's okay I would still like to do this in a follow-up PR with the lib.extendMkDerivation switch.

# See https://www.jetbrains.com/help/pycharm/2022.1/cython-speedups.html
}
);
patchSharedLibs = lib.optionalString stdenv.hostPlatform.isLinux ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this could be packaged as a hook, jetbrains.patchSharedLibsHook. That way packages that use it could access it via callPackage args and its definition could be in a dedicated file.

Out of scope for this PR, I think.

meta = {
homepage = "https://www.jetbrains.com/pycharm/";
description = "Free Python IDE from JetBrains (built from source)";
longDescription = "Python IDE with complete set of tools for productive development with Python programming language. In addition, the IDE provides high-class capabilities for professional Web development with Django framework and Google App Engine. It has powerful coding assistance, navigation, a lot of refactoring features, tight integration with various Version Control Systems, Unit testing, powerful all-singing all-dancing Debugger and entire customization. PyCharm is developer driven IDE. It was developed with the aim of providing you almost everything you need for your comfortable and productive development!";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we are defining the longDescription manually in nix, it should follow standard one sentence per line formatting (using an indented string '').

Aside: was the longDescription auto-generated by the old update-script? If so, maybe that could be a TODO item for the new script.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it wasn't, it was created manually. Those could all use some clean-up in general.
However with multi-line strings this changes whitespaces and causes rebuilds, is it okay I do this in a follow-up PR, potentially together with the lib.extendMkDerivation related refactoring?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing in meta should cause rebuilds, with a few specific exceptions like meta.mainProgram when using versionCheckHook.

Copy link
Member Author

@theCapypara theCapypara Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately right now it does. I'll investigate why.

Edit: I'm pretty sure it's the desktop file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that makes sense.

IIUC, using meta.* attrs to construct desktop files (or other build outputs) is considered a bit of an anti-pattern.

It's not really this PRs job to clean that up, but we could:

  1. Add a NOTE to each meta block (kinda repetitive)

    NOTE: meta attrs are used by the desktop entry, so changing them may cause rebuilds.

  2. Fix the formatting and still avoid rebuilds by using lib.replaceString "\n" " " (and maybe lib.trim).

Ideally, this'd be a precursor commit "normalise newlines in desktop entry description", then the "split into separate files" commit comes after with correct formatting from the start.

I appreciate if you don't want to do this and would rather leave a FIXME, but it seems like such a small change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about this a bit, but I think it's better to do this afterwards. Even if this PR doesn't end up getting merged, I'd still try and keep this PR as minimal as possible with how much it already changes, so that we can focus on improvements separately.

Funnily enough, the lib.replaceString was already there: comment = lib.replaceStrings [ "\n" ] [ " " ] meta.longDescription;. Probably would need some extra trimming, but I haven't tried it.

I added a NOTE to each meta block for now and a FIXME to the linux.nix and README.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, addressing this separately is fine.

If it already has a replaceStrings the it's probably a trailing newline from the end of the indented string causing the rebuild, so a trim should solve this.

This splits each IDE into its own `.nix` file and refactors all related
build machinery to support this.

Motivations (in order of priority):

- Fixing reviews for update PRs: Currently update PRs get no maintainers
  assigned, since the `versions.json` was changed. Due to the way CI
works, packages outside of `by-name` only have their maintainers added
to PRs if the file that contains the derivation (`meta.position`) is
changed.
- Reducing the size of `default.nix` and making the differences &
  patches required for each IDE more clear and with that also actually
cutting the code into separately maintainable chunks
- Overall improving readability and code structure

This commit was half-automatically generated by a script I wrote:
https://gist.github.com/theCapypara/2939ff9f83a5f30f1d3dff74d725a9bf

**Note that this commit itself does not cause any rebuilds. This is
important. It is just a refactoring without any functional changes.**
@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from 51e668f to c53edcc Compare December 31, 2025 15:05
This adds `passthru.updateScript` to the IDEs for automatic updates and
rewrites all existing update scripts into one Python CLI app. This app
is re-using most of the existing scripts in some way:

- Most of `bin/update_bin.py` has been moved to
  `updater/jetbrains_nix_updater/fetcher.py`
- Most of `source/update.py` has been moved to
  `updater/jetbrains_nix_updater/update_src.py`
- `source/build_maven.py` has been moved almost as-is to
  `updater/jetbrains_nix_updater/update_src_maven.py`

Since we are now no longer using JSON files but Nix files directly, I
opted to use a simple "marker" approach for replacing things like
versions and URLs in the files. I didn't want to implement complicated
regex patterns like the `update-source-version` script does, it seemed
overkill and I wanted to keep things as simple as possible.

Co-Authored-By: Matt Sturgeon <matt@sturgeon.me.uk>
@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from c53edcc to 55ca18e Compare December 31, 2025 15:18
@theCapypara
Copy link
Member Author

I added some TODOs to the README that came from review for this PR.
After this PR is merged, or even if it isn't, I plan to go through them in order as separate follow-up PRs.

@theCapypara theCapypara force-pushed the jetbrains/auto-updates-v2 branch from e289a35 to bd6f98b Compare January 5, 2026 20:35
Copy link
Contributor

@MattSturgeon MattSturgeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clear structural improvement.

I'm very confident in the nix changes, especially due to zero rebuilds. I'm less confident reviewing the update scripts, but @theCapypara is probably one of the most familiar with the jetbrains update scripts, so I trust his judgement.

I'd ideally like to have ACK from some jetbrains maintainers, but if no one has any immediate feedback I plan to merge soon to unblock any planned followup work.

Comment on lines +3 to +4
# This actually just ignores a lot of options passed to it... (e.g. buildInputs)
# - not entirely sure how this hasn't caused big problems yet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this seems entirely broken. Maybe no one is using the Nixpkgs jetbrains packages on darwin?

Maybe the binary packages get away with missing buildInputs because the dependencies happen to be available impurely on the system?

I'm not really familiar with darwin so I'm just guessing.

Either way, using the }@args: mkDerivation (removeAttrs args excludeAttrs // { pattern,1 or switching to extendMkDerivation (which does that under the hood), will resolve this.

Footnotes

  1. As per https://github.com/NixOS/nixpkgs/pull/475183#discussion_r2655305961

};
aarch64-darwin = {
url = "https://download.jetbrains.com/aqua/aqua-2024.3.2-aarch64.dmg";
sha256 = "43974cdbbb71aaf5bfcfaf2cfd0e69e9920dda3973e64671936c1d52b267494d";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other files are using SRI hashes, but this still has base64 encoding. Did it get missed when tweaking the update script?

EDIT: ah, I see all these instances are in deprecated packages.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this, since I just updated the other packages to test my changes at the same time. I guess it doesn't really matter since we'll remove these anyway.

};
aarch64-darwin = {
url = "https://download.jetbrains.com/writerside/writerside-243.22562.371-aarch64.dmg";
sha256 = "9d86ef50b4c6d2a07d236219e9b05c0557241fb017d52ac395719bdb425130f5";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

};
aarch64-darwin = {
url = "https://download.jetbrains.com/idea/ideaIC-2025.2.5-aarch64.dmg";
sha256 = "52065492d433f0ea9df4debd5f0683154ab4dab5846394cabc8a49903d70e5bc";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same; maybe this is intentional as a deprecated package no longer being updated?

};
aarch64-darwin = {
url = "https://download.jetbrains.com/python/pycharm-community-2025.2.5-aarch64.dmg";
sha256 = "040a4ed6bb7563972d844c450f615d0d11385e524fbbfdbfc9fc68d78811e994";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same; also deprecated though

@nixpkgs-ci nixpkgs-ci bot added the 12.approvals: 1 This PR was reviewed and approved by one person. label Jan 6, 2026
@MattSturgeon
Copy link
Contributor

I'd ideally like to have ACK from some jetbrains maintainers, but if no one has any immediate feedback I plan to merge soon to unblock any planned followup work.

Merging

@MattSturgeon MattSturgeon added this pull request to the merge queue Jan 8, 2026
Merged via the queue into NixOS:master with commit 9fcdaa6 Jan 8, 2026
32 of 34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. 12.approvals: 1 This PR was reviewed and approved by one person.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants