| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import org.jetbrains.jps.gant.JpsGantTool |
| import org.jetbrains.jps.gant.TeamCityBuildInfoPrinter |
| import org.jetbrains.jps.model.java.JavaSourceRootType |
| import org.jetbrains.jps.model.module.JpsModule |
| |
| includeTool << JpsGantTool |
| |
| binding.setVariable("p", {String key -> |
| return getProperty(key) as String |
| }) |
| |
| binding.setVariable("guessJdk", { |
| String javaHome = p("java.home") |
| |
| if (new File(javaHome).getName() == "jre") { |
| javaHome = new File(javaHome).getParent() |
| } |
| |
| return javaHome |
| }) |
| |
| binding.setVariable("includeFile", {String filePath -> |
| Script s = groovyShell.parse(new File(filePath)) |
| s.setBinding(binding) |
| s |
| }) |
| |
| binding.setVariable("isMac", { |
| return System.getProperty("os.name").toLowerCase().startsWith("mac") |
| }) |
| |
| binding.setVariable("isWin", { |
| return System.getProperty("os.name").toLowerCase().startsWith("windows") |
| }) |
| |
| binding.setVariable("isEap", { |
| return "true" == p("component.version.eap") |
| }) |
| |
| binding.setVariable("mem32", "-server -Xms128m -Xmx512m -XX:MaxPermSize=250m -XX:ReservedCodeCacheSize=150m") |
| binding.setVariable("mem64", "-Xms128m -Xmx750m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=225m") |
| binding.setVariable("common_vmoptions", "-ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true " + |
| "-Didea.project.structure.max.errors.to.show=0 " + |
| "-Djsse.enableSNIExtension=false " + |
| "-XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50") |
| |
| binding.setVariable("vmOptions", { "$common_vmoptions ${isEap() ? '-XX:+HeapDumpOnOutOfMemoryError' : ''}".trim() }) |
| binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() }) |
| binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() }) |
| |
| binding.setVariable("yjpOptions", { String systemSelector, String platformSuffix = "" -> |
| "-agentlib:yjpagent$platformSuffix=probe_disable=*,disablealloc,disabletracing,onlylocal,disableexceptiontelemetry,delay=10000,sessionname=$systemSelector".trim() |
| }) |
| binding.setVariable("vmOptions32yjp", { String systemSelector -> |
| "${vmOptions32()} ${yjpOptions(systemSelector)}".trim() |
| }) |
| binding.setVariable("vmOptions64yjp", { String systemSelector -> |
| "${vmOptions64()} ${yjpOptions(systemSelector, "64")}".trim() |
| }) |
| |
| binding.setVariable("isDefined", {String key -> |
| try { |
| this[key] |
| return true |
| } |
| catch (MissingPropertyException ignored) { |
| return false |
| } |
| }) |
| |
| private String require(String key) { |
| try { |
| this[key] |
| } |
| catch (MissingPropertyException ignored) { |
| projectBuilder.error("Property '$key' is required") |
| } |
| } |
| |
| private String require(String key, String defaultValue) { |
| try { |
| this[key] |
| } |
| catch (MissingPropertyException ignored) { |
| projectBuilder.info("'$key' is not defined. Defaulting to '$defaultValue'") |
| this[key] = defaultValue |
| } |
| } |
| |
| binding.setVariable("requireProperty", {String key, String defaultValue = null -> |
| if (defaultValue == null) { |
| require(key) |
| } |
| else { |
| require(key, defaultValue) |
| } |
| }) |
| |
| binding.setVariable("guessHome", { |
| // current file is supposed to be at build/scripts/*.gant path |
| String uri = requireProperty("gant.file") |
| new File(new URI(uri).getSchemeSpecificPart()).getParentFile().getParentFile().getParent() |
| }) |
| |
| binding.setVariable("loadProject", { |
| requireProperty("jdkHome", guessJdk()) |
| def mac = isMac() |
| jdk("IDEA jdk", jdkHome) { |
| if (!mac) { |
| classpath "$jdkHome/lib/tools.jar" |
| } |
| } |
| projectBuilder.dataStorageRoot = new File("$home/.jps-build-data") |
| loadProjectFromPath(home) |
| }) |
| |
| boolean hasSourceRoots(JpsModule module) { |
| return module.getSourceRoots(JavaSourceRootType.SOURCE).iterator().hasNext() |
| } |
| |
| binding.setVariable("findModule", {String name -> |
| project.modules.find { it.name == name } |
| }) |
| |
| binding.setVariable("allModules", { |
| return project.modules |
| }) |
| |
| binding.setVariable("printUnusedModules", {Set<String> usedModules -> |
| allModules().each {JpsModule m -> |
| if (!usedModules.contains(m.name) && hasSourceRoots(m)) { |
| projectBuilder.warning("Module $m.name is not used in project layout") |
| } |
| } |
| }) |
| |
| requireProperty("home", guessHome()) |
| |
| String readSnapshotBuild() { |
| def file = new File("$home/community/build.txt") |
| if (!file.exists()) { |
| file = new File("$home/build.txt") |
| } |
| |
| return file.readLines().get(0) |
| } |
| |
| binding.setVariable("snapshot", readSnapshotBuild()) |
| |
| projectBuilder.buildInfoPrinter = new TeamCityBuildInfoPrinter() |
| projectBuilder.compressJars = false |
| |
| binding.setVariable("notifyArtifactBuilt", { String artifactPath -> |
| if (!artifactPath.startsWith(home)) { |
| // AndroidStudio: make this to be just an info as the out folder is typically |
| // not in the home folder |
| projectBuilder.info("Artifact path $artifactPath should start with $home") |
| return |
| } |
| def relativePath = artifactPath.substring(home.length()) |
| if (relativePath.startsWith("/")) { |
| relativePath = relativePath.substring(1) |
| } |
| def file = new File(artifactPath) |
| if (file.isDirectory()) { |
| relativePath += "=>" + file.name |
| } |
| projectBuilder.info("##teamcity[publishArtifacts '$relativePath']") |
| }) |
| |
| def suspendUntilDebuggerConnect = System.getProperty("debug.suspend") ?: "n" |
| def debugPort = System.getProperty("debug.port") ?: 5555 |
| if (suspendUntilDebuggerConnect == 'y') { |
| println """\ |
| ------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<---- |
| -------------------------------------------^------^------^------^------^------^------^----------------------- |
| """ |
| } |
| |
| binding.setVariable("patchFiles", { List files, Map args, String marker = "__" -> |
| files.each { file -> |
| args.each { arg -> |
| ant.replace(file: file, token: "${marker}${arg.key}${marker}", value: arg.value) |
| } |
| } |
| }) |
| |
| binding.setVariable("copyAndPatchFile", { String file, String target, Map args, String marker = "__" -> |
| ant.copy(file: file, tofile: target, overwrite: "true") { |
| filterset(begintoken: marker, endtoken: marker) { |
| args.each { |
| filter(token: it.key, value: it.value) |
| } |
| } |
| } |
| }) |
| |
| binding.setVariable("copyAndPatchFiles", { Closure files, String target, Map args, String marker = "__" -> |
| ant.copy(todir: target, overwrite: "true") { |
| files() |
| |
| filterset(begintoken: marker, endtoken: marker) { |
| args.each { |
| filter(token: it.key, value: it.value) |
| } |
| } |
| } |
| }) |
| |
| binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile -> |
| ant.tstamp() |
| patchFiles([appInfoFile], ["BUILD_NUMBER": buildNumber, "BUILD_DATE": DSTAMP, |
| "PACKAGE_CODE": buildNumber.substring(0, buildNumber.indexOf('-'))]) |
| }) |
| |
| binding.setVariable("commonJvmArgs", { |
| return [ |
| "-ea", |
| "-server", |
| "-Didea.home.path=$home", |
| "-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}", |
| "-XX:+HeapDumpOnOutOfMemoryError", |
| "-Didea.system.path=${p("teamcity.build.tempDir")}/system", |
| "-Didea.config.path=${p("teamcity.build.tempDir")}/config"] |
| // We don't want this on the Jenkins build server |
| // "-Xdebug", |
| // "-Xrunjdwp:transport=dt_socket,server=y,suspend=$suspendUntilDebuggerConnect,address=$debugPort"] |
| }) |
| |
| binding.setVariable("classPathLibs", [ |
| "bootstrap.jar", |
| "extensions.jar", |
| "util.jar", |
| "jdom.jar", |
| "log4j.jar", |
| "trove4j.jar", |
| "jna.jar" |
| ]) |
| |
| binding.setVariable("platformApiModules", [ |
| "analysis-api", |
| "core-api", |
| "dvcs-api", |
| "editor-ui-api", |
| "external-system-api", |
| "indexing-api", |
| "jps-model-api", |
| "lang-api", |
| "lvcs-api", |
| "projectModel-api", |
| "platform-api", |
| "structure-view-api", |
| "usageView", |
| "vcs-api", |
| "vcs-api-core", |
| "vcs-log-api", |
| "vcs-log-graph-api", |
| "xdebugger-api", |
| "remote-servers-api", |
| "remote-servers-agent-rt", |
| "xml-analysis-api", |
| "xml-openapi", |
| "xml-psi-api", |
| "xml-structure-view-api", |
| ]) |
| |
| |
| binding.setVariable("platformImplementationModules", [ |
| "analysis-impl", |
| "core-impl", |
| "dvcs-impl", |
| "editor-ui-ex", |
| "images", |
| "indexing-impl", |
| "jps-model-impl", |
| "jps-model-serialization", |
| "lang-impl", |
| "lvcs-impl", |
| "projectModel-impl", |
| "platform-impl", |
| "structure-view-impl", |
| "vcs-impl", |
| "vcs-log-graph", |
| "vcs-log-impl", |
| "testRunner", |
| "smRunner", |
| "relaxng", |
| "RegExpSupport", |
| "spellchecker", |
| "xdebugger-impl", |
| "remote-servers-impl", |
| "xml", |
| "xml-analysis-impl", |
| "xml-psi-impl", |
| "xml-structure-view-impl", |
| "protocol-reader-runtime", |
| "script-debugger-backend", |
| "script-debugger-ui" |
| ]) |
| |
| binding.setVariable("layoutMacApp", { String path, String ch, Map args -> |
| ant.copy(todir: "$path/bin") { |
| fileset(dir: "$ch/bin/mac") |
| } |
| |
| ant.copy(todir: path) { |
| fileset(dir: "$ch/build/conf/mac/Contents") |
| } |
| |
| ant.tstamp() { |
| format(property: "todayYear", pattern: "yyyy") |
| } |
| |
| String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase() |
| String helpId = args.help_id != null ? args.help_id : "IJ" |
| String icns = "idea.icns" |
| String helpIcns = "$path/Resources/${helpId}.help/Contents/Resources/Shared/product.icns" |
| if (args.icns != null) { |
| ant.delete(file: "$path/Resources/idea.icns") |
| ant.copy(file: args.icns, todir: "$path/Resources") |
| ant.copy(file: args.icns, tofile: helpIcns) |
| icns = new File((String)args.icns).getName(); |
| } else { |
| ant.copy(file: "$path/Resources/idea.icns", tofile: helpIcns) |
| } |
| |
| String fullName = args.fullName != null ? args.fullName : p("component.names.fullname") |
| |
| String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none" |
| |
| String minor = p("component.version.minor") |
| String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}" |
| |
| Map properties = readIdeaProperties(args) |
| |
| def coreKeys = ["idea.platform.prefix", "idea.paths.selector"] |
| |
| String coreProperties = submapToXml(properties, coreKeys); |
| |
| StringBuilder effectiveProperties = new StringBuilder() |
| properties.each { k, v -> |
| if (!coreKeys.contains(k)) { |
| effectiveProperties.append("$k=$v\n"); |
| } |
| } |
| |
| new File("$path/bin/idea.properties").text = effectiveProperties.toString() |
| String ideaVmOptions = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n") |
| if (isEap() && !args.mac_no_yjp) { |
| ideaVmOptions += " ${yjpOptions(args.system_selector)}" |
| } |
| new File("$path/bin/idea.vmoptions").text = ideaVmOptions |
| |
| String classPath = classPathLibs.collect {"\$APP_PACKAGE/Contents/lib/${it}" }.join(":") |
| |
| String archs = """ |
| <key>LSArchitecturePriority</key> |
| <array>""" |
| (args.archs != null ? args.archs : ["x86_64", "i386"]).each { |
| archs += "<string>${it}</string>" |
| } |
| archs +="</array>\n" |
| |
| String urlSchemes = "" |
| if (args.urlSchemes != null) { |
| urlSchemes += """ |
| <key>CFBundleURLTypes</key> |
| <array> |
| <dict> |
| <key>CFBundleTypeRole</key> |
| <string>Editor</string> |
| <key>CFBundleURLName</key> |
| <string>Stacktrace</string> |
| <key>CFBundleURLSchemes</key> |
| <array> |
| """ |
| args.urlSchemes.each { scheme -> |
| urlSchemes += " <string>${scheme}</string>" |
| } |
| urlSchemes += """ |
| </array> |
| </dict> |
| </array> |
| """ |
| } |
| |
| ant.replace(file: "$path/Info.plist") { |
| replacefilter(token: "@@build@@", value: args.buildNumber) |
| replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, "")) |
| replacefilter(token: "@@executable@@", value: executable) |
| replacefilter(token: "@@icns@@", value: icns) |
| replacefilter(token: "@@bundle_name@@", value: fullName) |
| replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier) |
| replacefilter(token: "@@year@@", value: "$todayYear") |
| replacefilter(token: "@@company_name@@", value: args.companyName) |
| replacefilter(token: "@@min_year@@", value: "2013") |
| replacefilter(token: "@@max_year@@", value: "$todayYear") |
| replacefilter(token: "@@version@@", value: version) |
| replacefilter(token: "@@vmoptions@@", value: vmOptions) |
| replacefilter(token: "@@idea_properties@@", value: coreProperties) |
| replacefilter(token: "@@class_path@@", value: classPath) |
| replacefilter(token: "@@help_id@@", value: helpId) |
| replacefilter(token: "@@url_schemes@@", value: urlSchemes) |
| replacefilter(token: "@@archs@@", value: archs) |
| replacefilter(token: "@@min_osx@@", value: ifNull(args.min_osx, "10.6")) |
| } |
| |
| if (executable != "idea") { |
| ant.move(file: "$path/MacOS/idea", tofile: "$path/MacOS/$executable") |
| } |
| |
| ant.replace(file: "$path/bin/inspect.sh") { |
| replacefilter(token: "@@product_full@@", value: fullName) |
| replacefilter(token: "@@script_name@@", value: executable) |
| } |
| if (args.inspect_script != null && args.inspect_script != "inspect") { |
| ant.move(file: "$path/bin/inspect.sh", tofile: "$path/bin/${args.inspect_script}.sh") |
| } |
| |
| ant.fixcrlf(srcdir: "$path/bin", includes: "*.sh", eol: "unix") |
| }) |
| |
| binding.setVariable("winScripts", { String target, String home, String name, Map args -> |
| String fullName = args.fullName != null ? args.fullName : p("component.names.fullname") |
| String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase().replace(" ", "_") |
| String vm_options = args.vm_options != null ? args.vm_options : "${p("component.names.product").toLowerCase().replace(" ", "-")}.exe" |
| if (vm_options.endsWith(".exe")) { |
| vm_options = vm_options.replace(".exe", "%BITS%.exe") |
| } |
| else { |
| vm_options = vm_options + "%BITS%" |
| } |
| |
| String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${classPathLibs[0]}\n" |
| classPath += classPathLibs[1..-1].collect {"SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${it}"}.join("\n") |
| if (args.tools_jar) classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar" |
| |
| ant.copy(todir: "$target/bin") { |
| fileset(dir: "$home/bin/scripts/win") |
| |
| filterset(begintoken: "@@", endtoken: "@@") { |
| filter(token: "product_full", value: fullName) |
| filter(token: "product_uc", value: product_uc) |
| filter(token: "vm_options", value: vm_options) |
| filter(token: "isEap", value: isEap()) |
| filter(token: "system_selector", value: args.system_selector) |
| filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, "")) |
| filter(token: "class_path", value: classPath) |
| filter(token: "script_name", value: name) |
| } |
| } |
| |
| if (name != "idea.bat") { |
| ant.move(file: "$target/bin/idea.bat", tofile: "$target/bin/$name") |
| } |
| if (args.inspect_script != null && args.inspect_script != "inspect") { |
| ant.move(file: "$target/bin/inspect.bat", tofile: "$target/bin/${args.inspect_script}.bat") |
| } |
| |
| ant.fixcrlf(srcdir: "$target/bin", includes: "*.bat", eol: "dos") |
| }) |
| |
| private ifNull(v, defVal) { v != null ? v : defVal } |
| |
| binding.setVariable("unixScripts", { String target, String home, String name, Map args -> |
| String fullName = args.fullName != null ? args.fullName : p("component.names.fullname") |
| String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase() |
| String vm_options = args.vm_options != null ? args.vm_options : p("component.names.product").toLowerCase() |
| |
| String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${classPathLibs[0]}\"\n" |
| classPath += classPathLibs[1..-1].collect {"CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\""}.join("\n") |
| if (args.tools_jar) classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\"" |
| |
| ant.copy(todir: "$target/bin") { |
| fileset(dir: "$home/bin/scripts/unix") |
| |
| filterset(begintoken: "@@", endtoken: "@@") { |
| filter(token: "product_full", value: fullName) |
| filter(token: "product_uc", value: product_uc) |
| filter(token: "vm_options", value: vm_options) |
| filter(token: "isEap", value: isEap()) |
| filter(token: "system_selector", value: args.system_selector) |
| filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, "")) |
| filter(token: "class_path", value: classPath) |
| filter(token: "script_name", value: name) |
| } |
| } |
| |
| if (name != "idea.sh") { |
| ant.move(file: "$target/bin/idea.sh", tofile: "$target/bin/$name") |
| } |
| if (args.inspect_script != null && args.inspect_script != "inspect") { |
| ant.move(file: "$target/bin/inspect.sh", tofile: "$target/bin/${args.inspect_script}.sh") |
| } |
| |
| ant.fixcrlf(srcdir: "$target/bin", includes: "*.sh", eol: "unix") |
| }) |
| |
| binding.setVariable("winVMOptions", { String target, Map args, String name, String name64 = null -> |
| if (name != null) { |
| def options = vmOptions32() |
| options = options.replace(" -XX:+UseCodeCacheFlushing", "") |
| options += " -Didea.platform.prefix=" + args.platform_prefix |
| options += " -Didea.paths.selector=" + args.system_selector |
| ant.echo(file: "$target/bin/${name}.vmoptions", message: options.replace(' ', '\n')) |
| } |
| |
| if (name64 != null) { |
| def options = vmOptions64() |
| options += " -Didea.platform.prefix=" + args.platform_prefix |
| options += " -Didea.paths.selector=" + args.system_selector |
| ant.echo(file: "$target/bin/${name64}.vmoptions", message: options.replace(' ', '\n')) |
| } |
| |
| ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "dos") |
| }) |
| |
| binding.setVariable("unixVMOptions", { String target, String name, String name64 = (name + "64") -> |
| if (name != null) { |
| ant.echo(file: "$target/bin/${name}.vmoptions", message: "${vmOptions32()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n')) |
| } |
| if (name64 != null) { |
| ant.echo(file: "$target/bin/${name64}.vmoptions", message: "${vmOptions64()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n')) |
| } |
| ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "unix") |
| }) |
| |
| binding.setVariable("unixReadme", { String target, String home, Map args -> |
| String fullName = args.fullName != null ? args.fullName : p("component.names.fullname") |
| String settings_dir = args.system_selector.replaceFirst("\\d+", "") |
| copyAndPatchFile("$home/build/Install-Linux-tar.txt", "$target/Install-Linux-tar.txt", |
| ["product_full": fullName, |
| "product": p("component.names.product").toLowerCase(), |
| "system_selector": args.system_selector, |
| "script_name" : args.script_name, |
| "settings_dir": settings_dir], "@@") |
| ant.fixcrlf(file: "$target/bin/Install-Linux-tar.txt", eol: "unix") |
| }) |
| |
| binding.setVariable("forceDelete", { String dirPath -> |
| // if wasn't deleted - retry several times |
| attempt = 1 |
| while (attempt < 21 && (new File(dirPath).exists())) { |
| if (attempt > 1) { |
| ant.echo "Deleting $dirPath ... (attempt=$attempt)" |
| |
| // let's wait a bit and try again - may be help |
| // in some cases on our windows 7 agents |
| sleep(2000) |
| } |
| |
| ant.delete(failonerror: false, dir: dirPath) |
| |
| attempt++ |
| } |
| |
| if (new File(dirPath).exists()) { |
| ant.project.log ("Cannot delete directory: $dirPath" ) |
| System.exit (1) |
| } |
| }) |
| |
| binding.setVariable("patchPropertiesFile", { String target, Map args = [:] -> |
| String file = "$target/bin/idea.properties" |
| |
| if (args.appendices != null) { |
| ant.concat(destfile: file, append: true) { |
| args.appendices.each { |
| fileset(file: it) |
| } |
| } |
| } |
| |
| String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase() |
| String settings_dir = args.system_selector.replaceFirst("\\d+", "") |
| ant.replace(file: file) { |
| replacefilter(token: "@@product_uc@@", value: product_uc) |
| replacefilter(token: "@@settings_dir@@", value: settings_dir) |
| } |
| |
| String message = (isEap() ? """ |
| #----------------------------------------------------------------------- |
| # Change to 'disabled' if you don't want to receive instant visual notifications |
| # about fatal errors that happen to an IDE or plugins installed. |
| #----------------------------------------------------------------------- |
| idea.fatal.error.notification=enabled |
| """ |
| : """ |
| #----------------------------------------------------------------------- |
| # Change to 'enabled' if you want to receive instant visual notifications |
| # about fatal errors that happen to an IDE or plugins installed. |
| #----------------------------------------------------------------------- |
| idea.fatal.error.notification=disabled |
| """) |
| ant.echo(file: file, append: true, message: message) |
| }) |
| |
| binding.setVariable("zipSources", { String home, String targetDir -> |
| String sources = "$targetDir/sources.zip" |
| projectBuilder.stage("zip sources to $sources") |
| |
| ant.mkdir(dir: targetDir) |
| ant.delete(file: sources) |
| ant.zip(destfile: sources) { |
| fileset(dir: home) { |
| ["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each { |
| include(name: "**/*.$it") |
| } |
| exclude(name: "**/testData/**") |
| } |
| } |
| |
| notifyArtifactBuilt(sources) |
| }) |
| |
| /** |
| * E.g. |
| * |
| * Load all properties from file: |
| * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties") |
| * |
| * Load all properties except "idea.cycle.buffer.size", change "idea.max.intellisense.filesize" to 3000 |
| * and enable "idea.is.internal" mode: |
| * readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties", |
| * "idea.properties" : ["idea.max.intellisense.filesize" : 3000, |
| * "idea.cycle.buffer.size" : null, |
| * "idea.is.internal" : true ]) |
| * @param args |
| * @return text xml properties description in xml |
| */ |
| private Map readIdeaProperties(Map args) { |
| String ideaPropertiesPath = args == null ? null : args.get("idea.properties.path") |
| if (ideaPropertiesPath == null) { |
| return [:] |
| } |
| |
| // read idea.properties file |
| Properties ideaProperties = new Properties(); |
| FileInputStream ideaPropertiesFile = new FileInputStream(ideaPropertiesPath); |
| ideaProperties.load(ideaPropertiesFile); |
| ideaPropertiesFile.close(); |
| |
| def defaultProperties = ["CVS_PASSFILE": "~/.cvspass", |
| "com.apple.mrj.application.live-resize": "false", |
| "idea.paths.selector": args.system_selector, |
| "java.endorsed.dirs": "", |
| "idea.smooth.progress": "false", |
| "apple.laf.useScreenMenuBar": "true", |
| "apple.awt.graphics.UseQuartz": "true", |
| "apple.awt.fullscreencapturealldisplays": "false"] |
| if (args.platform_prefix != null) { |
| defaultProperties.put("idea.platform.prefix", args.platform_prefix) |
| } |
| |
| Map properties = defaultProperties |
| def customProperties = args.get("idea.properties") |
| if (customProperties != null) { |
| properties += customProperties |
| } |
| |
| properties.each {k, v -> |
| if (v == null) { |
| // if overridden with null - ignore property |
| ideaProperties.remove(k) |
| } else { |
| // if property is overridden in args map - use new value |
| ideaProperties.put(k, v) |
| } |
| } |
| |
| return ideaProperties; |
| } |
| |
| private String submapToXml(Map properties, List keys) { |
| // generate properties description for Info.plist |
| StringBuilder buff = new StringBuilder() |
| |
| keys.each { key -> |
| String value = properties[key] |
| if (value != null) { |
| String string = |
| """ |
| <key>$key</key> |
| <string>$value</string> |
| """ |
| buff.append(string) |
| } |
| } |
| return buff.toString() |
| } |
| |
| binding.setVariable("buildWinZip", { String zipRoot, String zipPath, List paths -> |
| projectBuilder.stage(".win.zip") |
| |
| fixIdeaPropertiesEol(paths, "dos") |
| |
| ant.zip(zipfile: zipPath) { |
| paths.each { |
| zipfileset(dir: it, prefix: zipRoot) |
| } |
| } |
| |
| notifyArtifactBuilt(zipPath) |
| }) |
| |
| binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths, String macPath, List extraBins = [] -> |
| projectBuilder.stage(".mac.zip") |
| |
| allPaths = paths + [macPath] |
| ant.zip(zipfile: zipPath) { |
| allPaths.each { |
| zipfileset(dir: it, prefix: zipRoot) { |
| exclude(name: "bin/*.sh") |
| exclude(name: "bin/*.py") |
| exclude(name: "bin/fsnotifier") |
| exclude(name: "bin/restarter") |
| exclude(name: "MacOS/*") |
| extraBins.each { |
| exclude(name: it) |
| } |
| exclude(name: "bin/idea.properties") |
| } |
| } |
| |
| allPaths.each { |
| zipfileset(dir: it, filemode: "755", prefix: zipRoot) { |
| include(name: "bin/*.sh") |
| include(name: "bin/*.py") |
| include(name: "bin/fsnotifier") |
| include(name: "bin/restarter") |
| include(name: "MacOS/*") |
| extraBins.each { |
| include(name: it) |
| } |
| } |
| } |
| |
| zipfileset(file: "$macPath/bin/idea.properties", prefix: "$zipRoot/bin") |
| } |
| }) |
| |
| binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths, List extraBins = [] -> |
| projectBuilder.stage(".tar.gz") |
| |
| fixIdeaPropertiesEol(paths, "unix") |
| |
| ant.tar(tarfile: tarPath, longfile: "gnu") { |
| paths.each { |
| tarfileset(dir: it, prefix: tarRoot) { |
| exclude(name: "bin/*.sh") |
| exclude(name: "bin/fsnotifier*") |
| extraBins.each { |
| exclude(name: it) |
| } |
| type(type: "file") |
| } |
| } |
| |
| paths.each { |
| tarfileset(dir: it, filemode: "755", prefix: tarRoot) { |
| include(name: "bin/*.sh") |
| include(name: "bin/fsnotifier*") |
| extraBins.each { |
| include(name: it) |
| } |
| type(type: "file") |
| } |
| } |
| } |
| |
| String gzPath = "${tarPath}.gz" |
| ant.gzip(src: tarPath, zipfile: gzPath) |
| ant.delete(file: tarPath) |
| notifyArtifactBuilt(gzPath) |
| }) |
| |
| private void fixIdeaPropertiesEol(List paths, String eol) { |
| paths.each { |
| String file = "$it/bin/idea.properties" |
| if (new File(file).exists()) { |
| ant.fixcrlf(file: file, eol: eol) |
| } |
| } |
| } |
| |
| binding.setVariable("buildWinLauncher", { String ch, String inputPath, String outputPath, String appInfo, |
| String launcherProperties, String pathsSelector, List resourcePaths -> |
| projectBuilder.stage("winLauncher") |
| |
| if (pathsSelector != null) { |
| def paths = getProperty("paths") |
| def launcherPropertiesTemp = "${paths.sandbox}/launcher.properties" |
| copyAndPatchFile(launcherProperties, launcherPropertiesTemp, ["PRODUCT_PATHS_SELECTOR": pathsSelector]) |
| launcherProperties = launcherPropertiesTemp |
| } |
| |
| ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true") { |
| sysproperty(key: "java.awt.headless", value: "true") |
| arg(value: inputPath) |
| arg(value: appInfo) |
| arg(value: "$ch/native/WinLauncher/WinLauncher/resource.h") |
| arg(value: launcherProperties) |
| arg(value: outputPath) |
| classpath { |
| pathelement(location: "$ch/build/lib/launcher-generator.jar") |
| fileset(dir: "$ch/lib") { |
| include(name: "guava*.jar") |
| include(name: "jdom.jar") |
| include(name: "sanselan*.jar") |
| } |
| resourcePaths.each { |
| pathelement(location: it) |
| } |
| } |
| } |
| }) |
| |
| binding.setVariable("layoutUpdater", { String target, String jarName = "updater.jar" -> |
| layout(target) { |
| jar(jarName) { |
| module("updater") |
| } |
| } |
| }) |
| |
| binding.setVariable("collectUsedJars", { List modules, List approvedJars, List forbiddenJars, List modulesToBuild -> |
| def usedJars = new HashSet(); |
| |
| modules.each { |
| def module = findModule(it) |
| if (module != null) { |
| projectBuilder.moduleRuntimeClasspath(module, false).each { |
| File file = new File(it) |
| if (file.exists()) { |
| String path = file.canonicalPath.replace('\\', '/') |
| if (path.endsWith(".jar") && approvedJars.any { path.startsWith(it) } && !forbiddenJars.any { path.contains(it) }) { |
| if (usedJars.add(path)) { |
| projectBuilder.info("\tADDED: $path for ${module.getName()}") |
| } |
| } |
| } |
| } |
| if (modulesToBuild != null) { |
| modulesToBuild << module |
| } |
| } |
| else { |
| projectBuilder.warning("$it is not a module") |
| } |
| } |
| |
| return usedJars |
| }) |
| |
| binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars -> |
| def modulesToBuild = [] |
| def usedJars = collectUsedJars(modules, approvedJars, forbiddenJars, modulesToBuild) |
| projectBuilder.cleanOutput() |
| projectBuilder.buildModules(modulesToBuild) |
| |
| return usedJars |
| }) |
| |
| binding.setVariable("buildSearchableOptions", { String target, List licenses, Closure cp, String jvmArgs = null, |
| def paths = getProperty("paths") -> |
| projectBuilder.stage("Building searchable options") |
| |
| String targetFile = "${target}/searchableOptions.xml" |
| ant.delete(file: targetFile) |
| |
| licenses.each { |
| ant.copy(file: it, todir: paths.ideaSystem) |
| } |
| |
| ant.path(id: "searchable.options.classpath") { cp() } |
| String classpathFile = "${paths.sandbox}/classpath.txt" |
| ant.echo(file: classpathFile, append: false, message: "\${toString:searchable.options.classpath}") |
| ant.replace(file: classpathFile, token: File.pathSeparator, value: "\n") |
| |
| ant.java(classname: "com.intellij.rt.execution.CommandLineWrapper", fork: true, failonerror: true) { |
| jvmarg(line: "-Xbootclasspath/a:${projectBuilder.moduleOutput(findModule("boot"))} -ea -Xmx500m -XX:MaxPermSize=200m") |
| jvmarg(line: "-Didea.home.path=$home -Didea.system.path=${paths.ideaSystem} -Didea.config.path=${paths.ideaConfig}") |
| if (jvmArgs != null) { |
| jvmarg(line: jvmArgs) |
| } |
| |
| arg(line: "${classpathFile} com.intellij.idea.Main traverseUI ${target}/searchableOptions.xml") |
| |
| classpath() { |
| pathelement(location: "${projectBuilder.moduleOutput(findModule("java-runtime"))}") |
| } |
| } |
| |
| ant.available(file: targetFile, property: "searchable.options.exists"); |
| ant.fail(unless: "searchable.options.exists", message: "Searchable options were not built.") |
| }) |
| |
| binding.setVariable("reassignAltClickToMultipleCarets", {String communityHome -> |
| String defaultKeymapContent = new File("$communityHome/platform/platform-resources/src/idea/Keymap_Default.xml").text |
| defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt button1\"/>", "") |
| defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt shift button1\"/>", |
| "<mouse-shortcut keystroke=\"alt button1\"/>") |
| patchedKeymapFile = new File("${paths.sandbox}/classes/production/platform-resources/idea/Keymap_Default.xml") |
| patchedKeymapFile.write(defaultKeymapContent) |
| }) |
| |
| // modules used in Upsource and in Kotlin as an API to IDEA |
| binding.setVariable("analysisApiModules", [ |
| "analysis-api", |
| "boot", |
| "core-api", |
| "duplicates-analysis", |
| "editor-ui-api", |
| "editor-ui-ex", |
| "extensions", |
| "indexing-api", |
| "java-analysis-api", |
| "java-indexing-api", |
| "java-psi-api", |
| "java-structure-view", |
| "jps-model-api", |
| "jps-model-serialization", |
| "projectModel-api", |
| "structure-view-api", |
| "util", |
| "util-rt", |
| "xml-analysis-api", |
| "xml-psi-api", |
| "xml-structure-view-api", |
| ]) |
| binding.setVariable("analysisImplModules", [ |
| "analysis-impl", |
| "core-impl", |
| "indexing-impl", |
| "java-analysis-impl", |
| "java-indexing-impl", |
| "java-psi-impl", |
| "projectModel-impl", |
| "structure-view-impl", |
| "xml-analysis-impl", |
| "xml-psi-impl", |
| "xml-structure-view-impl", |
| ]) |