package cuke4duke.mojo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
import org.codehaus.plexus.util.StringUtils;
import cuke4duke.ant.GemTask;
/**
* Base for all JRuby mojos.
*
* @requiresDependencyResolution test
*/
public abstract class AbstractJRubyMojo extends AbstractMojo {
/**
* @parameter expression="${project}"
*/
protected MavenProject mavenProject;
/**
* @parameter expression="${settings}"
* @required
* @readonly
*/
private Settings settings;
/**
* @parameter expression="${project.basedir}"
* @required
*/
protected File launchDirectory;
/**
* @parameter expression="${cucumber.gemDirectory}"
*/
protected File gemDirectory;
/**
* The project compile classpath.
*
* @parameter default-value="${project.compileClasspathElements}"
* @required
* @readonly
*/
protected List<String> compileClasspathElements;
/**
* The plugin dependencies.
*
* @parameter expression="${plugin.artifacts}"
* @required
* @readonly
*/
protected List<Artifact> pluginArtifacts;
/**
* The project test classpath
*
* @parameter expression="${project.testClasspathElements}"
* @required
* @readonly
*/
protected List<String> testClasspathElements;
/**
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
protected ArtifactRepository localRepository;
protected abstract List<String> getJvmArgs();
/**
* Installs a gem. Sources used:
* <ul>
* <li>http://gems.rubyforge.org</li>
* <li>http://gemcutter.org/</li>
* <li>http://gems.github.com</li>
* </ul>
*
* @param gemArgs
* name and optional arguments. Example:
* <ul>
* <li>awesome</li>
* <li>awesome --version 9.8</li>
* <li>awesome --version 9.8 --source http://some.gem.server</li>
* <li>awesome --version 9.8 --http-proxy http://your.proxy:8080</li>
* </ul>
* @throws org.apache.maven.plugin.MojoExecutionException
* if gem installation fails.
*/
protected void installGem(String gemArgs) throws MojoExecutionException {
GemTask gem = new GemTask();
if (gemDirectory != null && gemDirectory.exists()) {
gem.setDir(gemDirectory);
}
gem.setProject(getProject());
gem.setArgs(gemArgs + getProxyArg());
gem.execute();
}
/**
* Detect proxy from settings and convert to arg expected by RubyGems.
*/
protected String getProxyArg() {
Proxy activeProxy = this.settings.getActiveProxy();
if (activeProxy == null) {
return "";
}
String proxyArg = " --http-proxy " + activeProxy.getProtocol() + "://" + activeProxy.getHost() + ":"
+ activeProxy.getPort();
getLog().debug("Adding proxy from settings.xml: " + proxyArg);
return proxyArg;
}
protected File jrubyHome() {
return new File(localRepository.getBasedir(), ".jruby");
}
protected Project getProject() throws MojoExecutionException {
Project project = new Project();
project.setBaseDir(mavenProject.getBasedir());
project.setProperty("jruby.home", jrubyHome().getAbsolutePath());
project.addBuildListener(new LogAdapter());
Path jrubyClasspath = new Path(project);
project.addReference("jruby.classpath", jrubyClasspath);
try {
append(jrubyClasspath, testClasspathElements);
append(jrubyClasspath, compileClasspathElements);
append(jrubyClasspath, pluginArtifacts);
return project;
} catch (DependencyResolutionRequiredException e) {
throw new MojoExecutionException("error resolving dependencies", e);
}
}
protected void append(Path classPath, List<?> artifacts) throws DependencyResolutionRequiredException {
List<String> list = new ArrayList<String>(artifacts.size());
for (Object elem : artifacts) {
String path;
if (elem instanceof Artifact) {
Artifact a = (Artifact) elem;
File file = a.getFile();
if (file == null) {
throw new DependencyResolutionRequiredException(a);
}
path = file.getPath();
} else {
path = elem.toString();
}
list.add(path);
}
Path p = new Path(classPath.getProject());
p.setPath(StringUtils.join(list.iterator(), File.pathSeparator));
classPath.append(p);
}
public class LogAdapter implements BuildListener {
public void buildStarted(BuildEvent event) {
log(event);
}
public void buildFinished(BuildEvent event) {
log(event);
}
public void targetStarted(BuildEvent event) {
log(event);
}
public void targetFinished(BuildEvent event) {
log(event);
}
public void taskStarted(BuildEvent event) {
log(event);
}
public void taskFinished(BuildEvent event) {
log(event);
}
public void messageLogged(BuildEvent event) {
log(event);
}
private void log(BuildEvent event) {
int priority = event.getPriority();
Log log = getLog();
String message = event.getMessage();
switch (priority) {
case Project.MSG_ERR:
log.error(message);
break;
case Project.MSG_WARN:
log.warn(message);
break;
case Project.MSG_INFO:
log.info(message);
break;
case Project.MSG_VERBOSE:
log.debug(message);
break;
case Project.MSG_DEBUG:
log.debug(message);
break;
default:
log.info(message);
break;
}
}
}
}