org.wisdom.maven.mojos.CoffeeScriptCompilerMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wisdom-maven-plugin Show documentation
Show all versions of wisdom-maven-plugin Show documentation
The Maven Wisdom Plugin allows building applications for Wisdom.
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.wisdom.maven.mojos;
import com.google.common.base.Strings;
import org.apache.commons.io.FileUtils;
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.wisdom.maven.Constants;
import org.wisdom.maven.WatchingException;
import org.wisdom.maven.node.NPM;
import org.wisdom.maven.utils.WatcherUtils;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.wisdom.maven.node.NPM.npm;
/**
* Compiles CoffeeScript files to JavaScript.
* All '.coffee' files from 'src/main/resources/assets' are compiled to 'target/classes/',
* while 'src/main/assets/' are compiled to 'target/wisdom/assets'.
*/
@Mojo(name = "compile-coffeescript", threadSafe = false,
requiresDependencyResolution = ResolutionScope.COMPILE,
requiresProject = true,
defaultPhase = LifecyclePhase.COMPILE)
public class CoffeeScriptCompilerMojo extends AbstractWisdomWatcherMojo implements Constants {
public static final String COFFEE_SCRIPT_NPM_NAME = "coffee-script";
public static final String COFFEE_SCRIPT_COMMAND = "coffee";
public static final String ERROR_TITLE = "CoffeeScript Compilation Error";
public static final String COFFEESCRIPT_VERSION = "1.9.2";
private NPM coffee;
/**
* The CoffeeScript version.
* It must be a version available from the NPM registry
*
* @see NPM Web Site.
*/
@Parameter(defaultValue = COFFEESCRIPT_VERSION)
String coffeeScriptVersion;
/**
* Finds and compiles coffeescript files.
*
* @throws MojoExecutionException if the compilation failed.
*/
@Override
public void execute() throws MojoExecutionException {
coffee = npm(this, COFFEE_SCRIPT_NPM_NAME, coffeeScriptVersion);
try {
if (getInternalAssetsDirectory().isDirectory()) {
getLog().info("Compiling CoffeeScript files from " + getInternalAssetsDirectory().getAbsolutePath());
invokeCoffeeScriptCompiler(getInternalAssetsDirectory(), getInternalAssetOutputDirectory());
}
if (getExternalAssetsDirectory().isDirectory()) {
getLog().info("Compiling CoffeeScript files from " + getExternalAssetsDirectory().getAbsolutePath());
invokeCoffeeScriptCompiler(getExternalAssetsDirectory(), getExternalAssetsOutputDirectory());
}
} catch (WatchingException e) {
throw new MojoExecutionException("Error during the CoffeeScript compilation", e);
}
}
/**
* Accepts all `coffee` files that are in 'src/main/resources/assets' or in 'src/main/assets/'.
*
* @param file the file
* @return {@literal true} if the file is accepted.
*/
@Override
public boolean accept(File file) {
return
(WatcherUtils.isInDirectory(file, WatcherUtils.getInternalAssetsSource(basedir))
|| (WatcherUtils.isInDirectory(file, WatcherUtils.getExternalAssetsSource(basedir)))
)
&& WatcherUtils.hasExtension(file, "coffee");
}
private void compile(File file) throws WatchingException {
if (file == null) {
return;
}
File out = getOutputFile(file, "js");
getLog().info("Compiling CoffeeScript " + file.getAbsolutePath() + " to " + out.getAbsolutePath());
invokeCoffeeScriptCompiler(file, out.getParentFile());
}
private void invokeCoffeeScriptCompiler(File input, File out) throws WatchingException {
try {
int exit = coffee.execute(COFFEE_SCRIPT_COMMAND, "--compile", "--map", "--output", out.getAbsolutePath(),
input.getAbsolutePath());
getLog().debug("CoffeeScript compilation exits with " + exit + " status");
} catch (MojoExecutionException e) {
if (!Strings.isNullOrEmpty(coffee.getLastErrorStream())) {
throw build(coffee.getLastErrorStream(), input);
} else {
throw new WatchingException(ERROR_TITLE, "Error while compiling " + input
.getAbsolutePath(), input, e);
}
}
}
public static Pattern COFFEE_COMPILATION_ERROR = Pattern.compile("(.*):([0-9]*):([0-9]*):(.*)");
public WatchingException build(String message, File source) {
String[] lines = message.split("\n");
for (String l : lines) {
if (!Strings.isNullOrEmpty(l)) {
message = l.trim();
break;
}
}
final Matcher matcher = COFFEE_COMPILATION_ERROR.matcher(message);
if (matcher.matches()) {
String path = matcher.group(1);
String line = matcher.group(2);
String character = matcher.group(3);
String reason = matcher.group(4);
File file = new File(path);
return new WatchingException(ERROR_TITLE, reason, file,
Integer.valueOf(line), Integer.valueOf(character), null);
} else {
return new WatchingException(ERROR_TITLE, message, source, null);
}
}
/**
* A file is created - compiles it.
*
* @param file the file
* @return {@literal true}
* @throws WatchingException if the compilation failed
*/
@Override
public boolean fileCreated(File file) throws WatchingException {
compile(file);
return true;
}
/**
* A file is updated - compiles it.
*
* @param file the file
* @return {@literal true}
* @throws WatchingException if the compilation failed
*/
@Override
public boolean fileUpdated(File file) throws WatchingException {
compile(file);
return true;
}
/**
* A file is deleted - delete the output files (".js" and ".map").
*
* @param file the file
* @return {@literal true}
*/
@Override
public boolean fileDeleted(File file) {
FileUtils.deleteQuietly(getOutputFile(file, "js"));
FileUtils.deleteQuietly(getOutputFile(file, "js.map"));
// Keep the deletion of .map file for coffeescript < 1.8.0
FileUtils.deleteQuietly(getOutputFile(file, "map"));
return true;
}
}