2 * Copyright 2000-2014 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 import org.jetbrains.jps.LayoutInfo
19 setProperty("home", getHome())
20 includeTargets << new File("$home/community/build/scripts/utils.gant")
21 includeTargets << new File("$home/community/build/scripts/libLicenses.gant")
22 includeTargets << new File("$home/build/scripts/ultimate_utils.gant")
24 requireProperty("buildNumber", requireProperty("build.number", snapshot))
25 setProperty("buildName", "EDU-$buildNumber")
26 setProperty("ch", "$home/community")
27 setProperty("pythonCommunityHome", "$ch/python")
28 setProperty("pythonEduHome", "$ch/python/educational-python")
30 // load ApplicationInfo.xml properties
31 ant.xmlproperty(file: "$pythonEduHome/resources/idea/PyCharmEduApplicationInfo.xml", collapseAttributes: "true")
32 setProperty("system_selector", "PyCharmEdu${p("component.version.major")}0")
33 setProperty("dryRun", false)
34 setProperty("jdk16", guessJdk())
37 setProperty("pluginFilter", new File("$pythonEduHome/build/plugin-list.txt").readLines())
39 private String getHome(){
40 // current file is supposed to be at build/scripts/*.gant path
41 String uri = this["gant.file"]
42 return new File(new URI(uri).getSchemeSpecificPart()).getParentFile().getParentFile().getParentFile().getParentFile().getParentFile()
45 private List<String> pycharmPlatformApiModules() {
46 return [platformApiModules, "dom-openapi"].flatten()
50 private List pycharmImplementationModules() { //modules to put into pycharm.jar
51 return [platformImplementationModules, "dom-impl", "python-community", "python-community-ide-resources",
52 "python-ide-community", "python-community-configure", "educational-python", "python-openapi", "python-psi-api", "platform-main"].flatten()
55 private List modules() {
57 "python-pydev", "colorSchemes", pycharmPlatformApiModules(), pycharmImplementationModules(), pluginFilter
61 private List approvedJars() {
62 def normalizedHome = ch.replace('\\', '/')
63 def normalizedPythonHome = pythonCommunityHome.replace('\\', '/')
64 return ["$normalizedHome/lib/", "$normalizedPythonHome/lib/", "$normalizedHome/xml/relaxng/lib/"]
77 def Paths(String home) {
78 sandbox = "$home/out/pycharmEDU"
80 distAll = "$sandbox/layout"
81 distWin = "$sandbox/win"
82 distMac = "$sandbox/mac"
83 distUnix = "$sandbox/unix"
84 artifacts = "$sandbox/artifacts"
86 ideaSystem = "$sandbox/system"
87 ideaConfig = "$sandbox/config"
91 setProperty("paths", new Paths(home))
93 target('default': "Build artifacts") {
97 projectBuilder.stage("Cleaning up sandbox folder")
99 projectBuilder.targetFolder = "${paths.sandbox}/classes"
100 projectBuilder.dryRun = dryRun
103 forceDelete(paths.sandbox)
104 ant.mkdir(dir: paths.sandbox)
105 //Use EDU versions of IdeTipsAndTricks.xml and icon-robots.txt.
106 ant.delete(file: "${pythonCommunityHome}/src/META-INF/IdeTipsAndTricks.xml")
107 ant.delete(file: "${pythonCommunityHome}/resources/icon-robots.txt")
111 format(property: "todayYear", pattern: "yyyy")
116 ant.patternset(id: "resources.included") {
117 include(name: "**/*.properties")
118 include(name: "fileTemplates/**/*")
119 include(name: "inspectionDescriptions/**/*")
120 include(name: "intentionDescriptions/**/*")
121 include(name: "tips/**/*")
122 include(name: "search/**/*")
125 ant.patternset(id: "resources.excluded") {
126 exclude(name: "**/*.properties")
127 exclude(name: "fileTemplates/**/*")
128 exclude(name: "fileTemplates")
129 exclude(name: "inspectionDescriptions/**/*")
130 exclude(name: "inspectionDescriptions")
131 exclude(name: "intentionDescriptions/**/*")
132 exclude(name: "intentionDescriptions")
133 exclude(name: "tips/**/*")
134 exclude(name: "tips")
135 exclude(name: "courses")
136 exclude(name: "courses/*")
139 zipSources(home, paths.artifacts)
141 def usedJars = buildModulesAndCollectUsedJars(modules(), approvedJars(), ["/ant/"])
143 layoutEducational("${paths.sandbox}/classes/production", usedJars)
145 def extraArgs = ["build.code": "pycharm${buildName}", "build.number": "PE-$buildNumber", "artifacts.path": "${paths.artifacts}"]
146 def sitFileName = "pycharm${buildName}"
147 ant.copy(file: "${paths.artifacts}/pycharm${buildName}.mac.zip", tofile: "${paths.artifacts}/${sitFileName}-no-jdk.sit")
149 signMacZip("pycharm", extraArgs + ["sitFileName": "${sitFileName}-no-jdk"])
150 notifyArtifactBuilt("${paths.artifacts}/${sitFileName}-no-jdk.sit")
151 buildDmg("pycharm", "${pythonEduHome}/build/DMG_background.png", extraArgs + ["sitFileName": "${sitFileName}-no-jdk"])
153 if (p("jdk.mac") != "false" && new File(macCustomJDK).exists()) {
154 ant.copy(file: "${paths.artifacts}/pycharm${buildName}.mac.zip", tofile: "${paths.artifacts}/${sitFileName}.sit")
155 signMacZip("pycharm", extraArgs + ["sitFileName": "${sitFileName}", "jdk_archive_name": macCustomJDK])
156 buildDmg("pycharm", "${pythonEduHome}/build/DMG_background.png", extraArgs + ["sitFileName": "${sitFileName}"])
159 ant.delete(file: "${paths.artifacts}/pycharm${buildName}.mac.zip")
162 public layoutEducational(String classesPath, Set usedJars) {
163 setProperty("pluginFilter", new File("$pythonEduHome/build/plugin-list.txt").readLines())
165 if (usedJars == null) {
166 usedJars = collectUsedJars(modules(), approvedJars(), ["/ant/"], null)
169 def paths = new Paths(home)
170 buildSearchableOptions("${projectBuilder.moduleOutput(findModule("platform-resources"))}/search", [], {
171 projectBuilder.moduleRuntimeClasspath(findModule("main_pycharm_edu"), false).each {
172 ant.pathelement(location: it)
174 }, "-Didea.platform.prefix=PyCharmEdu")
176 def appInfo = appInfoFile()
178 wireBuildDate("PE-${buildNumber}", appInfo)
182 buildNumber: "PE-${buildNumber}",
183 system_selector: system_selector,
184 ide_jvm_args: "-Didea.platform.prefix=PyCharmEdu"]
186 LayoutInfo layoutInfo = layoutFull(args, paths.distAll, usedJars)
187 generateLicensesTable("$paths.artifacts/third-party-libraries.txt", layoutInfo.usedModules);
189 layoutWin(args, paths.distWin)
190 layoutUnix(args, paths.distUnix)
191 layoutMac(args, paths.distMac)
193 ant.echo(message: "PE-${buildNumber}", file: "${paths.distAll}/build.txt")
195 def launcher = "${paths.distWin}/bin/pycharm.exe"
196 List resourcePaths = ["$ch/community-resources/src",
197 "$ch/platform/icons/src",
198 "$pythonCommunityHome/python-community-ide-resources/resources",
199 "$pythonCommunityHome/resources",
200 "$pythonEduHome/resources"]
201 buildWinLauncher(ch, "$ch/bin/WinLauncher/WinLauncher.exe", launcher,
202 appInfo, "$pythonEduHome/build/pycharm_edu_launcher.properties", system_selector, resourcePaths)
203 signExecutableFiles("${paths.distWin}/bin")
205 buildWinZip("${paths.artifacts}/pycharm${buildName}.zip", [paths.distAll, paths.distWin, "${paths.sandbox}/jdk.win"])
207 //EDU installation with a custom page dialog
208 ant.copy(file: "$ch/python/educational-python/build/desktop.ini", tofile: "${paths.sandbox}/nsiconf/desktop.ini", overwrite: "true")
209 ant.copy(file: "$ch/python/educational-python/build/customInstallActions.nsi", tofile: "${paths.sandbox}/nsiconf/customInstallActions.nsi", overwrite: "true")
210 buildNSIS([paths.distAll, paths.distWin],
211 "$pythonEduHome/build/strings.nsi", "$pythonEduHome/build/paths.nsi",
212 "pycharmEDU-", false, true, system_selector)
214 String tarRoot = isEap() ? "pycharm-edu-$buildNumber" : "pycharm-edu-${p("component.version.major")}.${p("component.version.minor")}"
215 buildTarGz(tarRoot, "$paths.artifacts/pycharm${buildName}-no-jdk.tar", [paths.distAll, paths.distUnix])
216 if (p("jdk.linux") != "false") {
217 buildTarGz(tarRoot, "$paths.artifacts/pycharm${buildName}.tar", [paths.distAll, paths.distUnix, "${paths.sandbox}/jdk.linux"], ["jre/jre/bin/*"])
221 String macAppRoot = isEap() ? "PyCharm Edu ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm Edu.app/Contents"
222 buildMacZip(macAppRoot, "${paths.artifacts}/pycharm${buildName}.mac.zip", [paths.distAll], paths.distMac)
225 private layoutPlugins(layouts) {
227 layouts.layoutPlugin("student")
228 layouts.layoutPlugin("student-python") {
230 fileset(dir: "$pythonEduHome/student-python/resources/courses")
233 layouts.layoutPlugin("course-creator")
234 layouts.layoutPlugin("course-creator-python")
235 layouts.layoutPlugin("ipnb") {
236 fileset(dir: "$pythonCommunityHome/ipnb/lib")
240 layouts.layoutCommunityPlugins(ch)
243 private String appInfoFile() {
244 return "$home/out/pycharmEDU/classes/production/educational-python/idea/PyCharmEduApplicationInfo.xml"
247 private layoutFull(Map args, String target, Set usedJars) {
248 def openapiModules = pycharmPlatformApiModules()
249 def superLayouts = includeFile("$ch/build/scripts/layouts.gant")
251 reassignAltClickToMultipleCarets("$ch")
253 def result = layout(target) {
261 openapiModules.each { module it }
264 jar("annotations.jar") {
265 module("annotations-common")
266 module("annotations")
268 jar("extensions.jar") { module("extensions") }
270 jar([name: "pycharm.jar", duplicate: "preserve"]) {
271 pycharmImplementationModules().each {
273 exclude(name: "**/tips/**")
278 jar("pycharm-pydev.jar") {
279 module("python-pydev")
282 jar("bootstrap.jar") { module("bootstrap") }
283 jar("resources.jar") {
284 module("platform-resources")
285 module("colorSchemes")
288 jar("forms_rt.jar") {
292 //noinspection GroovyAssignabilityCheck
293 jar([name: "resources_en.jar", duplicate: "preserve"]) {
294 // custom resources should go first
295 module("python-community-ide-resources") {
297 include(name: "**/tips/**")
300 module("platform-resources-en") {
302 exclude(name: "tips/images/switcher.png")
303 exclude(name: "tips/images/navigateToFilePath.gif")
308 jar("icons.jar") { module("icons") }
309 jar("boot.jar") { module("boot") }
315 fileset(dir: "$ch/build/kotlinc/lib") {
316 include(name: "kotlin-runtime.jar")
317 include(name: "kotlin-reflect.jar")
321 fileset(dir: "$ch/lib/libpty") {
322 exclude(name: "*.txt")
327 fileset(dir: "$ch/lib") {
328 include(name: "cglib*.jar")
333 fileset(dir: "$ch/lib/src") {
334 include(name: "trove4j_changes.txt")
335 include(name: "trove4j_src.jar")
338 jar("pycharm-pydev-src.zip") {
339 fileset(dir: "$pythonCommunityHome/pydevSrc")
341 jar("pycharm-openapi-src.zip") {
342 fileset(dir: "$pythonCommunityHome/openapi/src")
343 fileset(dir: "$pythonCommunityHome/psi-api/src")
349 fileset(dir: "$home/python/help") {
350 include(name: "*.pdf")
355 fileset(dir: "$pythonCommunityHome/helpers")
359 fileset(dir: "$ch/license")
360 fileset(dir: "$ch") {
361 include(name: "LICENSE.txt")
362 include(name: "NOTICE.txt")
366 layoutPlugins(superLayouts)
369 fileset(dir: "$ch/bin") {
370 exclude(name: "appletviewer.policy")
375 patchPropertiesFile(target, args + [appendices: ["$home/build/conf/ideaJNC.properties"]])
379 private layoutWin(Map args, String target) {
382 fileset(dir: "$ch/bin/win") {
383 exclude(name: "breakgen*")
388 fileset(dir: "$pythonCommunityHome/skeletons") {
389 include(name: "skeletons-win*.zip")
394 winScripts(target, ch, "pycharm.bat", args)
395 winVMOptions(target, null, "pycharm.exe")
397 ant.copy(file: "$home/python/help/pycharm-eduhelp.jar", todir: "$target/help", failonerror: false)
400 private layoutUnix(Map args, String target) {
403 fileset(dir: "$ch/bin/linux") {
404 exclude(name: "libbreakgen*")
409 ant.copy(file: "$pythonCommunityHome/resources/PyCharmCore128.png", tofile: "$target/bin/pycharm.png")
411 unixScripts(target, ch, "pycharm.sh", args)
412 unixVMOptions(target, "pycharm")
414 ant.copy(file: "$home/python/help/pycharm-eduhelp.jar", todir: "$target/help", failonerror: false)
417 private layoutMac(Map _args, String target) {
420 fileset(dir: "$home/bin") {
421 include(name: "*.jnilib")
426 fileset(dir: "$pythonCommunityHome/skeletons") {
427 include(name: "skeletons-mac*.zip")
432 Map args = new HashMap(_args)
433 args.icns = "$pythonCommunityHome/educational-python/resources/PyCharmEdu.icns"
434 args.bundleIdentifier = "com.jetbrains.pycharm"
435 args.platform_prefix = "PyCharmEdu"
437 args."idea.properties.path" = "${paths.distAll}/bin/idea.properties"
438 args."idea.properties" = ["ide.mac.useNativeClipboard": "false"];
439 args.executable = "pycharm"
440 layoutMacApp(target, ch, args)