blob: b19062870eb17d0d28252e0a348ec7bf96f12e1f [file] [log] [blame]
package com.intellij.internalUtilities.ant;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.FileSet;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/**
* Ant task to facilitate building NSIS installer.
*
* @author max
* @since Jan 11, 2005
*/
@SuppressWarnings("UnusedDeclaration")
public class NsiFiles extends MatchingTask {
private File myInstFile;
private File myUnInstFile;
private File myBaseDir;
private final List<FileSet> myFileSets = new ArrayList<FileSet>();
private final Map<String, List<String>> myDirToFiles = new LinkedHashMap<String, List<String>>();
private final Map<String, String> myAbsoluteToRelative = new HashMap<String, String>();
/**
* The file to create; required
* @param nsiFile new file to generate file install list to.
*/
public void setInstFile(File nsiFile) {
myInstFile = nsiFile;
}
/**
* The file to create; required
* @param nsiFile new file to generate file uninstall list to.
*/
public void setUninstFile(File nsiFile) {
myUnInstFile = nsiFile;
}
/**
* ;optional
* @param fileSet to be included in processing
*/
public void addFileSet(FileSet fileSet) {
myFileSets.add(fileSet);
}
/**
* ;optional
* @param baseDir of the files to be processed.
*/
public void setBaseDir(File baseDir) {
myBaseDir = baseDir;
}
public void execute() throws BuildException {
if (myInstFile == null) throw new BuildException("Specify required isntFile attribute.");
if (myUnInstFile == null) throw new BuildException("Specify required unisntFile attribute.");
if (myBaseDir == null && myFileSets.size() == 0) {
throw new BuildException("basedir attribute must be set, "
+ "or at least "
+ "one fileset must be given!");
}
try {
if (myBaseDir != null) {
FileSet fs = (FileSet) getImplicitFileSet().clone();
fs.setDir(myBaseDir);
processFileSet(fs);
}
for (FileSet fileSet : myFileSets) {
processFileSet(fileSet);
}
generateInstFile();
generateUninstFile();
}
catch (IOException e) {
throw new BuildException(e);
}
finally {
cleanup();
}
}
private void generateUninstFile() throws IOException {
BufferedWriter uninstWriter = new BufferedWriter(new FileWriter(myUnInstFile));
try {
List<String> allFiles = new ArrayList<String>();
final Collection<List<String>> lists = myDirToFiles.values();
for (final List<String> list : lists) {
allFiles.addAll(list);
}
Collections.sort(allFiles);
for (String file : allFiles) {
uninstWriter.newLine();
final String relPath = myAbsoluteToRelative.get(file);
uninstWriter.write("Delete \"$INSTDIR\\" + relPath + "\"");
if (relPath.endsWith(".py")) {
uninstWriter.newLine();
uninstWriter.write("Delete \"$INSTDIR\\" + relPath + "c\""); // .pyc
}
}
uninstWriter.newLine();
List<String> dirs = new ArrayList<String>(myDirToFiles.keySet());
Collections.sort(dirs);
for (int i = dirs.size() - 1; i >= 0; i--) {
final String dir = dirs.get(i);
if (dir.length() == 0) continue;
uninstWriter.newLine();
uninstWriter.write("RmDir /r \"$INSTDIR\\" + dir + "\\__pycache__\"");
uninstWriter.newLine();
uninstWriter.write("RmDir \"$INSTDIR\\" + dir + "\"");
}
uninstWriter.newLine();
uninstWriter.write("RmDir \"$INSTDIR\"");
}
finally{
uninstWriter.close();
}
}
private void generateInstFile() throws IOException {
BufferedWriter instWriter = new BufferedWriter(new FileWriter(myInstFile));
try {
Collection<String> dirs = myDirToFiles.keySet();
for (String dir : dirs) {
final List<String> files = myDirToFiles.get(dir);
if (files.size() == 0) continue;
instWriter.newLine();
instWriter.newLine();
if (dir.length() > 0) {
instWriter.write("SetOutPath $INSTDIR\\" + dir);
}
else {
instWriter.write("SetOutPath $INSTDIR");
}
for (String file : files) {
instWriter.newLine();
instWriter.write("File \"" + file + "\"");
}
}
}
finally {
instWriter.close();
}
}
private void processFileSet(final FileSet fileSet) throws IOException {
final DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
final String[] files = scanner.getIncludedFiles();
String base = fileSet.getDir(getProject()).getCanonicalPath() + "\\";
for (String file : files) {
String lastDir = "";
getDirFileList(lastDir);
int idx = -1;
do {
idx = file.indexOf('\\', idx + 1);
if (idx == -1) break;
lastDir = file.substring(0, idx);
getDirFileList(lastDir);
}
while (true);
List<String> fileList = getDirFileList(lastDir);
final String absolute = base + file;
fileList.add(absolute);
myAbsoluteToRelative.put(absolute, file);
}
}
private List<String> getDirFileList(final String dir) {
List<String> fileList = myDirToFiles.get(dir);
if (fileList == null) {
fileList = new ArrayList<String>();
myDirToFiles.put(dir, fileList);
}
return fileList;
}
private void cleanup() {
myBaseDir = null;
myInstFile = null;
myFileSets.clear();
myDirToFiles.clear();
myAbsoluteToRelative.clear();
}
}