/* * Copyright (c) Mark Derricutt 2010. * * The use and distribution terms for this software are covered by the Eclipse Public License 1.0 * (http://opensource.org/licenses/eclipse-1.0.php) which can be found in the file epl-v10.html * at the root of this distribution. * * By using this software in any fashion, you are agreeing to be bound by the terms of this license. * * You must not remove this notice, or any other, from this software. */ package com.theoryinpractise.clojure; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Vector; /** * Mojo for running Marginalia. Allows configuration of the source list * and target directory. */ @Mojo(name = "marginalia", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.TEST) public class ClojureMarginaliaMojo extends AbstractClojureCompilerMojo { /** * The Maven Project. */ @Parameter(readonly = true, required = true, property = "project") private MavenProject project = null; @Parameter(property = "project.name") private String projectName; @Parameter(property = "project.version") private String projectVersion; @Parameter(property = "project.description") private String projectDescription; @Parameter(property = "project.build.directory") private String projectBuildDir; /** * Location of the source files. */ @Parameter private String[] marginaliaSourceDirectories; /** * Location of the output files. */ @Parameter(defaultValue = "${project.build.directory}/marginalia") private String marginaliaTargetDirectory; @Parameter private Map<String, String> marginalia; private Set<Artifact> filterScope(Set<Artifact> artifacts, String scope) { Vector to_remove = new Vector(); for (Artifact artifact : artifacts) { if (artifact.getScope() != scope) to_remove.add(artifact); } artifacts.removeAll(to_remove); return artifacts; } private String quote(String s) { StringBuilder sb = new StringBuilder(); sb.append("\""); sb.append(s); sb.append("\""); return sb.toString(); } private String formatDependencies(Set<Artifact> artifacts) { StringBuilder sb = new StringBuilder(); sb.append("[\n"); for (Artifact artifact : artifacts) { sb.append("[\""); sb.append(artifact.getGroupId()); sb.append("/"); sb.append(artifact.getArtifactId()); sb.append("\" \""); sb.append(artifact.getVersion()); sb.append("\"]\n"); } sb.append("]"); return sb.toString(); } private String formatMap(Map<String, String> map) { StringBuilder sb = new StringBuilder(); sb.append("{\n"); for (Map.Entry<String, String> entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(" :" + key + " "); if (value != null) { sb.append(value); } else { sb.append("nil"); } sb.append("\n"); } sb.append("}\n"); return sb.toString(); } public void execute() throws MojoExecutionException { // Build a project info map Map<String, String> effectiveProps = new HashMap<String, String>(); effectiveProps.put("name", quote(projectName)); effectiveProps.put("version", quote(projectVersion)); effectiveProps.put("description", quote(projectDescription)); effectiveProps.put("dependencies", formatDependencies(filterScope(project.getDependencyArtifacts(), Artifact.SCOPE_COMPILE))); effectiveProps.put("dev-dependencies", formatDependencies(filterScope(project.getDependencyArtifacts(), Artifact.SCOPE_TEST))); if (marginalia != null) { effectiveProps.put("marginalia", formatMap(marginalia)); } boolean multiDoc = (marginalia == null ? false : ("true".equals(marginalia.get("multi")))); // Build the script to run marginalia StringBuilder sb = new StringBuilder(); sb.append("(use `marginalia.core '[marginalia.html :only (*resources*)])\n"); // fix per https://github.com/fogus/marginalia/issues/43 sb.append("(binding [*resources* \"\"]\n"); sb.append("(ensure-directory! \""); sb.append(marginaliaTargetDirectory); sb.append("\")\n"); sb.append(multiDoc ? "(multidoc!\n" : "(uberdoc!\n"); // Create the output destination sb.append(" \""); sb.append(marginaliaTargetDirectory); if (!multiDoc) sb.append("/uberdoc.html"); sb.append("\"\n"); // Create the list of sources to process sb.append(" (format-sources ["); // Append the explicit marginalia source paths, or project source paths for (String entry : (marginaliaSourceDirectories != null && marginaliaSourceDirectories.length > 0 ? marginaliaSourceDirectories : sourceDirectories)) { sb.append("\""); sb.append(baseDirectory); sb.append("/"); sb.append(entry); sb.append("\" "); } sb.append("])\n"); // and the project map sb.append(formatMap(effectiveProps)); sb.append(")\n"); sb.append(")\n"); // Run it try { File marginaliaClj = File.createTempFile("marginalia", ".clj"); final PrintWriter pw = new PrintWriter(marginaliaClj); pw.print(sb.toString()); pw.close(); getLog().info("Generating marginalia docs"); getLog().debug(sb.toString()); callClojureWith( getSourceDirectories(SourceDirectory.COMPILE, SourceDirectory.TEST), outputDirectory, testClasspathElements, "clojure.main", new String[] {marginaliaClj.getPath()}); } catch (IOException e) { throw new MojoExecutionException(e.getMessage()); } } }