/*******************************************************************************
* Copyright (c) 2006-2015
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Dresden, Amtsgericht Dresden, HRB 34001
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Dresden, Germany
* - initial API and implementation
******************************************************************************/
package de.devboost.buildboost.util;
import static de.devboost.buildboost.IConstants.ARTIFACTS_FOLDER;
import static de.devboost.buildboost.IConstants.BUILD_BOOST_BIN_FOLDER;
import static de.devboost.buildboost.IConstants.BUILD_BOOST_CORE_PROJECT_ID;
import static de.devboost.buildboost.IConstants.PROJECTS_FOLDER;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import de.devboost.buildboost.BuildException;
import de.devboost.buildboost.BuildScriptGeneratorRunner;
import de.devboost.buildboost.ant.AntScript;
import de.devboost.buildboost.ant.AntTarget;
import de.devboost.buildboost.model.IBuildStage;
/**
* The {@link ScriptSaver} class can be used to save the script generated by build stages to disc.
*/
public class ScriptSaver {
/**
* Creates one build script for each build stage and a master script that calls the stages subsequently. All script
* are saved in the given target directory and using names.
*
* @param targetDir
* the directory where to save the scripts
* @param stages
* the stages used to obtain the scripts
* @throws BuildException
* thrown if something goes wrong while generating build scripts
*/
public void saveStages(File targetDir, List<IBuildStage> stages) throws BuildException {
// first save scripts for stages
int stageNumber = 1;
for (IBuildStage stage : stages) {
String fileName = getStageFileName(stageNumber);
saveStage(targetDir, stage, fileName);
stageNumber++;
}
saveMasterScript(targetDir, stages);
}
public void saveMasterScript(File targetDir, List<IBuildStage> stages) throws BuildException {
// then create master script that calls the scripts for the stages
AntScript masterScript = new AntScript();
masterScript.setName("BuildBoostMaster");
XMLContent content = new XMLContent();
int lastStageNumber = stages.size() + 1;
for (int i = 1; i < lastStageNumber; i++) {
IBuildStage stage = stages.get(i - 1);
if (stage.isEnabled()) {
content.append("<ant antfile=\"" + getStageFileName(i) + "\" />");
} else {
content.append("<echo message=\"Build stage " + i + " is disabled and will not be executed.\" />");
}
if (i < lastStageNumber - 1) {
// we must regenerate the build scripts after each stage,
// because stages can rely on the output of the previous one.
content.append("<echo message=\"Regenerate build scripts (to consider changes from previous build stage)\" />");
// TODO put this into a macro
content.append("<echo message=\"Run custom script generator via script runner\" />");
content.append("<java fork=\"true\" classname=\"" + BuildScriptGeneratorRunner.class.getName()
+ "\" failonerror=\"true\">");
content.append("<arg value=\"${workspace}\" />");
content.append("<arg value=\"${build_plugin_id}.BuildScriptGenerator\"/>");
content.append("<classpath>");
content.append("<pathelement path=\"${basedir}/" + ARTIFACTS_FOLDER + "/" + PROJECTS_FOLDER + "/"
+ BUILD_BOOST_CORE_PROJECT_ID + "\" />");
content.append("<pathelement path=\"${basedir}/" + BUILD_BOOST_BIN_FOLDER + "\" />");
content.append("<pathelement path=\"${java.class.path}\"/>");
content.append("</classpath>");
content.append("<jvmarg value=\"-DBUILD_BOOST_IGNORE_STAGES=${BUILD_BOOST_IGNORE_STAGES}\"/>");
content.append("</java>");
}
}
AntTarget masterTarget = new AntTarget("buildboost-master", content);
masterScript.addTarget(masterTarget);
// save master script that calls all the stage scripts
save(targetDir, masterScript.getScript(), "buildboost_master.xml");
}
public void saveStage(File targetDir, IBuildStage stage, String fileName) throws BuildException {
AntScript script = stage.getScript();
save(targetDir, script.getScript(), fileName);
}
/**
* Returns an auto-generated name for the build stage with the given index.
*
* @param stageNumber
* the index of the build stage
* @return a file name that is unique for each index
*/
public String getStageFileName(int stageNumber) {
return "buildboost_stage_" + stageNumber + ".xml";
}
/**
* Saves the given content to a file.
*
* @param targetDir
* the directory to save the file to
* @param content
* the content to save
* @param fileName
* the name of the file to save
*
* @throws BuildException
* if something goes wrong
*/
private void save(File targetDir, String content, String fileName) throws BuildException {
if (!targetDir.exists()) {
boolean success = targetDir.mkdirs();
if (!success) {
throw new BuildException("Can't create directory '" + targetDir + "'.");
}
}
try {
FileWriter writer = new FileWriter(new File(targetDir.getAbsolutePath() + File.separator + fileName));
writer.append(content);
writer.close();
} catch (IOException e) {
throw new BuildException("IOException while saving script '" + fileName + "' (" + e.getMessage() + ").");
}
}
}