@@ -68,21 +68,53 @@ module JBUpdater
6868 data = JSON .parse(body)
6969 version = data[product_code][0 ][" version" ].as_s
7070 downloads = data[product_code][0 ][" downloads" ]
71- link = nil
7271
73- arch = opts.arch || autodetect_arch
72+ platform_key = download_key_for(platform, opts.arch)
7473
75- if arch == " arm" && downloads[" macM1" ]?
76- link = downloads[" macM1" ][" link" ].as_s
77- else
78- link = downloads[" mac" ][" link" ].as_s
79- end
74+ entry = downloads[platform_key]? || raise " No download entry found for platform '#{ platform } ' (#{ platform_key } ) for #{ product_code } "
75+ link = entry[" link" ].as_s
8076
8177 dmg_url = link
8278 Log .success(" Latest version #{ version } " )
8379 URI .parse(dmg_url)
8480 end
8581
82+ # Determines the current OS platform.
83+ #
84+ # @return [String] `"mac"`, `"linux"`, or `"windows"`
85+ private def platform : String
86+ {% if flag?(:darwin ) % }
87+ " mac"
88+ {% elsif flag?(:linux ) % }
89+ " linux"
90+ {% elsif flag?(:win32 ) % }
91+ " windows"
92+ {% else % }
93+ raise " Unsupported OS"
94+ {% end % }
95+ end
96+
97+ # Maps platform + architecture to the JetBrains releases API download key.
98+ #
99+ # - **mac** (Apple Silicon): `macM1`; otherwise: `mac`
100+ # - **linux** (ARM64): `linuxARM64`; otherwise: `linux`
101+ # - **windows**: `windows`
102+ #
103+ # @param platform [String] OS platform (`"mac"`, `"linux"`, `"windows"`)
104+ # @param arch [String?] Architecture (`"arm"` or `"intel"`); autodetected if nil
105+ # @return [String] Download key in the JetBrains releases API payload
106+ private def download_key_for (platform : String , arch : String ?) : String
107+ cpu = arch || autodetect_arch
108+ case platform
109+ when " mac"
110+ cpu == " arm" ? " macM1" : " mac"
111+ when " linux"
112+ cpu == " arm" ? " linuxARM64" : " linux"
113+ else
114+ " windows"
115+ end
116+ end
117+
86118 # Detects the CPU architecture by running `uname -m`.
87119 #
88120 # @return [String] `"arm"` or `"intel"`
@@ -104,16 +136,12 @@ module JBUpdater
104136
105137 # Maps a product name to its JetBrains product code.
106138 #
107- # @param product [String] Product name (e.g. `"RubyMine2025.2"`)
108- # @return [String] Product code (e.g. `"RM"`)
139+ # Delegates to {JBUpdater.Utils.product_code} (case-insensitive).
140+ #
141+ # @param product [String] Product name (e.g. `"PhpStorm2025.1"` or `"phpstorm"`)
142+ # @return [String] Product code (e.g. `"PS"`)
109143 private def infer_product_code (product : String ) : String
110- {
111- " RubyMine" => " RM" ,
112- " WebStorm" => " WS" ,
113- " PyCharm" => " PY" ,
114- " CLion" => " CL" ,
115- " GoLand" => " GO" ,
116- }[product.gsub(/\d +.*/ , " " )] || product[0 , 2 ].upcase
144+ Utils .product_code(product)
117145 end
118146
119147 # ------------------------------------------------------------------------
@@ -126,7 +154,12 @@ module JBUpdater
126154 # @param product [String] Product name (for logging)
127155 # @param uri [URI] Download URL (with CDN override already applied)
128156 private def upgrade_direct (product : String , uri : URI ) : Nil
129- dmg_path = File .join(Dir .tempdir, " upgrade-#{ product } -#{ Time .utc.to_unix} .dmg" )
157+ ext = case platform
158+ when " mac" then " .dmg"
159+ when " windows" then " .exe"
160+ else " .tar.gz"
161+ end
162+ dmg_path = File .join(Dir .tempdir, " upgrade-#{ product } -#{ Time .utc.to_unix} #{ ext } " )
130163
131164 cdn_uri = uri
132165
0 commit comments