1 package org.codehaus.mojo.rspec;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.net.MalformedURLException;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.Properties;
11
12 import org.apache.maven.plugin.AbstractMojo;
13 import org.apache.maven.plugin.MojoExecutionException;
14 import org.apache.maven.plugin.MojoFailureException;
15
16
17
18
19
20
21
22
23 public class RspecRunnerMojo extends AbstractMojo {
24
25
26
27
28
29
30
31
32 protected String basedir;
33
34
35
36
37
38
39
40
41 protected List<String> classpathElements;
42
43
44
45
46
47
48
49 protected String sourceDirectory;
50
51
52
53
54
55
56
57 protected String outputDirectory;
58
59
60
61
62
63
64 protected String reportName;
65
66
67
68
69
70
71
72 protected String jrubyHome;
73
74
75
76
77
78
79 protected boolean ignoreFailure;
80
81
82
83
84
85
86 protected boolean skipTests;
87
88
89
90
91
92
93 protected Properties systemProperties;
94
95 private RSpecScriptFactory rspecScriptFactory = new RSpecScriptFactory();
96 private ShellScriptFactory shellScriptFactory = new ShellScriptFactory();
97
98 public RspecRunnerMojo() {
99
100 }
101
102 public void execute() throws MojoExecutionException, MojoFailureException {
103 if (skipTests) {
104 getLog().info("Skipping RSpec tests");
105 return;
106 }
107 getLog().info("Running RSpec tests from " + sourceDirectory);
108
109 String reportPath = outputDirectory + "/" + reportName;
110
111 initScriptFactory( rspecScriptFactory, reportPath);
112 initScriptFactory( shellScriptFactory, reportPath);
113
114 try {
115 rspecScriptFactory.emit();
116 } catch (Exception e) {
117 getLog().error( "error emitting .rb", e );
118 }
119 try {
120 shellScriptFactory.emit();
121 } catch (Exception e) {
122 getLog().error( "error emitting .sh", e );
123 }
124
125 try {
126 runScript(rspecScriptFactory.getScript() );
127 } catch (MalformedURLException e) {
128 getLog().error( "error running script", e );
129 }
130 }
131
132 private void initScriptFactory(ScriptFactory factory, String reportPath) {
133 factory.setBaseDir(basedir);
134 factory.setClasspathElements(classpathElements);
135 factory.setOutputDir(new File(outputDirectory));
136 factory.setReportPath(reportPath);
137 factory.setSourceDir(sourceDirectory);
138 factory.setSystemProperties( systemProperties );
139 }
140
141 private void runScript(String script) {
142
143
144 List<String> cmdLine = new ArrayList<String>();
145 cmdLine.add( jrubyHome + "/bin/jruby");
146
147 cmdLine.add( "-J-Dbasedir=" + basedir );
148 for (Object propName : systemProperties.keySet()) {
149 String propValue = systemProperties.getProperty(propName.toString());
150 cmdLine.add("-J-D" + propName + "=" + propValue);
151 }
152
153
154
155 StringBuilder classpath = new StringBuilder();
156 boolean first = true;
157
158 for (String element : classpathElements) {
159 if (first) {
160 first = false;
161 } else {
162 classpath.append(":");
163 }
164 classpath.append(element);
165 }
166
167 ProcessBuilder builder = new ProcessBuilder(cmdLine);
168
169 builder.environment().put("JRUBY_HOME", jrubyHome);
170 builder.environment().put("CLASSPATH", classpath.toString());
171
172 try {
173 Process process = builder.start();
174 new InputConsumer(process.getInputStream(), System.out).start();
175 new InputConsumer(process.getErrorStream(), System.err).start();
176
177 OutputStream out = process.getOutputStream();
178 out.write(script.getBytes());
179 out.close();
180
181 process.waitFor();
182 System.err.println("exit: " + process.exitValue());
183 } catch (IOException e) {
184 getLog().error(e);
185 } catch (InterruptedException e) {
186 getLog().error(e);
187 }
188 }
189
190 private class InputConsumer extends Thread {
191
192 private InputStream input;
193 private OutputStream sink;
194
195 public InputConsumer(InputStream input, OutputStream sink) {
196 this.input = input;
197 this.sink = sink;
198 }
199
200 public void run() {
201 byte[] buf = new byte[128];
202 int len = 0;
203 try {
204 while ((len = this.input.read(buf)) >= 0) {
205 this.sink.write(buf, 0, len);
206 }
207 } catch (IOException e) {
208 e.printStackTrace();
209 }
210 }
211
212 }
213
214 }