PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/atlassian/bamboo/plugin/dotnet/msbuild/MsBuildTaskType.java

https://bitbucket.org/atlassian/bamboo-dotnet-plugin/
Java | 171 lines | 139 code | 25 blank | 7 comment | 1 complexity | 19cf81dc59ab63386a4869d64d948732 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. package com.atlassian.bamboo.plugin.dotnet.msbuild;
  2. import com.atlassian.bamboo.build.logger.BuildLogger;
  3. import com.atlassian.bamboo.build.logger.interceptors.ErrorMemorisingInterceptor;
  4. import com.atlassian.bamboo.build.logger.interceptors.LogMemorisingInterceptor;
  5. import com.atlassian.bamboo.plugin.dotnet.support.DotNetLogHelper;
  6. import com.atlassian.bamboo.process.EnvironmentVariableAccessor;
  7. import com.atlassian.bamboo.process.ExternalProcessBuilder;
  8. import com.atlassian.bamboo.process.ProcessService;
  9. import com.atlassian.bamboo.task.CommonTaskContext;
  10. import com.atlassian.bamboo.task.CommonTaskType;
  11. import com.atlassian.bamboo.task.TaskException;
  12. import com.atlassian.bamboo.task.TaskResult;
  13. import com.atlassian.bamboo.task.TaskResultBuilder;
  14. import com.atlassian.bamboo.util.SecureTemporaryFiles;
  15. import com.atlassian.bamboo.utils.SystemProperty;
  16. import com.atlassian.bamboo.v2.build.CurrentResult;
  17. import com.atlassian.bamboo.v2.build.agent.capability.CapabilityContext;
  18. import com.atlassian.bamboo.v2.build.agent.capability.CapabilityDefaultsHelper;
  19. import com.google.common.collect.ImmutableList;
  20. import com.google.common.collect.Lists;
  21. import org.apache.commons.io.FileUtils;
  22. import org.apache.log4j.Logger;
  23. import org.jetbrains.annotations.NotNull;
  24. import java.io.File;
  25. import java.io.IOException;
  26. import java.util.List;
  27. public class MsBuildTaskType implements CommonTaskType
  28. {
  29. @SuppressWarnings("UnusedDeclaration")
  30. private static final Logger log = Logger.getLogger(MsBuildTaskType.class);
  31. // ------------------------------------------------------------------------------------------------------- Constants
  32. public static final String MSBUILD_CAPABILITY_PREFIX = CapabilityDefaultsHelper.CAPABILITY_BUILDER_PREFIX + ".msbuild";
  33. public static final String PROPERTY_USE_RESPONSE_FILE = "bamboo.plugin.dotnet.msbuild.useResponseFile";
  34. private static final int LINES_TO_PARSE_FOR_ERRORS = 200;
  35. // TODO next upgrade should use response file as default option
  36. private static final SystemProperty.BooleanSystemProperty USE_RESPONSE_FILE = new SystemProperty.BooleanSystemProperty(false, true, PROPERTY_USE_RESPONSE_FILE);
  37. // ------------------------------------------------------------------------------------------------- Type Properties
  38. // ---------------------------------------------------------------------------------------------------- Dependencies
  39. private final ProcessService processService;
  40. private final EnvironmentVariableAccessor environmentVariableAccessor;
  41. private final CapabilityContext capabilityContext;
  42. // ---------------------------------------------------------------------------------------------------- Constructors
  43. public MsBuildTaskType(final ProcessService processService,
  44. final EnvironmentVariableAccessor environmentVariableAccessor,
  45. final CapabilityContext capabilityContext)
  46. {
  47. this.processService = processService;
  48. this.environmentVariableAccessor = environmentVariableAccessor;
  49. this.capabilityContext = capabilityContext;
  50. }
  51. // ----------------------------------------------------------------------------------------------- Interface Methods
  52. @Override
  53. public TaskResult execute(@NotNull CommonTaskContext taskContext) throws TaskException
  54. {
  55. final BuildLogger buildLogger = taskContext.getBuildLogger();
  56. final CurrentResult currentBuildResult = taskContext.getCommonContext().getCurrentResult();
  57. LogMemorisingInterceptor recentLogLines = new LogMemorisingInterceptor(LINES_TO_PARSE_FOR_ERRORS);
  58. final ErrorMemorisingInterceptor errorLines = ErrorMemorisingInterceptor.newInterceptor();
  59. buildLogger.getInterceptorStack().add(recentLogLines);
  60. buildLogger.getInterceptorStack().add(errorLines);
  61. File intermediateFile = null;
  62. try
  63. {
  64. final MsBuildConfig msBuildConfig = MsBuildConfig.build(taskContext, capabilityContext, environmentVariableAccessor);
  65. final ExternalProcessBuilder epb;
  66. if (USE_RESPONSE_FILE.getTypedValue())
  67. {
  68. intermediateFile = createResponseFile(taskContext, msBuildConfig);
  69. epb = epbWithResponseFile(msBuildConfig, intermediateFile);
  70. }
  71. else
  72. {
  73. intermediateFile = createBatchFile(msBuildConfig);
  74. epb = epbWithCommandLine(msBuildConfig, intermediateFile);
  75. }
  76. epb
  77. .env(msBuildConfig.getEnvironmentMap())
  78. .workingDirectory(taskContext.getWorkingDirectory());
  79. return TaskResultBuilder.newBuilder(taskContext)
  80. .checkReturnCode(processService.executeExternalProcess(taskContext, epb))
  81. .build();
  82. }
  83. finally
  84. {
  85. FileUtils.deleteQuietly(intermediateFile);
  86. currentBuildResult.addBuildErrors(errorLines.getErrorStringList());
  87. currentBuildResult.addBuildErrors(DotNetLogHelper.parseErrorOutput(recentLogLines.getLogEntries()));
  88. }
  89. }
  90. // -------------------------------------------------------------------------------------------------- Helper Methods
  91. private ExternalProcessBuilder epbWithCommandLine(MsBuildConfig msBuildConfig, @NotNull final File batchFile)
  92. {
  93. return new ExternalProcessBuilder()
  94. .command(Lists.newArrayList(batchFile.getAbsolutePath(), getCommand(msBuildConfig)));
  95. }
  96. private File createBatchFile(MsBuildConfig msBuildConfig)
  97. {
  98. final String command = getCommand(msBuildConfig);
  99. final SecureTemporaryFiles.FileSpecBuilder fileSpecBuilder =
  100. SecureTemporaryFiles.builder()
  101. .setPrefix("epb")
  102. .setSuffix(".bat")
  103. .setExecutable(true);
  104. File batchFile;
  105. try
  106. {
  107. batchFile = SecureTemporaryFiles.create(fileSpecBuilder.build());
  108. FileUtils.writeStringToFile(batchFile, command);
  109. }
  110. catch (IOException e)
  111. {
  112. throw new IllegalStateException(e);
  113. }
  114. batchFile.setReadOnly();
  115. return batchFile;
  116. }
  117. private String getCommand(MsBuildConfig msBuildConfig) {
  118. return "\"" +
  119. msBuildConfig.getMsBuildExecutable() + "\" " +
  120. msBuildConfig.getOptions() + " " +
  121. msBuildConfig.getSolution();
  122. }
  123. private ExternalProcessBuilder epbWithResponseFile(@NotNull final MsBuildConfig msBuildConfig, @NotNull final File responseFile) throws TaskException
  124. {
  125. final List<String> command = Lists.newArrayList(msBuildConfig.getMsBuildExecutable(),
  126. "@" + responseFile.getAbsolutePath());
  127. final ExternalProcessBuilder externalProcessBuilder = new ExternalProcessBuilder()
  128. .command(command);
  129. return externalProcessBuilder;
  130. }
  131. private File createResponseFile(@NotNull CommonTaskContext taskContext, @NotNull MsBuildConfig msBuildConfig) throws TaskException
  132. {
  133. try
  134. {
  135. final String prefix = taskContext.getCommonContext().getResultKey().getKey() + "-" + getClass().getSimpleName() + "-";
  136. final File responseFile = File.createTempFile(prefix, ".rsp");
  137. FileUtils.writeLines(responseFile, ImmutableList.of("# MSBuild response file generated by Atlassian Bamboo", msBuildConfig.getOptions(), msBuildConfig.getSolution()));
  138. responseFile.setReadOnly();
  139. return responseFile;
  140. }
  141. catch (IOException e)
  142. {
  143. throw new TaskException("Error while creating temporary file for script", e);
  144. }
  145. }
  146. }