diff --git a/pkgs/applications/editors/jetbrains/bin/update_bin.py b/pkgs/applications/editors/jetbrains/bin/update_bin.py deleted file mode 100755 index 2c6fdfe29eac1..0000000000000 --- a/pkgs/applications/editors/jetbrains/bin/update_bin.py +++ /dev/null @@ -1,151 +0,0 @@ -#! /usr/bin/env nix-shell -#! nix-shell -i python3 -p python3 python3.pkgs.packaging python3.pkgs.requests python3.pkgs.xmltodict -import json -import pathlib -import logging -import requests -import subprocess -import sys -from urllib.error import HTTPError -import urllib.request -import xmltodict -from packaging import version - -updates_url = "https://www.jetbrains.com/updates/updates.xml" -current_path = pathlib.Path(__file__).parent -ides_file_path = current_path.joinpath("..").joinpath("ides.json").resolve() -versions_file_path = current_path.joinpath("versions.json").resolve() -fromVersions = {} -toVersions = {} - -logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) - - -def one_or_more(x): - return x if isinstance(x, list) else [x] - - -def download_channels(): - logging.info("Checking for updates from %s", updates_url) - updates_response = requests.get(updates_url) - updates_response.raise_for_status() - root = xmltodict.parse(updates_response.text) - products = root["products"]["product"] - return { - channel["@name"]: channel - for product in products - if "channel" in product - for channel in one_or_more(product["channel"]) - } - - -def build_version(build): - build_number = build["@fullNumber"] if "@fullNumber" in build else build["@number"] - return version.parse(build_number) - - -def latest_build(channel): - builds = one_or_more(channel["build"]) - latest = max(builds, key=build_version) - return latest - - -def download_sha256(url): - url = f"{url}.sha256" - download_response = requests.get(url) - download_response.raise_for_status() - return download_response.content.decode('UTF-8').split(' ')[0] - - -channels = download_channels() - - -def get_url(template, version_or_build_number, version_number): - release = [str(n) for n in version.parse(version_number).release] - for k in range(len(release), 0, -1): - s = ".".join(release[0:k]) - url = template.format(version=version_or_build_number, versionMajorMinor=s) - try: - if urllib.request.urlopen(url).getcode() == 200: - return url - except HTTPError: - pass - return None - - -def update_product(name, ide, version_info): - update_channel = ide["updateChannel"] - logging.info("Updating %s", name) - channel = channels.get(update_channel) - if channel is None: - logging.error("Failed to find channel %s.", update_channel) - logging.error("Check that the update-channel in %s matches the name in %s", versions_file_path, updates_url) - else: - try: - build = latest_build(channel) - new_version = build["@version"] - new_build_number = "" - if "@fullNumber" not in build: - new_build_number = build["@number"] - else: - new_build_number = build["@fullNumber"] - if "EAP" not in channel["@name"]: - version_or_build_number = new_version - else: - version_or_build_number = new_build_number - version_number = new_version.split(' ')[0] - download_url = get_url(version_info["url-template"], version_or_build_number, version_number) - if not download_url: - raise Exception(f"No valid url for {name} version {version_or_build_number}") - version_info["url"] = download_url - if "sha256" not in version_info or version_info.get("build_number") != new_build_number: - fromVersions[name] = version_info["version"] - toVersions[name] = new_version - logging.info("Found a newer version %s with build number %s.", new_version, new_build_number) - version_info["version"] = new_version - version_info["build_number"] = new_build_number - version_info["sha256"] = download_sha256(download_url) - else: - logging.info("Already at the latest version %s with build number %s.", new_version, new_build_number) - except Exception as e: - logging.exception("Update failed:", exc_info=e) - logging.warning("Skipping %s due to the above error.", name) - logging.warning("It may be out-of-date. Fix the error and rerun.") - - -def update_products(versioned_products, ides): - for name, version_info in versioned_products.items(): - update_product(name, ides[name], version_info) - - -with open(versions_file_path, "r") as versions_file: - versions = json.load(versions_file) - -with open(ides_file_path, "r") as ides_file: - ides = json.load(ides_file) - -for versioned_products in versions.values(): - update_products(versioned_products, ides) - -with open(versions_file_path, "w") as versions_file: - json.dump(versions, versions_file, indent=2) - versions_file.write("\n") - -if len(toVersions) == 0: - # No Updates found - sys.exit(0) - -if len(toVersions) == 1: - commitMessage = "" -else: - lowestVersion = min(fromVersions.values()) - highestVersion = max(toVersions.values()) - commitMessage = f"jetbrains: {lowestVersion} -> {highestVersion}" - commitMessage += "\n\n" - -for name in toVersions.keys(): - commitMessage += f"jetbrains.{name}: {fromVersions[name]} -> {toVersions[name]}\n" - -# Commit the result -logging.info("#### Committing changes... ####") -subprocess.run(['git', 'commit', f'-m{commitMessage}', '--', f'{versions_file_path}'], check=True) diff --git a/pkgs/applications/editors/jetbrains/bin/versions.json b/pkgs/applications/editors/jetbrains/bin/versions.json deleted file mode 100644 index f5998c0c1457e..0000000000000 --- a/pkgs/applications/editors/jetbrains/bin/versions.json +++ /dev/null @@ -1,490 +0,0 @@ -{ - "x86_64-linux": { - "aqua": { - "url-template": "https://download.jetbrains.com/aqua/aqua-{version}.tar.gz", - "version": "2024.3.2", - "sha256": "de073e8a3734a2c4ef984b3e1bd68f5de72a6180e73400889510439ac3f419aa", - "url": "https://download.jetbrains.com/aqua/aqua-2024.3.2.tar.gz", - "build_number": "243.23654.154" - }, - "clion": { - "url-template": "https://download.jetbrains.com/cpp/CLion-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "44ae3da5358ba010a62d55ab412b72f364c5dcd2c2dcd2004ae34b7463807bbd", - "url": "https://download.jetbrains.com/cpp/CLion-2025.3.1.tar.gz", - "build_number": "253.29346.141" - }, - "datagrip": { - "url-template": "https://download.jetbrains.com/datagrip/datagrip-{version}.tar.gz", - "version": "2025.3.2", - "sha256": "cb6ed6475d21eb8d30754131bd24003c114096bfa84ffccf334dc11cf8ac60cc", - "url": "https://download.jetbrains.com/datagrip/datagrip-2025.3.2.tar.gz", - "build_number": "253.29346.170" - }, - "dataspell": { - "url-template": "https://download.jetbrains.com/python/dataspell-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "37f13426ce4f5d859d7db246f2328ccbad61adf361d43c784cb6932af6644c28", - "url": "https://download.jetbrains.com/python/dataspell-2025.3.1.tar.gz", - "build_number": "253.29346.157" - }, - "gateway": { - "url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.tar.gz", - "version": "2025.3", - "sha256": "90c8a54f619245a5435c343f94f39595ab59cd3cbada569e2b1e28bcacdbcb4a", - "url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3.tar.gz", - "build_number": "253.28294.342" - }, - "goland": { - "url-template": "https://download.jetbrains.com/go/goland-{version}.tar.gz", - "version": "2025.3", - "sha256": "6151856286ea546eb8af9aeb025772cee6bd57134f45494a818e8da20a8691c6", - "url": "https://download.jetbrains.com/go/goland-2025.3.tar.gz", - "build_number": "253.28294.337" - }, - "idea-community": { - "url-template": "https://download.jetbrains.com/idea/ideaIC-{version}.tar.gz", - "version": "2025.2.5", - "sha256": "995c334cc3e143f13467abafef07a1ccf7d06275512bb6f4c91123948786ab7c", - "url": "https://download.jetbrains.com/idea/ideaIC-2025.2.5.tar.gz", - "build_number": "252.28238.7" - }, - "idea": { - "url-template": "https://download.jetbrains.com/idea/ideaIU-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "21e1b90b5ec684767a03498ba424ef3f9acc5dbf759cceefd5edd474f043ad6c", - "url": "https://download.jetbrains.com/idea/ideaIU-2025.3.1.tar.gz", - "build_number": "253.29346.138" - }, - "mps": { - "url-template": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}.tar.gz", - "version": "2025.3", - "sha256": "c4023e52b4e17824d61d2768238619be14e5ae5735db533e3951647f377b6b79", - "url": "https://download.jetbrains.com/mps/2025.3/MPS-2025.3.tar.gz", - "build_number": "253.28294.432" - }, - "phpstorm": { - "url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "fd8937ab6b79605cefc9917ffe6a08e05a6b7cc0256fa2178623d24ec322fa29", - "url": "https://download.jetbrains.com/webide/PhpStorm-2025.3.1.tar.gz", - "build_number": "253.29346.151", - "version-major-minor": "2022.3" - }, - "pycharm-community": { - "url-template": "https://download.jetbrains.com/python/pycharm-community-{version}.tar.gz", - "version": "2025.2.5", - "sha256": "7f49a014f53f0f6f7c46f6710b131f390302287f4046b606331d88081cdb551f", - "url": "https://download.jetbrains.com/python/pycharm-community-2025.2.5.tar.gz", - "build_number": "252.28238.29" - }, - "pycharm": { - "url-template": "https://download.jetbrains.com/python/pycharm-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "933fd42d7cc2a76ad4ba23f9112294e4df013fa4c3362435a1e3368051c07391", - "url": "https://download.jetbrains.com/python/pycharm-2025.3.1.tar.gz", - "build_number": "253.29346.142" - }, - "rider": { - "url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "ba840f7c48da7f118cf57aa8c22df30120d16f175fbce3bec6a65590ed87f2e8", - "url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1.tar.gz", - "build_number": "253.29346.144" - }, - "ruby-mine": { - "url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "e9eb2011ca2d5694c58c011690bf544d026e3a7c1c0c8de9bb37a18fa0cf8118", - "url": "https://download.jetbrains.com/ruby/RubyMine-2025.3.1.tar.gz", - "build_number": "253.29346.140" - }, - "rust-rover": { - "url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "5a1b34e10a1c59eee30694236baa8233c7787580769381be01b4ccb09618ec89", - "url": "https://download.jetbrains.com/rustrover/RustRover-2025.3.1.tar.gz", - "build_number": "253.29346.139" - }, - "webstorm": { - "url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}.tar.gz", - "version": "2025.3.1", - "sha256": "08a851d216b741c49ebb6846e178fb823d329fe7b9824a2134b68c8fd25ba2ae", - "url": "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1.tar.gz", - "build_number": "253.29346.143" - }, - "writerside": { - "url-template": "https://download.jetbrains.com/writerside/writerside-{version}.tar.gz", - "version": "2024.3 EAP", - "sha256": "d49e58020d51ec4ccdbdffea5d42b5a2d776a809fc00789cef5abda7b23bd3f6", - "url": "https://download.jetbrains.com/writerside/writerside-243.22562.371.tar.gz", - "build_number": "243.22562.371" - } - }, - "aarch64-linux": { - "aqua": { - "url-template": "https://download.jetbrains.com/aqua/aqua-{version}-aarch64.tar.gz", - "version": "2024.3.2", - "sha256": "d2a3c781756a83ccea63dc6d9aebf85f819de1edb5bcd4e5a1a161eaa0779c84", - "url": "https://download.jetbrains.com/aqua/aqua-2024.3.2-aarch64.tar.gz", - "build_number": "243.23654.154" - }, - "clion": { - "url-template": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "b96c38c3d2f7ff7b988d75c970fd0e90363e09b8273106defc9ae3defa868ed7", - "url": "https://download.jetbrains.com/cpp/CLion-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.141" - }, - "datagrip": { - "url-template": "https://download.jetbrains.com/datagrip/datagrip-{version}-aarch64.tar.gz", - "version": "2025.3.2", - "sha256": "1a6feb3aa255dace332cc18b868593181b6ea62c3d9f0d36f90032ca0517d068", - "url": "https://download.jetbrains.com/datagrip/datagrip-2025.3.2-aarch64.tar.gz", - "build_number": "253.29346.170" - }, - "dataspell": { - "url-template": "https://download.jetbrains.com/python/dataspell-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "40afd38cc704cdff2be89b9f0d67bdbcb1699d7b37b25d34d44d2d52ef6a46d3", - "url": "https://download.jetbrains.com/python/dataspell-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.157" - }, - "gateway": { - "url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.tar.gz", - "version": "2025.3", - "sha256": "204ed3f7262877d0a46aaf30c5bafb7216b4e9736bebee71425c993c18486af8", - "url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3-aarch64.tar.gz", - "build_number": "253.28294.342" - }, - "goland": { - "url-template": "https://download.jetbrains.com/go/goland-{version}-aarch64.tar.gz", - "version": "2025.3", - "sha256": "c530dd4bcc7a075a040b64859ecb34142c8fc0399625c5a13ae2d7a8f5974340", - "url": "https://download.jetbrains.com/go/goland-2025.3-aarch64.tar.gz", - "build_number": "253.28294.337" - }, - "idea-community": { - "url-template": "https://download.jetbrains.com/idea/ideaIC-{version}-aarch64.tar.gz", - "version": "2025.2.5", - "sha256": "4c57a783f31ee6f2c82d8c43bb5d0334a9afbc8bfb4542e732048c41f61e63a0", - "url": "https://download.jetbrains.com/idea/ideaIC-2025.2.5-aarch64.tar.gz", - "build_number": "252.28238.7" - }, - "idea": { - "url-template": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "095711329d1e9c14641ba426e652d4dbd3885b27c9a046e44725ae677491e8c3", - "url": "https://download.jetbrains.com/idea/ideaIU-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.138" - }, - "mps": { - "url-template": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}.tar.gz", - "version": "2025.3", - "sha256": "c4023e52b4e17824d61d2768238619be14e5ae5735db533e3951647f377b6b79", - "url": "https://download.jetbrains.com/mps/2025.3/MPS-2025.3.tar.gz", - "build_number": "253.28294.432" - }, - "phpstorm": { - "url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "7648667f85b4c45928b04d4c26f22882a8aa65a787a64fa2f7affe51a1bc2a61", - "url": "https://download.jetbrains.com/webide/PhpStorm-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.151", - "version-major-minor": "2022.3" - }, - "pycharm-community": { - "url-template": "https://download.jetbrains.com/python/pycharm-community-{version}-aarch64.tar.gz", - "version": "2025.2.5", - "sha256": "67b61a3e788b043d93b3cc3e0dd3cea350e6d170402fd94adaf792cfc57e5462", - "url": "https://download.jetbrains.com/python/pycharm-community-2025.2.5-aarch64.tar.gz", - "build_number": "252.28238.29" - }, - "pycharm": { - "url-template": "https://download.jetbrains.com/python/pycharm-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "2b6f5a430132773ea7caf3046f7763ea7a031dbfab6e1be72bdc86f3cc7a758b", - "url": "https://download.jetbrains.com/python/pycharm-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.142" - }, - "rider": { - "url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "19080fcdc48fa0f743ed60927b71975a3c478b805296161cfd8a0aa2c04c8f52", - "url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.144" - }, - "ruby-mine": { - "url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "bf603c6a1ba1e618afdb70589648447cfce53b4daa7a0cc68073c1b77e727d55", - "url": "https://download.jetbrains.com/ruby/RubyMine-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.140" - }, - "rust-rover": { - "url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "fb0f81c9d2a2a604718484954b261a642be9ed6f51de98fcdc6cedb32b0a4c9e", - "url": "https://download.jetbrains.com/rustrover/RustRover-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.139" - }, - "webstorm": { - "url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.tar.gz", - "version": "2025.3.1", - "sha256": "fd8bb3ee70c549165d9102437bca03e857fc147281c1d7382249d4690c31dd87", - "url": "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1-aarch64.tar.gz", - "build_number": "253.29346.143" - }, - "writerside": { - "url-template": "https://download.jetbrains.com/writerside/writerside-{version}-aarch64.tar.gz", - "version": "2024.3 EAP", - "sha256": "6067f6f73c4a178e2d0ae42bd18669045d85b5b5ed2c9115c2488ba7aa2a3d88", - "url": "https://download.jetbrains.com/writerside/writerside-243.22562.371-aarch64.tar.gz", - "build_number": "243.22562.371" - } - }, - "x86_64-darwin": { - "aqua": { - "url-template": "https://download.jetbrains.com/aqua/aqua-{version}.dmg", - "version": "2024.3.2", - "sha256": "423d492e9849beb7edbbd1771650a04e8df9f469bf1789b41bc5878c84cee393", - "url": "https://download.jetbrains.com/aqua/aqua-2024.3.2.dmg", - "build_number": "243.23654.154" - }, - "clion": { - "url-template": "https://download.jetbrains.com/cpp/CLion-{version}.dmg", - "version": "2025.3.1", - "sha256": "9a8174c9229f9c86f86da1a8e2bdab52ffb369ea0781b57eb245703ebc8307e2", - "url": "https://download.jetbrains.com/cpp/CLion-2025.3.1.dmg", - "build_number": "253.29346.141" - }, - "datagrip": { - "url-template": "https://download.jetbrains.com/datagrip/datagrip-{version}.dmg", - "version": "2025.3.2", - "sha256": "0383a0a4f2fde583b62ea7d342e5718b0fa306fc8349541c75bec5ae841fb4fc", - "url": "https://download.jetbrains.com/datagrip/datagrip-2025.3.2.dmg", - "build_number": "253.29346.170" - }, - "dataspell": { - "url-template": "https://download.jetbrains.com/python/dataspell-{version}.dmg", - "version": "2025.3.1", - "sha256": "388d956dd6243697a162c062c76b2fee4098f4f3405badb07a69ce6df7de6017", - "url": "https://download.jetbrains.com/python/dataspell-2025.3.1.dmg", - "build_number": "253.29346.157" - }, - "gateway": { - "url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.dmg", - "version": "2025.3", - "sha256": "282fd7f302d95adeed022f8d6c679d3292778f96205394af52dd090f6201f338", - "url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3.dmg", - "build_number": "253.28294.342" - }, - "goland": { - "url-template": "https://download.jetbrains.com/go/goland-{version}.dmg", - "version": "2025.3", - "sha256": "e1df4f10b158c7788736559666244e994500a40db5b08661e2691357d269dbf4", - "url": "https://download.jetbrains.com/go/goland-2025.3.dmg", - "build_number": "253.28294.337" - }, - "idea-community": { - "url-template": "https://download.jetbrains.com/idea/ideaIC-{version}.dmg", - "version": "2025.2.5", - "sha256": "ff48a1e60869342a91db867fa482a49d4cdf38476496911c109f34a7e8d6523d", - "url": "https://download.jetbrains.com/idea/ideaIC-2025.2.5.dmg", - "build_number": "252.28238.7" - }, - "idea": { - "url-template": "https://download.jetbrains.com/idea/ideaIU-{version}.dmg", - "version": "2025.3.1", - "sha256": "adf5af3839e07ba6387bf0eca94df2f44c829023a1898170eacbc5cbafce0393", - "url": "https://download.jetbrains.com/idea/ideaIU-2025.3.1.dmg", - "build_number": "253.29346.138" - }, - "mps": { - "url-template": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}-macos.dmg", - "version": "2025.3", - "sha256": "c216008ca905efd9ab9271df9599ef38ecb66cba2c61482e7a56434ae3eddee6", - "url": "https://download.jetbrains.com/mps/2025.3/MPS-2025.3-macos.dmg", - "build_number": "253.28294.432" - }, - "phpstorm": { - "url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}.dmg", - "version": "2025.3.1", - "sha256": "11988bcee5d94b271ea67aeacd3e836029595a6cfebfec2659565fc18a4ad2d1", - "url": "https://download.jetbrains.com/webide/PhpStorm-2025.3.1.dmg", - "build_number": "253.29346.151", - "version-major-minor": "2022.3" - }, - "pycharm-community": { - "url-template": "https://download.jetbrains.com/python/pycharm-community-{version}.dmg", - "version": "2025.2.5", - "sha256": "08ba97a278031ff1942ddefb18d8acf7582f0bb4a28ccdf5d65721bfb80ca456", - "url": "https://download.jetbrains.com/python/pycharm-community-2025.2.5.dmg", - "build_number": "252.28238.29" - }, - "pycharm": { - "url-template": "https://download.jetbrains.com/python/pycharm-{version}.dmg", - "version": "2025.3.1", - "sha256": "586c9eed67da609fc1e565a8bfc36eb155b23e5483d5dc6e9dcf8b5540f47fa5", - "url": "https://download.jetbrains.com/python/pycharm-2025.3.1.dmg", - "build_number": "253.29346.142" - }, - "rider": { - "url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.dmg", - "version": "2025.3.1", - "sha256": "addd816dbdf130e2ef5e7dc184d7a8087f8bfbf6eba4e32ead2452069a49607d", - "url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1.dmg", - "build_number": "253.29346.144" - }, - "ruby-mine": { - "url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}.dmg", - "version": "2025.3.1", - "sha256": "4fce84983a6ace16d8479150b765280250a260b3d24fb37258d114000c6c1115", - "url": "https://download.jetbrains.com/ruby/RubyMine-2025.3.1.dmg", - "build_number": "253.29346.140" - }, - "rust-rover": { - "url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}.dmg", - "version": "2025.3.1", - "sha256": "3899875452a5182db93b132c00dbc84394ffb637430b97f2390be8abb0412537", - "url": "https://download.jetbrains.com/rustrover/RustRover-2025.3.1.dmg", - "build_number": "253.29346.139" - }, - "webstorm": { - "url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}.dmg", - "version": "2025.3.1", - "sha256": "a6cb906562f95b37e9c1e34c9bd9561dea653a726c95d02bfa957acbe909b88d", - "url": "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1.dmg", - "build_number": "253.29346.143" - }, - "writerside": { - "url-template": "https://download.jetbrains.com/writerside/writerside-{version}.dmg", - "version": "2024.3 EAP", - "sha256": "0c78b8035497c855aea5666256716778abd46dadf68f51e4f91c0db01f62b280", - "url": "https://download.jetbrains.com/writerside/writerside-243.22562.371.dmg", - "build_number": "243.22562.371" - } - }, - "aarch64-darwin": { - "aqua": { - "url-template": "https://download.jetbrains.com/aqua/aqua-{version}-aarch64.dmg", - "version": "2024.3.2", - "sha256": "43974cdbbb71aaf5bfcfaf2cfd0e69e9920dda3973e64671936c1d52b267494d", - "url": "https://download.jetbrains.com/aqua/aqua-2024.3.2-aarch64.dmg", - "build_number": "243.23654.154" - }, - "clion": { - "url-template": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "11cae8aeb43d1870d96980f1d927ff545fabed989f3bf4e7327911b441e149f1", - "url": "https://download.jetbrains.com/cpp/CLion-2025.3.1-aarch64.dmg", - "build_number": "253.29346.141" - }, - "datagrip": { - "url-template": "https://download.jetbrains.com/datagrip/datagrip-{version}-aarch64.dmg", - "version": "2025.3.2", - "sha256": "a7224548dc9da3863727b0c11cef9d613fd951d16baa016ca1407c56a9ec6964", - "url": "https://download.jetbrains.com/datagrip/datagrip-2025.3.2-aarch64.dmg", - "build_number": "253.29346.170" - }, - "dataspell": { - "url-template": "https://download.jetbrains.com/python/dataspell-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "fe0d8ef15e6e36af0ea4361bd474f204ee5c307ef90af8ec833976a1dae5a5a3", - "url": "https://download.jetbrains.com/python/dataspell-2025.3.1-aarch64.dmg", - "build_number": "253.29346.157" - }, - "gateway": { - "url-template": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.dmg", - "version": "2025.3", - "sha256": "b10cabda93c88d27bcc135a44a1fd98fe60fe8305606d6e75a0d5b736f0df274", - "url": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3-aarch64.dmg", - "build_number": "253.28294.342" - }, - "goland": { - "url-template": "https://download.jetbrains.com/go/goland-{version}-aarch64.dmg", - "version": "2025.3", - "sha256": "d4ee20b5c3df6151d366d6cc9b06b915499ff0c1eb1184aab53a01078908ec89", - "url": "https://download.jetbrains.com/go/goland-2025.3-aarch64.dmg", - "build_number": "253.28294.337" - }, - "idea-community": { - "url-template": "https://download.jetbrains.com/idea/ideaIC-{version}-aarch64.dmg", - "version": "2025.2.5", - "sha256": "52065492d433f0ea9df4debd5f0683154ab4dab5846394cabc8a49903d70e5bc", - "url": "https://download.jetbrains.com/idea/ideaIC-2025.2.5-aarch64.dmg", - "build_number": "252.28238.7" - }, - "idea": { - "url-template": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "2137863cc3a5f4acd25ba38a82e004e935d3a94fa566f8e3851d6b8a8ac12777", - "url": "https://download.jetbrains.com/idea/ideaIU-2025.3.1-aarch64.dmg", - "build_number": "253.29346.138" - }, - "mps": { - "url-template": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}-macos-aarch64.dmg", - "version": "2025.3", - "url": "https://download.jetbrains.com/mps/2025.3/MPS-2025.3-macos-aarch64.dmg", - "sha256": "dc79c41ce851448f4862306173914eee1e63e230410ed65356498efd2d5f0444", - "build_number": "253.28294.432" - }, - "phpstorm": { - "url-template": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "0453e0a6ee86c3cbf97b8c48f2826751d8085bf8211b541a04752621c5af16bc", - "url": "https://download.jetbrains.com/webide/PhpStorm-2025.3.1-aarch64.dmg", - "build_number": "253.29346.151", - "version-major-minor": "2022.3" - }, - "pycharm-community": { - "url-template": "https://download.jetbrains.com/python/pycharm-community-{version}-aarch64.dmg", - "version": "2025.2.5", - "sha256": "040a4ed6bb7563972d844c450f615d0d11385e524fbbfdbfc9fc68d78811e994", - "url": "https://download.jetbrains.com/python/pycharm-community-2025.2.5-aarch64.dmg", - "build_number": "252.28238.29" - }, - "pycharm": { - "url-template": "https://download.jetbrains.com/python/pycharm-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "ec8e97856f00da902020c72b0f079cc10983de6bb4438292ea5faa1e5b0cb935", - "url": "https://download.jetbrains.com/python/pycharm-2025.3.1-aarch64.dmg", - "build_number": "253.29346.142" - }, - "rider": { - "url-template": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "d7080323412900f5d37270233e5a4c773011c6853d6031ce1f5e635c77511426", - "url": "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1-aarch64.dmg", - "build_number": "253.29346.144" - }, - "ruby-mine": { - "url-template": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "67f1aa674b90ec54ba21f3523ad940218f979befd7429e38ad822bc8146d16a4", - "url": "https://download.jetbrains.com/ruby/RubyMine-2025.3.1-aarch64.dmg", - "build_number": "253.29346.140" - }, - "rust-rover": { - "url-template": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "103a12ed1c37b6b38cff5d637e7dc7b8dcc78f5c576ba38b8f862c6ba3647d52", - "url": "https://download.jetbrains.com/rustrover/RustRover-2025.3.1-aarch64.dmg", - "build_number": "253.29346.139" - }, - "webstorm": { - "url-template": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.dmg", - "version": "2025.3.1", - "sha256": "1c21990cee2bbbffdd8f6c90e8071bc03ec7fe5a3662e51931c15222d4b7ccb2", - "url": "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1-aarch64.dmg", - "build_number": "253.29346.143" - }, - "writerside": { - "url-template": "https://download.jetbrains.com/writerside/writerside-{version}-aarch64.dmg", - "version": "2024.3 EAP", - "sha256": "9d86ef50b4c6d2a07d236219e9b05c0557241fb017d52ac395719bdb425130f5", - "url": "https://download.jetbrains.com/writerside/writerside-243.22562.371-aarch64.dmg", - "build_number": "243.22562.371" - } - } -} diff --git a/pkgs/applications/editors/jetbrains/bin/darwin.nix b/pkgs/applications/editors/jetbrains/builder/darwin.nix similarity index 75% rename from pkgs/applications/editors/jetbrains/bin/darwin.nix rename to pkgs/applications/editors/jetbrains/builder/darwin.nix index a698d9ab205ad..d9250c686cbd2 100644 --- a/pkgs/applications/editors/jetbrains/bin/darwin.nix +++ b/pkgs/applications/editors/jetbrains/builder/darwin.nix @@ -1,3 +1,8 @@ +# Darwin-specific base builder. +# TODO: +# 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. + { lib, stdenvNoCC, @@ -9,13 +14,14 @@ meta, pname, product, - productShort ? product, + productShort, src, version, + passthru, + plugins ? [ ], - buildNumber, ... -}@args: +}: let loname = lib.toLower productShort; @@ -26,10 +32,8 @@ stdenvNoCC.mkDerivation { src version plugins + passthru ; - passthru.buildNumber = buildNumber; - passthru.product = product; - passthru.tests = args.passthru.tests; meta = meta // { mainProgram = loname; }; diff --git a/pkgs/applications/editors/jetbrains/builder/default.nix b/pkgs/applications/editors/jetbrains/builder/default.nix new file mode 100644 index 0000000000000..32787728e8030 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/builder/default.nix @@ -0,0 +1,87 @@ +# Builder for JetBrains IDEs (`mkJetBrainsProduct`) + +{ + lib, + stdenv, + callPackage, + + jdk, + fontconfig, + libGL, + libX11, + + vmopts ? null, + forceWayland ? false, +}: +let + baseBuilder = if stdenv.hostPlatform.isDarwin then ./darwin.nix else ./linux.nix; + mkJetBrainsProductCore = callPackage baseBuilder { inherit vmopts; }; +in +# Makes a JetBrains IDE +{ + pname, + src, + version, + buildNumber, + wmClass, + product, + productShort ? product, + meta, + + libdbm, + fsnotifier, + + extraWrapperArgs ? [ ], + extraLdPath ? [ ], + buildInputs ? [ ], + passthru ? { }, +}: +mkJetBrainsProductCore { + inherit + pname + extraLdPath + jdk + src + version + buildNumber + wmClass + product + productShort + libdbm + fsnotifier + ; + + buildInputs = + buildInputs + ++ [ stdenv.cc.cc ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + fontconfig + libGL + libX11 + ]; + + extraWrapperArgs = + extraWrapperArgs + ++ lib.optionals (stdenv.hostPlatform.isLinux && forceWayland) [ + ''--add-flags "\''${WAYLAND_DISPLAY:+-Dawt.toolkit.name=WLToolkit}"'' + ]; + + passthru = lib.recursiveUpdate passthru { + inherit + buildNumber + product + libdbm + fsnotifier + ; + + updateScript = ../updater/main.py; + + tests = { + plugins = callPackage ../plugins/tests.nix { ideName = pname; }; + }; + }; + + meta = meta // { + teams = [ lib.teams.jetbrains ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/bin/linux.nix b/pkgs/applications/editors/jetbrains/builder/linux.nix similarity index 94% rename from pkgs/applications/editors/jetbrains/bin/linux.nix rename to pkgs/applications/editors/jetbrains/builder/linux.nix index 14532161233b7..bb406773d834e 100644 --- a/pkgs/applications/editors/jetbrains/bin/linux.nix +++ b/pkgs/applications/editors/jetbrains/builder/linux.nix @@ -1,3 +1,5 @@ +# Linux-specific base builder. + { stdenv, lib, @@ -23,18 +25,20 @@ { pname, product, - productShort ? product, + productShort, version, src, wmClass, - buildNumber, jdk, meta, + passthru, + libdbm, fsnotifier, + extraLdPath ? [ ], extraWrapperArgs ? [ ], - extraBuildInputs ? [ ], + buildInputs ? [ ], ... }@args: @@ -47,13 +51,18 @@ in with stdenv; lib.makeOverridable mkDerivation ( rec { - inherit pname version src; - passthru.buildNumber = buildNumber; - passthru.tests = args.passthru.tests; + inherit + pname + version + src + buildInputs + passthru + ; meta = args.meta // { mainProgram = pname; }; + # FIXME: Do not use meta attributes, see README (`TODO` section) desktopItem = makeDesktopItem { name = pname; exec = pname; @@ -74,7 +83,6 @@ lib.makeOverridable mkDerivation ( unzip autoPatchelfHook ]; - buildInputs = extraBuildInputs; postPatch = '' rm -rf jbr diff --git a/pkgs/applications/editors/jetbrains/default.nix b/pkgs/applications/editors/jetbrains/default.nix index 2994e787f57c2..f574d87cbd6d5 100644 --- a/pkgs/applications/editors/jetbrains/default.nix +++ b/pkgs/applications/editors/jetbrains/default.nix @@ -1,165 +1,60 @@ -let - # `ides.json` is handwritten and contains information that doesn't change across updates, like maintainers and other metadata - # `versions.json` contains everything generated/needed by the update script version numbers, build numbers and tarball hashes - ideInfo = builtins.fromJSON (builtins.readFile ./ides.json); - versions = builtins.fromJSON (builtins.readFile ./bin/versions.json); -in - { - config, lib, + config, stdenv, callPackage, - fetchurl, - jdk, - zlib, python3, - lldb, - dotnetCorePackages, - maven, - openssl, - expat, - libxcrypt, - libxcrypt-legacy, - fontconfig, - libxml2, - runCommand, - musl, - R, - libgcc, - lttng-ust_2_12, - xz, - xorg, - libGL, - - libICE, - libSM, - libX11, + jdk, vmopts ? null, forceWayland ? false, }: let - inherit (stdenv.hostPlatform) system; - - products = versions.${system} or (throw "Unsupported system: ${system}"); - - dotnet-sdk = dotnetCorePackages.sdk_10_0-source; - - package = if stdenv.hostPlatform.isDarwin then ./bin/darwin.nix else ./bin/linux.nix; - mkJetBrainsProductCore = callPackage package { inherit vmopts; }; - mkMeta = meta: fromSource: { - inherit (meta) homepage longDescription; - description = - meta.description - + lib.optionalString meta.isOpenSource ( - if fromSource then " (built from source)" else " (patched binaries from jetbrains)" - ); - maintainers = map (x: lib.maintainers."${x}") meta.maintainers; - teams = [ lib.teams.jetbrains ]; - license = if meta.isOpenSource then lib.licenses.asl20 else lib.licenses.unfree; - sourceProvenance = - if fromSource then - [ lib.sourceTypes.fromSource ] - else - ( - if stdenv.hostPlatform.isDarwin then - [ lib.sourceTypes.binaryNativeCode ] - else - [ lib.sourceTypes.binaryBytecode ] - ); - }; - - mkJetBrainsProduct = - { - pname, - fromSource ? false, - extraWrapperArgs ? [ ], - extraLdPath ? [ ], - extraBuildInputs ? [ ], - extraTests ? { }, - }: - mkJetBrainsProductCore { - inherit - pname - extraLdPath - jdk - ; - extraBuildInputs = - extraBuildInputs - ++ [ stdenv.cc.cc ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ - fontconfig - libGL - libX11 - ]; - extraWrapperArgs = - extraWrapperArgs - ++ lib.optionals (stdenv.hostPlatform.isLinux && forceWayland) [ - ''--add-flags "\''${WAYLAND_DISPLAY:+-Dawt.toolkit.name=WLToolkit}"'' - ]; - src = - if fromSource then - communitySources."${pname}" - else - fetchurl { - url = products."${pname}".url; - sha256 = products."${pname}".sha256; - }; - version = if fromSource then communitySources."${pname}".version else products."${pname}".version; - buildNumber = - if fromSource then communitySources."${pname}".buildNumber else products."${pname}".build_number; - inherit (ideInfo."${pname}") wmClass product; - productShort = ideInfo."${pname}".productShort or ideInfo."${pname}".product; - meta = mkMeta ideInfo."${pname}".meta fromSource; - passthru.tests = extraTests // { - plugins = callPackage ./plugins/tests.nix { ideName = pname; }; - }; - libdbm = communitySources."${pname}".libdbm or communitySources.idea-oss.libdbm; - fsnotifier = communitySources."${pname}".fsnotifier or communitySources.idea-oss.fsnotifier; - }; - - communitySources = callPackage ./source { }; - - buildIdea = - args: - mkJetBrainsProduct ( - args - // { - extraLdPath = [ zlib ]; - extraWrapperArgs = [ - ''--set M2_HOME "${maven}/maven"'' - ''--set M2 "${maven}/maven/bin"'' - ]; - } - ); - - buildPycharm = - args: - (mkJetBrainsProduct args).overrideAttrs ( - finalAttrs: previousAttrs: - lib.optionalAttrs stdenv.hostPlatform.isLinux { - buildInputs = - with python3.pkgs; - (previousAttrs.buildInputs or [ ]) - ++ [ - python3 - setuptools - ]; - preInstall = '' - echo "compiling cython debug speedups" - if [[ -d plugins/python-ce ]]; then - ${python3.interpreter} plugins/python-ce/helpers/pydev/setup_cython.py build_ext --inplace - else - ${python3.interpreter} plugins/python/helpers/pydev/setup_cython.py build_ext --inplace - fi - ''; - # See https://www.jetbrains.com/help/pycharm/2022.1/cython-speedups.html + mkJetBrainsProduct = callPackage ./builder/default.nix { inherit jdk forceWayland vmopts; }; + mkJetBrainsSource = callPackage ./source/build.nix { }; + + mkSrcIde = + path: extras: callPackage path ({ inherit mkJetBrainsProduct mkJetBrainsSource; } // extras); + + _idea-oss = mkSrcIde ./ides/idea-oss.nix { }; + + # The binary builds use the same libdbm and fsnotifier as the current idea-oss source build. + mkBinIde = + path: extras: + callPackage path ( + { + inherit mkJetBrainsProduct; + libdbm = _idea-oss.libdbm; + fsnotifier = _idea-oss.fsnotifier; } + // extras ); + # Common build overrides, fixes, etc. + # TODO: These should eventually be moved outside of this file + pyCharmCommonOverrides = ( + finalAttrs: previousAttrs: + lib.optionalAttrs stdenv.hostPlatform.isLinux { + buildInputs = + with python3.pkgs; + (previousAttrs.buildInputs or [ ]) + ++ [ + python3 + setuptools + ]; + preInstall = '' + echo "compiling cython debug speedups" + if [[ -d plugins/python-ce ]]; then + ${python3.interpreter} plugins/python-ce/helpers/pydev/setup_cython.py build_ext --inplace + else + ${python3.interpreter} plugins/python/helpers/pydev/setup_cython.py build_ext --inplace + fi + ''; + # See https://www.jetbrains.com/help/pycharm/2022.1/cython-speedups.html + } + ); patchSharedLibs = lib.optionalString stdenv.hostPlatform.isLinux '' ls -d \ $out/*/bin/*/linux/*/lib/liblldb.so \ @@ -174,203 +69,27 @@ let --replace-needed libcrypt.so.1 libcrypt.so \ ${lib.optionalString stdenv.hostPlatform.isAarch "--replace-needed libxml2.so.2 libxml2.so"} ''; - - # TODO: These can be moved down again when we don't need the aliases anymore: - _idea = buildIdea { - pname = "idea"; - extraBuildInputs = [ - lldb - musl - ]; - }; - _idea-oss = buildIdea { - pname = "idea-oss"; - fromSource = true; - }; - _pycharm = buildPycharm { - pname = "pycharm"; - extraBuildInputs = [ musl ]; - }; - _pycharm-oss = buildPycharm { - pname = "pycharm-oss"; - fromSource = true; - }; in { # Sorted alphabetically. Deprecated products and aliases are at the very end. - - clion = - (mkJetBrainsProduct { - pname = "clion"; - extraBuildInputs = - lib.optionals stdenv.hostPlatform.isLinux [ - python3 - openssl - libxcrypt-legacy - lttng-ust_2_12 - musl - ] - ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ - expat - libxml2 - xz - ]; - }).overrideAttrs - (attrs: { - postInstall = - (attrs.postInstall or "") - + lib.optionalString stdenv.hostPlatform.isLinux '' - for dir in $out/clion/plugins/clion-radler/DotFiles/linux-*; do - rm -rf $dir/dotnet - ln -s ${dotnet-sdk}/share/dotnet $dir/dotnet - done - ''; - - postFixup = '' - ${attrs.postFixup or ""} - ${patchSharedLibs} - ''; - }); - - datagrip = mkJetBrainsProduct { - pname = "datagrip"; - }; - - dataspell = - let - libr = runCommand "libR" { } '' - mkdir -p $out/lib - ln -s ${R}/lib/R/lib/libR.so $out/lib/libR.so - ''; - in - mkJetBrainsProduct { - pname = "dataspell"; - extraBuildInputs = [ - libgcc - libr - ]; - }; - - gateway = mkJetBrainsProduct { - pname = "gateway"; - extraBuildInputs = [ libgcc ]; - }; - - goland = - (mkJetBrainsProduct { - pname = "goland"; - extraWrapperArgs = [ - # fortify source breaks build since delve compiles with -O0 - ''--prefix CGO_CPPFLAGS " " "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0"'' - ]; - extraBuildInputs = [ - libgcc - ]; - }).overrideAttrs - (attrs: { - postFixup = - (attrs.postFixup or "") - + lib.optionalString stdenv.hostPlatform.isLinux '' - interp="$(cat $NIX_CC/nix-support/dynamic-linker)" - patchelf --set-interpreter $interp $out/goland/plugins/go-plugin/lib/dlv/linux/dlv - chmod +x $out/goland/plugins/go-plugin/lib/dlv/linux/dlv - ''; - }); - - idea = _idea; - + clion = mkBinIde ./ides/clion.nix { inherit patchSharedLibs; }; + datagrip = mkBinIde ./ides/datagrip.nix { }; + dataspell = mkBinIde ./ides/dataspell.nix { }; + gateway = mkBinIde ./ides/gateway.nix { }; + goland = mkBinIde ./ides/goland.nix { }; + idea = mkBinIde ./ides/idea.nix { }; idea-oss = _idea-oss; - - mps = mkJetBrainsProduct { pname = "mps"; }; - - phpstorm = mkJetBrainsProduct { - pname = "phpstorm"; - extraBuildInputs = [ - musl - ]; - }; - - pycharm = _pycharm; - - pycharm-oss = _pycharm-oss; - - rider = - (mkJetBrainsProduct { - pname = "rider"; - extraBuildInputs = [ - openssl - libxcrypt - lttng-ust_2_12 - musl - ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ - xorg.xcbutilkeysyms - ] - ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ - expat - libxml2 - xz - ]; - extraLdPath = lib.optionals (stdenv.hostPlatform.isLinux) [ - # Avalonia dependencies needed for dotMemory - libICE - libSM - libX11 - ]; - }).overrideAttrs - (attrs: { - postInstall = - (attrs.postInstall or "") - + lib.optionalString stdenv.hostPlatform.isLinux '' - ${patchSharedLibs} - - for dir in $out/rider/lib/ReSharperHost/linux-*; do - rm -rf $dir/dotnet - ln -s ${dotnet-sdk}/share/dotnet $dir/dotnet - done - ''; - }); - - ruby-mine = mkJetBrainsProduct { - pname = "ruby-mine"; - extraBuildInputs = [ - musl - ]; - }; - - rust-rover = - (mkJetBrainsProduct { - pname = "rust-rover"; - extraBuildInputs = - lib.optionals stdenv.hostPlatform.isLinux [ - python3 - openssl - libxcrypt-legacy - ] - ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ - expat - libxml2 - xz - ]; - }).overrideAttrs - (attrs: { - postFixup = '' - ${attrs.postFixup or ""} - ${patchSharedLibs} - ''; - }); - - webstorm = mkJetBrainsProduct { - pname = "webstorm"; - extraBuildInputs = [ - musl - ]; - }; + mps = mkBinIde ./ides/mps.nix { }; + phpstorm = mkBinIde ./ides/phpstorm.nix { }; + pycharm = mkBinIde ./ides/pycharm.nix { inherit pyCharmCommonOverrides; }; + pycharm-oss = mkSrcIde ./ides/pycharm-oss.nix { inherit pyCharmCommonOverrides; }; + rider = mkBinIde ./ides/rider.nix { inherit patchSharedLibs; }; + ruby-mine = mkBinIde ./ides/ruby-mine.nix { }; + rust-rover = mkBinIde ./ides/rust-rover.nix { inherit patchSharedLibs; }; + webstorm = mkBinIde ./ides/webstorm.nix { }; # Plugins - plugins = callPackage ./plugins { }; - } // lib.optionalAttrs config.allowAliases rec { @@ -380,12 +99,7 @@ in aqua = lib.warnOnInstantiate "jetbrains.aqua: Aqua has been discontinued by Jetbrains and is not receiving updates. It will be removed in NixOS 26.05." - (mkJetBrainsProduct { - pname = "aqua"; - extraBuildInputs = [ - lldb - ]; - }); + (mkBinIde ./ides/aqua.nix { }); idea-community = lib.warnOnInstantiate @@ -400,37 +114,41 @@ in idea-community-bin = lib.warnOnInstantiate "jetbrains.idea-community-bin: IntelliJ IDEA Community has been discontinued by Jetbrains. This binary build is no longer updated. Switch to 'jetbrains.idea-oss' for open source builds (from source) or 'jetbrains.idea' for commercial builds (binary, unfree). See: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/" - (buildIdea { - pname = "idea-community"; - }); + (mkBinIde ./ides/idea-community.nix { }); - idea-ultimate = lib.warnOnInstantiate "'jetbrains.idea-ultimate' has been renamed to/replaced by 'jetbrains.idea'" _idea; + idea-ultimate = + lib.warnOnInstantiate "'jetbrains.idea-ultimate' has been renamed to/replaced by 'jetbrains.idea'" + (mkBinIde ./ides/idea.nix { }); idea-community-src = lib.warnOnInstantiate "jetbrains.idea-community-src: IntelliJ IDEA Community has been discontinued by Jetbrains. This is now an alias for 'jetbrains.idea-oss', the Open Source build of IntelliJ. See: https://blog.jetbrains.com/idea/2025/07/intellij-idea-unified-distribution-plan/" _idea-oss; pycharm-community = lib.warnOnInstantiate "pycharm-comminity: PyCharm Community has been discontinued by Jetbrains. This deprecated alias uses the, no longer updated, binary build on Darwin. On Linux it uses PyCharm Open Source, built from source. Either switch to 'jetbrains.pycharm-oss' or 'jetbrains.pycharm'. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025" - (if stdenv.hostPlatform.isDarwin then pycharm-community-bin else _pycharm-oss); + ( + if stdenv.hostPlatform.isDarwin then + pycharm-community-bin + else + (mkSrcIde ./ides/pycharm-oss.nix { inherit pyCharmCommonOverrides; }) + ); pycharm-community-bin = lib.warnOnInstantiate "pycharm-comminity-bin: PyCharm Community has been discontinued by Jetbrains. This binary build is no longer updated. Switch to 'jetbrains.pycharm-oss' for open source builds (from source) or 'jetbrains.pycharm' for commercial builds (binary, unfree). See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025" - (buildPycharm { - pname = "pycharm-community"; - }); + (mkBinIde ./ides/pycharm-community.nix { inherit pyCharmCommonOverrides; }); - pycharm-community-src = lib.warnOnInstantiate "jetbrains.idea-community-src: PyCharm Community has been discontinued by Jetbrains. This is now an alias for 'jetbrains.pycharm-oss', the Open Source build of PyCharm. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025" _pycharm-oss; + pycharm-community-src = + lib.warnOnInstantiate + "jetbrains.idea-community-src: PyCharm Community has been discontinued by Jetbrains. This is now an alias for 'jetbrains.pycharm-oss', the Open Source build of PyCharm. See: https://blog.jetbrains.com/pycharm/2025/04/pycharm-2025" + (mkSrcIde ./ides/pycharm-oss.nix { inherit pyCharmCommonOverrides; }); - pycharm-professional = lib.warnOnInstantiate "'jetbrains.pycharm-professional' has been renamed to/replaced by 'jetbrains.pycharm'" _pycharm; + pycharm-professional = + lib.warnOnInstantiate + "'jetbrains.pycharm-professional' has been renamed to/replaced by 'jetbrains.pycharm'" + (mkBinIde ./ides/pycharm.nix { inherit pyCharmCommonOverrides; }); writerside = lib.warnOnInstantiate "jetbrains.writerside: Writerside has been discontinued by Jetbrains and is not receiving updates. It will be removed in NixOS 26.05." - (mkJetBrainsProduct { - pname = "writerside"; - extraBuildInputs = [ - musl - ]; - }); + (mkBinIde ./ides/writerside.nix { }); } diff --git a/pkgs/applications/editors/jetbrains/ides.json b/pkgs/applications/editors/jetbrains/ides.json deleted file mode 100644 index ffe3240f5c099..0000000000000 --- a/pkgs/applications/editors/jetbrains/ides.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "aqua": { - "product": "Aqua", - "updateChannel": "Aqua RELEASE", - "wmClass": "jetbrains-aqua", - "meta": { - "isOpenSource": false, - "description": "Test automation IDE from JetBrains", - "maintainers": [ "remcoschrijver" ], - "longDescription": "Aqua is a test automation IDE from jetbrains that can deal with many languages and frameworks to improve your test workflows. Has support for popular testing frameworks like Selenium, Cypress, and Playwright.", - "homepage": "https://www.jetbrains.com/aqua/" - } - }, - "clion": { - "product": "CLion", - "updateChannel": "CLion RELEASE", - "wmClass": "jetbrains-clion", - "meta": { - "isOpenSource": false, - "description": "C/C++ IDE from JetBrains", - "maintainers": [ "mic92", "tymscar" ], - "longDescription": "Enhancing productivity for every C and C++ developer on Linux, macOS and Windows.", - "homepage": "https://www.jetbrains.com/clion/" - } - }, - "datagrip": { - "product": "DataGrip", - "updateChannel": "DataGrip RELEASE", - "wmClass": "jetbrains-datagrip", - "meta": { - "isOpenSource": false, - "description": "Database IDE from JetBrains", - "maintainers": [ ], - "longDescription": "DataGrip is a new IDE from JetBrains built for database admins. It allows you to quickly migrate and refactor relational databases, construct efficient, statically checked SQL queries and much more.", - "homepage": "https://www.jetbrains.com/datagrip/" - } - }, - "dataspell": { - "product": "DataSpell", - "updateChannel": "DataSpell RELEASE", - "wmClass": "jetbrains-dataspell", - "meta": { - "isOpenSource": false, - "description": "Data science IDE from JetBrains", - "maintainers": [ "leona" ], - "longDescription": "DataSpell is a new IDE from JetBrains built for Data Scientists. Mainly it integrates Jupyter notebooks in the IntelliJ platform.", - "homepage": "https://www.jetbrains.com/dataspell/" - } - }, - "gateway": { - "product": "JetBrains Gateway", - "updateChannel": "Gateway RELEASE", - "productShort": "Gateway", - "wmClass": "jetbrains-gateway", - "meta": { - "isOpenSource": false, - "description": "Remote development for JetBrains products", - "maintainers": [ ], - "longDescription": "JetBrains Gateway is a lightweight launcher that connects a remote server with your local machine, downloads necessary components on the backend, and opens your project in JetBrains Client.", - "homepage": "https://www.jetbrains.com/remote-development/gateway/" - } - }, - "goland": { - "product": "Goland", - "updateChannel": "GoLand RELEASE", - "wmClass": "jetbrains-goland", - "meta": { - "isOpenSource": false, - "description": "Go IDE from JetBrains", - "maintainers": [ "tymscar" ], - "longDescription": "Goland is the codename for a new commercial IDE by JetBrains aimed at providing an ergonomic environment for Go development.\n The new IDE extends the IntelliJ platform with the coding assistance and tool integrations specific for the Go language", - "homepage": "https://www.jetbrains.com/go/" - } - }, - "idea": { - "product": "IntelliJ IDEA", - "updateChannel": "IntelliJ IDEA RELEASE", - "productShort": "IDEA", - "wmClass": "jetbrains-idea", - "meta": { - "isOpenSource": false, - "description": "Java, Kotlin, Groovy and Scala IDE from Jetbrains", - "maintainers": [ "gytis-ivaskevicius", "tymscar" ], - "longDescription": "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ.", - "homepage": "https://www.jetbrains.com/idea/" - } - }, - "idea-community": { - "product": "IntelliJ IDEA CE", - "updateChannel": "IntelliJ IDEA RELEASE", - "productShort": "IDEA", - "wmClass": "jetbrains-idea-ce", - "meta": { - "isOpenSource": true, - "description": "Free Java, Kotlin, Groovy and Scala IDE from Jetbrains", - "maintainers": [ "gytis-ivaskevicius", "tymscar" ], - "longDescription": "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ.", - "homepage": "https://www.jetbrains.com/idea/" - } - }, - "idea-oss": { - "product": "IntelliJ IDEA Open Source", - "updateChannel": "IntelliJ IDEA RELEASE", - "productShort": "IDEA", - "wmClass": "jetbrains-idea-ce", - "meta": { - "isOpenSource": true, - "description": "Free Java, Kotlin, Groovy and Scala IDE from Jetbrains", - "maintainers": [ "gytis-ivaskevicius", "tymscar" ], - "longDescription": "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ.", - "homepage": "https://www.jetbrains.com/idea/" - } - }, - "mps": { - "product": "MPS", - "updateChannel": "MPS RELEASE", - "wmClass": "jetbrains-MPS", - "meta": { - "isOpenSource": false, - "description": "IDE for building domain-specific languages from JetBrains", - "maintainers": [ ], - "longDescription": "A metaprogramming system which uses projectional editing which allows users to overcome the limits of language parsers, and build DSL editors, such as ones with tables and diagrams.", - "homepage": "https://www.jetbrains.com/mps/" - } - }, - "phpstorm": { - "product": "PhpStorm", - "updateChannel": "PhpStorm RELEASE", - "wmClass": "jetbrains-phpstorm", - "meta": { - "isOpenSource": false, - "description": "PHP IDE from JetBrains", - "maintainers": [ "dritter", "tymscar" ], - "longDescription": "PhpStorm provides an editor for PHP, HTML and JavaScript with on-the-fly code analysis, error prevention and automated refactorings for PHP and JavaScript code. ", - "homepage": "https://www.jetbrains.com/phpstorm/" - } - }, - "pycharm": { - "product": "PyCharm", - "productShort": "PyCharm", - "updateChannel": "PyCharm RELEASE", - "wmClass": "jetbrains-pycharm", - "meta": { - "isOpenSource": false, - "description": "Python IDE from JetBrains", - "maintainers": [ "genericnerdyusername", "tymscar" ], - "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!", - "homepage": "https://www.jetbrains.com/pycharm/" - } - }, - "pycharm-community": { - "product": "PyCharm CE", - "productShort": "PyCharm", - "updateChannel": "PyCharm RELEASE", - "wmClass": "jetbrains-pycharm-ce", - "meta": { - "isOpenSource": true, - "description": "Free Python IDE from JetBrains", - "maintainers": [ "genericnerdyusername", "tymscar" ], - "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!", - "homepage": "https://www.jetbrains.com/pycharm/" - } - }, - "pycharm-oss": { - "product": "PyCharm Open Source", - "productShort": "PyCharm", - "updateChannel": "PyCharm RELEASE", - "wmClass": "jetbrains-pycharm-ce", - "meta": { - "isOpenSource": true, - "description": "Free Python IDE from JetBrains", - "maintainers": [ "genericnerdyusername", "tymscar" ], - "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!", - "homepage": "https://www.jetbrains.com/pycharm/" - } - }, - "rider": { - "product": "Rider", - "updateChannel": "Rider RELEASE", - "wmClass": "jetbrains-rider", - "meta": { - "isOpenSource": false, - "description": ".NET IDE from JetBrains", - "maintainers": [ "raphaelr" ], - "longDescription": "JetBrains Rider is a new .NET IDE based on the IntelliJ platform and ReSharper. Rider supports .NET Core, .NET Framework and Mono based projects. This lets you develop a wide array of applications including .NET desktop apps, services and libraries, Unity games, ASP.NET and ASP.NET Core web applications.", - "homepage": "https://www.jetbrains.com/rider/" - } - }, - "ruby-mine": { - "product": "RubyMine", - "updateChannel": "RubyMine RELEASE", - "wmClass": "jetbrains-rubymine", - "meta": { - "isOpenSource": false, - "description": "Ruby IDE from JetBrains", - "maintainers": [ "tymscar"], - "longDescription": "Ruby IDE from JetBrains", - "homepage": "https://www.jetbrains.com/ruby/" - } - }, - "rust-rover": { - "product": "RustRover", - "updateChannel": "RustRover RELEASE", - "wmClass": "jetbrains-rustrover", - "meta": { - "isOpenSource": false, - "description": "Rust IDE from JetBrains", - "maintainers": [ "genericnerdyusername"], - "longDescription": "Rust IDE from JetBrains", - "homepage": "https://www.jetbrains.com/rust/" - } - }, - "webstorm": { - "product": "WebStorm", - "updateChannel": "WebStorm RELEASE", - "wmClass": "jetbrains-webstorm", - "meta": { - "isOpenSource": false, - "description": "Web IDE from JetBrains", - "maintainers": [ "abaldeau", "tymscar"], - "longDescription": "WebStorm provides an editor for HTML, JavaScript (incl. Node.js), and CSS with on-the-fly code analysis, error prevention and automated refactorings for JavaScript code.", - "homepage": "https://www.jetbrains.com/webstorm/" - } - }, - "writerside": { - "product": "Writerside", - "updateChannel": "Writerside EAP", - "wmClass": "jetbrains-writerside", - "meta": { - "isOpenSource": false, - "description": "Documentation IDE from JetBrains", - "maintainers": [ "zlepper"], - "longDescription": "The most powerful development environment – now adapted for writing documentation.", - "homepage": "https://www.jetbrains.com/writerside/" - } - } -} diff --git a/pkgs/applications/editors/jetbrains/ides/aqua.nix b/pkgs/applications/editors/jetbrains/ides/aqua.nix new file mode 100644 index 0000000000000..ff219361821e5 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/aqua.nix @@ -0,0 +1,66 @@ +# TODO: This IDE is deprecated and scheduled for removal in 26.05 +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + lldb, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/aqua/aqua-2024.3.2.tar.gz"; + sha256 = "de073e8a3734a2c4ef984b3e1bd68f5de72a6180e73400889510439ac3f419aa"; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/aqua/aqua-2024.3.2-aarch64.tar.gz"; + sha256 = "d2a3c781756a83ccea63dc6d9aebf85f819de1edb5bcd4e5a1a161eaa0779c84"; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/aqua/aqua-2024.3.2.dmg"; + sha256 = "423d492e9849beb7edbbd1771650a04e8df9f469bf1789b41bc5878c84cee393"; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/aqua/aqua-2024.3.2-aarch64.dmg"; + sha256 = "43974cdbbb71aaf5bfcfaf2cfd0e69e9920dda3973e64671936c1d52b267494d"; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "aqua"; + + wmClass = "jetbrains-aqua"; + product = "Aqua"; + + # update-script-start: version + version = "2024.3.2"; + buildNumber = "243.23654.154"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + lldb + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/aqua/"; + description = "Test automation IDE from JetBrains"; + longDescription = "Aqua is a test automation IDE from jetbrains that can deal with many languages and frameworks to improve your test workflows. Has support for popular testing frameworks like Selenium, Cypress, and Playwright."; + maintainers = with lib.maintainers; [ remcoschrijver ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/clion.nix b/pkgs/applications/editors/jetbrains/ides/clion.nix new file mode 100644 index 0000000000000..0391c23f03ce7 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/clion.nix @@ -0,0 +1,102 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + patchSharedLibs, + dotnetCorePackages, + python3, + openssl, + libxcrypt-legacy, + lttng-ust_2_12, + musl, + expat, + libxml2, + xz, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/cpp/CLion-2025.3.1.tar.gz"; + hash = "sha256-RK49pTWLoBCmLVWrQSty82TF3NLC3NIASuNLdGOAe70="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/cpp/CLion-2025.3.1-aarch64.tar.gz"; + hash = "sha256-uWw4w9L3/3uYjXXJcP0OkDY+CbgnMQbe/Jrj3vqGjtc="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/cpp/CLion-2025.3.1.dmg"; + hash = "sha256-moF0ySKfnIb4baGo4r2rUv+zaeoHgbV+skVwPryDB+I="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/cpp/CLion-2025.3.1-aarch64.dmg"; + hash = "sha256-EcrorrQ9GHDZaYDx2Sf/VF+r7ZifO/TnMnkRtEHhSfE="; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "clion"; + + wmClass = "jetbrains-clion"; + product = "CLion"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.141"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = + lib.optionals stdenv.hostPlatform.isLinux [ + python3 + openssl + libxcrypt-legacy + lttng-ust_2_12 + musl + ] + ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ + expat + libxml2 + xz + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/clion/"; + description = "C/C++ IDE from JetBrains"; + longDescription = "Enhancing productivity for every C and C++ developer on Linux, macOS and Windows."; + maintainers = with lib.maintainers; [ + mic92 + tymscar + ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +}).overrideAttrs + (attrs: { + postInstall = + (attrs.postInstall or "") + + lib.optionalString stdenv.hostPlatform.isLinux '' + for dir in $out/clion/plugins/clion-radler/DotFiles/linux-*; do + rm -rf $dir/dotnet + ln -s ${dotnetCorePackages.sdk_10_0-source}/share/dotnet $dir/dotnet + done + ''; + + postFixup = '' + ${attrs.postFixup or ""} + ${patchSharedLibs} + ''; + }) diff --git a/pkgs/applications/editors/jetbrains/ides/datagrip.nix b/pkgs/applications/editors/jetbrains/ides/datagrip.nix new file mode 100644 index 0000000000000..15be98d7cfd30 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/datagrip.nix @@ -0,0 +1,61 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/datagrip/datagrip-2025.3.2.tar.gz"; + hash = "sha256-y27WR10h640wdUExvSQAPBFAlr+oT/zPM03BHPisYMw="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/datagrip/datagrip-2025.3.2-aarch64.tar.gz"; + hash = "sha256-Gm/rOqJV2s4zLMGLhoWTGBtupiw9nw02+QAyygUX0Gg="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/datagrip/datagrip-2025.3.2.dmg"; + hash = "sha256-A4OgpPL95YO2LqfTQuVxiw+jBvyDSVQcdb7FroQftPw="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/datagrip/datagrip-2025.3.2-aarch64.dmg"; + hash = "sha256-pyJFSNydo4Y3J7DBHO+dYT/ZUdFrqgFsoUB8VqnsaWQ="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "datagrip"; + + wmClass = "jetbrains-datagrip"; + product = "DataGrip"; + + # update-script-start: version + version = "2025.3.2"; + buildNumber = "253.29346.170"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/datagrip/"; + description = "Database IDE from JetBrains"; + longDescription = "DataGrip is a new IDE from JetBrains built for database admins. It allows you to quickly migrate and refactor relational databases, construct efficient, statically checked SQL queries and much more."; + maintainers = [ ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/dataspell.nix b/pkgs/applications/editors/jetbrains/ides/dataspell.nix new file mode 100644 index 0000000000000..2b9bc50d65084 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/dataspell.nix @@ -0,0 +1,71 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + libgcc, + runCommand, + R, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/python/dataspell-2025.3.1.tar.gz"; + hash = "sha256-N/E0Js5PXYWdfbJG8jKMy61hrfNh1Dx4TLaTKvZkTCg="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/python/dataspell-2025.3.1-aarch64.tar.gz"; + hash = "sha256-QK/TjMcEzf8r6JufDWe9vLFpnXs3sl001E0tUu9qRtM="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/python/dataspell-2025.3.1.dmg"; + hash = "sha256-OI2VbdYkNpehYsBix2sv7kCY9PNAW62wemnObffeYBc="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/python/dataspell-2025.3.1-aarch64.dmg"; + hash = "sha256-/g2O8V5uNq8OpDYb1HTyBO5cMH75Cvjsgzl2odrlpaM="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "dataspell"; + + wmClass = "jetbrains-dataspell"; + product = "DataSpell"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.157"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + libgcc + (runCommand "libR" { } '' + mkdir -p $out/lib + ln -s ${R}/lib/R/lib/libR.so $out/lib/libR.so + '') + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/dataspell/"; + description = "Data science IDE from JetBrains"; + longDescription = "DataSpell is a new IDE from JetBrains built for Data Scientists. Mainly it integrates Jupyter notebooks in the IntelliJ platform."; + maintainers = with lib.maintainers; [ leona ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/gateway.nix b/pkgs/applications/editors/jetbrains/ides/gateway.nix new file mode 100644 index 0000000000000..4610e98e9a6bf --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/gateway.nix @@ -0,0 +1,66 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + libgcc, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3.tar.gz"; + hash = "sha256-kMilT2GSRaVDXDQ/lPOVlatZzTy62laeKx4ovKzby0o="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3-aarch64.tar.gz"; + hash = "sha256-IE7T9yYod9Ckaq8wxbr7cha06XNr6+5xQlyZPBhIavg="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3.dmg"; + hash = "sha256-KC/X8wLZWt7tAi+NbGedMpJ3j5YgU5SvUt0JD2IB8zg="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-2025.3-aarch64.dmg"; + hash = "sha256-sQyr2pPIjSe8wTWkSh/Zj+YP6DBWBtbnWg1bc28N8nQ="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "gateway"; + + wmClass = "jetbrains-gateway"; + product = "JetBrains Gateway"; + productShort = "Gateway"; + + # update-script-start: version + version = "2025.3"; + buildNumber = "253.28294.342"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + libgcc + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/remote-development/gateway/"; + description = "Remote development for JetBrains products"; + longDescription = "JetBrains Gateway is a lightweight launcher that connects a remote server with your local machine, downloads necessary components on the backend, and opens your project in JetBrains Client."; + maintainers = [ ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/goland.nix b/pkgs/applications/editors/jetbrains/ides/goland.nix new file mode 100644 index 0000000000000..e2ca7a5502ca0 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/goland.nix @@ -0,0 +1,79 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + libgcc, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/go/goland-2025.3.tar.gz"; + hash = "sha256-YVGFYobqVG64r5rrAldyzua9VxNPRUlKgY6NogqGkcY="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/go/goland-2025.3-aarch64.tar.gz"; + hash = "sha256-xTDdS8x6B1oEC2SFnss0FCyPwDmWJcWhOuLXqPWXQ0A="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/go/goland-2025.3.dmg"; + hash = "sha256-4d9PELFYx3iHNlWWZiROmUUApA21sIZh4mkTV9Jp2/Q="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/go/goland-2025.3-aarch64.dmg"; + hash = "sha256-1O4gtcPfYVHTZtbMmwa5FUmf8MHrEYSqtToBB4kI7Ik="; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "goland"; + + wmClass = "jetbrains-goland"; + product = "Goland"; + + # update-script-start: version + version = "2025.3"; + buildNumber = "253.28294.337"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + extraWrapperArgs = [ + # fortify source breaks build since delve compiles with -O0 + ''--prefix CGO_CPPFLAGS " " "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0"'' + ]; + buildInputs = [ + libgcc + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/go/"; + description = "Go IDE from JetBrains"; + longDescription = "Goland is the codename for a new commercial IDE by JetBrains aimed at providing an ergonomic environment for Go development. + The new IDE extends the IntelliJ platform with the coding assistance and tool integrations specific for the Go language"; + maintainers = with lib.maintainers; [ tymscar ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +}).overrideAttrs + (attrs: { + postFixup = + (attrs.postFixup or "") + + lib.optionalString stdenv.hostPlatform.isLinux '' + interp="$(cat $NIX_CC/nix-support/dynamic-linker)" + patchelf --set-interpreter $interp $out/goland/plugins/go-plugin/lib/dlv/linux/dlv + chmod +x $out/goland/plugins/go-plugin/lib/dlv/linux/dlv + ''; + }) diff --git a/pkgs/applications/editors/jetbrains/ides/idea-community.nix b/pkgs/applications/editors/jetbrains/ides/idea-community.nix new file mode 100644 index 0000000000000..19b81e1233675 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/idea-community.nix @@ -0,0 +1,69 @@ +# TODO: This IDE is deprecated and scheduled for removal in 26.05 +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + maven, + zlib, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/idea/ideaIC-2025.2.5.tar.gz"; + sha256 = "995c334cc3e143f13467abafef07a1ccf7d06275512bb6f4c91123948786ab7c"; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/idea/ideaIC-2025.2.5-aarch64.tar.gz"; + sha256 = "4c57a783f31ee6f2c82d8c43bb5d0334a9afbc8bfb4542e732048c41f61e63a0"; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/idea/ideaIC-2025.2.5.dmg"; + sha256 = "ff48a1e60869342a91db867fa482a49d4cdf38476496911c109f34a7e8d6523d"; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/idea/ideaIC-2025.2.5-aarch64.dmg"; + sha256 = "52065492d433f0ea9df4debd5f0683154ab4dab5846394cabc8a49903d70e5bc"; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "idea-community"; + + wmClass = "jetbrains-idea-ce"; + product = "IntelliJ IDEA CE"; + productShort = "IDEA"; + + # update-script-start: version + version = "2025.2.5"; + buildNumber = "252.28238.7"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + extraLdPath = [ zlib ]; + extraWrapperArgs = [ + ''--set M2_HOME "${maven}/maven"'' + ''--set M2 "${maven}/maven/bin"'' + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/idea/"; + description = "Free Java, Kotlin, Groovy and Scala IDE from Jetbrains (built from source)"; + longDescription = "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ."; + maintainers = with lib.maintainers; [ + gytis-ivaskevicius + tymscar + ]; + license = lib.licenses.asl20; + sourceProvenance = [ lib.sourceTypes.fromSource ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/idea-oss.nix b/pkgs/applications/editors/jetbrains/ides/idea-oss.nix new file mode 100644 index 0000000000000..e2ac3e14d325d --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/idea-oss.nix @@ -0,0 +1,72 @@ +{ + lib, + mkJetBrainsProduct, + mkJetBrainsSource, + maven, + zlib, +}: +let + src = mkJetBrainsSource { + # update-script-start: source-args + version = "2025.3.1"; + buildNumber = "253.29346.138"; + buildType = "idea"; + ideaHash = "sha256-eAq/lgv6ZcN9SR2E1KYnnhDHe/rBQ3GqqbbF6GstDoU="; + androidHash = "sha256-quMCzrjCKIo1pkzw4PWewAs5tz7A2aq7TI5zd+QaaUY="; + jpsHash = "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk="; + restarterHash = "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag="; + mvnDeps = ../source/idea_maven_artefacts.json; + repositories = [ + "repo1.maven.org/maven2" + "packages.jetbrains.team/maven/p/ij/intellij-dependencies" + "dl.google.com/dl/android/maven2" + "download.jetbrains.com/teamcity-repository" + "maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies" + "packages.jetbrains.team/maven/p/grazi/grazie-platform-public" + "packages.jetbrains.team/maven/p/kpm/public" + "packages.jetbrains.team/maven/p/ki/maven" + "maven.pkg.jetbrains.space/public/p/compose/dev" + "packages.jetbrains.team/maven/p/amper/amper" + "packages.jetbrains.team/maven/p/kt/bootstrap" + ]; + kotlin-jps-plugin = { + version = "2.2.20"; + hash = "sha256-+jGghK2+yq+YFm5zT7ob+WTgTiJnHXAjDtlZjOzSISQ="; + }; + # update-script-end: source-args + }; +in +mkJetBrainsProduct { + inherit src; + inherit (src) + version + buildNumber + libdbm + fsnotifier + ; + + pname = "idea-oss"; + + wmClass = "jetbrains-idea-ce"; + product = "IntelliJ IDEA Open Source"; + productShort = "IDEA"; + + extraLdPath = [ zlib ]; + extraWrapperArgs = [ + ''--set M2_HOME "${maven}/maven"'' + ''--set M2 "${maven}/maven/bin"'' + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/idea/"; + description = "Free Java, Kotlin, Groovy and Scala IDE from Jetbrains (built from source)"; + longDescription = "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ."; + maintainers = with lib.maintainers; [ + gytis-ivaskevicius + tymscar + ]; + license = lib.licenses.asl20; + sourceProvenance = [ lib.sourceTypes.fromSource ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/idea.nix b/pkgs/applications/editors/jetbrains/ides/idea.nix new file mode 100644 index 0000000000000..beea85af05ef5 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/idea.nix @@ -0,0 +1,79 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + maven, + zlib, + lldb, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/idea/ideaIU-2025.3.1.tar.gz"; + hash = "sha256-IeG5C17GhHZ6A0mLpCTvP5rMXb91nM7v1e3UdPBDrWw="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/idea/ideaIU-2025.3.1-aarch64.tar.gz"; + hash = "sha256-CVcRMp0enBRkG6Qm5lLU29OIWyfJoEbkRyWuZ3SR6MM="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/idea/ideaIU-2025.3.1.dmg"; + hash = "sha256-rfWvODnge6Y4e/DsqU3y9EyCkCOhiYFw6svFy6/OA5M="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/idea/ideaIU-2025.3.1-aarch64.dmg"; + hash = "sha256-ITeGPMOl9KzSW6OKguAE6TXTqU+lZvjjhR1riorBJ3c="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "idea"; + + wmClass = "jetbrains-idea"; + product = "IntelliJ IDEA"; + productShort = "IDEA"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.138"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + extraLdPath = [ zlib ]; + extraWrapperArgs = [ + ''--set M2_HOME "${maven}/maven"'' + ''--set M2 "${maven}/maven/bin"'' + ]; + + buildInputs = [ + lldb + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/idea/"; + description = "Java, Kotlin, Groovy and Scala IDE from Jetbrains"; + longDescription = "IDE for Java SE, Groovy & Scala development Powerful environment for building Google Android apps Integration with JUnit, TestNG, popular SCMs, Ant & Maven. Also known as IntelliJ."; + maintainers = with lib.maintainers; [ + gytis-ivaskevicius + tymscar + ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/mps.nix b/pkgs/applications/editors/jetbrains/ides/mps.nix new file mode 100644 index 0000000000000..d01b9ad29d856 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/mps.nix @@ -0,0 +1,61 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/mps/2025.3/MPS-2025.3.tar.gz"; + hash = "sha256-xAI+UrTheCTWHSdoI4YZvhTlrlc121M+OVFkfzd7a3k="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/mps/2025.3/MPS-2025.3.tar.gz"; + hash = "sha256-xAI+UrTheCTWHSdoI4YZvhTlrlc121M+OVFkfzd7a3k="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/mps/2025.3/MPS-2025.3-macos.dmg"; + hash = "sha256-whYAjKkF79mrknHflZnvOOy2bLosYUguelZDSuPt3uY="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/mps/2025.3/MPS-2025.3-macos-aarch64.dmg"; + hash = "sha256-3HnEHOhRRI9IYjBhc5FO7h5j4jBBDtZTVkmO/S1fBEQ="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "mps"; + + wmClass = "jetbrains-MPS"; + product = "MPS"; + + # update-script-start: version + version = "2025.3"; + buildNumber = "253.28294.432"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/mps/"; + description = "IDE for building domain-specific languages from JetBrains"; + longDescription = "A metaprogramming system which uses projectional editing which allows users to overcome the limits of language parsers, and build DSL editors, such as ones with tables and diagrams."; + maintainers = [ ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/phpstorm.nix b/pkgs/applications/editors/jetbrains/ides/phpstorm.nix new file mode 100644 index 0000000000000..3c05396678d4a --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/phpstorm.nix @@ -0,0 +1,68 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/webide/PhpStorm-2025.3.1.tar.gz"; + hash = "sha256-/Yk3q2t5YFzvyZF//moI4FprfMAlb6IXhiPSTsMi+ik="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/webide/PhpStorm-2025.3.1-aarch64.tar.gz"; + hash = "sha256-dkhmf4W0xFkosE1MJvIogqiqZaeHpk+i96/+UaG8KmE="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/webide/PhpStorm-2025.3.1.dmg"; + hash = "sha256-EZiLzuXZSycepnrqzT6DYClZWmz+v+wmWVZfwYpK0tE="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/webide/PhpStorm-2025.3.1-aarch64.dmg"; + hash = "sha256-BFPgpu6Gw8v5e4xI8oJnUdgIW/ghG1QaBHUmIcWvFrw="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "phpstorm"; + + wmClass = "jetbrains-phpstorm"; + product = "PhpStorm"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.151"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/phpstorm/"; + description = "PHP IDE from JetBrains"; + longDescription = "PhpStorm provides an editor for PHP, HTML and JavaScript with on-the-fly code analysis, error prevention and automated refactorings for PHP and JavaScript code. "; + maintainers = with lib.maintainers; [ + dritter + tymscar + ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/pycharm-community.nix b/pkgs/applications/editors/jetbrains/ides/pycharm-community.nix new file mode 100644 index 0000000000000..2adad4bf52464 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/pycharm-community.nix @@ -0,0 +1,63 @@ +# TODO: This IDE is deprecated and scheduled for removal in 26.05 +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + pyCharmCommonOverrides, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/python/pycharm-community-2025.2.5.tar.gz"; + sha256 = "7f49a014f53f0f6f7c46f6710b131f390302287f4046b606331d88081cdb551f"; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/python/pycharm-community-2025.2.5-aarch64.tar.gz"; + sha256 = "67b61a3e788b043d93b3cc3e0dd3cea350e6d170402fd94adaf792cfc57e5462"; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/python/pycharm-community-2025.2.5.dmg"; + sha256 = "08ba97a278031ff1942ddefb18d8acf7582f0bb4a28ccdf5d65721bfb80ca456"; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/python/pycharm-community-2025.2.5-aarch64.dmg"; + sha256 = "040a4ed6bb7563972d844c450f615d0d11385e524fbbfdbfc9fc68d78811e994"; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "pycharm-community"; + + wmClass = "jetbrains-pycharm-ce"; + product = "PyCharm CE"; + productShort = "PyCharm"; + + # update-script-start: version + version = "2025.2.5"; + buildNumber = "252.28238.29"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + 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!"; + maintainers = with lib.maintainers; [ + genericnerdyusername + tymscar + ]; + license = lib.licenses.asl20; + sourceProvenance = [ lib.sourceTypes.fromSource ]; + }; +}).overrideAttrs + pyCharmCommonOverrides diff --git a/pkgs/applications/editors/jetbrains/ides/pycharm-oss.nix b/pkgs/applications/editors/jetbrains/ides/pycharm-oss.nix new file mode 100644 index 0000000000000..9b79a69e0ed9f --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/pycharm-oss.nix @@ -0,0 +1,66 @@ +{ + lib, + mkJetBrainsProduct, + mkJetBrainsSource, + pyCharmCommonOverrides, +}: +let + src = mkJetBrainsSource { + # update-script-start: source-args + version = "2025.3.1"; + buildNumber = "253.29346.142"; + buildType = "pycharm"; + ideaHash = "sha256-eAq/lgv6ZcN9SR2E1KYnnhDHe/rBQ3GqqbbF6GstDoU="; + androidHash = "sha256-quMCzrjCKIo1pkzw4PWewAs5tz7A2aq7TI5zd+QaaUY="; + jpsHash = "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk="; + restarterHash = "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag="; + mvnDeps = ../source/pycharm_maven_artefacts.json; + repositories = [ + "repo1.maven.org/maven2" + "packages.jetbrains.team/maven/p/ij/intellij-dependencies" + "dl.google.com/dl/android/maven2" + "download.jetbrains.com/teamcity-repository" + "maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies" + "packages.jetbrains.team/maven/p/grazi/grazie-platform-public" + "packages.jetbrains.team/maven/p/kpm/public" + "packages.jetbrains.team/maven/p/ki/maven" + "maven.pkg.jetbrains.space/public/p/compose/dev" + "packages.jetbrains.team/maven/p/amper/amper" + "packages.jetbrains.team/maven/p/kt/bootstrap" + ]; + kotlin-jps-plugin = { + version = "2.2.20"; + hash = "sha256-+jGghK2+yq+YFm5zT7ob+WTgTiJnHXAjDtlZjOzSISQ="; + }; + # update-script-end: source-args + }; +in +(mkJetBrainsProduct { + inherit src; + inherit (src) + version + buildNumber + libdbm + fsnotifier + ; + + pname = "pycharm-oss"; + + wmClass = "jetbrains-pycharm-ce"; + product = "PyCharm Open Source"; + productShort = "PyCharm"; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + 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!"; + maintainers = with lib.maintainers; [ + genericnerdyusername + tymscar + ]; + license = lib.licenses.asl20; + sourceProvenance = [ lib.sourceTypes.fromSource ]; + }; +}).overrideAttrs + pyCharmCommonOverrides diff --git a/pkgs/applications/editors/jetbrains/ides/pycharm.nix b/pkgs/applications/editors/jetbrains/ides/pycharm.nix new file mode 100644 index 0000000000000..222642ace59d4 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/pycharm.nix @@ -0,0 +1,71 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + pyCharmCommonOverrides, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/python/pycharm-2025.3.1.tar.gz"; + hash = "sha256-kz/ULXzCp2rUuiP5ESKU5N8BP6TDNiQ1oeM2gFHAc5E="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/python/pycharm-2025.3.1-aarch64.tar.gz"; + hash = "sha256-K29aQwEydz6nyvMEb3dj6noDHb+rbhvnK9yG88x6dYs="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/python/pycharm-2025.3.1.dmg"; + hash = "sha256-WGye7WfaYJ/B5WWov8NusVWyPlSD1dxunc+LVUD0f6U="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/python/pycharm-2025.3.1-aarch64.dmg"; + hash = "sha256-7I6XhW8A2pAgIMcrDwecwQmD3mu0Q4KS6l+qHlsMuTU="; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "pycharm"; + + wmClass = "jetbrains-pycharm"; + product = "PyCharm"; + productShort = "PyCharm"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.142"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/pycharm/"; + description = "Python IDE from JetBrains"; + 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!"; + maintainers = with lib.maintainers; [ + genericnerdyusername + tymscar + ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +}).overrideAttrs + pyCharmCommonOverrides diff --git a/pkgs/applications/editors/jetbrains/ides/rider.nix b/pkgs/applications/editors/jetbrains/ides/rider.nix new file mode 100644 index 0000000000000..9b454d68c5099 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/rider.nix @@ -0,0 +1,106 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + patchSharedLibs, + openssl, + libxcrypt, + lttng-ust_2_12, + musl, + libICE, + libSM, + libX11, + dotnetCorePackages, + xorg, + expat, + libxml2, + xz, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1.tar.gz"; + hash = "sha256-uoQPfEjafxGM9Xqowi3zASDRbxdfvOO+xqZVkO2H8ug="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1-aarch64.tar.gz"; + hash = "sha256-GQgPzcSPoPdD7WCSe3GXWjxHi4BSlhYc/YoKosBMj1I="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1.dmg"; + hash = "sha256-rd2Bbb3xMOLvXn3BhNeoCH+L+/brpOMurSRSBppJYH0="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/rider/JetBrains.Rider-2025.3.1-aarch64.dmg"; + hash = "sha256-1wgDI0EpAPXTcnAjPlpMdzARxoU9YDHOH15jXHdRFCY="; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "rider"; + + wmClass = "jetbrains-rider"; + product = "Rider"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.144"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + openssl + libxcrypt + lttng-ust_2_12 + musl + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + xorg.xcbutilkeysyms + ] + ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ + expat + libxml2 + xz + ]; + extraLdPath = lib.optionals (stdenv.hostPlatform.isLinux) [ + # Avalonia dependencies needed for dotMemory + libICE + libSM + libX11 + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/rider/"; + description = ".NET IDE from JetBrains"; + longDescription = "JetBrains Rider is a new .NET IDE based on the IntelliJ platform and ReSharper. Rider supports .NET Core, .NET Framework and Mono based projects. This lets you develop a wide array of applications including .NET desktop apps, services and libraries, Unity games, ASP.NET and ASP.NET Core web applications."; + maintainers = with lib.maintainers; [ raphaelr ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +}).overrideAttrs + (attrs: { + postInstall = + (attrs.postInstall or "") + + lib.optionalString stdenv.hostPlatform.isLinux '' + ${patchSharedLibs} + + for dir in $out/rider/lib/ReSharperHost/linux-*; do + rm -rf $dir/dotnet + ln -s ${dotnetCorePackages.sdk_10_0-source}/share/dotnet $dir/dotnet + done + ''; + }) diff --git a/pkgs/applications/editors/jetbrains/ides/ruby-mine.nix b/pkgs/applications/editors/jetbrains/ides/ruby-mine.nix new file mode 100644 index 0000000000000..84dc6cb1d887d --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/ruby-mine.nix @@ -0,0 +1,65 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/ruby/RubyMine-2025.3.1.tar.gz"; + hash = "sha256-6esgEcotVpTFjAEWkL9UTQJuOnwcDI3puzehj6DPgRg="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/ruby/RubyMine-2025.3.1-aarch64.tar.gz"; + hash = "sha256-v2A8ahuh5hiv23BYlkhEfPzlO02qegzGgHPBt35yfVU="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/ruby/RubyMine-2025.3.1.dmg"; + hash = "sha256-T86EmDpqzhbYR5FQt2UoAlCiYLPST7NyWNEUAAxsERU="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/ruby/RubyMine-2025.3.1-aarch64.dmg"; + hash = "sha256-Z/GqZ0uQ7FS6IfNSOtlAIY+Xm+/XQp44rYIryBRtFqQ="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "ruby-mine"; + + wmClass = "jetbrains-rubymine"; + product = "RubyMine"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.140"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/ruby/"; + description = "Ruby IDE from JetBrains"; + longDescription = "Ruby IDE from JetBrains"; + maintainers = with lib.maintainers; [ tymscar ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/rust-rover.nix b/pkgs/applications/editors/jetbrains/ides/rust-rover.nix new file mode 100644 index 0000000000000..30289c80def17 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/rust-rover.nix @@ -0,0 +1,85 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + patchSharedLibs, + python3, + openssl, + libxcrypt-legacy, + expat, + libxml2, + xz, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/rustrover/RustRover-2025.3.1.tar.gz"; + hash = "sha256-Whs04QocWe7jBpQja6qCM8d4dYB2k4G+AbTMsJYY7Ik="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/rustrover/RustRover-2025.3.1-aarch64.tar.gz"; + hash = "sha256-+w+BydKipgRxhISVSyYaZCvp7W9R3pj83GztsysKTJ4="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/rustrover/RustRover-2025.3.1.dmg"; + hash = "sha256-OJmHVFKlGC25OxMsANvIQ5T/tjdDC5fyOQvoq7BBJTc="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/rustrover/RustRover-2025.3.1-aarch64.dmg"; + hash = "sha256-EDoS7Rw3trOM/11jfn3HuNzHj1xXa6OLj4Ysa6NkfVI="; + }; + }; + # update-script-end: urls +in +(mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "rust-rover"; + + wmClass = "jetbrains-rustrover"; + product = "RustRover"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.139"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = + lib.optionals stdenv.hostPlatform.isLinux [ + python3 + openssl + libxcrypt-legacy + ] + ++ lib.optionals (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch) [ + expat + libxml2 + xz + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/rust/"; + description = "Rust IDE from JetBrains"; + longDescription = "Rust IDE from JetBrains"; + maintainers = with lib.maintainers; [ genericnerdyusername ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +}).overrideAttrs + (attrs: { + postFixup = '' + ${attrs.postFixup or ""} + ${patchSharedLibs} + ''; + }) diff --git a/pkgs/applications/editors/jetbrains/ides/webstorm.nix b/pkgs/applications/editors/jetbrains/ides/webstorm.nix new file mode 100644 index 0000000000000..bce2d34a87b0d --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/webstorm.nix @@ -0,0 +1,68 @@ +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1.tar.gz"; + hash = "sha256-CKhR0ha3QcSeu2hG4Xj7gj0yn+e5gkohNLaMj9Jboq4="; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1-aarch64.tar.gz"; + hash = "sha256-/Yuz7nDFSRZdkQJDe8oD6Ff8FHKBwdc4IknUaQwx3Yc="; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1.dmg"; + hash = "sha256-psuQZWL5WzfpweNMm9lWHeplOnJsldAr+pV6y+kJuI0="; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/webstorm/WebStorm-2025.3.1-aarch64.dmg"; + hash = "sha256-HCGZDO4ru//dj2yQ6AcbwD7H/lo2YuUZMcFSItS3zLI="; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "webstorm"; + + wmClass = "jetbrains-webstorm"; + product = "WebStorm"; + + # update-script-start: version + version = "2025.3.1"; + buildNumber = "253.29346.143"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/webstorm/"; + description = "Web IDE from JetBrains"; + longDescription = "WebStorm provides an editor for HTML, JavaScript (incl. Node.js), and CSS with on-the-fly code analysis, error prevention and automated refactorings for JavaScript code."; + maintainers = with lib.maintainers; [ + abaldeau + tymscar + ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/ides/writerside.nix b/pkgs/applications/editors/jetbrains/ides/writerside.nix new file mode 100644 index 0000000000000..a156e8fdbec55 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/ides/writerside.nix @@ -0,0 +1,66 @@ +# TODO: This IDE is deprecated and scheduled for removal in 26.05 +{ + stdenv, + lib, + fetchurl, + mkJetBrainsProduct, + libdbm, + fsnotifier, + musl, +}: +let + system = stdenv.hostPlatform.system; + # update-script-start: urls + urls = { + x86_64-linux = { + url = "https://download.jetbrains.com/writerside/writerside-243.22562.371.tar.gz"; + sha256 = "d49e58020d51ec4ccdbdffea5d42b5a2d776a809fc00789cef5abda7b23bd3f6"; + }; + aarch64-linux = { + url = "https://download.jetbrains.com/writerside/writerside-243.22562.371-aarch64.tar.gz"; + sha256 = "6067f6f73c4a178e2d0ae42bd18669045d85b5b5ed2c9115c2488ba7aa2a3d88"; + }; + x86_64-darwin = { + url = "https://download.jetbrains.com/writerside/writerside-243.22562.371.dmg"; + sha256 = "0c78b8035497c855aea5666256716778abd46dadf68f51e4f91c0db01f62b280"; + }; + aarch64-darwin = { + url = "https://download.jetbrains.com/writerside/writerside-243.22562.371-aarch64.dmg"; + sha256 = "9d86ef50b4c6d2a07d236219e9b05c0557241fb017d52ac395719bdb425130f5"; + }; + }; + # update-script-end: urls +in +mkJetBrainsProduct { + inherit libdbm fsnotifier; + + pname = "writerside"; + + wmClass = "jetbrains-writerside"; + product = "Writerside"; + + # update-script-start: version + version = "2024.3 EAP"; + buildNumber = "243.22562.371"; + # update-script-end: version + + src = fetchurl (urls.${system} or (throw "Unsupported system: ${system}")); + + buildInputs = [ + musl + ]; + + # NOTE: meta attrs are currently used by the desktop entry, so changing them may cause rebuilds (see TODO in README) + meta = { + homepage = "https://www.jetbrains.com/writerside/"; + description = "Documentation IDE from JetBrains"; + longDescription = "The most powerful development environment – now adapted for writing documentation."; + maintainers = with lib.maintainers; [ zlepper ]; + license = lib.licenses.unfree; + sourceProvenance = + if stdenv.hostPlatform.isDarwin then + [ lib.sourceTypes.binaryNativeCode ] + else + [ lib.sourceTypes.binaryBytecode ]; + }; +} diff --git a/pkgs/applications/editors/jetbrains/readme.md b/pkgs/applications/editors/jetbrains/readme.md index 43744856818eb..220c2b210d9cc 100644 --- a/pkgs/applications/editors/jetbrains/readme.md +++ b/pkgs/applications/editors/jetbrains/readme.md @@ -1,4 +1,4 @@ -This directory contains the build expressions needed to build any of the jetbrains IDEs. +This directory contains the build expressions needed to build any of the JetBrains IDEs. The jdk is in `pkgs/development/compilers/jetbrains-jdk`. ## Tests: @@ -35,31 +35,39 @@ fetchurl { } ``` -## How to update stuff: - - Run ./bin/update_bin.py, this will update binary IDEs, and automatically commit them - - Source builds need a bit more effort, as they **aren't automated at the moment**: - - Run ./source/update.py ./source/sources.json. This will update the source version to the latest available version. - - Run these commands respectively: - - `nix build .#jetbrains.idea-oss.src.src && ./source/build_maven.py source/idea_maven_artefacts.json result/` for IDEA - - `nix build .#jetbrains.pycharm-oss.src.src && ./source/build_maven.py source/pycharm_maven_artefacts.json result/` for PyCharm - - Make sure the Kotlin version used is correct. - - Check the recommended Kotlin version in `.idea/kotlinc.xml` in the IDEA source root - - Do a test build - - If it succeeds, make a commit - - make a PR/merge - - If it fails, ping/message GenericNerdyUsername or the nixpkgs Jetbrains maintainer team +## How to update IDEs: + - Run `./updater/main.py`. + This will update binary and source IDEs. + After this you can commit them. + - See `./updater/main.py --help` for additional flags. + - The IDEs have `passthru.updateScript` set up to run `./updater/main.py`. + The script then uses the `UPDATE_NIX_*` environment variables as documented. + +To keep things simple, the update script will search for the following markers and may replace any content between them: +- `update-script-start: urls` / `update-script-end: urls`: URLs for binary IDEs +- `update-script-start: version` / `update-script-end: version`: Version and build number for binary IDEs +- `update-script-start: source-args` / `update-script-end: source-args`: Arguments for `mkJetBrainsSource` for source IDEs. + +Any comments or other manual changes between these markers will be removed when the script runs. ## How to add an IDE: - - Make dummy entries in `bin/versions.json` (make sure to set the version to something older than the real one) - - Run `bin/update_bin.py` - - Add an entry in `ides.json` - - Add an entry in `default.nix` + - Add a new derivation in `ides/` + - Add an entry to the URL templates in `updater/updateInfo.json` + - Add it to `default.nix` ### TODO: + - remove the usage of `meta.` properties for building the Linux desktop files + (JetBrains already provides their own Desktop files, we can just use those probably?) + - drop the community IDEs + - Switch `mkJetbrainsProduct` to use `lib.extendMkDerivation`, see also: + - https://github.com/NixOS/nixpkgs/pull/475183#discussion_r2655305961 + - https://github.com/NixOS/nixpkgs/pull/475183#discussion_r2655348886 + - move PyCharm overrides to a common place outside of `default.nix` + - package `patchSharedLibs` from `default.nix` as a hook + - cleanup this TODO list, especially the following points, which have been here since 2023 - replace `libxcrypt-legacy` with `libxcrypt` when supported - make `jetbrains-remote-dev.patch` cleaner - is extraLdPath needed for IDEA? - - set meta.sourceProvenance for everything - from source builds: - remove timestamps in output `.jar` of `jps-bootstrap` - automated update scripts diff --git a/pkgs/applications/editors/jetbrains/source/build.nix b/pkgs/applications/editors/jetbrains/source/build.nix index 84ee92265ac44..2359ad1dc47b6 100644 --- a/pkgs/applications/editors/jetbrains/source/build.nix +++ b/pkgs/applications/editors/jetbrains/source/build.nix @@ -23,7 +23,8 @@ p7zip, pkg-config, xorg, - +}: +{ version, buildNumber, buildType, @@ -35,7 +36,6 @@ repositories, kotlin-jps-plugin, }: - let kotlin' = kotlin.overrideAttrs (oldAttrs: { version = "2.2.20"; @@ -313,6 +313,12 @@ stdenvNoCC.mkDerivation rec { ''; passthru = { - inherit libdbm fsnotifier jps-bootstrap; + inherit + version + buildNumber + libdbm + fsnotifier + jps-bootstrap + ; }; } diff --git a/pkgs/applications/editors/jetbrains/source/build_maven.py b/pkgs/applications/editors/jetbrains/source/build_maven.py deleted file mode 100755 index d549072cf489b..0000000000000 --- a/pkgs/applications/editors/jetbrains/source/build_maven.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env nix-shell -#! nix-shell -i python3 -p python3 python3.pkgs.xmltodict -import os -import urllib -from argparse import ArgumentParser -from xmltodict import parse -from json import dump -from sys import stdout - -def get_args() -> (str, list[str]): - parser = ArgumentParser( - description="Given the path of a intellij source tree, make a list of urls and hashes of maven artefacts required to build" - ) - parser.add_argument("out", help="File to output json to") - parser.add_argument("path", help="Path to the intellij-community source dir") - args = parser.parse_args() - return args.path, args.out - - -def ensure_is_list(x): - if type(x) != list: - return [x] - return x - -def add_entries(sources, targets, hashes): - for artefact in sources: - target = None - base_jar_name = os.path.basename(urllib.parse.urlparse(artefact["@url"]).path) - for candidate in targets: - if candidate["@url"].endswith(base_jar_name + "!/"): - target = candidate - break - if target is None: - raise ValueError(f"Did not find target for source {artefact}") - - url = artefact["@url"].removeprefix("file://$MAVEN_REPOSITORY$/") - if url == artefact["@url"]: - raise ValueError(f"Unexpected artefact URL {url}") - - path = target["@url"].removeprefix("jar://$MAVEN_REPOSITORY$/").removesuffix("!/") - if path == target["@url"]: - raise ValueError(f"Unexpected target path {path}") - - hashes.append({ - "url": url, - "hash": artefact["sha256sum"], - "path": path - }) - - -def add_libraries(root_path: str, hashes: list[dict[str, str]], projects_to_process: list[str]): - library_paths = os.listdir(root_path + "/libraries/") - for path in library_paths: - file_contents = parse(open(root_path + "/libraries/" + path).read()) - if "properties" not in file_contents["component"]["library"]: - continue - sources = ensure_is_list(file_contents["component"]["library"]["properties"]["verification"]["artifact"]) - targets = ensure_is_list(file_contents["component"]["library"]["CLASSES"]["root"]) - add_entries(sources, targets, hashes) - - modules_xml = parse(open(root_path+"/modules.xml").read()) - for module in modules_xml["project"]["component"]["modules"]["module"]: - projects_to_process.append(module["@filepath"]) - - -def add_iml(path: str, hashes: list[dict[str, str]], projects_to_process: list[str]): - try: - contents = parse(open(path).read()) - except FileNotFoundError: - print(f"Warning: path {path} does not exist (did you forget the android directory?)") - return - for manager in ensure_is_list(contents["module"]["component"]): - if manager["@name"] != "NewModuleRootManager": - continue - - for entry in manager["orderEntry"]: - if type(entry) != dict or \ - entry["@type"] != "module-library" or \ - "properties" not in entry["library"]: - continue - - sources = ensure_is_list(entry["library"]["properties"]["verification"]["artifact"]) - targets = ensure_is_list(entry["library"]["CLASSES"]["root"]) - add_entries(sources, targets, hashes) - - -def main(): - root_path, out = get_args() - file_hashes = [] - projects_to_process: list[str] = [root_path+"/.idea"] - - while projects_to_process: - elem = projects_to_process.pop() - elem = elem.replace("$PROJECT_DIR$", root_path) - if elem.endswith(".iml"): - add_iml(elem, file_hashes, projects_to_process) - else: - add_libraries(elem, file_hashes, projects_to_process) - - if out == "stdout": - dump(file_hashes, stdout, indent=4) - else: - file = open(out, "w") - dump(file_hashes, file, indent=4) - file.write("\n") - - -if __name__ == '__main__': - main() diff --git a/pkgs/applications/editors/jetbrains/source/default.nix b/pkgs/applications/editors/jetbrains/source/default.nix deleted file mode 100644 index 84a27ee601353..0000000000000 --- a/pkgs/applications/editors/jetbrains/source/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -let - ides = builtins.fromJSON (builtins.readFile ./sources.json); -in -{ - callPackage, -}: -builtins.mapAttrs ( - _: info: callPackage ./build.nix (info // { mvnDeps = ./. + "/${info.mvnDeps}"; }) -) ides diff --git a/pkgs/applications/editors/jetbrains/source/sources.json b/pkgs/applications/editors/jetbrains/source/sources.json deleted file mode 100644 index d3bc51dd97c97..0000000000000 --- a/pkgs/applications/editors/jetbrains/source/sources.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "idea-oss": { - "version": "2025.3.1", - "buildNumber": "253.29346.138", - "buildType": "idea", - "ideaHash": "sha256-eAq/lgv6ZcN9SR2E1KYnnhDHe/rBQ3GqqbbF6GstDoU=", - "androidHash": "sha256-quMCzrjCKIo1pkzw4PWewAs5tz7A2aq7TI5zd+QaaUY=", - "jpsHash": "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk=", - "restarterHash": "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag=", - "mvnDeps": "idea_maven_artefacts.json", - "repositories": [ - "repo1.maven.org/maven2", - "packages.jetbrains.team/maven/p/ij/intellij-dependencies", - "dl.google.com/dl/android/maven2", - "download.jetbrains.com/teamcity-repository", - "maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies", - "packages.jetbrains.team/maven/p/grazi/grazie-platform-public", - "packages.jetbrains.team/maven/p/kpm/public", - "packages.jetbrains.team/maven/p/ki/maven", - "maven.pkg.jetbrains.space/public/p/compose/dev", - "packages.jetbrains.team/maven/p/amper/amper", - "packages.jetbrains.team/maven/p/kt/bootstrap" - ], - "kotlin-jps-plugin": { - "version": "2.2.20", - "hash": "sha256-+jGghK2+yq+YFm5zT7ob+WTgTiJnHXAjDtlZjOzSISQ=" - } - }, - "pycharm-oss": { - "version": "2025.3.1", - "buildNumber": "253.29346.142", - "buildType": "pycharm", - "ideaHash": "sha256-eAq/lgv6ZcN9SR2E1KYnnhDHe/rBQ3GqqbbF6GstDoU=", - "androidHash": "sha256-quMCzrjCKIo1pkzw4PWewAs5tz7A2aq7TI5zd+QaaUY=", - "jpsHash": "sha256-iHpt926BDLNUwHRXvkqVgwlWiLo1qSZEaGeJcS0Fjmk=", - "restarterHash": "sha256-acCmC58URd6p9uKZrm0qWgdZkqu9yqCs23v8qgxV2Ag=", - "mvnDeps": "pycharm_maven_artefacts.json", - "repositories": [ - "repo1.maven.org/maven2", - "packages.jetbrains.team/maven/p/ij/intellij-dependencies", - "dl.google.com/dl/android/maven2", - "download.jetbrains.com/teamcity-repository", - "maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies", - "packages.jetbrains.team/maven/p/grazi/grazie-platform-public", - "packages.jetbrains.team/maven/p/kpm/public", - "packages.jetbrains.team/maven/p/ki/maven", - "maven.pkg.jetbrains.space/public/p/compose/dev", - "packages.jetbrains.team/maven/p/amper/amper", - "packages.jetbrains.team/maven/p/kt/bootstrap" - ], - "kotlin-jps-plugin": { - "version": "2.2.20", - "hash": "sha256-+jGghK2+yq+YFm5zT7ob+WTgTiJnHXAjDtlZjOzSISQ=" - } - } -} diff --git a/pkgs/applications/editors/jetbrains/source/update.py b/pkgs/applications/editors/jetbrains/source/update.py deleted file mode 100755 index 967ee9f1dca8b..0000000000000 --- a/pkgs/applications/editors/jetbrains/source/update.py +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/env nix-shell -#! nix-shell -i python3 -p python3 python3.pkgs.packaging python3.pkgs.xmltodict python3.pkgs.requests nurl -import os -import subprocess -import pprint -import pathlib -import requests -import json -import re -from argparse import ArgumentParser -from xmltodict import parse -from json import dump, loads -from sys import stdout -from packaging import version - -UPDATES_URL = "https://www.jetbrains.com/updates/updates.xml" -IDES_FILE_PATH = pathlib.Path(__file__).parent.joinpath("..").joinpath("ides.json").resolve() - - -def convert_hash_to_sri(base32: str) -> str: - result = subprocess.run(["nix-hash", "--to-sri", "--type", "sha256", base32], capture_output=True, check=True, text=True) - return result.stdout.strip() - - -def ensure_is_list(x): - if type(x) != list: - return [x] - return x - - -def one_or_more(x): - return x if isinstance(x, list) else [x] - - -# TODO: Code duplication to update_bin.py - eventually refactor or merge scripts -def download_channels(): - print(f"Checking for updates from {UPDATES_URL}") - updates_response = requests.get(UPDATES_URL) - updates_response.raise_for_status() - root = parse(updates_response.text) - products = root["products"]["product"] - return { - channel["@name"]: channel - for product in products - if "channel" in product - for channel in one_or_more(product["channel"]) - } - - -# TODO: Code duplication to update_bin.py - eventually refactor or merge scripts -def build_version(build): - build_number = build["@fullNumber"] if "@fullNumber" in build else build["@number"] - return version.parse(build_number) - - -# TODO: Code duplication to update_bin.py - eventually refactor or merge scripts -def latest_build(channel): - builds = one_or_more(channel["build"]) - latest = max(builds, key=build_version) - return latest - - -def jar_repositories(root_path: str) -> list[str]: - repositories = [] - file_contents = parse(open(root_path + "/.idea/jarRepositories.xml").read()) - component = file_contents['project']['component'] - if component['@name'] != 'RemoteRepositoriesConfiguration': - return repositories - options = component['remote-repository'] - for option in ensure_is_list(options): - for item in option['option']: - if item['@name'] == 'url': - repositories.append( - # Remove protocol and cache-redirector server, we only want the original URL. We try both the original - # URL and the URL via the cache-redirector for download in build.nix - re.sub(r'^https?://', '', item['@value']).removeprefix("cache-redirector.jetbrains.com/") - ) - - return repositories - - -def kotlin_jps_plugin_info(root_path: str) -> (str, str): - file_contents = parse(open(root_path + "/.idea/kotlinc.xml").read()) - components = file_contents['project']['component'] - for component in components: - if component['@name'] != 'KotlinJpsPluginSettings': - continue - - option = component['option'] - version = option['@value'] - - print(f"* Prefetching Kotlin JPS Plugin version {version}...") - prefetch = subprocess.run(["nix-prefetch-url", "--type", "sha256", f"https://packages.jetbrains.team/maven/p/ij/intellij-dependencies/org/jetbrains/kotlin/kotlin-jps-plugin-classpath/{version}/kotlin-jps-plugin-classpath-{version}.jar"], capture_output=True, check=True, text=True) - - return (version, convert_hash_to_sri(prefetch.stdout.strip())) - - -def requested_kotlinc_version(root_path: str) -> str: - file_contents = parse(open(root_path + "/.idea/kotlinc.xml").read()) - components = file_contents['project']['component'] - for component in components: - if component['@name'] != 'KotlinJpsPluginSettings': - continue - - option = component['option'] - version = option['@value'] - - return version - - -def prefetch_intellij_community(variant: str, buildNumber: str) -> (str, str): - print("* Prefetching IntelliJ community source code...") - prefetch = subprocess.run(["nix-prefetch-url", "--print-path", "--unpack", "--name", "source", "--type", "sha256", f"https://github.com/jetbrains/intellij-community/archive/{variant}/{buildNumber}.tar.gz"], capture_output=True, check=True, text=True) - parts = prefetch.stdout.strip().split() - - hash = convert_hash_to_sri(parts[0]) - outPath = parts[1] - - return (hash, outPath) - - -def prefetch_android(variant: str, buildNumber: str) -> str: - print("* Prefetching Android plugin source code...") - prefetch = subprocess.run(["nix-prefetch-url", "--unpack", "--name", "source", "--type", "sha256", f"https://github.com/jetbrains/android/archive/{variant}/{buildNumber}.tar.gz"], capture_output=True, check=True, text=True) - return convert_hash_to_sri(prefetch.stdout.strip()) - - -def generate_restarter_hash(nixpkgs_path: str, root_path: str) -> str: - print("* Generating restarter Cargo hash...") - root_name = pathlib.Path(root_path).name - output = subprocess.run(["nurl", "--expr", f''' - (import {nixpkgs_path} {{}}).rustPlatform.buildRustPackage {{ - name = "restarter"; - src = {root_path}; - sourceRoot = "{root_name}/native/restarter"; - cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - }} - '''], capture_output=True, check=True, text=True) - return output.stdout.strip() - - -def generate_jps_hash(nixpkgs_path: str, root_path: str) -> str: - print("* Generating jps repo hash...") - jps_repo_nix = pathlib.Path(__file__).parent.joinpath("jps_repo.nix").resolve() - output = subprocess.run(["nurl", "--expr", f''' - (import {nixpkgs_path} {{}}).callPackage {jps_repo_nix} {{ - jbr = (import {nixpkgs_path} {{}}).jetbrains.jdk-no-jcef; - src = {root_path}; - jpsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - }} - '''], capture_output=True, check=True, text=True) - return output.stdout.strip() - - -def get_args() -> str: - parser = ArgumentParser( - description="Updates the IDEA / PyCharm source build infomations" - ) - parser.add_argument("out", help="File to output json to") - args = parser.parse_args() - return args.out - - -# TODO: Code duplication to update_bin.py - eventually refactor or merge scripts -def get_latest_versions(channels: dict, ides: dict, name: str) -> (str, str): - update_channel = ides[name]['updateChannel'] - print(f"Fetching latest {name} (channel: {update_channel}) release...") - channel = channels[update_channel] - - build = latest_build(channel) - new_version = build["@version"] - new_build_number = "" - if "@fullNumber" not in build: - new_build_number = build["@number"] - else: - new_build_number = build["@fullNumber"] - version_number = new_version.split(' ')[0] - - print(f"* Version: {version_number} - Build: {new_build_number}") - return version_number, new_build_number - - -def main(): - out = get_args() - - # source Path: + if current_path.joinpath("flake.nix").exists(): + return current_path + parent = current_path.parent + if parent == current_path: + raise Exception("nixpkgs could not be found, please provide --nixpkgs-root") + return find_nixpkgs(parent) + + +@dataclasses.dataclass(slots=True) +class UpdaterConfig: + nixpkgs_root: Path + jetbrains_root: Path + ide: str | None # If None: Run for all IDEs + old_version: str | None + no_bin: bool + no_src: bool + no_maven_deps: bool + + def __init__(self, argparse_result): + self.nixpkgs_root = ( + Path(argparse_result.nixpkgs_root) + if argparse_result.nixpkgs_root is not None + else find_nixpkgs(Path.cwd()) + ) + self.jetbrains_root = ( + self.nixpkgs_root / "pkgs" / "applications" / "editors" / "jetbrains" + ) + self.ide = ( + argparse_result.ide + if argparse_result.ide is not None + else os.environ.get("UPDATE_NIX_PNAME") + ) + self.old_version = ( + argparse_result.old_version + if argparse_result.old_version is not None + else os.environ.get("UPDATE_NIX_OLD_VERSION") + ) + self.no_bin = argparse_result.no_bin + self.no_src = argparse_result.no_src + self.no_maven_deps = argparse_result.no_maven_deps diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/fetcher.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/fetcher.py new file mode 100644 index 0000000000000..077bd6306e4a4 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/fetcher.py @@ -0,0 +1,132 @@ +import dataclasses +from urllib import request +from urllib.error import HTTPError + +import requests +import xmltodict +from packaging import version + +from jetbrains_nix_updater.config import SUPPORTED_SYSTEMS +from jetbrains_nix_updater.ides import Ide +from jetbrains_nix_updater.util import one_or_more + +UPDATES_URL = "https://www.jetbrains.com/updates/updates.xml" + + +@dataclasses.dataclass(slots=True) +class VersionInfo: + version: str + build_number: str + urls: dict[str, str | None] + + def download_sha256(self, system: str) -> str: + if self.urls[system] is None: + raise Exception("No URL available") + print(f"[.] Downloading sha256 for {self.urls[system]}") + url = f"{self.urls[system]}.sha256" + download_response = requests.get(url) + download_response.raise_for_status() + return download_response.content.decode("UTF-8").split(" ")[0] + + +class VersionFetcher: + # Cached updates.xml content + _channels: dict | None = None + + @property + def channels(self) -> dict: + if self._channels is None: + self._channels = self.download_channels() + return self._channels + + def latest_version_info( + self, ide: Ide, ignore_no_url_error=False + ) -> VersionInfo | None: + if ide.update_info is None: + print(f"[!] no update info for {ide.name} in `updateInfo.json` - skipping!") + return None + channel_name = ide.update_info["channel"] + channel = self.channels.get(channel_name) + if channel is None: + print( + f"[!] failed to find IDE channel {channel_name} - skipping! check {ide.name}'s `channel`!" + ) + return None + try: + build = self.latest_build(channel) + new_version = build["@version"] + if "@fullNumber" not in build: + new_build_number = build["@number"] + else: + new_build_number = build["@fullNumber"] + if "EAP" not in channel["@name"]: + version_or_build_number = new_version + else: + version_or_build_number = new_build_number + version_number = new_version.split(" ")[0] + download_urls = {} + for system in SUPPORTED_SYSTEMS: + download_url = self.make_url( + ide.update_info["urls"].get(system, None), + version_or_build_number, + version_number, + ) + if not download_url and not ignore_no_url_error: + print( + f"[!] no valid URL found for '{ide.name}' for '{system}'! make sure `updater/updateInfo.json` contains an entry and is correct." + ) + download_urls[system] = None + else: + download_urls[system] = download_url + return VersionInfo( + version=new_version, + build_number=new_build_number, + urls=download_urls, + ) + except Exception as e: + print(f"[!] exception while trying to fetch version: {e} - skipping!") + return None + + @classmethod + def latest_build(cls, channel: dict) -> dict: + builds = one_or_more(channel["build"]) + latest = max(builds, key=cls.build_version) + return latest + + @staticmethod + def download_channels(): + print(f"[-] Checking for updates from {UPDATES_URL}") + updates_response = requests.get(UPDATES_URL) + updates_response.raise_for_status() + root = xmltodict.parse(updates_response.text) + products = root["products"]["product"] + return { + channel["@name"]: channel + for product in products + if "channel" in product + for channel in one_or_more(product["channel"]) + } + + @staticmethod + def build_version(build): + build_number = ( + build["@fullNumber"] if "@fullNumber" in build else build["@number"] + ) + return version.parse(build_number) + + @staticmethod + def make_url( + template: str | None, version_or_build_number: str, version_number: str + ) -> str | None: + if template is None: + return None + release = [str(n) for n in version.parse(version_number).release] + for k in range(len(release), 0, -1): + s = ".".join(release[0:k]) + url = template.format(version=version_or_build_number, versionMajorMinor=s) + try: + if request.urlopen(url).getcode() == 200: + return url + except HTTPError: + pass + return None diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/ides.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/ides.py new file mode 100644 index 0000000000000..bbe68b3a7d2ff --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/ides.py @@ -0,0 +1,64 @@ +import sys + +from subprocess import CalledProcessError +from typing import Iterable, TypedDict + +import dataclasses +from pathlib import Path + +from jetbrains_nix_updater.util import run_command + + +class UpdateInfo(TypedDict): + channel: str + urls: dict[str, str] + + +@dataclasses.dataclass(slots=True) +class Ide: + name: str + drv_path: Path + is_source: bool + 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 get_single_ide(update_info: dict[str, UpdateInfo], jb_root: Path, name: str) -> Ide: + drv_path = jb_root / "ides" / f"{name}.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), + 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), + ) diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_bin.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_bin.py new file mode 100644 index 0000000000000..49095eedcaed9 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_bin.py @@ -0,0 +1,37 @@ +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.util import replace_blocks, convert_hash_to_sri + + +def run_bin_update(ide: Ide, info: VersionInfo, config: UpdaterConfig): + urls_nix = "" + for system, url in info.urls.items(): + urls_nix += f""" + {system} = {{ + url = "{url}"; + hash = "{convert_hash_to_sri(info.download_sha256(system))}"; + }};""" + + try: + replace_blocks( + config, + ide.drv_path, + [ + ( + "version", + f""" + version = "{info.version}"; + buildNumber = "{info.build_number}"; + """, + ), + ( + "urls", + f""" + urls = {{{urls_nix}}}; + """, + ), + ], + ) + except Exception as e: + print(f"[!] Writing update info to file failed: {e}") diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src.py new file mode 100644 index 0000000000000..54cb9249bee4e --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src.py @@ -0,0 +1,205 @@ +import json +import re +from pathlib import Path +from xmltodict import parse + +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.update_src_maven import ( + get_maven_deps_for_ide, + ensure_is_list, +) +from jetbrains_nix_updater.util import replace_blocks, run_command, convert_hash_to_sri + + +def jar_repositories(root_path: Path) -> list[str]: + repositories = [] + file_contents = parse(open(root_path / ".idea" / "jarRepositories.xml").read()) + component = file_contents["project"]["component"] + if component["@name"] != "RemoteRepositoriesConfiguration": + return repositories + options = component["remote-repository"] + for option in ensure_is_list(options): + for item in option["option"]: + if item["@name"] == "url": + repositories.append( + # Remove protocol and cache-redirector server, we only want the original URL. We try both the original + # URL and the URL via the cache-redirector for download in build.nix + re.sub(r"^https?://", "", item["@value"]).removeprefix( + "cache-redirector.jetbrains.com/" + ) + ) + + return repositories + + +def kotlin_jps_plugin_info(root_path: Path) -> tuple[str, str]: + file_contents = parse(open(root_path / ".idea" / "kotlinc.xml").read()) + components = file_contents["project"]["component"] + for component in components: + if component["@name"] != "KotlinJpsPluginSettings": + continue + + option = component["option"] + version = option["@value"] + + print(f"[*] Prefetching Kotlin JPS Plugin version {version}...") + prefetch = run_command( + [ + "nix-prefetch-url", + "--type", + "sha256", + f"https://packages.jetbrains.team/maven/p/ij/intellij-dependencies/org/jetbrains/kotlin/kotlin-jps-plugin-classpath/{version}/kotlin-jps-plugin-classpath-{version}.jar", + ] + ) + + return (version, convert_hash_to_sri(prefetch)) + + +def requested_kotlinc_version(root_path: Path) -> str: + file_contents = parse(open(root_path / ".idea" / "kotlinc.xml").read()) + components = file_contents["project"]["component"] + for component in components: + if component["@name"] != "KotlinJpsPluginSettings": + continue + + option = component["option"] + version = option["@value"] + + return version + + +def prefetch_intellij_community(variant: str, build_number: str) -> tuple[str, Path]: + print("[*] Prefetching IntelliJ community source code...") + prefetch = run_command( + [ + "nix-prefetch-url", + "--print-path", + "--unpack", + "--name", + "source", + "--type", + "sha256", + f"https://github.com/jetbrains/intellij-community/archive/{variant}/{build_number}.tar.gz", + ] + ) + parts = prefetch.split() + + hash = convert_hash_to_sri(parts[0]) + out_path = parts[1] + + return (hash, Path(out_path)) + + +def prefetch_android(variant: str, build_number: str) -> str: + print("[*] Prefetching Android plugin source code...") + prefetch = run_command( + [ + "nix-prefetch-url", + "--unpack", + "--name", + "source", + "--type", + "sha256", + f"https://github.com/jetbrains/android/archive/{variant}/{build_number}.tar.gz", + ] + ) + return convert_hash_to_sri(prefetch) + + +def generate_restarter_hash(config: UpdaterConfig, root_path: Path) -> str: + print("[*] Generating restarter Cargo hash...") + root_name = root_path.name + return run_command( + [ + "nurl", + "--expr", + f''' + (import {config.nixpkgs_root} {{}}).rustPlatform.buildRustPackage {{ + name = "restarter"; + src = {root_path}; + sourceRoot = "{root_name}/native/restarter"; + cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + }} + ''', + ] + ) + + +def generate_jps_hash(config: UpdaterConfig, root_path: Path) -> str: + print("[*] Generating jps repo hash...") + jps_repo_nix = config.jetbrains_root / "source" / "jps_repo.nix" + return run_command( + [ + "nurl", + "--expr", + f""" + (import {config.nixpkgs_root} {{}}).callPackage {jps_repo_nix} {{ + jbr = (import {config.nixpkgs_root} {{}}).jetbrains.jdk-no-jcef; + src = {root_path}; + jpsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + }} + """, + ] + ) + + +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): + variant = ide.name.removesuffix("-oss") + intellij_hash, intellij_outpath = prefetch_intellij_community( + variant, info.build_number + ) + android_hash = prefetch_android(variant, info.build_number) + jps_hash = generate_jps_hash(config, intellij_outpath) + restarter_hash = generate_restarter_hash(config, intellij_outpath) + repositories = jar_repositories(intellij_outpath) + kjps_plugin_version, kjps_plugin_hash = kotlin_jps_plugin_info(intellij_outpath) + kotlinc_version = requested_kotlinc_version(intellij_outpath) + print( + f"[i] Prefetched IDEA Open Source requested Kotlin compiler {kotlinc_version}" + ) + + repositories_nix = " ".join(f'"{x}"' for x in repositories) + + try: + replace_blocks( + config, + ide.drv_path, + [ + ( + "source-args", + f""" + version = "{info.version}"; + buildNumber = "{info.build_number}"; + buildType = "{variant}"; + ideaHash = "{intellij_hash}"; + androidHash = "{android_hash}"; + jpsHash = "{jps_hash}"; + restarterHash = "{restarter_hash}"; + mvnDeps = ../source/{variant}_maven_artefacts.json; + repositories = [ + {repositories_nix} + ]; + kotlin-jps-plugin = {{ + version = "{kjps_plugin_version}"; + hash = "{kjps_plugin_hash}"; + }}; + """, + ) + ], + ) + except Exception as e: + print(f"[!] Writing update info to file failed: {e}") + return + + 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") diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src_maven.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src_maven.py new file mode 100644 index 0000000000000..7082cb783cc59 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/update_src_maven.py @@ -0,0 +1,111 @@ +import os +from pathlib import Path +from tempfile import TemporaryDirectory +from urllib.parse import urlparse +from xmltodict import parse + +from jetbrains_nix_updater.config import UpdaterConfig +from jetbrains_nix_updater.ides import Ide +from jetbrains_nix_updater.util import ensure_is_list, run_command + + +def add_entries(sources, targets, hashes): + for artefact in sources: + target = None + base_jar_name = os.path.basename(urlparse(artefact["@url"]).path) + for candidate in targets: + if candidate["@url"].endswith(base_jar_name + "!/"): + target = candidate + break + if target is None: + raise ValueError(f"Did not find target for source {artefact}") + + url = artefact["@url"].removeprefix("file://$MAVEN_REPOSITORY$/") + if url == artefact["@url"]: + raise ValueError(f"Unexpected artefact URL {url}") + + path = ( + target["@url"].removeprefix("jar://$MAVEN_REPOSITORY$/").removesuffix("!/") + ) + if path == target["@url"]: + raise ValueError(f"Unexpected target path {path}") + + hashes.append({"url": url, "hash": artefact["sha256sum"], "path": path}) + + +def add_libraries( + root_path: str, hashes: list[dict[str, str]], projects_to_process: list[str] +): + library_paths = os.listdir(root_path + "/libraries/") + for path in library_paths: + file_contents = parse(open(root_path + "/libraries/" + path).read()) + if "properties" not in file_contents["component"]["library"]: + continue + sources = ensure_is_list( + file_contents["component"]["library"]["properties"]["verification"][ + "artifact" + ] + ) + targets = ensure_is_list( + file_contents["component"]["library"]["CLASSES"]["root"] + ) + add_entries(sources, targets, hashes) + + modules_xml = parse(open(root_path + "/modules.xml").read()) + for module in modules_xml["project"]["component"]["modules"]["module"]: + projects_to_process.append(module["@filepath"]) + + +def add_iml(path: str, hashes: list[dict[str, str]], projects_to_process: list[str]): + try: + contents = parse(open(path).read()) + except FileNotFoundError: + print( + f"Warning: path {path} does not exist (did you forget the android directory?)" + ) + return + for manager in ensure_is_list(contents["module"]["component"]): + if manager["@name"] != "NewModuleRootManager": + continue + + for entry in manager["orderEntry"]: + if ( + type(entry) != dict + or entry["@type"] != "module-library" + or "properties" not in entry["library"] + ): + continue + + sources = ensure_is_list( + entry["library"]["properties"]["verification"]["artifact"] + ) + targets = ensure_is_list(entry["library"]["CLASSES"]["root"]) + add_entries(sources, targets, hashes) + + +def get_maven_deps_for_ide(config: UpdaterConfig, ide: Ide) -> list[dict]: + with TemporaryDirectory() as tmp_dir: + root_path = Path(tmp_dir) / "result" + run_command( + [ + "nix-build", + "--out-link", + root_path, + "--attr", + f"jetbrains.{ide.name}.src.src", + ], + cwd=config.nixpkgs_root, + ) + + file_hashes = [] + projects_to_process: list[str] = [str(root_path / ".idea")] + + while projects_to_process: + elem = projects_to_process.pop() + elem = elem.replace("$PROJECT_DIR$", str(root_path)) + if elem.endswith(".iml"): + add_iml(elem, file_hashes, projects_to_process) + else: + add_libraries(elem, file_hashes, projects_to_process) + + return file_hashes diff --git a/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/util.py b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/util.py new file mode 100644 index 0000000000000..69a23a5a7263d --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/jetbrains_nix_updater/util.py @@ -0,0 +1,82 @@ +from typing import Iterable + +import subprocess +from pathlib import Path + +from jetbrains_nix_updater.config import UpdaterConfig + + +def run_command(cmd: list[str], **kwargs) -> str: + result = subprocess.run(cmd, capture_output=True, check=True, text=True, **kwargs) + return result.stdout.strip() + + +def convert_hash_to_sri(base32: str) -> str: + return run_command(["nix-hash", "--to-sri", "--type", "sha256", base32]) + + +def ensure_is_list(x): + if type(x) is not list: + return [x] + return x + + +def one_or_more(x): + return x if isinstance(x, list) else [x] + + +def replace_blocks( + config: UpdaterConfig, file: Path, blocks: Iterable[tuple[str, str]] +): + """ + Replace placeholder blocks in a nix file. + + The blocks must be enclosed in the `file` with lines + `# update-script-start: XXX` and `# update-script-end: XXX`, + where these lines must only contain that string and optionally any + number of leading and trailing whitespaces. `XXX` in this example is the + identifier of the block. + + The lines between these markers are replaced with the content of the block. + The content is stripped of trailin and leading lines containing only whitespaces first. + + The file is formatted with `nixfmt` after saving. + """ + with open(file, "r") as f: + lines = f.readlines() + + for name, block in blocks: + old_lines = lines + lines = [] + have_found_start = False + have_found_end = False + for line in old_lines: + if not have_found_start and line.lstrip().startswith( + f"# update-script-start: {name}" + ): + have_found_start = True + lines.append(line) + elif have_found_start and line.lstrip().startswith( + f"# update-script-end: {name}" + ): + for replacement_line in block.splitlines(True): + if replacement_line.rstrip("\n") == "": + # Skip empty lines in replacement + continue + lines.append(replacement_line) + have_found_end = True + lines.append(line) + elif not have_found_start or have_found_end: + lines.append(line) + if not have_found_start or not have_found_end: + raise Exception( + f"Either start or end marker for `{name}` block missing in `{file}`" + ) + + with open(file, "w") as f: + f.writelines(lines) + + run_command( + ["nix-shell", "--run", f"treefmt --no-cache {file.absolute()}"], + cwd=config.nixpkgs_root, + ) diff --git a/pkgs/applications/editors/jetbrains/updater/main.py b/pkgs/applications/editors/jetbrains/updater/main.py new file mode 100755 index 0000000000000..08e62cc176953 --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/main.py @@ -0,0 +1,82 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i python3 -p python3 python3.pkgs.packaging python3.pkgs.xmltodict python3.pkgs.requests nurl +import argparse +import json + +from jetbrains_nix_updater.config import UpdaterConfig +from jetbrains_nix_updater.fetcher import VersionFetcher +from jetbrains_nix_updater.ides import get_single_ide, get_all_ides +from jetbrains_nix_updater.update_bin import run_bin_update +from jetbrains_nix_updater.update_src import run_src_update + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "ide", + nargs="?", + help="pname of the IDE to update. If not set, uses UPDATE_NIX_PNAME. " + "If that is also not set, all IDEs are updated", + ) + parser.add_argument( + "--nixpkgs-root", help="root directory of nixpkgs, auto-detected if not given" + ) + parser.add_argument( + "--no-bin", action="store_true", help="do not update binary IDEs" + ) + parser.add_argument( + "--no-src", action="store_true", help="do not update source IDEs" + ) + parser.add_argument( + "--no-maven-deps", + action="store_true", + help="do not update maven dependencies for source IDEs", + ) + parser.add_argument( + "--old-version", + type=str, + help="old version of the IDE, only used if `ide` (or UPDATE_NIX_PNAME) is also used. " + "Defaults to UPDATE_NIX_OLD_VERSION. If the new version matches the old version, " + "exits early without making changes.", + ) + + config = UpdaterConfig(parser.parse_args()) + print(f"[i] running jetbrains updater with: {config}") + + with open(config.jetbrains_root / "updater" / "updateInfo.json", "r") as f: + update_info = json.load(f) + version_fetcher = VersionFetcher() + + ides_to_run_for = ( + [get_single_ide(update_info, config.jetbrains_root, config.ide)] + if config.ide is not None + else list(get_all_ides(update_info, config.jetbrains_root)) + ) + + print(f"[.] found IDEs to update: {', '.join(ide.name for ide in ides_to_run_for)}") + for ide in ides_to_run_for: + if ide.is_source and config.no_src: + print(f"[!] skipping {ide.name}, due to --no-src") + continue + if not ide.is_source and config.no_bin: + print(f"[!] skipping {ide.name}, due to --no-bin") + continue + + print(f"[@] updating IDE {ide.name}") + + info = version_fetcher.latest_version_info( + ide, ignore_no_url_error=ide.is_source + ) + if info is not None: + if config.old_version == info.version: + print("[o] Version is the same, no update required") + return + + if ide.is_source: + run_src_update(ide, info, config) + else: + run_bin_update(ide, info, config) + + +if __name__ == "__main__": + main() diff --git a/pkgs/applications/editors/jetbrains/updater/updateInfo.json b/pkgs/applications/editors/jetbrains/updater/updateInfo.json new file mode 100644 index 0000000000000..6c95f480814fc --- /dev/null +++ b/pkgs/applications/editors/jetbrains/updater/updateInfo.json @@ -0,0 +1,127 @@ +{ + "clion": { + "channel": "CLion RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/cpp/CLion-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/cpp/CLion-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/cpp/CLion-{version}-aarch64.dmg" + } + }, + "datagrip": { + "channel": "DataGrip RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/datagrip/datagrip-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/datagrip/datagrip-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/datagrip/datagrip-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/datagrip/datagrip-{version}-aarch64.dmg" + } + }, + "dataspell": { + "channel": "DataSpell RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/python/dataspell-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/python/dataspell-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/python/dataspell-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/python/dataspell-{version}-aarch64.dmg" + } + }, + "gateway": { + "channel": "Gateway 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", + "x86_64-darwin": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/idea/gateway/JetBrainsGateway-{version}-aarch64.dmg" + } + }, + "goland": { + "channel": "GoLand RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/go/goland-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/go/goland-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/go/goland-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/go/goland-{version}-aarch64.dmg" + } + }, + "idea": { + "channel": "IntelliJ IDEA RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/idea/ideaIU-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/idea/ideaIU-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/idea/ideaIU-{version}-aarch64.dmg" + } + }, + "idea-oss": { + "channel": "IntelliJ IDEA RELEASE", + "urls": {} + }, + "mps": { + "channel": "MPS RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}-macos.dmg", + "aarch64-darwin": "https://download.jetbrains.com/mps/{versionMajorMinor}/MPS-{version}-macos-aarch64.dmg" + } + }, + "phpstorm": { + "channel": "PhpStorm RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/webide/PhpStorm-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/webide/PhpStorm-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/webide/PhpStorm-{version}-aarch64.dmg" + } + }, + "pycharm": { + "channel": "PyCharm RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/python/pycharm-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/python/pycharm-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/python/pycharm-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/python/pycharm-{version}-aarch64.dmg" + } + }, + "pycharm-oss": { + "channel": "PyCharm RELEASE", + "urls": {} + }, + "rider": { + "channel": "Rider RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/rider/JetBrains.Rider-{version}-aarch64.dmg" + } + }, + "ruby-mine": { + "channel": "RubyMine RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/ruby/RubyMine-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/ruby/RubyMine-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/ruby/RubyMine-{version}-aarch64.dmg" + } + }, + "rust-rover": { + "channel": "RustRover RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/rustrover/RustRover-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/rustrover/RustRover-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/rustrover/RustRover-{version}-aarch64.dmg" + } + }, + "webstorm": { + "channel": "WebStorm RELEASE", + "urls": { + "x86_64-linux": "https://download.jetbrains.com/webstorm/WebStorm-{version}.tar.gz", + "aarch64-linux": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.tar.gz", + "x86_64-darwin": "https://download.jetbrains.com/webstorm/WebStorm-{version}.dmg", + "aarch64-darwin": "https://download.jetbrains.com/webstorm/WebStorm-{version}-aarch64.dmg" + } + } +}