build scripts redesign: generate list of files for NSIS installer via groovy script instead of using separate ant task

This commit is contained in:
nik
2016-07-12 10:53:01 +03:00
parent 64c2496d08
commit fedcae5510
2 changed files with 125 additions and 15 deletions
@@ -0,0 +1,113 @@
/*
* Copyright 2000-2016 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.
*/
/*
* Copyright 2000-2016 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.
*/
package org.jetbrains.intellij.build.impl
import com.intellij.openapi.util.io.FileUtil
import java.util.regex.Pattern
/**
* @author nik
*/
class NsisFileListGenerator {
private final Map<String, List<File>> directoryToFiles = [:]
private final List<String> filesRelativePaths = []
public void addDirectory(String directoryPath, List<String> relativeFileExcludePatterns = []) {
def excludePatterns = relativeFileExcludePatterns.collect { Pattern.compile(FileUtil.convertAntToRegexp(it)) }
processDirectory(new File(directoryPath), "", excludePatterns)
}
public void generateInstallerFile(File outputFile) {
outputFile.withWriter { BufferedWriter out ->
directoryToFiles.each {
if (!it.value.empty) {
out.newLine()
out.writeLine("SetOutPath \$INSTDIR${it.key.isEmpty() ? "" : "\\"}${toWinPath(it.key)}")
it.value.each {
out.writeLine("File \"${it.absolutePath}\"")
}
}
}
}
}
public void generateUninstallerFile(File outputFile) {
outputFile.withWriter { BufferedWriter out ->
filesRelativePaths.toSorted().each {
out.writeLine("Delete \"\$INSTDIR\\${toWinPath(it)}\"")
if (it.endsWith(".py")) {
out.writeLine("Delete \"\$INSTDIR\\${toWinPath(it)}c\"") //.pyc
}
}
out.newLine()
directoryToFiles.keySet().toSorted().reverseEach {
if (!it.empty) {
out.writeLine("RmDir /r \"\$INSTDIR\\${toWinPath(it)}\\__pycache__\"");
out.writeLine("RmDir \"\$INSTDIR\\${toWinPath(it)}\"");
}
}
out.writeLine("RmDir \"\$INSTDIR\"")
}
}
private static String toWinPath(String dir) {
return dir.replace('/', '\\');
}
private void processDirectory(File directory, String relativePath, List<Pattern> excludePatterns) {
def files = directory.listFiles()
if (files == null) {
throw new IOException("Not a directory: $directory")
}
files.sort { it.name }
for (child in files) {
String childPath = "${(relativePath.isEmpty() ? "" : "$relativePath/")}$child.name"
if (excludePatterns.any { it.matcher(childPath).matches() }) {
continue
}
if (child.isFile()) {
filesRelativePaths << childPath
directoryToFiles.get(relativePath, []) << child
}
else {
processDirectory(child, childPath, excludePatterns)
if (directoryToFiles.containsKey(childPath)) {
//register all parent directories for directories with files to ensure that they will be deleted by uninstaller
directoryToFiles.putIfAbsent(relativePath, [])
}
}
}
}
}
@@ -43,7 +43,6 @@ class WinExeInstallerBuilder {
String communityHome = buildContext.paths.communityHome
String outFileName = buildContext.productProperties.baseArtifactName(buildContext.buildNumber)
buildContext.messages.progress("Building Windows installer $outFileName")
ant.taskdef(name: "nsis", classname: "com.intellij.internalUtilities.ant.NsiFiles", classpath: "$communityHome/build/lib/NsiFiles.jar")
def box = "$buildContext.paths.temp/winInstaller"
ant.mkdir(dir: "$box/bin")
@@ -56,28 +55,26 @@ class WinExeInstallerBuilder {
}
ant.copy(todir: "$box/nsiconf") {
fileset(dir: "$communityHome/build/conf/nsis") {
include(name: "*")
exclude(name: "strings*")
exclude(name: "paths*")
exclude(name: "version*")
}
fileset(dir: "$communityHome/build/conf/nsis")
}
if (SystemInfoRt.isLinux) {
File ideaNsiPath = new File(box, "nsiconf/idea.nsi")
ideaNsiPath.text = BuildUtils.replaceAll(ideaNsiPath.text, ["\${IMAGES_LOCATION}\\": "\${IMAGES_LOCATION}/"], "")
}
ant.nsis(instfile: "$box/nsiconf/idea_win.nsh", uninstfile: "$box/nsiconf/unidea_win.nsh") {
[buildContext.paths.distAll, winDistPath].each {
ant.fileset(dir: it, includes: "**/*") {
exclude(name: "**/idea.properties")
exclude(name: "**/*.vmoptions")
}
}
try {
def generator = new NsisFileListGenerator()
generator.addDirectory(buildContext.paths.distAll)
generator.addDirectory(winDistPath, ["**/idea.properties", "**/*.vmoptions"])
if (bundleJre) {
ant.fileset(dir: jreDirectoryPath, includes: "jre/**/*")
generator.addDirectory(jreDirectoryPath)
}
generator.generateInstallerFile(new File(box, "nsiconf/idea_win.nsh"))
generator.generateUninstallerFile(new File(box, "nsiconf/unidea_win.nsh"))
}
catch (IOException e) {
buildContext.messages.error("Failed to generated list of files for NSIS installer: $e")
}
prepareConfigurationFiles(box, winDistPath)