diff --git a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy index 8b495f85c6fd..f2348fdb8dbd 100644 --- a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -89,6 +89,10 @@ class IdeaCommunityProperties extends BaseIdeaProperties { return new LinuxDistributionCustomizer() { { iconPngPath = "$projectHome/platform/icons/src/icon_CE_128.png" + //snapName = "intellij-idea-community" + //snapDescription = + // "The most intelligent Java IDE. Every aspect of IntelliJ IDEA is specifically designed to maximize developer productivity. " + + // "Together, powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience." } @Override diff --git a/build/snap/idea-snap.properties b/build/snap/idea-snap.properties new file mode 100644 index 000000000000..2afae5831d38 --- /dev/null +++ b/build/snap/idea-snap.properties @@ -0,0 +1,6 @@ + +#----------------------------------------------------------------------- +# Snap-specific properties +#----------------------------------------------------------------------- +idea.skip.desktop.entry.step=true +ide.no.platform.update=Snap diff --git a/build/snap/snapcraft-template.yaml b/build/snap/snapcraft-template.yaml new file mode 100644 index 000000000000..9b18cc86b37d --- /dev/null +++ b/build/snap/snapcraft-template.yaml @@ -0,0 +1,25 @@ +# see platform/build-scripts/.../LinuxDistributionBuilder.groovy + +name: $NAME$ +version: '$VERSION$' +icon: $NAME$.png +summary: $SUMMARY$ +description: $DESCRIPTION$ +grade: stable +confinement: classic +architectures: [amd64] + +apps: + $NAME$: + command: $SCRIPT$ + +parts: + common: + plugin: dump + source: dist.all + bins: + plugin: dump + source: dist.unix + jre: + plugin: dump + source: jre \ No newline at end of file diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy index 06abe02a0ad2..211312a7ac45 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy @@ -68,6 +68,12 @@ class BuildOptions { public static final String BUILD_DMG_WITHOUT_BUNDLED_JRE = "intellij.build.dmg.without.bundled.jre" boolean buildDmgWithoutBundledJre = SystemProperties.getBooleanProperty(BUILD_DMG_WITHOUT_BUNDLED_JRE, SystemProperties.getBooleanProperty("artifact.mac.no.jdk", false)) + /** + * Pass 'true' to this system property to produce .snap packages. + * A build configuration should have "docker.version >= 17" in requirements. + */ + boolean buildUnixSnaps = SystemProperties.getBooleanProperty("intellij.build.unix.snaps", false) + /** * Path to a zip file containing 'production' and 'test' directories with compiled classes of the project modules inside. */ diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy index f2505eeb48fa..5b824b3d03a3 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -37,6 +37,12 @@ abstract class LinuxDistributionCustomizer { */ boolean buildTarGzWithoutBundledJre = true + /** + * If a .snap package should be produced + */ + String snapName = null + String snapDescription = null + /** * Name of the root directory inside linux .tar.gz archive */ diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy index e7209670c0af..e34feb20fd26 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -15,6 +15,7 @@ */ package org.jetbrains.intellij.build.impl +import com.intellij.openapi.util.text.StringUtil import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.JvmArchitecture @@ -71,6 +72,7 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder { def jreDirectoryPath = buildContext.bundledJreManager.extractLinuxJre() if (jreDirectoryPath != null) { buildTarGz(jreDirectoryPath, osSpecificDistPath) + buildSnapPackage(jreDirectoryPath, osSpecificDistPath) } else { buildContext.messages.info("Skipping building Linux distribution with bundled JRE because JRE archive is missing") @@ -182,4 +184,86 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder { buildContext.notifyArtifactBuilt(gzPath) } } + + private void buildSnapPackage(String jreDirectoryPath, String unixDistPath) { + if (!buildContext.options.buildUnixSnaps || customizer.snapName == null) return + + if (StringUtil.isEmpty(customizer.iconPngPath)) buildContext.messages.error("'iconPngPath' not set") + if (StringUtil.isEmpty(customizer.snapDescription)) buildContext.messages.error("'snapDescription' not set") + + String snapDir = "${buildContext.paths.buildOutputRoot}/dist.snap" + + buildContext.messages.block("Build Linux .snap package") { + buildContext.messages.progress("Preparing files") + + def desktopTemplate = "${buildContext.paths.communityHome}/platform/platform-resources/src/entry.desktop" + def ce = buildContext.productProperties.productCode in ["IC", "PC"] + def productName = buildContext.applicationInfo.productName + if (ce && !productName.contains("Community Edition")) productName += " Community Edition" // IdeaApplicationInfo.xml//names@product + buildContext.ant.copy(file: desktopTemplate, tofile: "${snapDir}/snap/gui/${customizer.snapName}.desktop") { + filterset(begintoken: '$', endtoken: '$') { + filter(token: "NAME", value: productName) + filter(token: "ICON", value: "/bin/${buildContext.productProperties.baseFileName}.png") + filter(token: "SCRIPT", value: "/bin/${buildContext.productProperties.baseFileName}.sh") + filter(token: "WM_CLASS", value: "jetbrains-${buildContext.applicationInfo.shortProductName.toLowerCase()}${ce ? "-ce" : ""}") + } + } + + buildContext.ant.copy(file: customizer.iconPngPath, tofile: "${snapDir}/${customizer.snapName}.png") + + def snapcraftTemplate = "${buildContext.paths.communityHome}/build/snap/snapcraft-template.yaml" + def version = "${buildContext.applicationInfo.majorVersion}.${buildContext.applicationInfo.minorVersion}" + buildContext.ant.copy(file: snapcraftTemplate, tofile: "${snapDir}/snapcraft.yaml") { + filterset(begintoken: '$', endtoken: '$') { + filter(token: "NAME", value: customizer.snapName) + filter(token: "VERSION", value: version) + filter(token: "SUMMARY", value: productName) + filter(token: "DESCRIPTION", value: customizer.snapDescription) + filter(token: "SCRIPT", value: "bin/${buildContext.productProperties.baseFileName}.sh") + } + } + + buildContext.ant.concat(destfile: "${unixDistPath}/bin/idea.properties", append: true) { + filelist(dir: "${buildContext.paths.communityHome}/build/snap", files: "idea-snap.properties") + } + + buildContext.ant.delete(quiet: true) { + fileset(dir: "${unixDistPath}/bin") { + include(name: "fsnotifier") + include(name: "fsnotifier-arm") + include(name: "libyjpagent-linux.so") + } + } + + buildContext.ant.chmod(perm: "755") { + fileset(dir: unixDistPath) { + include(name: "bin/*.sh") + include(name: "bin/*.py") + include(name: "bin/fsnotifier*") + customizer.extraExecutables.each { include(name: it) } + } + fileset(dir: jreDirectoryPath) { + include(name: "jre64/bin/*") + } + } + + buildContext.messages.progress("Building package") + + buildContext.ant.exec(executable: "docker", dir: snapDir, failonerror: true) { + arg(value: "run") + arg(value: "--volume=${snapDir}:/build") + arg(value: "--volume=${buildContext.paths.distAll}:/build/dist.all:ro") + arg(value: "--volume=${unixDistPath}:/build/dist.unix:ro") + arg(value: "--volume=${jreDirectoryPath}:/build/jre:ro") + arg(value: "--workdir=/build") + arg(value: "--env=SNAPCRAFT_SETUP_CORE=1") + arg(value: "snapcore/snapcraft") + arg(value: "snapcraft") + } + + def snapArtifact = "${customizer.snapName}_${version}_amd64.snap" + buildContext.ant.move(file: "${snapDir}/${snapArtifact}", todir: buildContext.paths.artifacts) + buildContext.notifyArtifactBuilt("${buildContext.paths.artifacts}/" + snapArtifact) + } + } } \ No newline at end of file diff --git a/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy b/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy index 059e48c073c5..e7a701d402f0 100644 --- a/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy +++ b/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -78,7 +78,12 @@ class PyCharmCommunityProperties extends PyCharmPropertiesBase { return new LinuxDistributionCustomizer() { { iconPngPath = "$projectHome/python/resources/PyCharmCore128.png" + //snapName = "pycharm-community" + //snapDescription = + // "Python IDE for professional developers. Save time while PyCharm takes care of the routine. " + // "Focus on bigger things and embrace the keyboard-centric approach to get the most of PyCharm’s many productivity features." } + @Override String getRootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) { "pycharm-community-${applicationInfo.isEAP ? buildNumber : applicationInfo.fullVersion}"