/******************************************************************************* * 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; 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_BUILD_PROJECT_ID_PATTERN; import static de.devboost.buildboost.IConstants.BUILD_BOOST_CORE_PROJECT_ID; import static de.devboost.buildboost.IConstants.BUILD_BOOST_GENEXT_PROJECT_ID_PATTERN; import static de.devboost.buildboost.IConstants.BUILD_FOLDER; import static de.devboost.buildboost.IConstants.REPOS_FOLDER; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import de.devboost.buildboost.ant.AbstractAntTargetGenerator; import de.devboost.buildboost.ant.AbstractAntTargetGeneratorProvider; import de.devboost.buildboost.ant.AntScript; import de.devboost.buildboost.ant.AntTarget; import de.devboost.buildboost.ant.IAntTargetGenerator; import de.devboost.buildboost.artifacts.Plugin; import de.devboost.buildboost.discovery.PluginFinder; import de.devboost.buildboost.filters.IdentifierFilter; import de.devboost.buildboost.filters.IdentifierRegexFilter; import de.devboost.buildboost.filters.OrFilter; import de.devboost.buildboost.model.IArtifact; import de.devboost.buildboost.model.IBuildConfiguration; import de.devboost.buildboost.model.IBuildContext; import de.devboost.buildboost.model.IBuildParticipant; import de.devboost.buildboost.model.IBuildStage; import de.devboost.buildboost.stages.AbstractBuildStage; import de.devboost.buildboost.stages.CloneRepositoriesStage; import de.devboost.buildboost.stages.CompileStage; import de.devboost.buildboost.stages.CopyProjectsStage; import de.devboost.buildboost.util.XMLContent; public class BuildScriptGenerator implements IBuildConfiguration { private class MergeBootstrapBinariesStage extends AbstractBuildStage { private String sourcePath; private String buildBoostBinDir; public MergeBootstrapBinariesStage(String sourcePath, String buildBoostBinDir) { super(); this.sourcePath = sourcePath; this.buildBoostBinDir = buildBoostBinDir; } @Override public AntScript getScript() throws BuildException { File buildDir = new File(sourcePath); BuildContext context = createContext(true); context.addBuildParticipant(new PluginFinder(buildDir)); context.addBuildParticipant(new MergeBinariesStepProvider(buildBoostBinDir)); AutoBuilder builder = new AutoBuilder(context); AntScript script = new AntScript(); script.setName("Merge bootstrapped binaries"); script.addTargets(builder.generateAntTargets()); return script; } @Override public int getPriority() { // TODO Is this correct? return 0; } } private class MergeBinariesStepProvider extends AbstractAntTargetGeneratorProvider { private String buildBoostBinDir; public MergeBinariesStepProvider(String buildBoostBinDir) { this.buildBoostBinDir = buildBoostBinDir; } @Override public List<IAntTargetGenerator> getAntTargetGenerators(IBuildContext context, IArtifact artifact) { if (artifact instanceof Plugin) { Plugin plugin = (Plugin) artifact; if (plugin.isProject()) { List<IAntTargetGenerator> steps = new ArrayList<IAntTargetGenerator>(); steps.add(new MergeBinariesStep(plugin, buildBoostBinDir)); return steps; } } return Collections.emptyList(); } } private class MergeBinariesStep extends AbstractAntTargetGenerator { private Plugin plugin; private String buildBoostBinDir; public MergeBinariesStep(Plugin plugin, String buildBoostBinDir) { this.plugin = plugin; this.buildBoostBinDir = buildBoostBinDir; } @Override public Collection<AntTarget> generateAntTargets() throws BuildException { XMLContent content = new XMLContent(); Set<Plugin> dependencies = plugin.getAllDependencies(); content.append("<!-- DEPENDENCIES: " + dependencies + " -->"); copyToSharedBinFolder(content, plugin); for (Plugin dependency : dependencies) { copyToSharedBinFolder(content, dependency); } String identifier = plugin.getIdentifier(); AntTarget target = new AntTarget("merge-bin-" + identifier, content); return Collections.singleton(target); } private void copyToSharedBinFolder(XMLContent content, Plugin plugin) { File pluginFile = plugin.getFile(); File binFolder; File tempDir = new File(buildBoostBinDir, "temp"); if (!plugin.isProject()) { content.append("<mkdir dir=\"" + tempDir + "\" />"); content.append("<unzip src=\"" + pluginFile.getAbsolutePath() + "\" dest=\"" + tempDir + "\" />"); binFolder = tempDir; } else { binFolder = pluginFile; } content.append("<copy todir=\"" + buildBoostBinDir + "\">"); content.append("<fileset dir=\"" + binFolder + "\" />"); content.append("</copy>"); Set<String> libs = plugin.getLibs(); for (String lib : libs) { if (plugin.isProject()) { String absoluteLibPath = plugin.getAbsoluteLibPath(lib); content.append("<unzip src=\"" + absoluteLibPath + "\" dest=\"" + buildBoostBinDir + "\" />"); } else { content.append("<unzip src=\"" + tempDir + "/" + lib + "\" dest=\"" + buildBoostBinDir + "\" />"); } } content.append("<delete dir=\"" + tempDir + "\" />"); } } @Override public List<IBuildStage> getBuildStages(String workspace) { File buildFolder = new File(workspace, BUILD_FOLDER); File buildBoostBinFolder = new File(buildFolder, BUILD_BOOST_BIN_FOLDER); File reposFolder = new File(workspace, REPOS_FOLDER); File artifactsFolder = new File(buildFolder, ARTIFACTS_FOLDER); List<IBuildStage> stages = new ArrayList<IBuildStage>(); CloneRepositoriesStage stage1 = new CloneRepositoriesStage(); stage1.setReposFolder(reposFolder.getAbsolutePath()); // TODO This is not correct and it also makes the builds slow. There // can be new '.repositories' files after the second clone and this // might go on even further. We need to come up with a more clever // solution here. // update a second time, since the first update might have revealed new // '.repository' files // CloneRepositoriesStage stage2 = new CloneRepositoriesStage(); // stage2.setReposFolder(reposFolder.getAbsolutePath()); CopyProjectsStage stage3 = new CopyProjectsStage(); stage3.setReposFolder(reposFolder.getAbsolutePath()); stage3.setArtifactsFolder(artifactsFolder.getAbsolutePath()); stage3.addBuildParticipant(createFilter()); CompileStage stage4 = new CompileStage(); stage4.setArtifactsFolder(artifactsFolder.getAbsolutePath()); stage4.addBuildParticipant(createFilter()); MergeBootstrapBinariesStage stage5 = new MergeBootstrapBinariesStage(artifactsFolder.getAbsolutePath(), buildBoostBinFolder.getAbsolutePath()); stage5.addBuildParticipant(createFilter()); stages.add(stage1); // stages.add(stage2); stages.add(stage3); stages.add(stage4); stages.add(stage5); return stages; } private IBuildParticipant createFilter() { IdentifierFilter filter1 = new IdentifierFilter(BUILD_BOOST_CORE_PROJECT_ID); IdentifierRegexFilter filter2 = new IdentifierRegexFilter(BUILD_BOOST_GENEXT_PROJECT_ID_PATTERN); IdentifierRegexFilter filter3 = new IdentifierRegexFilter(BUILD_BOOST_BUILD_PROJECT_ID_PATTERN); return new OrFilter(filter1, filter2, filter3); } }