blob: 40bae3a6f6b19e8a497cc4e202630f7f9e4becaa [file] [log] [blame]
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -08001/*
2 * Copyright 2000-2013 JetBrains s.r.o.
3 *
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
17import org.jetbrains.jps.Jps
18import org.jetbrains.jps.Module
19import org.jetbrains.jps.idea.IdeaProjectLoader
20
21includeTool << Jps
22
23binding.setVariable("p", {String key ->
24 return getProperty(key) as String
25})
26
27binding.setVariable("guessJdk", {
28 String javaHome = p("java.home")
29
30 if (new File(javaHome).getName() == "jre") {
31 javaHome = new File(javaHome).getParent()
32 }
33
34 return javaHome
35})
36
37binding.setVariable("includeFile", {String filePath ->
38 Script s = groovyShell.parse(new File(filePath))
39 s.setBinding(binding)
40 s
41})
42
43binding.setVariable("isMac", {
44 return System.getProperty("os.name").toLowerCase().startsWith("mac")
45})
46
47binding.setVariable("isWin", {
48 return System.getProperty("os.name").toLowerCase().startsWith("windows")
49})
50
51binding.setVariable("isEap", {
52 return "true" == p("component.version.eap")
53})
54
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070055binding.setVariable("mem32", "-server -Xms128m -Xmx512m -XX:MaxPermSize=250m -XX:ReservedCodeCacheSize=64m -XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseParNewGC")
56binding.setVariable("mem64", "-Xms128m -Xmx750m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=96m -XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseParNewGC")
57binding.setVariable("common_vmoptions", "-ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080058
59binding.setVariable("vmOptions", { "$common_vmoptions ${isEap() ? '-XX:+HeapDumpOnOutOfMemoryError' : ''}".trim() })
60binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() })
61binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() })
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070062
63binding.setVariable("yjpOptions", { String systemSelector, String platformSuffix = "" ->
64 "-agentlib:yjpagent$platformSuffix=disablej2ee,disablealloc,disabletracing,onlylocal,builtinprobes=none,disableexceptiontelemetry,sessionname=$systemSelector".trim()
65})
66
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080067binding.setVariable("vmOptions32yjp", { String systemSelector ->
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070068 "${vmOptions32()} ${yjpOptions(systemSelector)}".trim()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080069})
70binding.setVariable("vmOptions64yjp", { String systemSelector ->
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -070071 "${vmOptions64()} ${yjpOptions(systemSelector, "64")}".trim()
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -080072})
73
74binding.setVariable("isDefined", {String key ->
75 try {
76 this[key]
77 return true
78 }
79 catch (MissingPropertyException ignored) {
80 return false
81 }
82})
83
84private String require(String key) {
85 try {
86 this[key]
87 }
88 catch (MissingPropertyException ignored) {
89 projectBuilder.error("Property $key is required")
90 }
91}
92
93private String require(String key, String defaultValue) {
94 try {
95 this[key]
96 }
97 catch (MissingPropertyException ignored) {
98 projectBuilder.info("$key is not defined. Defaulting to $defaultValue")
99 this[key] = defaultValue
100 }
101}
102
103binding.setVariable("requireProperty", {String key, String defaultValue = null ->
104 if (defaultValue == null) {
105 require(key)
106 }
107 else {
108 require(key, defaultValue)
109 }
110})
111
112binding.setVariable("guessHome", {
113 // Current file is supposed to be at build/scripts/release.gant path
114 new File(requireProperty("gant.file").substring("file:".length())).getParentFile().getParentFile().getParent()
115})
116
117binding.setVariable("loadProject", {
118 requireProperty("jdkHome", guessJdk())
119 def mac = isMac()
120 jdk("IDEA jdk", jdkHome) {
121 if (!mac) {
122 classpath "$jdkHome/lib/tools.jar"
123 }
124 }
125 IdeaProjectLoader.loadFromPath(project, "${home}")
126})
127
128boolean hasSourceRoots(Module module) {
129 return !module.sourceRoots.isEmpty()
130}
131
132binding.setVariable("findModule", {String name ->
133 project.modules[name]
134})
135
136binding.setVariable("allModules", {
137 return project.modules.values()
138})
139
140binding.setVariable("printUnusedModules", {Set<String> usedModules ->
141 allModules().each {Module m ->
142 if (!usedModules.contains(m.name) && hasSourceRoots(m)) {
143 projectBuilder.warning("Module $m.name is not used in project layout")
144 }
145 }
146})
147
148requireProperty("home", guessHome())
149
150String readSnapshotBuild() {
151 def file = new File("$home/community/build.txt")
152 if (!file.exists()) {
153 file = new File("$home/build.txt")
154 }
155
156 return file.readLines().get(0)
157}
158
159binding.setVariable("snapshot", readSnapshotBuild())
160
161projectBuilder.buildInfoPrinter = new org.jetbrains.jps.teamcity.TeamcityBuildInfoPrinter()
162projectBuilder.compressJars = false
163
164binding.setVariable("notifyArtifactBuilt", { String artifactPath ->
165 if (!artifactPath.startsWith(home)) {
166 projectBuilder.error("Artifact path $artifactPath should start with $home")
167 }
168 def relativePath = artifactPath.substring(home.length())
169 if (relativePath.startsWith("/")) {
170 relativePath = relativePath.substring(1)
171 }
172 def file = new File(artifactPath)
173 if (file.isDirectory()) {
174 relativePath += "=>" + file.name
175 }
176 projectBuilder.info("##teamcity[publishArtifacts '$relativePath']")
177})
178
179def suspendUntilDebuggerConnect = System.getProperty("debug.suspend") ?: "n"
180def debugPort = System.getProperty("debug.port") ?: 5555
181if (suspendUntilDebuggerConnect == 'y') {
182 println """\
183------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<----
184-------------------------------------------^------^------^------^------^------^------^-----------------------
185"""
186}
187
188binding.setVariable("patchFiles", { List files, Map args, String marker = "__" ->
189 files.each { file ->
190 args.each { arg ->
191 ant.replace(file: file, token: "${marker}${arg.key}${marker}", value: arg.value)
192 }
193 }
194})
195
196binding.setVariable("copyAndPatchFile", { String file, String target, Map args, String marker = "__" ->
197 ant.copy(file: file, tofile: target, overwrite: "true") {
198 filterset(begintoken: marker, endtoken: marker) {
199 args.each {
200 filter(token: it.key, value: it.value)
201 }
202 }
203 }
204})
205
206binding.setVariable("copyAndPatchFiles", { Closure files, String target, Map args, String marker = "__" ->
207 ant.copy(todir: target, overwrite: "true") {
208 files()
209
210 filterset(begintoken: marker, endtoken: marker) {
211 args.each {
212 filter(token: it.key, value: it.value)
213 }
214 }
215 }
216})
217
218binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
219 ant.tstamp()
220 patchFiles([appInfoFile], ["BUILD_NUMBER": buildNumber, "BUILD_DATE": DSTAMP])
221})
222
223binding.setVariable("commonJvmArgs", {
224 return [
225 "-ea",
226 "-Didea.home.path=$home",
227 "-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
228 "-XX:+HeapDumpOnOutOfMemoryError",
229 "-Didea.system.path=${p("teamcity.build.tempDir")}/system",
230 "-Didea.config.path=${p("teamcity.build.tempDir")}/config",
231 "-Xdebug",
232 "-Xrunjdwp:transport=dt_socket,server=y,suspend=$suspendUntilDebuggerConnect,address=$debugPort"]
233})
234
235binding.setVariable("classPathLibs", [
236 "bootstrap.jar",
237 "extensions.jar",
238 "util.jar",
239 "jdom.jar",
240 "log4j.jar",
241 "trove4j.jar",
242 "jna.jar"
243])
244
245binding.setVariable("platformApiModules", [
246 "core-api",
247 "indexing-api",
248 "projectModel-api",
249 "jps-model-api",
250 "platform-api",
251 "lvcs-api",
252 "lang-api",
253 "vcs-api",
254 "usageView",
255 "xdebugger-api",
256 "xml-openapi",
257])
258
259
260binding.setVariable("platformImplementationModules", [
261 "core-impl",
262 "indexing-impl",
263 "jps-model-impl",
264 "jps-model-serialization",
265 "projectModel-impl",
266 "platform-impl",
267 "vcs-impl",
268 "lang-impl",
269 "testRunner",
270 "smRunner",
271 "xdebugger-impl",
272 "xml",
273 "relaxng",
274 "lvcs-impl",
275 "spellchecker",
276 "images",
277 "RegExpSupport",
278 "dvcs"
279])
280
281binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
282 ant.copy(todir: "$path/bin") {
283 fileset(dir: "$ch/bin/mac")
284 }
285
286 ant.copy(todir: path) {
287 fileset(dir: "$ch/build/conf/mac")
288 }
289
290 ant.tstamp() {
291 format(property: "todayYear", pattern: "yyyy")
292 }
293
294 String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase()
295 String helpId = args.help_id != null ? args.help_id : "IJ"
296 String icns = "idea.icns"
297 String helpIcns = "$path/Contents/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
298 if (args.icns != null) {
299 ant.delete(file: "$path/Contents/Resources/idea.icns")
300 ant.copy(file: args.icns, todir: "$path/Contents/Resources")
301 ant.copy(file: args.icns, tofile: helpIcns)
302 icns = new File((String)args.icns).getName();
303 } else {
304 ant.copy(file: "$path/Contents/Resources/idea.icns", tofile: helpIcns)
305 }
306
307 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
308
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700309 String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800310 if (isEap() && !args.mac_no_yjp) {
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700311 vmOptions += " ${yjpOptions(args.system_selector)}"
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800312 }
313
314 String minor = p("component.version.minor")
315 String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"
316
317 Map properties = readIdeaProperties(args)
318
319 def coreKeys = ["idea.platform.prefix", "idea.paths.selector"]
320
321 String coreProperties = submapToXml(properties, coreKeys);
322
323 StringBuilder effectiveProperties = new StringBuilder()
324 properties.each { k, v ->
325 if (!coreKeys.contains(k)) {
326 effectiveProperties.append("$k=$v\n");
327 }
328 }
329
330 new File("$path/bin/idea.properties").text = effectiveProperties.toString()
331 new File("$path/bin/idea.vmoptions").text = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
332
333 String classPath = classPathLibs.collect {"\$APP_PACKAGE/lib/${it}" }.join(":")
334
Jean-Baptiste Queru1d526b12013-02-27 09:41:48 -0800335 String urlSchemes = ""
336 if (args.urlSchemes != null) {
337 urlSchemes += """
338 <key>CFBundleURLTypes</key>
339 <array>
340 <dict>
341 <key>CFBundleTypeRole</key>
342 <string>Editor</string>
343 <key>CFBundleURLName</key>
344 <string>Stacktrace</string>
345 <key>CFBundleURLSchemes</key>
346 <array>
347"""
348 args.urlSchemes.each { scheme ->
349 urlSchemes += " <string>${scheme}</string>"
350 }
351 urlSchemes += """
352 </array>
353 </dict>
354 </array>
355"""
356 }
357
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800358 ant.replace(file: "$path/Contents/Info.plist") {
359 replacefilter(token: "@@build@@", value: args.buildNumber)
360 replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, ""))
361 replacefilter(token: "@@executable@@", value: executable)
362 replacefilter(token: "@@icns@@", value: icns)
363 replacefilter(token: "@@bundle_name@@", value: fullName)
364 replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier)
365 replacefilter(token: "@@year@@", value: "$todayYear")
366 replacefilter(token: "@@version@@", value: version)
367 replacefilter(token: "@@vmoptions@@", value: vmOptions)
368 replacefilter(token: "@@idea_properties@@", value: coreProperties)
369 replacefilter(token: "@@class_path@@", value: classPath)
370 replacefilter(token: "@@help_id@@", value: helpId)
Jean-Baptiste Queru1d526b12013-02-27 09:41:48 -0800371 replacefilter(token: "@@url_schemes@@", value: urlSchemes)
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800372 }
373
374 if (executable != "idea") {
375 ant.move(file: "$path/Contents/MacOS/idea", tofile: "$path/Contents/MacOS/$executable")
376 }
377
378 ant.replace(file: "$path/bin/inspect.sh") {
379 replacefilter(token: "@@product_full@@", value: fullName)
380 replacefilter(token: "@@script_name@@", value: executable)
381 }
382 if (args.inspect_script != null && args.inspect_script != "inspect") {
383 ant.move(file: "$path/bin/inspect.sh", tofile: "$path/bin/${args.inspect_script}.sh")
384 }
385})
386
387binding.setVariable("winScripts", { String target, String home, String name, Map args ->
388 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
389 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
390 String vm_options = args.vm_options != null ? args.vm_options : "${p("component.names.product").toLowerCase()}.exe"
391 if (vm_options.endsWith(".exe")) {
392 vm_options = vm_options.replace(".exe", "%BITS%.exe")
393 }
394 else {
395 vm_options = vm_options + "%BITS%"
396 }
397
398 String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${classPathLibs[0]}\n"
399 classPath += classPathLibs[1..-1].collect {"SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${it}"}.join("\n")
400 if (args.tools_jar) classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar"
401
402 ant.copy(todir: "$target/bin") {
403 fileset(dir: "$home/bin/scripts/win")
404
405 filterset(begintoken: "@@", endtoken: "@@") {
406 filter(token: "product_full", value: fullName)
407 filter(token: "product_uc", value: product_uc)
408 filter(token: "vm_options", value: vm_options)
409 filter(token: "isEap", value: isEap())
410 filter(token: "system_selector", value: args.system_selector)
411 filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
412 filter(token: "class_path", value: classPath)
413 filter(token: "script_name", value: name)
414 }
415 }
416
417 if (name != "idea.bat") {
418 ant.move(file: "$target/bin/idea.bat", tofile: "$target/bin/$name")
419 }
420 if (args.inspect_script != null && args.inspect_script != "inspect") {
421 ant.move(file: "$target/bin/inspect.bat", tofile: "$target/bin/${args.inspect_script}.bat")
422 }
423
424 ant.fixcrlf(srcdir: "$target/bin", includes: "*.bat", eol: "dos")
425})
426
427private ifNull(v, defVal) { v != null ? v : defVal }
428
429binding.setVariable("unixScripts", { String target, String home, String name, Map args ->
430 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
431 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
432 String vm_options = args.vm_options != null ? args.vm_options : p("component.names.product").toLowerCase()
433
434 String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${classPathLibs[0]}\"\n"
435 classPath += classPathLibs[1..-1].collect {"CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\""}.join("\n")
436 if (args.tools_jar) classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\""
437
438 ant.copy(todir: "$target/bin") {
439 fileset(dir: "$home/bin/scripts/unix")
440
441 filterset(begintoken: "@@", endtoken: "@@") {
442 filter(token: "product_full", value: fullName)
443 filter(token: "product_uc", value: product_uc)
444 filter(token: "vm_options", value: vm_options)
445 filter(token: "isEap", value: isEap())
446 filter(token: "system_selector", value: args.system_selector)
447 filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
448 filter(token: "class_path", value: classPath)
449 filter(token: "script_name", value: name)
450 }
451 }
452
453 if (name != "idea.sh") {
454 ant.move(file: "$target/bin/idea.sh", tofile: "$target/bin/$name")
455 }
456 if (args.inspect_script != null && args.inspect_script != "inspect") {
457 ant.move(file: "$target/bin/inspect.sh", tofile: "$target/bin/${args.inspect_script}.sh")
458 }
459
460 ant.fixcrlf(srcdir: "$target/bin", includes: "*.sh", eol: "unix")
461})
462
463binding.setVariable("winVMOptions", { String target, String system_selector, String name, String name64 = null ->
464 def options = isEap() && system_selector != null ? vmOptions32yjp(system_selector) : vmOptions32()
465 ant.echo(file: "$target/bin/${name}.vmoptions", message: options.replace(' ', '\n'))
466
467 if (name64 != null) {
468 options = isEap() && system_selector != null ? vmOptions64yjp(system_selector) : vmOptions64()
469 ant.echo(file: "$target/bin/${name64}.vmoptions", message: options.replace(' ', '\n'))
470 }
471
472 ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "dos")
473})
474
475binding.setVariable("unixVMOptions", { String target, String name ->
476 ant.echo(file: "$target/bin/${name}.vmoptions", message: vmOptions32().replace(' ', '\n'))
477 ant.echo(file: "$target/bin/${name}64.vmoptions", message: vmOptions64().replace(' ', '\n'))
478 ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "unix")
479})
480
481binding.setVariable("unixReadme", { String target, String home, Map args ->
482 String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
483 String settings_dir = args.system_selector.replaceFirst("\\d+", "")
484 copyAndPatchFile("$home/build/Install-Linux-tar.txt", "$target/Install-Linux-tar.txt",
485 ["product_full": fullName,
486 "product": p("component.names.product").toLowerCase(),
487 "system_selector": args.system_selector,
488 "settings_dir": settings_dir], "@@")
489 ant.fixcrlf(file: "$target/bin/Install-Linux-tar.txt", eol: "unix")
490})
491
492binding.setVariable("forceDelete", { String dirPath ->
493 // if wasn't deleted - retry several times
494 attempt = 1
495 while (attempt < 21 && (new File(dirPath).exists())) {
496 if (attempt > 1) {
497 ant.echo "Deleting $dirPath ... (attempt=$attempt)"
498
499 // let's wait a bit and try again - may be help
500 // in some cases on our windows 7 agents
501 sleep(2000)
502 }
503
504 ant.delete(failonerror: false, dir: dirPath)
505
506 attempt++
507 }
508
509 if (new File(dirPath).exists()) {
510 ant.project.log ("Cannot delete directory: $dirPath" )
511 System.exit (1)
512 }
513})
514
515binding.setVariable("patchPropertiesFile", { String target, Map args = [:] ->
516 String file = "$target/bin/idea.properties"
517
518 if (args.appendices != null) {
519 ant.concat(destfile: file, append: true) {
520 args.appendices.each {
521 fileset(file: it)
522 }
523 }
524 }
525
526 String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
527 String settings_dir = args.system_selector.replaceFirst("\\d+", "")
528 ant.replace(file: file) {
529 replacefilter(token: "@@product_uc@@", value: product_uc)
530 replacefilter(token: "@@settings_dir@@", value: settings_dir)
531 }
532
533 String message = (isEap() ? """
534#-----------------------------------------------------------------------
535# Change to 'disabled' if you don't want to receive instant visual notifications
536# about fatal errors that happen to an IDE or plugins installed.
537#-----------------------------------------------------------------------
538idea.fatal.error.notification=enabled
539"""
540 : """
541#-----------------------------------------------------------------------
542# Change to 'enabled' if you want to receive instant visual notifications
543# about fatal errors that happen to an IDE or plugins installed.
544#-----------------------------------------------------------------------
545idea.fatal.error.notification=disabled
546""")
547 ant.echo(file: file, append: true, message: message)
548})
549
550binding.setVariable("zipSources", { String home, String targetDir ->
551 String sources = "$targetDir/sources.zip"
552 projectBuilder.stage("zip sources to $sources")
553
554 ant.mkdir(dir: targetDir)
555 ant.delete(file: sources)
556 ant.zip(destfile: sources) {
557 fileset(dir: home) {
558 ["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each {
559 include(name: "**/*.$it")
560 }
561 exclude(name: "**/testData/**")
562 }
563 }
564
565 notifyArtifactBuilt(sources)
566})
567
568/**
569 * E.g.
570 *
571 * Load all properties from file:
572 * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties")
573 *
574 * Load all properties except "idea.cycle.buffer.size", change "idea.max.intellisense.filesize" to 3000
575 * and enable "idea.is.internal" mode:
576 * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties",
577 * "idea.properties" : ["idea.max.intellisense.filesize" : 3000,
578 * "idea.cycle.buffer.size" : null,
579 * "idea.is.internal" : true ])
580 * @param args
581 * @return text xml properties description in xml
582 */
583private Map readIdeaProperties(Map args) {
584 String ideaPropertiesPath = args == null ? null : args.get("idea.properties.path")
585 if (ideaPropertiesPath == null) {
586 return [:]
587 }
588
589 // read idea.properties file
590 Properties ideaProperties = new Properties();
591 FileInputStream ideaPropertiesFile = new FileInputStream(ideaPropertiesPath);
592 ideaProperties.load(ideaPropertiesFile);
593 ideaPropertiesFile.close();
594
595 def defaultProperties = ["CVS_PASSFILE": "~/.cvspass",
596 "com.apple.mrj.application.live-resize": "false",
597 "idea.paths.selector": args.system_selector,
598 "java.endorsed.dirs": "",
599 "idea.smooth.progress": "false",
600 "apple.laf.useScreenMenuBar": "true",
601 "apple.awt.graphics.UseQuartz": "true",
602 "apple.awt.fullscreencapturealldisplays": "false"]
603 if (args.platform_prefix != null) {
604 defaultProperties.put("idea.platform.prefix", args.platform_prefix)
605 }
606
607 Map properties = defaultProperties
608 def customProperties = args.get("idea.properties")
609 if (customProperties != null) {
610 properties += customProperties
611 }
612
613 properties.each {k, v ->
614 if (v == null) {
615 // if overridden with null - ignore property
616 ideaProperties.remove(k)
617 } else {
618 // if property is overridden in args map - use new value
619 ideaProperties.put(k, v)
620 }
621 }
622
623 return ideaProperties;
624}
625
626private String submapToXml(Map properties, List keys) {
627// generate properties description for Info.plist
628 StringBuilder buff = new StringBuilder()
629
630 keys.each { key ->
631 String value = properties[key]
632 if (value != null) {
633 String string =
634 """
635 <key>$key</key>
636 <string>$value</string>
637"""
638 buff.append(string)
639 }
640 }
641 return buff.toString()
642}
643
644binding.setVariable("buildWinZip", { String zipPath, List paths ->
645 projectBuilder.stage(".win.zip")
646
647 fixIdeaPropertiesEol(paths, "dos")
648
649 ant.zip(zipfile: zipPath) {
650 paths.each {
651 fileset(dir: it)
652 }
653 }
654
655 notifyArtifactBuilt(zipPath)
656})
657
658binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths, String macPath, List extraBins = [] ->
659 projectBuilder.stage(".mac.zip")
660
661 allPaths = paths + [macPath]
662 ant.zip(zipfile: zipPath) {
663 allPaths.each {
664 zipfileset(dir: it, prefix: zipRoot) {
665 exclude(name: "bin/*.sh")
666 exclude(name: "bin/fsnotifier")
Jean-Baptiste Queru9edc8f62013-02-08 15:14:04 -0800667 exclude(name: "bin/restarter")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800668 exclude(name: "Contents/MacOS/*")
669 extraBins.each {
670 exclude(name: it)
671 }
672 exclude(name: "bin/idea.properties")
673 }
674 }
675
676 allPaths.each {
677 zipfileset(dir: it, filemode: "755", prefix: zipRoot) {
678 include(name: "bin/*.sh")
679 include(name: "bin/fsnotifier")
Jean-Baptiste Queru9edc8f62013-02-08 15:14:04 -0800680 include(name: "bin/restarter")
Jean-Baptiste Querub56ea2a2013-01-08 11:11:20 -0800681 include(name: "Contents/MacOS/*")
682 extraBins.each {
683 include(name: it)
684 }
685 }
686 }
687
688 zipfileset(file: "$macPath/bin/idea.properties", prefix: "$zipRoot/bin")
689 }
690})
691
692binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths ->
693 projectBuilder.stage(".tar.gz")
694
695 fixIdeaPropertiesEol(paths, "unix")
696
697 ant.tar(tarfile: tarPath, longfile: "gnu") {
698 paths.each {
699 tarfileset(dir: it, prefix: tarRoot) {
700 exclude(name: "bin/*.sh")
701 exclude(name: "bin/fsnotifier*")
702 type(type: "file")
703 }
704 }
705
706 paths.each {
707 tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
708 include(name: "bin/*.sh")
709 include(name: "bin/fsnotifier*")
710 type(type: "file")
711 }
712 }
713 }
714
715 String gzPath = "${tarPath}.gz"
716 ant.gzip(src: tarPath, zipfile: gzPath)
717 ant.delete(file: tarPath)
718 notifyArtifactBuilt(gzPath)
719})
720
721private void fixIdeaPropertiesEol(List paths, String eol) {
722 paths.each {
723 String file = "$it/bin/idea.properties"
724 if (new File(file).exists()) {
725 ant.fixcrlf(file: file, eol: eol)
726 }
727 }
728}
Jean-Baptiste Queru2bd2b7c2013-04-01 14:41:51 -0700729
730binding.setVariable("buildWinLauncher", { String ch, String inputPath, String outputPath, String appInfo, String launcherProperties, List resourcePaths ->
731 projectBuilder.stage("winLauncher")
732
733 ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true") {
734 arg(value: inputPath)
735 arg(value: appInfo)
736 arg(value: "$ch/native/WinLauncher/WinLauncher/resource.h")
737 arg(value: launcherProperties)
738 arg(value: outputPath)
739 classpath {
740 pathelement(location: "$ch/build/lib/launcher-generator.jar")
741 fileset(dir: "$ch/lib") {
742 include(name: "guava*.jar")
743 include(name: "jdom.jar")
744 include(name: "sanselan*.jar")
745 }
746 resourcePaths.each {
747 pathelement(location: it)
748 }
749 }
750 }
751})