[build] initial support for building .snap packages (IDEA-173201)

This commit is contained in:
Roman Shevchenko
2017-07-21 19:17:06 +02:00
parent 5e3ae4ec4d
commit d7fc83aadf
7 changed files with 140 additions and 4 deletions
@@ -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
+6
View File
@@ -0,0 +1,6 @@
#-----------------------------------------------------------------------
# Snap-specific properties
#-----------------------------------------------------------------------
idea.skip.desktop.entry.step=true
ide.no.platform.update=Snap
+25
View File
@@ -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
@@ -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.
*/
@@ -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
*/
@@ -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)
}
}
}
@@ -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}"