Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Configuration options shown are default values and can be ignored for normal use
<srcDir>${basedir}/src/main/webapp</srcDir>
<outputDir>${basedir}/src/main/webapp</outputDir>
<bare>false</bare>
<sourceMap>false</sourceMap>
<modifiedOnly>false</modifiedOnly>
<allowedDelete>true</allowedDelete>
<compilerUrl></compilerUrl>
Expand Down Expand Up @@ -95,11 +96,12 @@ Compile coffeescript files to javascript files.

### Optional Parameters:

* bare Boolean - Bare mode. Default value is: false.
* modifiedOnly Boolean - Only compile modified files. Default value is: false.
* outputDir File - Output Directory. Expression: ${basedir}/src/main/webapp
* srcDir File - Source Directory. Expression: ${basedir}/src/main/webapp
* compilerUrl String - CoffeeScript compiler file url. It supports both url string and file path string. e.g. http://coffeescript.org/extras/coffee-script.js or ${basedir}/lib/coffee-script.js
* `bare Boolean` - Bare mode. Default value is: false.
* `sourceMap Boolean` - If true, will save source maps for compiled files. Also copies the source files to the output directory. Default value is: false.
* `modifiedOnly Boolean` - Only compile modified files. Default value is: false.
* `outputDir File` - Output Directory. Expression: ${basedir}/src/main/webapp
* `srcDir File` - Source Directory. Expression: ${basedir}/src/main/webapp
* `compilerUrl String` - CoffeeScript compiler file url. It supports both url string and file path string. e.g. http://coffeescript.org/extras/coffee-script.js or ${basedir}/lib/coffee-script.js

## Goal:watch

Expand Down
20 changes: 17 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<groupId>com.github.iron9light</groupId>
<artifactId>coffeescript-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.2-SNAPSHOT</version>
<version>1.3-SNAPSHOT</version>
<name>Coffeescript Maven Plugin</name>
<description>A Maven plugin for compiling coffeescript into javascript</description>
<inceptionYear>2011</inceptionYear>
Expand Down Expand Up @@ -130,6 +130,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>

Expand All @@ -142,12 +151,17 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r09</version>
<version>13.0</version>
</dependency>
<dependency>
<groupId>org.mozilla</groupId>
<artifactId>rhino</artifactId>
<version>1.7R3</version>
<version>1.7R4</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,30 @@
import com.google.common.base.Charsets;
import com.google.common.io.InputSupplier;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Scriptable;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.mozilla.javascript.NativeObject;

public class CoffeeScriptCompiler {

private final Scriptable globalScope;
private boolean bare;
private boolean sourceMap;
public String version;

public CoffeeScriptCompiler(URL url, boolean bare) {

public CoffeeScriptCompiler(URL url, boolean bare, boolean sourceMap) {
this.bare = bare;
this.sourceMap = sourceMap;

InputSupplier<InputStreamReader> supplier = Resources.newReaderSupplier(url, Charsets.UTF_8);
Context context = Context.enter();
context.setOptimizationLevel(-1); // Without this, Rhino hits a 64K bytecode limit and fails
Expand All @@ -35,20 +42,43 @@ public CoffeeScriptCompiler(URL url, boolean bare) {

}

public String compile(String coffeeScriptSource) {
/**
* Compile the source code.
*
* @param coffeeScriptSource source code.
* @param sourceFile source file name (used for source map generation).
* @param generatedFile generated file name (used for source map generation).
* @param sourceMapFile source map file name (used for source map generation).
* @return array of [complied code; source map]. Source map may be null if parameter was not specified.
*/
public String[] compile(String coffeeScriptSource, String sourceFile, String generatedFile, String sourceMapFile) {
Context context = Context.enter();
try {
Scriptable compileScope = context.newObject(globalScope);
compileScope.setParentScope(globalScope);
compileScope.put("coffeeScript", compileScope, coffeeScriptSource);
try {

String options = bare ? "{bare: true}" : "{}";
String options = getOptions(sourceFile, generatedFile);

String jsCode;
String sourceMapCode;

Object result = context.evaluateString(
compileScope,
String.format("CoffeeScript.compile(coffeeScript, %s);", options),
"source", 0, null);

if (!sourceMap) {
jsCode = result.toString();
sourceMapCode = null;
} else {
NativeObject object = (NativeObject) result;
jsCode = object.get("js").toString() + "\n//@ sourceMappingURL=" + sourceMapFile;
sourceMapCode = object.get("v3SourceMap").toString();
}

return (String) context.evaluateString(
compileScope,
String.format("CoffeeScript.compile(coffeeScript, %s);", options),
"source", 0, null);
return new String[] { jsCode, sourceMapCode };
} catch (JavaScriptException e) {
throw new CoffeeScriptException(e.getMessage());
}
Expand All @@ -57,4 +87,20 @@ public String compile(String coffeeScriptSource) {
}
}

private String getOptions(String sourceFile, String generatedFile) {
Map<String, Object> options = new HashMap<>();
if (bare) {
options.put("bare", true);
}
if (sourceMap) {
options.put("sourceMap", true);
options.put("sourceFiles", new String[]{sourceFile});
options.put("generatedFile", generatedFile);
}

Gson gson = new GsonBuilder().create();
String result = gson.toJson(options);
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public abstract class CoffeeScriptMojoBase extends AbstractMojo {
*/
private Boolean bare;

/**
* Source map support.
*
* @parameter default-value="false"
*/
private Boolean sourceMap;

/**
* Only compile modified files.
*
Expand All @@ -60,7 +67,7 @@ public abstract class CoffeeScriptMojoBase extends AbstractMojo {
private static URL defaultCoffeeScriptUrl = CoffeeScriptMojoBase.class.getResource("/coffee-script.js");

public void execute() throws MojoExecutionException, MojoFailureException {
CoffeeScriptCompiler compiler = new CoffeeScriptCompiler(getCoffeeScriptUrl(), bare);
CoffeeScriptCompiler compiler = new CoffeeScriptCompiler(getCoffeeScriptUrl(), bare, sourceMap);
getLog().info(String.format("Coffeescript version: %s", compiler.version));

if (!srcDir.exists()) {
Expand Down Expand Up @@ -88,8 +95,19 @@ protected void compileCoffeeFilesInDir(final CoffeeScriptCompiler compiler, fina
for (Path coffeeFile : coffeeFiles) {
String coffeeFileName = sourceDirectory.relativize(coffeeFile).toString();
String jsFileName = getJsFileName(coffeeFileName);
String sourceMapFileName = sourceMap ? getSourceMapFileName(jsFileName) : null;
Path jsFile = outputDirectory.resolve(jsFileName);
if (!compileCoffeeFile(compiler, coffeeFile, jsFile, coffeeFileName, jsFileName)) {
Path sourceMapFile = sourceMap ? outputDirectory.resolve(sourceMapFileName) : null;
Path copiedCoffeeFile = sourceMap ? outputDirectory.resolve(coffeeFileName) : null;
if (!compileCoffeeFile(
compiler,
coffeeFile,
copiedCoffeeFile,
jsFile,
sourceMapFile,
coffeeFileName,
jsFileName,
sourceMapFileName)) {
failedFileNames.add(coffeeFileName);
}
}
Expand Down Expand Up @@ -134,16 +152,29 @@ protected String getJsFileName(String coffeeFileName) {
return coffeeFileName.substring(0, coffeeFileName.length() - ".coffee".length()) + ".js";
}

protected String getSourceMapFileName(String jsFileName) {
return jsFileName + ".map";
}

protected boolean isCoffeeFile(Path file) {
return file.toString().endsWith(".coffee");
}

protected boolean compileCoffeeFile(CoffeeScriptCompiler compiler, Path coffeeFile, Path jsFile, String coffeeFileName, String jsFileName) throws IOException {
protected boolean compileCoffeeFile(
CoffeeScriptCompiler compiler,
Path coffeeFile,
Path copiedCoffeeFile,
Path jsFile,
Path sourceMapFile,
String coffeeFileName,
String jsFileName,
String sourceMapFileName) throws IOException {
Path jsParent = jsFile.getParent();
if (!Files.exists(jsParent)) {
Files.createDirectories(jsParent);
} else if (Files.isDirectory(jsFile)) {
getLog().warn(String.format("Cannot compile to %s, as there is a Directory with the same name", jsFileName));
} else if (!doDirectoryCheck(jsFile, jsFileName)
|| !doDirectoryCheck(copiedCoffeeFile, coffeeFileName)
|| !doDirectoryCheck(sourceMapFile, sourceMapFileName)) {
return false;
} else if (modifiedOnly && Files.exists(jsFile)) {
if (Files.getLastModifiedTime(jsFile).compareTo(Files.getLastModifiedTime(coffeeFile)) > 0) {
Expand All @@ -155,9 +186,19 @@ protected boolean compileCoffeeFile(CoffeeScriptCompiler compiler, Path coffeeFi
String coffeeSource = readAllString(coffeeFile);

try {
String jsSource = compiler.compile(coffeeSource);
String[] contents = compiler.compile(coffeeSource, coffeeFileName, jsFileName, sourceMapFileName);
String jsSource = contents[0];
writeString(jsFile, jsSource);
getLog().info(String.format("Compiled: %s [%s]", coffeeFileName, new java.util.Date()));

if (sourceMap) {
Files.copy(coffeeFile, copiedCoffeeFile, StandardCopyOption.REPLACE_EXISTING);
getLog().info(String.format("Copied: %s [%s]", coffeeFileName, new java.util.Date()));

String mapContent = contents[1];
writeString(sourceMapFile, mapContent);
getLog().info(String.format("Source map: %s [%s]", sourceMapFileName, new java.util.Date()));
}
} catch (CoffeeScriptException ex) {
getLog().error(String.format("Error: %s %s [%s]", coffeeFileName, ex.getMessage(), new java.util.Date()));
return false;
Expand All @@ -166,6 +207,19 @@ protected boolean compileCoffeeFile(CoffeeScriptCompiler compiler, Path coffeeFi
return true;
}

private boolean doDirectoryCheck(Path path, String fileName) {
if (path == null && fileName == null) {
return true;
}

if (Files.isDirectory(path)) {
getLog().warn(String.format("Cannot write to %s, as there is a directory with the same name", fileName));
return false;
} else {
return true;
}
}

private void writeString(Path path, String jsSource) throws IOException {
com.google.common.io.Files.write(jsSource, path.toFile(), charset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private void watch(final CoffeeScriptCompiler compiler, final Path sourceDirecto
changed = true;
}
} else if (event.kind().name().equals(StandardWatchEventKinds.ENTRY_MODIFY.name()) || event.kind().name().equals(StandardWatchEventKinds.ENTRY_CREATE.name())) {
compileCoffeeFile(compiler, file, jsFile, coffeeFileName, jsFileName);
compileCoffeeFile(compiler, file, null, jsFile, null, coffeeFileName, jsFileName, null);
changed = true;
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/main/resources/coffee-script.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class CoffeeScriptCompilerTest {
@Test
public void testVersion() throws MalformedURLException {
URL url = getClass().getResource("/coffee-script.js");
CoffeeScriptCompiler compiler = new CoffeeScriptCompiler(url, false);
assertThat(compiler.version, equalTo("1.3.3"));
CoffeeScriptCompiler compiler = new CoffeeScriptCompiler(url, false, false);
assertThat(compiler.version, equalTo("1.6.2"));
}
}