@NotNull\r
File getOutputDirectory() throws RunBuildException;\r
\r
+ boolean cleanOutputDirectory() throws RunBuildException;\r
+\r
@NotNull\r
File getBaseDirectory() throws RunBuildException;\r
\r
return getDirectory(context, NUGET_PACK_OUTPUT_DIR, "output directory");\r
}\r
\r
+ public boolean cleanOutputDirectory() throws RunBuildException {\r
+ return getBoolean(context, NUGET_PACK_OUTPUT_CLEAR);\r
+ }\r
+\r
@NotNull\r
public File getBaseDirectory() throws RunBuildException {\r
String path = getParameter(context, NUGET_PACK_BASE_DIR);\r
package jetbrains.buildServer.nuget.agent.runner.pack;\r
\r
import jetbrains.buildServer.RunBuildException;\r
-import jetbrains.buildServer.agent.AgentRunningBuild;\r
-import jetbrains.buildServer.agent.BuildProcess;\r
-import jetbrains.buildServer.agent.BuildRunnerContext;\r
+import jetbrains.buildServer.agent.*;\r
import jetbrains.buildServer.nuget.agent.commands.NuGetActionFactory;\r
import jetbrains.buildServer.nuget.agent.parameters.NuGetPackParameters;\r
import jetbrains.buildServer.nuget.agent.parameters.PackagesParametersFactory;\r
import jetbrains.buildServer.nuget.agent.runner.NuGetRunnerBase;\r
+import jetbrains.buildServer.nuget.agent.util.BuildProcessBase;\r
import jetbrains.buildServer.nuget.agent.util.CompositeBuildProcess;\r
import jetbrains.buildServer.nuget.agent.util.impl.CompositeBuildProcessImpl;\r
import jetbrains.buildServer.nuget.common.PackagesConstants;\r
+import org.apache.log4j.Logger;\r
import org.jetbrains.annotations.NotNull;\r
\r
+import java.io.File;\r
+\r
/**\r
* @author Eugene Petrenko (eugene.petrenko@gmail.com)\r
* Date: 23.08.11 12:11\r
*/\r
public class PackRunner extends NuGetRunnerBase {\r
+ private final SmartDirectoryCleaner myCleaner;\r
+\r
public PackRunner(@NotNull final NuGetActionFactory actionFactory,\r
- @NotNull final PackagesParametersFactory parametersFactory) {\r
+ @NotNull final PackagesParametersFactory parametersFactory,\r
+ @NotNull final SmartDirectoryCleaner cleaner) {\r
super(actionFactory, parametersFactory);\r
+ myCleaner = cleaner;\r
}\r
\r
@NotNull\r
final CompositeBuildProcess process = new CompositeBuildProcessImpl();\r
final NuGetPackParameters params = myParametersFactory.loadPackParameters(context);\r
\r
+ process.pushBuildProcess(new BuildProcessBase() {\r
+ @NotNull\r
+ @Override\r
+ protected BuildFinishedStatus waitForImpl() throws RunBuildException {\r
+ final File output = params.getOutputDirectory();\r
+\r
+ if (params.cleanOutputDirectory()) {\r
+ final CleanerCallback callback = new CleanerCallback(runningBuild.getBuildLogger(), Logger.getLogger(getClass()));\r
+ myCleaner.cleanFolder(output, callback);\r
+ if (callback.isHasErrors()) {\r
+ return BuildFinishedStatus.FINISHED_FAILED;\r
+ }\r
+ }\r
+\r
+ //noinspection ResultOfMethodCallIgnored\r
+ output.mkdirs();\r
+ if (!output.isDirectory()) {\r
+ runningBuild.getBuildLogger().error("Failed to create output directory: " + output);\r
+ return BuildFinishedStatus.FINISHED_FAILED;\r
+ }\r
+\r
+ return BuildFinishedStatus.FINISHED_SUCCESS;\r
+ }\r
+ });\r
+\r
process.pushBuildProcess(myActionFactory.createPack(context, params));\r
return process;\r
}\r
public String getType() {\r
return PackagesConstants.PACK_RUN_TYPE;\r
}\r
+\r
+ private class CleanerCallback implements SmartDirectoryCleanerCallback {\r
+ private final BuildProgressLogger myLogger;\r
+ private final Logger LOG;\r
+ private boolean myHasErrors = false;\r
+ private File myRoot;\r
+\r
+ public CleanerCallback(@NotNull final BuildProgressLogger logger, @NotNull final Logger LOG) {\r
+ myLogger = logger;\r
+ this.LOG = LOG;\r
+ }\r
+\r
+ public void logCleanStarted(final File f) {\r
+ myRoot = f;\r
+ myLogger.message("Cleaning " + f.getAbsolutePath());\r
+ LOG.info("Cleaning " + f.getAbsolutePath());\r
+ }\r
+\r
+ public void logFailedToDeleteEmptyDirectory(final File f) {\r
+ final String message = "Failed to delete empty directory: " + f.getAbsolutePath();\r
+ if (f != myRoot) {\r
+ myLogger.error(message);\r
+ } else {\r
+ myLogger.warning(message);\r
+ }\r
+ LOG.warn(message);\r
+ }\r
+\r
+ public void logFailedToCleanFilesUnderDirectory(final File problem) {\r
+ myLogger.error("Failed to clean all files under directory: " + problem.getAbsolutePath());\r
+ LOG.warn("Failed to clean all files under directory: " + problem.getAbsolutePath());\r
+ myHasErrors = true;\r
+ }\r
+\r
+ public void logFailedToCleanFile(final File problem) {\r
+ myLogger.error("Failed to delete file: " + problem.getAbsolutePath());\r
+ LOG.warn("Failed to delete file: " + problem.getAbsolutePath());\r
+ myHasErrors = true;\r
+ }\r
+\r
+ public void logFailedToCleanEntireFolder(final File file) {\r
+ myHasErrors = true;\r
+ }\r
+\r
+ public boolean isHasErrors() {\r
+ return myHasErrors;\r
+ }\r
+ }\r
}\r
public static final String NUGET_TOOL_REL_PATH = "tools/NuGet.exe";\r
\r
\r
+ public static final String NUGET_PACK_OUTPUT_CLEAR = "nuget.pack.output.clean";\r
public static final String NUGET_PACK_OUTPUT_DIR = "nuget.pack.output.directory";\r
public static final String NUGET_PACK_BASE_DIR = "nuget.pack.base.directory";\r
public static final String NUGET_PACK_VERSION = "nuget.pack.version";\r
\r
<l:settingsGroup title="Output">\r
<tr>\r
- <th><label for="${ib.packOutputDirectory}">Output Directory</label><l:star/>:</th>\r
+ <th rowspan="2"><label for="${ib.packOutputDirectory}">Output Directory</label><l:star/>:</th>\r
<td>\r
<props:textProperty name="${ib.packOutputDirectory}" className="longField"/>\r
<span class="smallNote">Specify path to put generated NuGet package</span>\r
<span id="error_${ib.packOutputDirectory}" class="error"></span>\r
</td>\r
</tr>\r
-\r
+ <tr>\r
+ <td>\r
+ <props:checkboxProperty name="${ib.packOutputClear}"/> Clean output directory before pack\r
+ </td>\r
+ </tr>\r
</l:settingsGroup>\r
\r
<l:settingsGroup title="Additionals parameters">\r
<%@ taglib prefix="l" tagdir="/WEB-INF/tags/layout" %>\r
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>\r
<jsp:useBean id="ib" class="jetbrains.buildServer.nuget.server.runner.pack.PackBean" scope="request"/>\r
+<jsp:useBean id="propertiesBean" scope="request" type="jetbrains.buildServer.controllers.BasePropertiesBean"/>\r
\r
\r
<div class="parameter">\r
\r
<div class="parameter">\r
Output Directory: <strong><props:displayValue name="${ib.packOutputDirectory}"/></strong>\r
+ <c:if test="${not empty propertiesBean.properties[ib.packOutputClear]}">(cleaned on start)</c:if>\r
</div>\r
\r
<div class="parameter">\r
public class PackBean {\r
public String getNuGetPathKey() { return PackagesConstants.NUGET_PATH; }\r
public String getPackOutputDirectory() { return PackagesConstants.NUGET_PACK_OUTPUT_DIR; }\r
+ public String getPackOutputClear() { return PackagesConstants.NUGET_PACK_OUTPUT_CLEAR; }\r
public String getPackBaseDirectory() { return PackagesConstants.NUGET_PACK_BASE_DIR;}\r
public String getPackVersion() { return PackagesConstants.NUGET_PACK_VERSION; }\r
public String getPackSpecFile() { return PackagesConstants.NUGET_PACK_SPEC_FILE;}\r
public Map<String, String> getDefaultRunnerProperties() {\r
return new HashMap<String, String>(){{\r
put(PackagesConstants.NUGET_PACK_VERSION, "%" + ServerProvidedProperties.BUILD_NUMBER_PROP + "%");\r
+ put(PackagesConstants.NUGET_PACK_OUTPUT_CLEAR, "checked");\r
}};\r
}\r
}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.tests.agent;\r
+\r
+import jetbrains.buildServer.RunBuildException;\r
+import jetbrains.buildServer.agent.*;\r
+import jetbrains.buildServer.nuget.agent.commands.NuGetActionFactory;\r
+import jetbrains.buildServer.nuget.agent.parameters.NuGetPackParameters;\r
+import jetbrains.buildServer.nuget.agent.parameters.PackagesParametersFactory;\r
+import jetbrains.buildServer.nuget.agent.runner.pack.PackRunner;\r
+import jetbrains.buildServer.nuget.tests.util.BuildProcessTestCase;\r
+import jetbrains.buildServer.util.FileUtil;\r
+import junit.framework.Assert;\r
+import org.hamcrest.BaseMatcher;\r
+import org.hamcrest.Description;\r
+import org.jmock.Expectations;\r
+import org.jmock.Mockery;\r
+import org.testng.annotations.BeforeMethod;\r
+import org.testng.annotations.Test;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * @author Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 24.08.11 12:31\r
+ */\r
+public class PackRunnerTest extends BuildProcessTestCase {\r
+ private Mockery m;\r
+ private NuGetActionFactory myActionFactory;\r
+ private PackagesParametersFactory myParametersFactory;\r
+ private SmartDirectoryCleaner myCleaner;\r
+ private AgentRunningBuild myBuild;\r
+ private BuildRunnerContext myContext;\r
+ private NuGetPackParameters myPackParameters;\r
+ private BuildProcess myProc;\r
+ private BuildProgressLogger myLogger;\r
+\r
+\r
+ @BeforeMethod\r
+ @Override\r
+ protected void setUp() throws Exception {\r
+ super.setUp();\r
+ m = new Mockery();\r
+ myActionFactory = m.mock(NuGetActionFactory.class);\r
+ myParametersFactory = m.mock(PackagesParametersFactory.class);\r
+ myCleaner = m.mock(SmartDirectoryCleaner.class);\r
+ myBuild = m.mock(AgentRunningBuild.class);\r
+ myContext = m.mock(BuildRunnerContext.class);\r
+ myPackParameters = m.mock(NuGetPackParameters.class);\r
+ myProc = m.mock(BuildProcess.class);\r
+ myLogger = m.mock(BuildProgressLogger.class);\r
+\r
+ m.checking(new Expectations(){{\r
+ allowing(myParametersFactory).loadPackParameters(myContext); will(returnValue(myPackParameters));\r
+ allowing(myActionFactory).createPack(myContext, myPackParameters); will(returnValue(myProc));\r
+\r
+ allowing(myBuild).getBuildLogger(); will(returnValue(myLogger));\r
+ allowing(myContext).getBuild(); will(returnValue(myBuild));\r
+\r
+ allowing(myLogger).message(with(any(String.class)));\r
+ allowing(myLogger).activityStarted(with(any(String.class)), with(any(String.class)), with(any(String.class)));\r
+ allowing(myLogger).activityStarted(with(any(String.class)), with(any(String.class)));\r
+ allowing(myLogger).activityFinished(with(any(String.class)), with(any(String.class)));\r
+\r
+\r
+ oneOf(myProc).start();\r
+ oneOf(myProc).waitFor(); will(returnValue(BuildFinishedStatus.FINISHED_SUCCESS));\r
+ }});\r
+ }\r
+\r
+ @Test\r
+ public void test_packRunner_outputDirectory_notCleaned() throws RunBuildException, IOException {\r
+ m.checking(new Expectations(){{\r
+ allowing(myPackParameters).cleanOutputDirectory(); will(returnValue(false));\r
+ allowing(myPackParameters).getOutputDirectory(); will(returnValue(createTempDir()));\r
+ }});\r
+\r
+ final PackRunner runner = new PackRunner(myActionFactory, myParametersFactory, myCleaner);\r
+ final BuildProcess process = runner.createBuildProcess(myBuild, myContext);\r
+ assertRunSuccessfully(process, BuildFinishedStatus.FINISHED_SUCCESS);\r
+ }\r
+\r
+ @Test\r
+ public void test_packRunner_outputDirectoryCleaned() throws RunBuildException, IOException {\r
+ final File temp = createTempDir();\r
+ m.checking(new Expectations(){{\r
+ allowing(myPackParameters).cleanOutputDirectory(); will(returnValue(true));\r
+ allowing(myPackParameters).getOutputDirectory();will(returnValue(temp));\r
+\r
+ oneOf(myCleaner).cleanFolder(with(equal(temp)), with(any(SmartDirectoryCleanerCallback.class)));\r
+ }});\r
+\r
+ FileUtil.delete(temp);\r
+ final PackRunner runner = new PackRunner(myActionFactory, myParametersFactory, myCleaner);\r
+ final BuildProcess process = runner.createBuildProcess(myBuild, myContext);\r
+ assertRunSuccessfully(process, BuildFinishedStatus.FINISHED_SUCCESS);\r
+\r
+ Assert.assertTrue(temp.isDirectory());\r
+ }\r
+\r
+ @Test\r
+ public void test_packRunner_outputDirectoryCleaned_error() throws RunBuildException, IOException {\r
+ final File temp = createTempDir();\r
+ m.checking(new Expectations(){{\r
+ allowing(myPackParameters).cleanOutputDirectory(); will(returnValue(true));\r
+ allowing(myPackParameters).getOutputDirectory();will(returnValue(temp));\r
+\r
+ allowing(myLogger).error(with(any(String.class)));\r
+\r
+ oneOf(myCleaner).cleanFolder(with(equal(temp)), with(new BaseMatcher<SmartDirectoryCleanerCallback>() {\r
+ public boolean matches(Object o) {\r
+ SmartDirectoryCleanerCallback cb = (SmartDirectoryCleanerCallback) o;\r
+ cb.logFailedToCleanFile(temp);\r
+\r
+ return true;\r
+ }\r
+\r
+ public void describeTo(Description description) {\r
+ description.appendText("Callback with failure");\r
+ }\r
+ }));\r
+ }});\r
+\r
+ final PackRunner runner = new PackRunner(myActionFactory, myParametersFactory, myCleaner);\r
+ final BuildProcess process = runner.createBuildProcess(myBuild, myContext);\r
+ assertRunSuccessfully(process, BuildFinishedStatus.FINISHED_FAILED);\r
+ }\r
+\r
+}\r
import jetbrains.buildServer.SimpleCommandLineProcessRunner;\r
import jetbrains.buildServer.agent.BuildFinishedStatus;\r
import jetbrains.buildServer.agent.BuildProcess;\r
+import jetbrains.buildServer.agent.SmartDirectoryCleaner;\r
import jetbrains.buildServer.nuget.agent.runner.pack.PackRunner;\r
import jetbrains.buildServer.nuget.agent.parameters.NuGetPackParameters;\r
import jetbrains.buildServer.util.FileUtil;\r
*/\r
public class PackIntegrationTest extends IntegrationTestBase {\r
protected NuGetPackParameters myPackParameters;\r
+ private SmartDirectoryCleaner myCleaner;\r
private File myOutputDir;\r
\r
@BeforeMethod\r
protected void setUp() throws Exception {\r
super.setUp();\r
myPackParameters = m.mock(NuGetPackParameters.class);\r
+ myCleaner = m.mock(SmartDirectoryCleaner.class);\r
\r
m.checking(new Expectations(){{\r
oneOf(myParametersFactory).loadPackParameters(myContext); will(returnValue(myPackParameters));\r
final File spec = new File(myRoot, "SamplePackage.nuspec");\r
FileUtil.copy(getTestDataPath("SamplePackage.nuspec"), spec);\r
\r
- callRunner(spec, false, false);\r
+ callRunner(spec, false, false, false);\r
\r
Assert.assertTrue(myOutputDir.list(new FilenameFilter() {\r
public boolean accept(File dir, String name) {\r
\r
msbuild(new File(myRoot, "nuget-proj.sln"));\r
\r
- callRunner(spec, false, false);\r
+ callRunner(spec, false, false, false);\r
\r
Assert.assertTrue(nupkgs().length == 1, "There should be only one package created");\r
\r
\r
msbuild(new File(myRoot, "nuget-proj.sln"));\r
\r
- callRunner(spec, true, false);\r
+ callRunner(spec, true, false, false);\r
\r
Assert.assertTrue(nupkgs().length == 1, "There should be only one package created");\r
final File nupkg = nupkgs()[0];\r
\r
msbuild(new File(myRoot, "nuget-proj.sln"));\r
\r
- callRunner(spec, false, true);\r
+ callRunner(spec, false, true, false);\r
\r
Assert.assertTrue(nupkgs().length == 1, "There should be only one package created");\r
Assert.assertTrue(symbolsNupkgs().length == 1, "There should be only one symbols package created");\r
Assert.assertEquals(0, result.getExitCode());\r
}\r
\r
- private void callRunner(@NotNull final File spec, final boolean packAsTool, final boolean symbols) throws RunBuildException {\r
+ private void callRunner(@NotNull final File spec, final boolean packAsTool, final boolean symbols, final boolean cleanOutput) throws RunBuildException {\r
m.checking(new Expectations(){{\r
allowing(myPackParameters).getCustomCommandline(); will(returnValue(Collections.<String>emptyList()));\r
allowing(myPackParameters).getProperties(); will(returnValue(Collections.<String>emptyList()));\r
allowing(myPackParameters).getExclude(); will(returnValue(Collections.<String>emptyList()));\r
allowing(myPackParameters).getVersion(); will(returnValue("45.239.32.12"));\r
allowing(myPackParameters).getOutputDirectory(); will(returnValue(myOutputDir));\r
+ allowing(myPackParameters).cleanOutputDirectory(); will(returnValue(cleanOutput));\r
\r
allowing(myPackParameters).packTool(); will(returnValue(packAsTool));\r
allowing(myPackParameters).packSymbols(); will(returnValue(symbols));\r
}});\r
\r
- final PackRunner runner = new PackRunner(myActionFactory, myParametersFactory);\r
+ final PackRunner runner = new PackRunner(myActionFactory, myParametersFactory, myCleaner);\r
final BuildProcess proc = runner.createBuildProcess(myBuild, myContext);\r
assertRunSuccessfully(proc, BuildFinishedStatus.FINISHED_SUCCESS);\r
}\r
<class name="jetbrains.buildServer.nuget.tests.server.tools.NuGetToolsInstallerTest"/>\r
\r
<class name="jetbrains.buildServer.nuget.tests.agent.NuGetPackActionFactoryTest"/>\r
+ <class name="jetbrains.buildServer.nuget.tests.agent.PackRunnerTest"/>\r
</classes>\r
</test>\r
</suite>\r