1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.release.exec;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.File;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.nio.file.Files;
31 import java.util.List;
32
33 import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer;
34 import org.apache.maven.shared.release.ReleaseResult;
35 import org.apache.maven.shared.release.env.ReleaseEnvironment;
36 import org.apache.maven.shared.release.util.MavenCrypto;
37 import org.codehaus.plexus.util.cli.CommandLineException;
38 import org.codehaus.plexus.util.cli.Commandline;
39
40 import static java.util.Objects.requireNonNull;
41
42
43
44
45
46
47 @Singleton
48 @Named("forked-path")
49 public class ForkedMavenExecutor extends AbstractMavenExecutor {
50
51
52
53 private final CommandLineFactory commandLineFactory;
54
55 @Inject
56 public ForkedMavenExecutor(MavenCrypto mavenCrypto, CommandLineFactory commandLineFactory) {
57 super(mavenCrypto);
58 this.commandLineFactory = requireNonNull(commandLineFactory);
59 }
60
61
62
63
64 @Override
65 public void executeGoals(
66 File workingDirectory,
67 List<String> goals,
68 ReleaseEnvironment releaseEnvironment,
69 boolean interactive,
70 String additionalArguments,
71 String pomFileName,
72 ReleaseResult relResult)
73 throws MavenExecutorException {
74 String mavenPath;
75
76 if (releaseEnvironment.getMavenHome() != null) {
77 mavenPath = releaseEnvironment.getMavenHome().getAbsolutePath();
78 } else {
79 mavenPath = System.getProperty("maven.home");
80 }
81
82 File settingsFile = null;
83 if (releaseEnvironment.getSettings() != null) {
84
85 try {
86 settingsFile = Files.createTempFile("release-settings", ".xml").toFile();
87 SettingsXpp3Writer writer = getSettingsWriter();
88
89 try (FileWriter fileWriter = new FileWriter(settingsFile)) {
90 writer.write(fileWriter, encryptSettings(releaseEnvironment.getSettings()));
91 }
92 } catch (IOException e) {
93 throw new MavenExecutorException("Could not create temporary file for release settings.xml", e);
94 }
95 }
96 try {
97
98 Commandline cl =
99 commandLineFactory.createCommandLine(mavenPath + File.separator + "bin" + File.separator + "mvn");
100
101 cl.setWorkingDirectory(workingDirectory.getAbsolutePath());
102
103
104
105
106 cl.addEnvironment("MAVEN_TERMINATE_CMD", "on");
107
108 if (releaseEnvironment.getJavaHome() != null) {
109 cl.addEnvironment("JAVA_HOME", releaseEnvironment.getJavaHome().getAbsolutePath());
110 }
111
112 if (settingsFile != null) {
113 cl.createArg().setValue("-s");
114 cl.createArg().setFile(settingsFile);
115 }
116
117 if (pomFileName != null) {
118 cl.createArg().setValue("-f");
119 cl.createArg().setValue(pomFileName);
120 }
121
122 for (String goal : goals) {
123 cl.createArg().setValue(goal);
124 }
125
126 if (!interactive) {
127 cl.createArg().setValue("--batch-mode");
128 }
129
130 if (!(additionalArguments == null || additionalArguments.isEmpty())) {
131 cl.createArg().setLine(additionalArguments);
132 }
133
134 TeeOutputStream stdOut = new TeeOutputStream(System.out);
135
136 TeeOutputStream stdErr = new TeeOutputStream(System.err);
137
138 try {
139 relResult.appendInfo("Executing: " + cl);
140 getLogger().info("Executing: " + cl);
141
142 int result = executeCommandLine(cl, System.in, stdOut, stdErr);
143
144 if (result != 0) {
145 throw new MavenExecutorException("Maven execution failed, exit code: '" + result + "'", result);
146 }
147 } catch (CommandLineException e) {
148 throw new MavenExecutorException("Can't run goal " + goals, e);
149 } finally {
150 relResult.appendOutput(stdOut.toString());
151 }
152 } finally {
153 if (settingsFile != null && settingsFile.exists() && !settingsFile.delete()) {
154 settingsFile.deleteOnExit();
155 }
156 }
157 }
158
159
160
161
162
163
164
165
166
167
168
169 public static int executeCommandLine(
170 Commandline cl, InputStream systemIn, OutputStream systemOut, OutputStream systemErr)
171 throws CommandLineException {
172 if (cl == null) {
173 throw new IllegalArgumentException("cl cannot be null.");
174 }
175
176 Process p = cl.execute();
177
178
179
180 RawStreamPumper inputFeeder = null;
181
182 if (systemIn != null) {
183 inputFeeder = new RawStreamPumper(systemIn, p.getOutputStream(), true);
184 }
185
186 RawStreamPumper outputPumper = new RawStreamPumper(p.getInputStream(), systemOut);
187 RawStreamPumper errorPumper = new RawStreamPumper(p.getErrorStream(), systemErr);
188
189 if (inputFeeder != null) {
190 inputFeeder.start();
191 }
192
193 outputPumper.start();
194
195 errorPumper.start();
196
197 try {
198 int returnValue = p.waitFor();
199
200 if (inputFeeder != null) {
201 inputFeeder.setDone();
202 }
203 outputPumper.setDone();
204 errorPumper.setDone();
205
206
207
208 return returnValue;
209 } catch (InterruptedException ex) {
210
211 throw new CommandLineException("Error while executing external command, process killed.", ex);
212 } finally {
213 try {
214 errorPumper.closeInput();
215 } catch (IOException e) {
216
217 }
218 try {
219 outputPumper.closeInput();
220 } catch (IOException e) {
221
222 }
223 if (inputFeeder != null) {
224 try {
225 inputFeeder.closeOutput();
226 } catch (IOException e) {
227
228 }
229 }
230 }
231 }
232 }