/* * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.agent.android.tools; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.openapi.util.Key; import jetbrains.buildServer.agent.BuildProgressLogger; import jetbrains.buildServer.agent.BuildRunnerContext; import jetbrains.buildServer.agent.FlowGenerator; import jetbrains.buildServer.agent.FlowLogger; import jetbrains.buildServer.agent.android.AndroidRunnersUtil; import jetbrains.buildServer.agent.android.NonZeroExitCodeException; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.util.List; abstract class AbstractTool { @NotNull private final String myToolPath; @NotNull private final BuildRunnerContext myContext; public AbstractTool(@NotNull final String toolPath, @NotNull final BuildRunnerContext context) { myToolPath = toolPath; myContext = context; } @NotNull protected File getWorkingDirectory() { return myContext.getWorkingDirectory(); } protected boolean isDebug() { return AndroidRunnersUtil.isDebug(myContext); } protected void execute(@NotNull final List argumentsBefore, @NotNull final List argumentsAfter, @NotNull final String additionalArguments) throws IOException, ExecutionException, NonZeroExitCodeException { final GeneralCommandLine commandLine = createCommandLine(argumentsBefore, argumentsAfter, additionalArguments); final BuildProgressLogger logger = myContext.getBuild().getBuildLogger(), stdOutLogger = createNewFlowLogger(), stdErrLogger = createNewFlowLogger(); final boolean isDebug = isDebug(); if (isDebug) { logger.message("Executing command: " + commandLine.getCommandLineString()); } final OSProcessHandler processHandler = createProcessHandler(commandLine); processHandler.addProcessListener(new ProcessAdapter() { @Override public void onTextAvailable(final ProcessEvent event, final Key outputType) { if (outputType == ProcessOutputTypes.STDERR) { stdErrLogger.error(event.getText()); } else if (isDebug && outputType == ProcessOutputTypes.STDOUT) { stdOutLogger.message(event.getText()); } } }); processHandler.startNotify(); processHandler.waitFor(); final int exitCode = processHandler.getProcess().exitValue(); if (exitCode != 0) { logger.error("Execution failed. Exit code is " + exitCode + "."); throw new NonZeroExitCodeException(); } } @NotNull private FlowLogger createNewFlowLogger() { return myContext.getBuild().getBuildLogger().getFlowLogger(FlowGenerator.generateNewFlow()); } @NotNull private static OSProcessHandler createProcessHandler(@NotNull final GeneralCommandLine commandLine) throws ExecutionException { return new OSProcessHandler(commandLine.createProcess(), "") { @Override protected Reader createProcessOutReader() { return new InputStreamReader(getProcess().getInputStream()); } @Override protected Reader createProcessErrReader() { return new InputStreamReader(getProcess().getErrorStream()); } }; } @NotNull private GeneralCommandLine createCommandLine(@NotNull final List argumentsBefore, @NotNull final List argumentsAfter, @NotNull final String additionalArguments) { final GeneralCommandLine cmd = new GeneralCommandLine(); cmd.setExePath(myToolPath); cmd.setWorkDirectory(getWorkingDirectory().getPath()); cmd.setPassParentEnvs(false); cmd.setEnvParams(myContext.getBuildParameters().getEnvironmentVariables()); cmd.addParameters(argumentsBefore); cmd.getParametersList().addParametersString(additionalArguments); cmd.addParameters(argumentsAfter); return cmd; } }