PageRenderTime 23ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/jenkins/plugins/shiningpanda/command/Command.java

https://github.com/jenkinsci/shiningpanda-plugin
Java | 247 lines | 80 code | 17 blank | 150 comment | 6 complexity | 4ece29cde7fef405d75092922a52e597 MD5 | raw file
  1. /*
  2. * ShiningPanda plug-in for Jenkins
  3. * Copyright (C) 2011-2015 ShiningPanda S.A.S.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of its license which incorporates the terms and
  7. * conditions of version 3 of the GNU Affero General Public License,
  8. * supplemented by the additional permissions under the GNU Affero GPL
  9. * version 3 section 7: if you modify this program, or any covered work,
  10. * by linking or combining it with other code, such other code is not
  11. * for that reason alone subject to any of the requirements of the GNU
  12. * Affero GPL version 3.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * license for more details.
  18. *
  19. * You should have received a copy of the license along with this program.
  20. * If not, see <https://raw.github.com/jenkinsci/shiningpanda-plugin/master/LICENSE.txt>.
  21. */
  22. package jenkins.plugins.shiningpanda.command;
  23. import java.io.IOException;
  24. import hudson.EnvVars;
  25. import hudson.FilePath;
  26. import hudson.Launcher;
  27. import hudson.Util;
  28. import hudson.model.TaskListener;
  29. import hudson.tasks.Messages;
  30. import hudson.util.ArgumentListBuilder;
  31. public abstract class Command {
  32. /**
  33. * Content of the execution script.
  34. */
  35. private String command;
  36. /**
  37. * Is exit code ignored?
  38. */
  39. private boolean ignoreExitCode;
  40. /**
  41. * Constructor using fields.
  42. *
  43. * @param command
  44. * The content of the execution script
  45. * @param ignoreExitCode
  46. * Is exit code ignored?
  47. */
  48. protected Command(String command, boolean ignoreExitCode) {
  49. // Call super
  50. super();
  51. // Store the content of the script
  52. setCommand(command);
  53. // Store the exit code flag
  54. setIgnoreExitCode(ignoreExitCode);
  55. }
  56. /**
  57. * Get the content of the script to execute.
  58. *
  59. * @return The content of the script to execute
  60. */
  61. protected String getCommand() {
  62. return command;
  63. }
  64. /**
  65. * Set the content of the script to execute.
  66. *
  67. * @param command
  68. * The content of the script to execute
  69. */
  70. private void setCommand(String command) {
  71. this.command = command;
  72. }
  73. /**
  74. * Is the exit code ignored?
  75. *
  76. * @return true of exit code is ignored, else false
  77. */
  78. protected boolean isExitCodeIgnored() {
  79. return ignoreExitCode;
  80. }
  81. /**
  82. * Set the exit code flag.
  83. *
  84. * @param ignoreExitCode
  85. * true if the exit code must be ignored
  86. */
  87. private void setIgnoreExitCode(boolean ignoreExitCode) {
  88. this.ignoreExitCode = ignoreExitCode;
  89. }
  90. /**
  91. * Get the extension of the script file.
  92. *
  93. * @return The extension
  94. */
  95. protected abstract String getExtension();
  96. /**
  97. * Get the content of the script file
  98. *
  99. * @return The content of the file
  100. */
  101. protected abstract String getContents();
  102. /**
  103. * Get the command line to execute.
  104. *
  105. * @param script
  106. * The script to execute
  107. * @return The arguments
  108. */
  109. protected abstract ArgumentListBuilder getArguments(FilePath script);
  110. /**
  111. * Be able to have a late environment processing.
  112. *
  113. * @param pwd
  114. * The working directory
  115. * @param environment
  116. * The environment
  117. * @return The processed environment
  118. */
  119. protected EnvVars getEnvironment(FilePath pwd, EnvVars environment) {
  120. return environment;
  121. }
  122. /**
  123. * Create content of the script execute.
  124. *
  125. * @param dir
  126. * The folder in which the script is created
  127. * @return The script file
  128. * @throws IOException
  129. * @throws InterruptedException
  130. */
  131. protected FilePath createScriptFile(FilePath dir) throws IOException, InterruptedException {
  132. return dir.createTextTempFile("shiningpanda", getExtension(), getContents(), false);
  133. }
  134. /**
  135. * Launch the command.
  136. *
  137. * @param launcher
  138. * The launcher
  139. * @param listener
  140. * The listener
  141. * @param environment
  142. * The environment
  143. * @param pwd
  144. * The current directory
  145. * @return true if successful, else false
  146. * @throws InterruptedException
  147. */
  148. public boolean launch(Launcher launcher, TaskListener listener, EnvVars environment, FilePath pwd)
  149. throws InterruptedException {
  150. // The script file
  151. FilePath script = null;
  152. // Be able to delete the script file in all cases
  153. try {
  154. // Try to create the script file
  155. try {
  156. // Create the script file
  157. script = createScriptFile(pwd);
  158. }
  159. // Failed to create the script file
  160. catch (IOException e) {
  161. // Display exception
  162. Util.displayIOException(e, listener);
  163. // Log the message
  164. e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_UnableToProduceScript()));
  165. // Do not continue
  166. return false;
  167. }
  168. // Be able to catch execution errors
  169. try {
  170. // Execute the script
  171. int exitCode = launcher.launch().cmds(getArguments(script)).envs(getEnvironment(pwd, environment))
  172. .stdout(listener).pwd(pwd).join();
  173. // Check if continue or not depending on the exit code ignore
  174. // flag
  175. return isExitCodeIgnored() ? true : exitCode == 0;
  176. }
  177. // Failed to execute the script
  178. catch (IOException e) {
  179. // Display exception
  180. Util.displayIOException(e, listener);
  181. // Log the error
  182. e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_CommandFailed()));
  183. // Do not continue
  184. return false;
  185. }
  186. }
  187. // Cleanup in all cases
  188. finally {
  189. // Catch cleanup errors
  190. try {
  191. // Check if the script was created
  192. if (script != null)
  193. // Delete it
  194. script.delete();
  195. } catch (IOException e) {
  196. // Failed to delete the script, display exception
  197. Util.displayIOException(e, listener);
  198. // Log the error
  199. e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script)));
  200. }
  201. }
  202. }
  203. /**
  204. * Get the right command executor.
  205. *
  206. * @param isUnix
  207. * Target execution platform
  208. * @param executable
  209. * The PYTHON executable
  210. * @param nature
  211. * The nature of the command: PYTHON, shell, X shell
  212. * @param command
  213. * The content of the script to execute
  214. * @param ignoreExitCode
  215. * Is exit code ignored?
  216. * @return The command object
  217. */
  218. public static Command get(boolean isUnix, String executable, CommandNature nature, String command,
  219. boolean ignoreExitCode) {
  220. // Check if this is a PYTHON script
  221. if (nature == CommandNature.PYTHON)
  222. // Create a new PYTHON command
  223. return new PythonCommand(isUnix, executable, command, ignoreExitCode);
  224. // Check if a conversion is required
  225. boolean convert = nature == CommandNature.XSHELL;
  226. // Create the right command depending of the OS and the conversion flag
  227. return (isUnix ? new UnixCommand(command, ignoreExitCode, convert)
  228. : new WindowsCommand(command, ignoreExitCode, convert));
  229. }
  230. }