blob: 7845d32938da56de93f37fc03bbf8c48235a1826 [file] [log] [blame]
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -08001/*
Tor Norbye814f8292014-03-06 17:27:18 -08002 * Copyright 2000-2014 JetBrains s.r.o.
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tor Norbye6739a8f2013-08-07 11:11:08 -070017import org.jetbrains.jps.gant.JpsGantTool
18import org.jetbrains.jps.gant.TeamCityBuildInfoPrinter
19import org.jetbrains.jps.model.java.JavaSourceRootType
20import org.jetbrains.jps.model.module.JpsModule
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080021
Tor Norbye6739a8f2013-08-07 11:11:08 -070022includeTool << JpsGantTool
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080023
24binding.setVariable("p", {String key ->
25 return getProperty(key) as String
26})
27
28binding.setVariable("guessJdk", {
29 String javaHome = p("java.home")
30
31 if (new File(javaHome).getName() == "jre") {
32 javaHome = new File(javaHome).getParent()
33 }
34
35 return javaHome
36})
37
38binding.setVariable("includeFile", {String filePath ->
39 Script s = groovyShell.parse(new File(filePath))
40 s.setBinding(binding)
41 s
42})
43
44binding.setVariable("isMac", {
45 return System.getProperty("os.name").toLowerCase().startsWith("mac")
46})
47
48binding.setVariable("isWin", {
49 return System.getProperty("os.name").toLowerCase().startsWith("windows")
50})
51
52binding.setVariable("isEap", {
53 return "true" == p("component.version.eap")
54})
55
Tor Norbye02cf98d62014-08-19 12:53:10 -070056binding.setVariable("mem32", "-server -Xms128m -Xmx512m -XX:MaxPermSize=250m -XX:ReservedCodeCacheSize=150m")
57binding.setVariable("mem64", "-Xms128m -Xmx750m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=225m")
Tor Norbyec1ace1f2013-07-08 11:26:24 -070058binding.setVariable("common_vmoptions", "-ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true " +
Tor Norbye814f8292014-03-06 17:27:18 -080059 "-Didea.project.structure.max.errors.to.show=0 " +
Tor Norbye92584642014-04-17 08:39:25 -070060 "-Djsse.enableSNIExtension=false " +
Tor Norbye02cf98d62014-08-19 12:53:10 -070061 "-XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080062
63binding.setVariable("vmOptions", { "$common_vmoptions ${isEap() ? '-XX:+HeapDumpOnOutOfMemoryError' : ''}".trim() })
64binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() })
65binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() })
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070066
67binding.setVariable("yjpOptions", { String systemSelector, String platformSuffix = "" ->
Tor Norbyec667c1f2014-05-28 17:06:51 -070068 "-agentlib:yjpagent$platformSuffix=probe_disable=*,disablealloc,disabletracing,onlylocal,disableexceptiontelemetry,delay=10000,sessionname=$systemSelector".trim()
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070069})
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080070binding.setVariable("vmOptions32yjp", { String systemSelector ->
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070071 "${vmOptions32()} ${yjpOptions(systemSelector)}".trim()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080072})
73binding.setVariable("vmOptions64yjp", { String systemSelector ->
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070074 "${vmOptions64()} ${yjpOptions(systemSelector, "64")}".trim()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080075})
76
77binding.setVariable("isDefined", {String key ->
78 try {
79 this[key]
80 return true
81 }
82 catch (MissingPropertyException ignored) {
83 return false
84 }
85})
86
87private String require(String key) {
88 try {
89 this[key]
90 }
91 catch (MissingPropertyException ignored) {
Tor Norbye2e5965e2014-07-25 12:24:15 -070092 projectBuilder.error("Property '$key' is required")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080093 }
94}
95
96private String require(String key, String defaultValue) {
97 try {
98 this[key]
99 }
100 catch (MissingPropertyException ignored) {
Tor Norbye2e5965e2014-07-25 12:24:15 -0700101 projectBuilder.info("'$key' is not defined. Defaulting to '$defaultValue'")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800102 this[key] = defaultValue
103 }
104}
105
106binding.setVariable("requireProperty", {String key, String defaultValue = null ->
107 if (defaultValue == null) {
108 require(key)
109 }
110 else {
111 require(key, defaultValue)
112 }
113})
114
115binding.setVariable("guessHome", {
Tor Norbye2e5965e2014-07-25 12:24:15 -0700116 // current file is supposed to be at build/scripts/*.gant path
117 String uri = requireProperty("gant.file")
118 new File(new URI(uri).getSchemeSpecificPart()).getParentFile().getParentFile().getParent()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800119})
120
121binding.setVariable("loadProject", {
122 requireProperty("jdkHome", guessJdk())
123 def mac = isMac()
124 jdk("IDEA jdk", jdkHome) {
125 if (!mac) {
126 classpath "$jdkHome/lib/tools.jar"
127 }
128 }
Tor Norbye6739a8f2013-08-07 11:11:08 -0700129 projectBuilder.dataStorageRoot = new File("$home/.jps-build-data")
130 loadProjectFromPath(home)
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800131})
132
Tor Norbye6739a8f2013-08-07 11:11:08 -0700133boolean hasSourceRoots(JpsModule module) {
134 return module.getSourceRoots(JavaSourceRootType.SOURCE).iterator().hasNext()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800135}
136
137binding.setVariable("findModule", {String name ->
Tor Norbye6739a8f2013-08-07 11:11:08 -0700138 project.modules.find { it.name == name }
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800139})
140
141binding.setVariable("allModules", {
Tor Norbye6739a8f2013-08-07 11:11:08 -0700142 return project.modules
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800143})
144
145binding.setVariable("printUnusedModules", {Set<String> usedModules ->
Tor Norbye6739a8f2013-08-07 11:11:08 -0700146 allModules().each {JpsModule m ->
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800147 if (!usedModules.contains(m.name) && hasSourceRoots(m)) {
148 projectBuilder.warning("Module $m.name is not used in project layout")
149 }
150 }
151})
152
153requireProperty("home", guessHome())
154
155String readSnapshotBuild() {
156 def file = new File("$home/community/build.txt")
157 if (!file.exists()) {
158 file = new File("$home/build.txt")
159 }
160
161 return file.readLines().get(0)
162}
163
164binding.setVariable("snapshot", readSnapshotBuild())
165
Tor Norbye6739a8f2013-08-07 11:11:08 -0700166projectBuilder.buildInfoPrinter = new TeamCityBuildInfoPrinter()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800167projectBuilder.compressJars = false
168
169binding.setVariable("notifyArtifactBuilt", { String artifactPath ->
170 if (!artifactPath.startsWith(home)) {
Siva Velusamy3ff7bb62013-09-06 15:47:55 -0700171 // AndroidStudio: make this to be just an info as the out folder is typically
172 // not in the home folder
173 projectBuilder.info("Artifact path $artifactPath should start with $home")
174 return
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800175 }
176 def relativePath = artifactPath.substring(home.length())
177 if (relativePath.startsWith("/")) {
178 relativePath = relativePath.substring(1)
179 }
180 def file = new File(artifactPath)
181 if (file.isDirectory()) {
182 relativePath += "=>" + file.name
183 }
184 projectBuilder.info("##teamcity[publishArtifacts '$relativePath']")
185})
186
187def suspendUntilDebuggerConnect = System.getProperty("debug.suspend") ?: "n"
188def debugPort = System.getProperty("debug.port") ?: 5555
189if (suspendUntilDebuggerConnect == 'y') {
190 println """\
191------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<----
Tor Norbye8fb002102013-05-01 12:55:43 -0700192-------------------------------------------^------^------^------^------^------^------^-----------------------
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800193"""
194}
195
196binding.setVariable("patchFiles", { List files, Map args, String marker = "__" ->
197 files.each { file ->
198 args.each { arg ->
199 ant.replace(file: file, token: "${marker}${arg.key}${marker}", value: arg.value)
200 }
201 }
202})
203
204binding.setVariable("copyAndPatchFile", { String file, String target, Map args, String marker = "__" ->
205 ant.copy(file: file, tofile: target, overwrite: "true") {
206 filterset(begintoken: marker, endtoken: marker) {
207 args.each {
208 filter(token: it.key, value: it.value)
209 }
210 }
211 }
212})
213
214binding.setVariable("copyAndPatchFiles", { Closure files, String target, Map args, String marker = "__" ->
215 ant.copy(todir: target, overwrite: "true") {
216 files()
217
218 filterset(begintoken: marker, endtoken: marker) {
219 args.each {
220 filter(token: it.key, value: it.value)
221 }
222 }
223 }
224})
225
226binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
227 ant.tstamp()
Siva Velusamy7be1af12013-09-06 16:46:31 -0700228 patchFiles([appInfoFile], ["BUILD_NUMBER": buildNumber, "BUILD_DATE": DSTAMP,
229 "PACKAGE_CODE": buildNumber.substring(0, buildNumber.indexOf('-'))])
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800230})
231
232binding.setVariable("commonJvmArgs", {
233 return [
234 "-ea",
Tor Norbye65f60eb2014-07-16 18:07:37 -0700235 "-server",
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800236 "-Didea.home.path=$home",
237 "-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
238 "-XX:+HeapDumpOnOutOfMemoryError",
239 "-Didea.system.path=${p("teamcity.build.tempDir")}/system",
Siva Velusamya3091f62014-04-30 07:15:29 -0700240 "-Didea.config.path=${p("teamcity.build.tempDir")}/config"]
241 // We don't want this on the Jenkins build server
242 // "-Xdebug",
243 // "-Xrunjdwp:transport=dt_socket,server=y,suspend=$suspendUntilDebuggerConnect,address=$debugPort"]
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800244})
245
246binding.setVariable("classPathLibs", [
247 "bootstrap.jar",
248 "extensions.jar",
249 "util.jar",
250 "jdom.jar",
251 "log4j.jar",
252 "trove4j.jar",
253 "jna.jar"
254])
255
256binding.setVariable("platformApiModules", [
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700257 "analysis-api",
258 "core-api",
Tor Norbye1aa2e092014-08-20 17:01:23 -0700259 "dvcs-api",
Tor Norbyec7f983b2013-09-05 16:07:26 -0700260 "editor-ui-api",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700261 "external-system-api",
262 "indexing-api",
263 "jps-model-api",
264 "lang-api",
265 "lvcs-api",
266 "projectModel-api",
267 "platform-api",
Tor Norbye814f8292014-03-06 17:27:18 -0800268 "structure-view-api",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700269 "usageView",
270 "vcs-api",
Tor Norbye1aa2e092014-08-20 17:01:23 -0700271 "vcs-api-core",
Tor Norbye32218cc2013-10-08 09:48:09 -0700272 "vcs-log-api",
Tor Norbyec667c1f2014-05-28 17:06:51 -0700273 "vcs-log-graph-api",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700274 "xdebugger-api",
Tor Norbye92584642014-04-17 08:39:25 -0700275 "remote-servers-api",
276 "remote-servers-agent-rt",
Tor Norbye3a2425a52013-11-04 10:16:08 -0800277 "xml-analysis-api",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700278 "xml-openapi",
279 "xml-psi-api",
Tor Norbye814f8292014-03-06 17:27:18 -0800280 "xml-structure-view-api",
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800281])
282
283
284binding.setVariable("platformImplementationModules", [
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700285 "analysis-impl",
286 "core-impl",
Tor Norbye1aa2e092014-08-20 17:01:23 -0700287 "dvcs-impl",
Tor Norbyea28de542013-09-11 15:53:32 -0700288 "editor-ui-ex",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700289 "images",
290 "indexing-impl",
291 "jps-model-impl",
292 "jps-model-serialization",
293 "lang-impl",
294 "lvcs-impl",
295 "projectModel-impl",
296 "platform-impl",
Tor Norbye814f8292014-03-06 17:27:18 -0800297 "structure-view-impl",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700298 "vcs-impl",
Tor Norbye32218cc2013-10-08 09:48:09 -0700299 "vcs-log-graph",
300 "vcs-log-impl",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700301 "testRunner",
302 "smRunner",
303 "relaxng",
304 "RegExpSupport",
305 "spellchecker",
306 "xdebugger-impl",
Tor Norbye92584642014-04-17 08:39:25 -0700307 "remote-servers-impl",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700308 "xml",
Tor Norbye3a2425a52013-11-04 10:16:08 -0800309 "xml-analysis-impl",
Tor Norbyeec3fb1e2013-05-31 07:45:51 -0700310 "xml-psi-impl",
Tor Norbye814f8292014-03-06 17:27:18 -0800311 "xml-structure-view-impl",
Tor Norbye92584642014-04-17 08:39:25 -0700312 "protocol-reader-runtime",
313 "script-debugger-backend",
314 "script-debugger-ui"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800315])
316
317binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
318 ant.copy(todir: "$path/bin") {
319 fileset(dir: "$ch/bin/mac")
320 }
321
322 ant.copy(todir: path) {
Tor Norbye65f60eb2014-07-16 18:07:37 -0700323 fileset(dir: "$ch/build/conf/mac/Contents")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800324 }
325
326 ant.tstamp() {
327 format(property: "todayYear", pattern: "yyyy")
328 }
329
330 String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase()
331 String helpId = args.help_id != null ? args.help_id : "IJ"
332 String icns = "idea.icns"
Tor Norbye65f60eb2014-07-16 18:07:37 -0700333 String helpIcns = "$path/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800334 if (args.icns != null) {
Tor Norbye65f60eb2014-07-16 18:07:37 -0700335 ant.delete(file: "$path/Resources/idea.icns")
336 ant.copy(file: args.icns, todir: "$path/Resources")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800337 ant.copy(file: args.icns, tofile: helpIcns)
338 icns = new File((String)args.icns).getName();
339 } else {
Tor Norbye65f60eb2014-07-16 18:07:37 -0700340 ant.copy(file: "$path/Resources/idea.icns", tofile: helpIcns)
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800341 }
342
343 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
344
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700345 String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800346
347 String minor = p("component.version.minor")
348 String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"
349
350 Map properties = readIdeaProperties(args)
351
352 def coreKeys = ["idea.platform.prefix", "idea.paths.selector"]
353
354 String coreProperties = submapToXml(properties, coreKeys);
355
356 StringBuilder effectiveProperties = new StringBuilder()
357 properties.each { k, v ->
358 if (!coreKeys.contains(k)) {
359 effectiveProperties.append("$k=$v\n");
360 }
361 }
362
363 new File("$path/bin/idea.properties").text = effectiveProperties.toString()
Tor Norbye65f60eb2014-07-16 18:07:37 -0700364 String ideaVmOptions = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
365 if (isEap() && !args.mac_no_yjp) {
366 ideaVmOptions += " ${yjpOptions(args.system_selector)}"
367 }
368 new File("$path/bin/idea.vmoptions").text = ideaVmOptions
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800369
Tor Norbye65f60eb2014-07-16 18:07:37 -0700370 String classPath = classPathLibs.collect {"\$APP_PACKAGE/Contents/lib/${it}" }.join(":")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800371
Tor Norbye814f8292014-03-06 17:27:18 -0800372 String archs = """
373 <key>LSArchitecturePriority</key>
374 <array>"""
Vladimir Orlov0344e5a2014-02-28 11:46:37 +0400375 (args.archs != null ? args.archs : ["x86_64", "i386"]).each {
Tor Norbye814f8292014-03-06 17:27:18 -0800376 archs += "<string>${it}</string>"
377 }
378 archs +="</array>\n"
379
Jean-Baptiste Queru1d526b12013-02-27 09:41:48 -0800380 String urlSchemes = ""
381 if (args.urlSchemes != null) {
382 urlSchemes += """
383 <key>CFBundleURLTypes</key>
384 <array>
385 <dict>
386 <key>CFBundleTypeRole</key>
387 <string>Editor</string>
388 <key>CFBundleURLName</key>
389 <string>Stacktrace</string>
390 <key>CFBundleURLSchemes</key>
391 <array>
392"""
393 args.urlSchemes.each { scheme ->
394 urlSchemes += " <string>${scheme}</string>"
395 }
396 urlSchemes += """
397 </array>
398 </dict>
399 </array>
400"""
401 }
402
Tor Norbye65f60eb2014-07-16 18:07:37 -0700403 ant.replace(file: "$path/Info.plist") {
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800404 replacefilter(token: "@@build@@", value: args.buildNumber)
405 replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, ""))
406 replacefilter(token: "@@executable@@", value: executable)
407 replacefilter(token: "@@icns@@", value: icns)
408 replacefilter(token: "@@bundle_name@@", value: fullName)
409 replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier)
410 replacefilter(token: "@@year@@", value: "$todayYear")
Siva Velusamy7be1af12013-09-06 16:46:31 -0700411 replacefilter(token: "@@company_name@@", value: args.companyName)
412 replacefilter(token: "@@min_year@@", value: "2013")
413 replacefilter(token: "@@max_year@@", value: "$todayYear")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800414 replacefilter(token: "@@version@@", value: version)
415 replacefilter(token: "@@vmoptions@@", value: vmOptions)
416 replacefilter(token: "@@idea_properties@@", value: coreProperties)
417 replacefilter(token: "@@class_path@@", value: classPath)
418 replacefilter(token: "@@help_id@@", value: helpId)
Jean-Baptiste Queru1d526b12013-02-27 09:41:48 -0800419 replacefilter(token: "@@url_schemes@@", value: urlSchemes)
Tor Norbye814f8292014-03-06 17:27:18 -0800420 replacefilter(token: "@@archs@@", value: archs)
Tor Norbye0f831a72014-04-25 07:38:52 -0700421 replacefilter(token: "@@min_osx@@", value: ifNull(args.min_osx, "10.6"))
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800422 }
423
424 if (executable != "idea") {
Tor Norbye65f60eb2014-07-16 18:07:37 -0700425 ant.move(file: "$path/MacOS/idea", tofile: "$path/MacOS/$executable")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800426 }
427
428 ant.replace(file: "$path/bin/inspect.sh") {
429 replacefilter(token: "@@product_full@@", value: fullName)
430 replacefilter(token: "@@script_name@@", value: executable)
431 }
432 if (args.inspect_script != null && args.inspect_script != "inspect") {
433 ant.move(file: "$path/bin/inspect.sh", tofile: "$path/bin/${args.inspect_script}.sh")
434 }
Tor Norbye814f8292014-03-06 17:27:18 -0800435
436 ant.fixcrlf(srcdir: "$path/bin", includes: "*.sh", eol: "unix")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800437})
438
439binding.setVariable("winScripts", { String target, String home, String name, Map args ->
440 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
Siva Velusamy7be1af12013-09-06 16:46:31 -0700441 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase().replace(" ", "_")
442 String vm_options = args.vm_options != null ? args.vm_options : "${p("component.names.product").toLowerCase().replace(" ", "-")}.exe"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800443 if (vm_options.endsWith(".exe")) {
444 vm_options = vm_options.replace(".exe", "%BITS%.exe")
445 }
446 else {
447 vm_options = vm_options + "%BITS%"
448 }
449
450 String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${classPathLibs[0]}\n"
451 classPath += classPathLibs[1..-1].collect {"SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${it}"}.join("\n")
452 if (args.tools_jar) classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar"
453
454 ant.copy(todir: "$target/bin") {
455 fileset(dir: "$home/bin/scripts/win")
456
457 filterset(begintoken: "@@", endtoken: "@@") {
458 filter(token: "product_full", value: fullName)
459 filter(token: "product_uc", value: product_uc)
460 filter(token: "vm_options", value: vm_options)
461 filter(token: "isEap", value: isEap())
462 filter(token: "system_selector", value: args.system_selector)
463 filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
464 filter(token: "class_path", value: classPath)
465 filter(token: "script_name", value: name)
466 }
467 }
468
469 if (name != "idea.bat") {
470 ant.move(file: "$target/bin/idea.bat", tofile: "$target/bin/$name")
471 }
472 if (args.inspect_script != null && args.inspect_script != "inspect") {
473 ant.move(file: "$target/bin/inspect.bat", tofile: "$target/bin/${args.inspect_script}.bat")
474 }
475
476 ant.fixcrlf(srcdir: "$target/bin", includes: "*.bat", eol: "dos")
477})
478
479private ifNull(v, defVal) { v != null ? v : defVal }
480
481binding.setVariable("unixScripts", { String target, String home, String name, Map args ->
482 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
483 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
484 String vm_options = args.vm_options != null ? args.vm_options : p("component.names.product").toLowerCase()
485
486 String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${classPathLibs[0]}\"\n"
487 classPath += classPathLibs[1..-1].collect {"CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\""}.join("\n")
488 if (args.tools_jar) classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\""
489
490 ant.copy(todir: "$target/bin") {
491 fileset(dir: "$home/bin/scripts/unix")
492
493 filterset(begintoken: "@@", endtoken: "@@") {
494 filter(token: "product_full", value: fullName)
495 filter(token: "product_uc", value: product_uc)
496 filter(token: "vm_options", value: vm_options)
497 filter(token: "isEap", value: isEap())
498 filter(token: "system_selector", value: args.system_selector)
499 filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
500 filter(token: "class_path", value: classPath)
501 filter(token: "script_name", value: name)
502 }
503 }
504
505 if (name != "idea.sh") {
506 ant.move(file: "$target/bin/idea.sh", tofile: "$target/bin/$name")
507 }
508 if (args.inspect_script != null && args.inspect_script != "inspect") {
509 ant.move(file: "$target/bin/inspect.sh", tofile: "$target/bin/${args.inspect_script}.sh")
510 }
511
512 ant.fixcrlf(srcdir: "$target/bin", includes: "*.sh", eol: "unix")
513})
514
Siva Velusamy7be1af12013-09-06 16:46:31 -0700515binding.setVariable("winVMOptions", { String target, Map args, String name, String name64 = null ->
Tor Norbye814f8292014-03-06 17:27:18 -0800516 if (name != null) {
517 def options = vmOptions32()
518 options = options.replace(" -XX:+UseCodeCacheFlushing", "")
519 options += " -Didea.platform.prefix=" + args.platform_prefix
520 options += " -Didea.paths.selector=" + args.system_selector
521 ant.echo(file: "$target/bin/${name}.vmoptions", message: options.replace(' ', '\n'))
522 }
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800523
524 if (name64 != null) {
Tor Norbye814f8292014-03-06 17:27:18 -0800525 def options = vmOptions64()
Siva Velusamy7be1af12013-09-06 16:46:31 -0700526 options += " -Didea.platform.prefix=" + args.platform_prefix
527 options += " -Didea.paths.selector=" + args.system_selector
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800528 ant.echo(file: "$target/bin/${name64}.vmoptions", message: options.replace(' ', '\n'))
529 }
530
531 ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "dos")
532})
533
Tor Norbye814f8292014-03-06 17:27:18 -0800534binding.setVariable("unixVMOptions", { String target, String name, String name64 = (name + "64") ->
535 if (name != null) {
536 ant.echo(file: "$target/bin/${name}.vmoptions", message: "${vmOptions32()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n'))
537 }
538 if (name64 != null) {
539 ant.echo(file: "$target/bin/${name64}.vmoptions", message: "${vmOptions64()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n'))
540 }
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800541 ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "unix")
542})
543
544binding.setVariable("unixReadme", { String target, String home, Map args ->
545 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
546 String settings_dir = args.system_selector.replaceFirst("\\d+", "")
547 copyAndPatchFile("$home/build/Install-Linux-tar.txt", "$target/Install-Linux-tar.txt",
548 ["product_full": fullName,
549 "product": p("component.names.product").toLowerCase(),
550 "system_selector": args.system_selector,
Siva Velusamya9491e22013-09-30 16:25:05 -0700551 "script_name" : args.script_name,
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800552 "settings_dir": settings_dir], "@@")
553 ant.fixcrlf(file: "$target/bin/Install-Linux-tar.txt", eol: "unix")
554})
555
556binding.setVariable("forceDelete", { String dirPath ->
557 // if wasn't deleted - retry several times
558 attempt = 1
559 while (attempt < 21 && (new File(dirPath).exists())) {
560 if (attempt > 1) {
561 ant.echo "Deleting $dirPath ... (attempt=$attempt)"
562
563 // let's wait a bit and try again - may be help
564 // in some cases on our windows 7 agents
565 sleep(2000)
566 }
567
568 ant.delete(failonerror: false, dir: dirPath)
569
570 attempt++
571 }
572
573 if (new File(dirPath).exists()) {
574 ant.project.log ("Cannot delete directory: $dirPath" )
575 System.exit (1)
576 }
577})
578
579binding.setVariable("patchPropertiesFile", { String target, Map args = [:] ->
580 String file = "$target/bin/idea.properties"
581
582 if (args.appendices != null) {
583 ant.concat(destfile: file, append: true) {
584 args.appendices.each {
585 fileset(file: it)
586 }
587 }
588 }
589
590 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
591 String settings_dir = args.system_selector.replaceFirst("\\d+", "")
592 ant.replace(file: file) {
593 replacefilter(token: "@@product_uc@@", value: product_uc)
594 replacefilter(token: "@@settings_dir@@", value: settings_dir)
595 }
596
597 String message = (isEap() ? """
598#-----------------------------------------------------------------------
599# Change to 'disabled' if you don't want to receive instant visual notifications
600# about fatal errors that happen to an IDE or plugins installed.
601#-----------------------------------------------------------------------
602idea.fatal.error.notification=enabled
603"""
604 : """
605#-----------------------------------------------------------------------
606# Change to 'enabled' if you want to receive instant visual notifications
607# about fatal errors that happen to an IDE or plugins installed.
608#-----------------------------------------------------------------------
609idea.fatal.error.notification=disabled
610""")
611 ant.echo(file: file, append: true, message: message)
612})
613
614binding.setVariable("zipSources", { String home, String targetDir ->
615 String sources = "$targetDir/sources.zip"
616 projectBuilder.stage("zip sources to $sources")
617
618 ant.mkdir(dir: targetDir)
619 ant.delete(file: sources)
620 ant.zip(destfile: sources) {
621 fileset(dir: home) {
622 ["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each {
623 include(name: "**/*.$it")
624 }
625 exclude(name: "**/testData/**")
626 }
627 }
628
629 notifyArtifactBuilt(sources)
630})
631
632/**
633 * E.g.
634 *
635 * Load all properties from file:
636 * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties")
637 *
638 * Load all properties except "idea.cycle.buffer.size", change "idea.max.intellisense.filesize" to 3000
639 * and enable "idea.is.internal" mode:
640 * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties",
641 * "idea.properties" : ["idea.max.intellisense.filesize" : 3000,
642 * "idea.cycle.buffer.size" : null,
643 * "idea.is.internal" : true ])
644 * @param args
645 * @return text xml properties description in xml
646 */
647private Map readIdeaProperties(Map args) {
648 String ideaPropertiesPath = args == null ? null : args.get("idea.properties.path")
649 if (ideaPropertiesPath == null) {
650 return [:]
651 }
652
653 // read idea.properties file
654 Properties ideaProperties = new Properties();
655 FileInputStream ideaPropertiesFile = new FileInputStream(ideaPropertiesPath);
656 ideaProperties.load(ideaPropertiesFile);
657 ideaPropertiesFile.close();
658
659 def defaultProperties = ["CVS_PASSFILE": "~/.cvspass",
660 "com.apple.mrj.application.live-resize": "false",
661 "idea.paths.selector": args.system_selector,
662 "java.endorsed.dirs": "",
663 "idea.smooth.progress": "false",
664 "apple.laf.useScreenMenuBar": "true",
665 "apple.awt.graphics.UseQuartz": "true",
666 "apple.awt.fullscreencapturealldisplays": "false"]
667 if (args.platform_prefix != null) {
668 defaultProperties.put("idea.platform.prefix", args.platform_prefix)
669 }
670
671 Map properties = defaultProperties
672 def customProperties = args.get("idea.properties")
673 if (customProperties != null) {
674 properties += customProperties
675 }
676
677 properties.each {k, v ->
678 if (v == null) {
679 // if overridden with null - ignore property
680 ideaProperties.remove(k)
681 } else {
682 // if property is overridden in args map - use new value
683 ideaProperties.put(k, v)
684 }
685 }
686
687 return ideaProperties;
688}
689
690private String submapToXml(Map properties, List keys) {
691// generate properties description for Info.plist
692 StringBuilder buff = new StringBuilder()
693
694 keys.each { key ->
695 String value = properties[key]
696 if (value != null) {
697 String string =
698 """
699 <key>$key</key>
700 <string>$value</string>
701"""
702 buff.append(string)
703 }
704 }
705 return buff.toString()
706}
707
Siva Velusamy7be1af12013-09-06 16:46:31 -0700708binding.setVariable("buildWinZip", { String zipRoot, String zipPath, List paths ->
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800709 projectBuilder.stage(".win.zip")
710
711 fixIdeaPropertiesEol(paths, "dos")
712
713 ant.zip(zipfile: zipPath) {
714 paths.each {
Siva Velusamy7be1af12013-09-06 16:46:31 -0700715 zipfileset(dir: it, prefix: zipRoot)
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800716 }
717 }
718
719 notifyArtifactBuilt(zipPath)
720})
721
722binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths, String macPath, List extraBins = [] ->
723 projectBuilder.stage(".mac.zip")
724
725 allPaths = paths + [macPath]
726 ant.zip(zipfile: zipPath) {
727 allPaths.each {
728 zipfileset(dir: it, prefix: zipRoot) {
729 exclude(name: "bin/*.sh")
Tor Norbye32218cc2013-10-08 09:48:09 -0700730 exclude(name: "bin/*.py")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800731 exclude(name: "bin/fsnotifier")
Jean-Baptiste Queru9edc8f62013-02-08 15:14:04 -0800732 exclude(name: "bin/restarter")
Tor Norbye65f60eb2014-07-16 18:07:37 -0700733 exclude(name: "MacOS/*")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800734 extraBins.each {
735 exclude(name: it)
736 }
737 exclude(name: "bin/idea.properties")
738 }
739 }
740
741 allPaths.each {
742 zipfileset(dir: it, filemode: "755", prefix: zipRoot) {
743 include(name: "bin/*.sh")
Tor Norbye32218cc2013-10-08 09:48:09 -0700744 include(name: "bin/*.py")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800745 include(name: "bin/fsnotifier")
Jean-Baptiste Queru9edc8f62013-02-08 15:14:04 -0800746 include(name: "bin/restarter")
Tor Norbye65f60eb2014-07-16 18:07:37 -0700747 include(name: "MacOS/*")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800748 extraBins.each {
749 include(name: it)
750 }
751 }
752 }
753
754 zipfileset(file: "$macPath/bin/idea.properties", prefix: "$zipRoot/bin")
755 }
756})
757
Tor Norbye814f8292014-03-06 17:27:18 -0800758binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths, List extraBins = [] ->
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800759 projectBuilder.stage(".tar.gz")
760
761 fixIdeaPropertiesEol(paths, "unix")
762
763 ant.tar(tarfile: tarPath, longfile: "gnu") {
764 paths.each {
765 tarfileset(dir: it, prefix: tarRoot) {
766 exclude(name: "bin/*.sh")
767 exclude(name: "bin/fsnotifier*")
Tor Norbye814f8292014-03-06 17:27:18 -0800768 extraBins.each {
769 exclude(name: it)
770 }
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800771 type(type: "file")
772 }
773 }
774
775 paths.each {
776 tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
777 include(name: "bin/*.sh")
778 include(name: "bin/fsnotifier*")
Tor Norbye814f8292014-03-06 17:27:18 -0800779 extraBins.each {
780 include(name: it)
781 }
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800782 type(type: "file")
783 }
784 }
785 }
786
787 String gzPath = "${tarPath}.gz"
788 ant.gzip(src: tarPath, zipfile: gzPath)
789 ant.delete(file: tarPath)
790 notifyArtifactBuilt(gzPath)
791})
792
793private void fixIdeaPropertiesEol(List paths, String eol) {
794 paths.each {
795 String file = "$it/bin/idea.properties"
796 if (new File(file).exists()) {
797 ant.fixcrlf(file: file, eol: eol)
798 }
799 }
800}
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700801
Tor Norbyec1ace1f2013-07-08 11:26:24 -0700802binding.setVariable("buildWinLauncher", { String ch, String inputPath, String outputPath, String appInfo,
803 String launcherProperties, String pathsSelector, List resourcePaths ->
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700804 projectBuilder.stage("winLauncher")
805
Tor Norbyed1a59a02013-04-03 16:27:26 -0700806 if (pathsSelector != null) {
Tor Norbye814f8292014-03-06 17:27:18 -0800807 def paths = getProperty("paths")
808 def launcherPropertiesTemp = "${paths.sandbox}/launcher.properties"
809 copyAndPatchFile(launcherProperties, launcherPropertiesTemp, ["PRODUCT_PATHS_SELECTOR": pathsSelector])
810 launcherProperties = launcherPropertiesTemp
Tor Norbyed1a59a02013-04-03 16:27:26 -0700811 }
812
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700813 ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true") {
Tor Norbye814f8292014-03-06 17:27:18 -0800814 sysproperty(key: "java.awt.headless", value: "true")
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700815 arg(value: inputPath)
816 arg(value: appInfo)
817 arg(value: "$ch/native/WinLauncher/WinLauncher/resource.h")
818 arg(value: launcherProperties)
819 arg(value: outputPath)
820 classpath {
821 pathelement(location: "$ch/build/lib/launcher-generator.jar")
822 fileset(dir: "$ch/lib") {
823 include(name: "guava*.jar")
824 include(name: "jdom.jar")
825 include(name: "sanselan*.jar")
826 }
827 resourcePaths.each {
828 pathelement(location: it)
829 }
830 }
831 }
832})
Siva Velusamy7be1af12013-09-06 16:46:31 -0700833
834binding.setVariable("layoutUpdater", { String target, String jarName = "updater.jar" ->
835 layout(target) {
836 jar(jarName) {
837 module("updater")
838 }
839 }
840})
841
Tor Norbyef7998d02013-09-27 10:19:19 -0700842binding.setVariable("collectUsedJars", { List modules, List approvedJars, List forbiddenJars, List modulesToBuild ->
Tor Norbyebeca9832013-09-19 12:39:22 -0700843 def usedJars = new HashSet();
844
Tor Norbyebeca9832013-09-19 12:39:22 -0700845 modules.each {
846 def module = findModule(it)
847 if (module != null) {
848 projectBuilder.moduleRuntimeClasspath(module, false).each {
849 File file = new File(it)
850 if (file.exists()) {
851 String path = file.canonicalPath.replace('\\', '/')
852 if (path.endsWith(".jar") && approvedJars.any { path.startsWith(it) } && !forbiddenJars.any { path.contains(it) }) {
853 if (usedJars.add(path)) {
854 projectBuilder.info("\tADDED: $path for ${module.getName()}")
855 }
856 }
857 }
858 }
Tor Norbyef7998d02013-09-27 10:19:19 -0700859 if (modulesToBuild != null) {
860 modulesToBuild << module
861 }
Tor Norbyebeca9832013-09-19 12:39:22 -0700862 }
863 else {
864 projectBuilder.warning("$it is not a module")
865 }
866 }
Tor Norbyef7998d02013-09-27 10:19:19 -0700867
868 return usedJars
869})
870
871binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
872 def modulesToBuild = []
873 def usedJars = collectUsedJars(modules, approvedJars, forbiddenJars, modulesToBuild)
874 projectBuilder.cleanOutput()
Tor Norbyebeca9832013-09-19 12:39:22 -0700875 projectBuilder.buildModules(modulesToBuild)
876
877 return usedJars
878})
879
880binding.setVariable("buildSearchableOptions", { String target, List licenses, Closure cp, String jvmArgs = null,
881 def paths = getProperty("paths") ->
882 projectBuilder.stage("Building searchable options")
883
884 String targetFile = "${target}/searchableOptions.xml"
885 ant.delete(file: targetFile)
886
887 licenses.each {
888 ant.copy(file: it, todir: paths.ideaSystem)
889 }
890
891 ant.path(id: "searchable.options.classpath") { cp() }
892 String classpathFile = "${paths.sandbox}/classpath.txt"
893 ant.echo(file: classpathFile, append: false, message: "\${toString:searchable.options.classpath}")
894 ant.replace(file: classpathFile, token: File.pathSeparator, value: "\n")
895
896 ant.java(classname: "com.intellij.rt.execution.CommandLineWrapper", fork: true, failonerror: true) {
897 jvmarg(line: "-Xbootclasspath/a:${projectBuilder.moduleOutput(findModule("boot"))} -ea -Xmx500m -XX:MaxPermSize=200m")
898 jvmarg(line: "-Didea.home.path=$home -Didea.system.path=${paths.ideaSystem} -Didea.config.path=${paths.ideaConfig}")
899 if (jvmArgs != null) {
900 jvmarg(line: jvmArgs)
901 }
902
903 arg(line: "${classpathFile} com.intellij.idea.Main traverseUI ${target}/searchableOptions.xml")
904
905 classpath() {
906 pathelement(location: "${projectBuilder.moduleOutput(findModule("java-runtime"))}")
907 }
908 }
909
910 ant.available(file: targetFile, property: "searchable.options.exists");
911 ant.fail(unless: "searchable.options.exists", message: "Searchable options were not built.")
912})
Tor Norbye92584642014-04-17 08:39:25 -0700913
914binding.setVariable("reassignAltClickToMultipleCarets", {String communityHome ->
915 String defaultKeymapContent = new File("$communityHome/platform/platform-resources/src/idea/Keymap_Default.xml").text
916 defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt button1\"/>", "")
917 defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt shift button1\"/>",
918 "<mouse-shortcut keystroke=\"alt button1\"/>")
919 patchedKeymapFile = new File("${paths.sandbox}/classes/production/platform-resources/idea/Keymap_Default.xml")
920 patchedKeymapFile.write(defaultKeymapContent)
Siva Velusamya3091f62014-04-30 07:15:29 -0700921})
Tor Norbye65f60eb2014-07-16 18:07:37 -0700922
923// modules used in Upsource and in Kotlin as an API to IDEA
924binding.setVariable("analysisApiModules", [
925 "analysis-api",
926 "boot",
927 "core-api",
928 "duplicates-analysis",
929 "editor-ui-api",
930 "editor-ui-ex",
931 "extensions",
932 "indexing-api",
933 "java-analysis-api",
934 "java-indexing-api",
935 "java-psi-api",
936 "java-structure-view",
937 "jps-model-api",
938 "jps-model-serialization",
939 "projectModel-api",
940 "structure-view-api",
941 "util",
942 "util-rt",
943 "xml-analysis-api",
944 "xml-psi-api",
945 "xml-structure-view-api",
946])
Tor Norbye02cf98d62014-08-19 12:53:10 -0700947binding.setVariable("analysisImplModules", [
948 "analysis-impl",
949 "core-impl",
950 "indexing-impl",
951 "java-analysis-impl",
952 "java-indexing-impl",
953 "java-psi-impl",
954 "projectModel-impl",
955 "structure-view-impl",
956 "xml-analysis-impl",
957 "xml-psi-impl",
958 "xml-structure-view-impl",
959])