diff --git a/pkgs/applications/editors/jetbrains/default.nix b/pkgs/applications/editors/jetbrains/default.nix index eaef3156099b..d1807a684eeb 100644 --- a/pkgs/applications/editors/jetbrains/default.nix +++ b/pkgs/applications/editors/jetbrains/default.nix @@ -12,7 +12,7 @@ let # Sorted alphabetically - buildClion = { name, version, src, license, description, wmClass }: + buildClion = { name, version, src, license, description, wmClass, update-channel }: lib.overrideDerivation (mkJetBrainsProduct rec { inherit name version src wmClass jdk; product = "CLion"; @@ -54,7 +54,7 @@ let ''; }); - buildDataGrip = { name, version, src, license, description, wmClass }: + buildDataGrip = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct { inherit name version src wmClass jdk; product = "DataGrip"; @@ -71,7 +71,7 @@ let }; }); - buildGogland = { name, version, src, license, description, wmClass }: + buildGogland = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct { inherit name version src wmClass jdk; product = "Gogland"; @@ -89,7 +89,7 @@ let }; }); - buildIdea = { name, version, src, license, description, wmClass }: + buildIdea = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct rec { inherit name version src wmClass jdk; product = "IDEA"; @@ -106,7 +106,7 @@ let }; }); - buildPhpStorm = { name, version, src, license, description, wmClass }: + buildPhpStorm = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct { inherit name version src wmClass jdk; product = "PhpStorm"; @@ -123,7 +123,7 @@ let }; }); - buildPycharm = { name, version, src, license, description, wmClass }: + buildPycharm = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct rec { inherit name version src wmClass jdk; product = "PyCharm"; @@ -150,7 +150,7 @@ let propagatedUserEnvPkgs = [ python ]; }; - buildRider = { name, version, src, license, description, wmClass }: + buildRider = { name, version, src, license, description, wmClass, update-channel }: lib.overrideDerivation (mkJetBrainsProduct rec { inherit name version src wmClass jdk; product = "Rider"; @@ -176,7 +176,7 @@ let ''; }); - buildRubyMine = { name, version, src, license, description, wmClass }: + buildRubyMine = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct rec { inherit name version src wmClass jdk; product = "RubyMine"; @@ -189,7 +189,7 @@ let }; }); - buildWebStorm = { name, version, src, license, description, wmClass }: + buildWebStorm = { name, version, src, license, description, wmClass, update-channel }: (mkJetBrainsProduct { inherit name version src wmClass jdk; product = "WebStorm"; @@ -221,18 +221,20 @@ in sha256 = "045pkbbf4ypk9qkhldz08i7hbc6vaq68a8v9axnpndnvcrf0vf7g"; }; wmClass = "jetbrains-clion"; + update-channel = "CLion_Release"; # channel's id as in http://www.jetbrains.com/updates/updates.xml }; datagrip = buildDataGrip rec { name = "datagrip-${version}"; - version = "2017.1.4"; + version = "2017.1.4"; /* updated by script */ description = "Your Swiss Army Knife for Databases and SQL"; license = stdenv.lib.licenses.unfree; src = fetchurl { url = "https://download.jetbrains.com/datagrip/${name}.tar.gz"; - sha256 = "0f03hgiiwlxnsvcm4dg2qf8pc5dy7w5phbj6qwgmppba2x5f8lf3"; + sha256 = "c351e44a176add5b1fc7462e780b3fbe157691c3e23552d9d6b6531ee3830338"; /* updated by script */ }; wmClass = "jetbrains-datagrip"; + update-channel = "datagrip_2017_1"; }; gogland = buildGogland rec { @@ -245,6 +247,7 @@ in sha256 = "0q2f8bi2i49j0xcpn824sihz2015jhn338cjaqy0jd988nxik6jk"; }; wmClass = "jetbrains-gogland"; + update-channel = "gogland_1.0_EAP"; }; idea14-community = buildIdea rec { @@ -257,6 +260,7 @@ in sha256 = "1i4mdjm9dd6zvxlpdgd3bqg45ir0cfc9hl55cdc0hg5qwbz683fz"; }; wmClass = "jetbrains-idea-ce"; + update-channel = "IDEA14.1"; }; idea-community = buildIdea rec { @@ -269,6 +273,7 @@ in sha256 = "1w1knq969dl8rxlkhr9mw8cr2vszn384acwhspimrd3zs9825r45"; }; wmClass = "jetbrains-idea-ce"; + update-channel = "IDEA_Release"; }; idea14-ultimate = buildIdea rec { @@ -281,6 +286,7 @@ in sha256 = "1hhga1i2zbsipgq283gn19kv9n94inhr1bxh2yx19gz7yr4r49d2"; }; wmClass = "jetbrains-idea"; + update-channel = "IDEA14.1"; }; idea15-ultimate = buildIdea rec { @@ -293,6 +299,7 @@ in sha256 = "012aap2qn0jx4x34bdv9ivrsr86vvf683srb5vpj27hc4l6rw6ll"; }; wmClass = "jetbrains-idea"; + update-channel = null; }; idea-ultimate = buildIdea rec { @@ -305,6 +312,7 @@ in sha256 = "0byrsbsscpzb0syamzpavny879src5dlclnissa7173rh8hgkna4"; }; wmClass = "jetbrains-idea"; + update-channel = "IDEA_Release"; }; phpstorm = buildPhpStorm rec { @@ -317,6 +325,7 @@ in sha256 = "0zrbcziznz6dwh56snr27752xcsnl2gsxzi6jiraplkd92f2xlaf"; }; wmClass = "jetbrains-phpstorm"; + update-channel = "PS2017.1"; }; phpstorm10 = buildPhpStorm rec { @@ -329,42 +338,46 @@ in sha256 = "0fi042zvjpg5pn2mnhj3bbrdkl1b9vmhpf2l6ca4nr0rhjjv7dsm"; }; wmClass = "jetbrains-phpstorm"; + update-channel = "WI10"; }; pycharm-community = buildPycharm rec { name = "pycharm-community-${version}"; - version = "2017.1.3"; + version = "2017.1.4"; /* updated by script */ description = "PyCharm Community Edition"; license = stdenv.lib.licenses.asl20; src = fetchurl { url = "https://download.jetbrains.com/python/${name}.tar.gz"; - sha256 = "06sai589zli5xaggfk4g0j0grbw9mya9qlwabmxh9414qq3bzvbd"; + sha256 = "1e69ab29215a9c8c4626de6727df433ae0d9f6ed46eba2a6f48ffa52c2b04256"; /* updated by script */ }; wmClass = "jetbrains-pycharm-ce"; + update-channel = "PyCharm_Release"; }; pycharm-professional = buildPycharm rec { name = "pycharm-professional-${version}"; - version = "2017.1.3"; + version = "2017.1.4"; /* updated by script */ description = "PyCharm Professional Edition"; license = stdenv.lib.licenses.unfree; src = fetchurl { url = "https://download.jetbrains.com/python/${name}.tar.gz"; - sha256 = "1wzgh83504px7q93h9xkarih2qjchiavgysy4di82q7377s6xd0c"; + sha256 = "bbae5602b9cf6d26ccce9e1bf8b388d79c27cf89673d1a56f248bf0a50e518ed"; /* updated by script */ }; wmClass = "jetbrains-pycharm"; + update-channel = "PyCharm_Release"; }; rider = buildRider rec { name = "rider-${version}"; - version = "171.3655.1246"; + version = "171.4456.575"; /* updated by script */ description = "A cross-platform .NET IDE based on the IntelliJ platform and ReSharper"; license = stdenv.lib.licenses.unfree; src = fetchurl { url = "https://download.jetbrains.com/resharper/riderRS-${version}.tar.gz"; - sha256 = "90f9f8f1919e0f1dad42387f1a308483448323b089c13c409f3dd4d52992266b"; + sha256 = "9b7f46e9c800a091f2cdbe9fda08041729e2abc0ce57252731da659b2424707b"; /* updated by script */ }; wmClass = "jetbrains-rider"; + update-channel = "rider1.0EAP"; }; ruby-mine = buildRubyMine rec { @@ -377,6 +390,7 @@ in sha256 = "06jk0anlnc4gr240i51kam47shdjgda6zg3hglk5w3bpvbyix68z"; }; wmClass = "jetbrains-rubymine"; + update-channel = "rm2017.1"; }; ruby-mine7 = buildRubyMine rec { @@ -389,6 +403,7 @@ in sha256 = "04fcxj1xlap9mxmwf051s926p2darlj5kwl4lms2gy5d8b2lhd5l"; }; wmClass = "jetbrains-rubymine"; + update-channel = null; }; ruby-mine8 = buildRubyMine rec { @@ -401,6 +416,7 @@ in sha256 = "0hipxib7377232w1jbf8h98bmh0djkllsrq3lq0w3fdxqglma43a"; }; wmClass = "jetbrains-rubymine"; + update-channel = null; }; webstorm = buildWebStorm rec { @@ -413,6 +429,7 @@ in sha256 = "0aw2728wknss5vn2fkgz8rkm5vwk031305f32dirfrh51bvmq2zm"; }; wmClass = "jetbrains-webstorm"; + update-channel = "WS_Release"; }; webstorm10 = buildWebStorm rec { @@ -425,6 +442,7 @@ in sha256 = "0a5s6f99wyql5pgjl94pf4ljdbviik3b8dbr1s6b7c6jn1gk62ic"; }; wmClass = "jetbrains-webstorm"; + update-channel = null; }; webstorm11 = buildWebStorm rec { @@ -437,5 +455,6 @@ in sha256 = "17agyqdyz6naxyx6p0y240ar93gja0ypw01nm2qmfzvh7ch03r24"; }; wmClass = "jetbrains-webstorm"; + update-channel = null; }; } diff --git a/pkgs/applications/editors/jetbrains/update.pl b/pkgs/applications/editors/jetbrains/update.pl new file mode 100755 index 000000000000..9503212df43a --- /dev/null +++ b/pkgs/applications/editors/jetbrains/update.pl @@ -0,0 +1,92 @@ +#!/usr/bin/env perl + +use strict; +use List::Util qw(reduce); +use File::Basename qw(dirname); +use LWP::Simple; + +sub readFile { + my ($filename) = @_; + local $/ = undef; + open FILE, $filename or die "readFile($filename) failed: $!"; + binmode FILE; + my $data = ; + close FILE; + return $data; +} + +sub writeFile { + my ($filename, $content) = @_; + make_path(dirname($filename)) or die "$!" unless -d dirname($filename); + open FH, ">$filename" or die "writeFile($filename) failed: $!"; + binmode FH; # do not emit \r + print FH $content; + close FH; +} + +sub semantic_less { + my ($a, $b) = @_; + $a =~ s/\b(\d+)\b/sprintf("%010s", $1)/eg; + $b =~ s/\b(\d+)\b/sprintf("%010s", $1)/eg; + return $a lt $b; +} + +sub get_latest_versions { + my @channels = get("http://www.jetbrains.com/updates/updates.xml") =~ /()/gs; + my %h = {}; + for my $ch (@channels) { + my ($id) = $ch =~ /^)/gs; + my $latest_build = reduce { + my ($aversion) = $a =~ /^]*version="([^"]+)"/; die "no version in $a" unless $aversion; + my ($bversion) = $b =~ /^]*version="([^"]+)"/; die "no version in $b" unless $bversion; + semantic_less($aversion, $bversion) ? $b : $a; + } @builds; + next unless $latest_build; + + # version as in download url + my ($latest_version) = $latest_build =~ /^]*version="([^"]+)"/; + ($latest_version) = $latest_build =~ /^]*fullNumber="([^"]+)"/ if $latest_version =~ / /; + + $h{$id} = $latest_version; + } + return %h; +} + +my %latest_versions = get_latest_versions(); +#for my $ch (sort keys %latest_versions) { +# print("$ch $latest_versions{$ch}\n"); +#} + +sub update_nix_block { + my ($block) = @_; + my ($channel) = $block =~ /update-channel\s*=\s*"([^"]+)"/; + if ($channel) { + die "unknown update-channel $channel" unless $latest_versions{$channel}; + my ($version) = $block =~ /version\s*=\s*"([^"]+)"/; + die "no version in $block" unless $version; + if ($version eq $latest_versions{$channel}) { + print("$channel is up to date at $version\n"); + } else { + print("updating $channel: $version -> $latest_versions{$channel}\n"); + my ($url) = $block =~ /url\s*=\s*"([^"]+)"/; + # try to interpret some nix + my ($name) = $block =~ /name\s*=\s*"([^"]+)"/; + $name =~ s/\$\{version\}/$latest_versions{$channel}/; + $url =~ s/\$\{name\}/$name/; + $url =~ s/\$\{version\}/$latest_versions{$channel}/; + die "$url still has some interpolation" if $url =~ /\$/; + + my ($sha256) = get("$url.sha256") =~ /^([0-9a-f]{64})/; + die "invalid sha256 in $url.sha256" unless $sha256; + + $block =~ s#version\s*=\s*"([^"]+)".+$#version = "$latest_versions{$channel}"; /* updated by script */#m; + $block =~ s#sha256\s*=\s*"([^"]+)".+$#sha256 = "$sha256"; /* updated by script */#m; + } + } + return $block; +} + +my $nix = readFile 'default.nix'; +$nix =~ s/(= build\w+ rec \{.+?\};\n\n)/update_nix_block($1)/gse; +writeFile 'default.nix', $nix;