Skip to content

Commit

Permalink
Fix #546 - Add typescript support to the wisdom maven plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
cescoffier committed Dec 12, 2015
1 parent 46e7af1 commit 51ece68
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 54 deletions.
2 changes: 1 addition & 1 deletion core/wisdom-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<properties>
<mavenVersion>3.2.1</mavenVersion>
<mavenPluginPluginVersion>3.2</mavenPluginPluginVersion>
<mavenPluginPluginVersion>3.4</mavenPluginPluginVersion>
<plexusCompilerVersion>2.4</plexusCompilerVersion>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public abstract class AbstractWisdomMojo extends AbstractMojo {
/**
* The current build session instance.
*/
@Component
@Parameter(defaultValue = "${session}", readonly = true )
public MavenSession session;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
*/
package org.wisdom.maven.mojos;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
Expand Down Expand Up @@ -171,7 +174,7 @@ public TypeScript setNoImplicitAny(boolean noImplicitAny) {
return this;
}

public List<String> createTypeScriptComilerArgumentList(File input, File destination) {
public List<String> createTypeScriptCompilerArgumentList(File input, File destination) {
List<String> arguments = new ArrayList<>();
if (removeComments) {
arguments.add("--removeComments");
Expand Down Expand Up @@ -223,9 +226,16 @@ public List<String> createTypeScriptComilerArgumentList(File input, File destina
arguments.addAll(otherArguments);
}

arguments.add("--out");
arguments.add("--outDir");
arguments.add(destination.getAbsolutePath());

arguments.add("--rootDir");
arguments.add(input.getAbsolutePath());

// Now we need to list all .ts files
Collection<File> files = FileUtils.listFiles(input, new String[]{"ts"}, true);
files.stream().forEach(f -> arguments.add(f.getAbsolutePath()));

return arguments;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.wisdom.maven.utils.WatcherUtils;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -113,22 +112,12 @@ public void execute() throws MojoExecutionException {
try {
if (internalSources.isDirectory()) {
getLog().info("Compiling TypeScript files with 'tsc' from " + internalSources.getAbsolutePath());
Collection<File> files = FileUtils.listFiles(internalSources, new String[]{"ts"}, true);
for (File file : files) {
if (file.isFile()) {
process(file);
}
}
processDirectory(internalSources, destinationForInternals);
}

if (externalSources.isDirectory()) {
getLog().info("Compiling TypeScript files with 'tsc' from " + externalSources.getAbsolutePath());
Collection<File> files = FileUtils.listFiles(externalSources, new String[]{"ts"}, true);
for (File file : files) {
if (file.isFile()) {
process(file);
}
}
processDirectory(externalSources, destinationForExternals);
}
} catch (WatchingException e) {
throw new MojoExecutionException(e.getMessage(), e);
Expand Down Expand Up @@ -159,52 +148,37 @@ public boolean accept(File file) {
*/
@Override
public boolean fileCreated(File file) throws WatchingException {
process(file);
if (WatcherUtils.isInDirectory(file, internalSources)) {
processDirectory(internalSources, destinationForInternals);
} else if (WatcherUtils.isInDirectory(file, externalSources)) {
processDirectory(externalSources, destinationForExternals);
}
return true;
}

/**
* Processes the TypeScript file to create the JS file (compiled).
* Process all typescripts file from the given directory. Output files are generated in the given destination.
*
* @param input the input file
* @throws WatchingException if the file cannot be processed
* @param input the input directory
* @param destination the output directory
* @throws WatchingException if the compilation failed
*/
private void process(File input) throws WatchingException {
// We are going to process a 'ts' file using the TypeScript compiler.
// First, determine which file we must process, indeed, the file may already have been copies to the
// destination directory
File destination = getOutputFile(input, "js");

File theInput = input;

// Create the destination folder.
if (!destination.getParentFile().isDirectory()) {
getLog().debug("Creating the parent of " + destination.getAbsolutePath() + ":"
+ destination.getParentFile().mkdirs());
}

// If the destination file is more recent (or equally recent) than the input file, process that one
if (destination.isFile() && destination.lastModified() >= input.lastModified()) {
getLog().info("Processing " + destination.getAbsolutePath() + " instead of " + input.getAbsolutePath() +
" - the file was already processed");
theInput = destination;
}

private void processDirectory(File input, File destination) throws WatchingException {
// Now execute the compiler
// We compute the set of argument according to the Mojo's configuration.
try {
List<String> arguments = typescript.createTypeScriptComilerArgumentList(input, destination);
List<String> arguments = typescript.createTypeScriptCompilerArgumentList(input, destination);
getLog().info("Invoking the TypeScript compiler with " + arguments);
int exit = npm.execute(TYPE_SCRIPT_COMMAND,
arguments.toArray(new String[arguments.size()]));
getLog().debug("TypeScript Compiler execution exiting with status: " + exit);
} catch (MojoExecutionException e) {
// If the NPM execution has caught an error stream, try to create the associated watching exception.
if (!Strings.isNullOrEmpty(npm.getLastErrorStream())) {
throw build(npm.getLastErrorStream(), theInput);
throw build(npm.getLastErrorStream(), input);
} else {
throw new WatchingException(ERROR_TITLE, "Error while compiling " + theInput
.getAbsolutePath(), theInput, e);
throw new WatchingException(ERROR_TITLE, "Error while compiling " + input
.getAbsolutePath(), input, e);
}
}
}
Expand Down Expand Up @@ -247,8 +221,7 @@ private WatchingException build(String message, File source) {
*/
@Override
public boolean fileUpdated(File file) throws WatchingException {
process(file);
return true;
return fileCreated(file);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
</process-resources>
<compile>
org.wisdom-framework:wisdom-maven-plugin:compile-coffeescript,
org.wisdom-framework:wisdom-maven-plugin:compile-typescript,
org.wisdom-framework:wisdom-maven-plugin:compile-less,
org.wisdom-framework:wisdom-maven-plugin:optimize-images,
org.wisdom-framework:wisdom-maven-plugin:compile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ public void setUp() throws IOException {
mojo.buildDirectory = new File(FAKE_PROJECT_TARGET);
mojo.buildDirectory.mkdirs();

TypeScript ts = new TypeScript();
mojo.typescript = ts;
mojo.typescript = new TypeScript();

NodeManager manager = new NodeManager(log, nodeDirectory, mojo);
manager.installIfNotInstalled();
Expand All @@ -88,6 +87,43 @@ public void testProcessingOfTypeScriptFiles() throws MojoFailureException, MojoE
assertThat(map).isFile();
}

@Test
public void testProcessingOfTypeScriptWithModuleSetToCommonJS() throws MojoFailureException, MojoExecutionException, IOException {
cleanup();

// Copy math app
File dir = new File(FAKE_PROJECT, "src/main/resources/assets/math");
FileUtils.copyDirectory(new File("src/test/resources/typescript/math"), dir);

mojo.typescript.setModuleType("commonjs");
mojo.execute();

File js = new File(FAKE_PROJECT_TARGET, "classes/assets/ts/Animal.js");
File decl = new File(FAKE_PROJECT_TARGET, "classes/assets/ts/Animal.d.ts");
File map = new File(FAKE_PROJECT_TARGET, "classes/assets/ts/Animal.js.map");
assertThat(js).isFile();
assertThat(decl).isFile();
assertThat(map).isFile();


js = new File(FAKE_PROJECT_TARGET, "wisdom/assets/ts/raytracer.js");
decl = new File(FAKE_PROJECT_TARGET, "wisdom/assets/ts/raytracer.d.ts");
map = new File(FAKE_PROJECT_TARGET, "wisdom/assets/ts/raytracer.js.map");
assertThat(js).isFile();
assertThat(decl).isFile();
assertThat(map).isFile();

// Check the math app
js = new File(FAKE_PROJECT_TARGET, "classes/assets/math/demos.js");
decl = new File(FAKE_PROJECT_TARGET, "classes/assets/math/interfaces.js");
File impl = new File(FAKE_PROJECT_TARGET, "classes/assets/math/impl/math_demo.js");
assertThat(js).isFile();
assertThat(decl).doesNotExist(); // ts.d are not compiled.
assertThat(impl).isFile();

FileUtils.deleteQuietly(dir);
}

@Test
public void testProcessingOfTypeScriptFilesWithDifferentConfiguration() throws MojoFailureException,
MojoExecutionException, IOException {
Expand Down Expand Up @@ -153,14 +189,19 @@ public void testWatching() throws MojoFailureException, MojoExecutionException,
final File newAnimal = new File(FAKE_PROJECT, "src/main/resources/assets/ts/Animal2.ts");
final File originalRT = new File(FAKE_PROJECT, "src/main/assets/assets/ts/raytracer.ts");
String originalAnimalContent = FileUtils.readFileToString(originalAnimal);
FileUtils.copyFile(originalAnimal, newAnimal);
String newContent = originalAnimalContent.replace("Animal", "Animal2")
.replace("Snake", "Snake2")
.replace("Horse", "Horse2")
.replace("tom", "tom2")
.replace("sam", "sam2");
FileUtils.write(newAnimal, newContent);

mojo.execute();

final File anim = new File(FAKE_PROJECT_TARGET, "classes/assets/ts/Animal2.js");
assertThat(anim).isFile();
String content = FileUtils.readFileToString(anim);
assertThat(content).contains("var sam = new Snake(\"Sammy the Python\");");
assertThat(content).contains("var sam2 = new Snake2(\"Sammy the Python\");");

final File rt = new File(FAKE_PROJECT_TARGET, "wisdom/assets/ts/raytracer.js");
assertThat(rt).isFile();
Expand All @@ -178,12 +219,17 @@ public void testWatching() throws MojoFailureException, MojoExecutionException,

// Recreate the file with another name (same content)
File newFile = new File(FAKE_PROJECT, "src/main/resources/Animal3.ts");
FileUtils.write(newFile, originalAnimalContent);
newContent = originalAnimalContent.replace("Animal", "Animal3")
.replace("Snake", "Snake3")
.replace("Horse", "Horse3")
.replace("tom", "tom3")
.replace("sam", "sam3");
FileUtils.write(newFile, newContent);
mojo.fileCreated(newFile);
File var3 = new File(FAKE_PROJECT_TARGET, "classes/Animal3.js");
assertThat(var3).isFile();
content = FileUtils.readFileToString(var3);
assertThat(content).contains("var sam = new Snake(\"Sammy the Python\");");
assertThat(content).contains("var sam3 = new Snake3(\"Sammy the Python\");");

// Update link
long originalLastModified = rt.lastModified();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
///<reference path="./interfaces.d.ts" />

import { MathDemo } from "./impl/math_demo";

var math = new MathDemo();
console.log(math.pow(2, 2));
console.log(math.PI);
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
///<reference path="./../interfaces.d.ts" />

class MathDemo implements MathInterface{
public PI : number;

constructor() {
this.PI = 3.14159265359;
}

// used to showcase how to test a sync function
public pow(base: number, exponent: number) {
var result = base;
for(var i = 1; i < exponent; i++){
result = result * base;
}
return result;
}

// used to show case how to test async code with done()
public powAsync(base: number, exponent: number, cb : (result : number) => void) {
var result = this.pow(base, exponent);
cb(result);
}

// simulate slow > 40ms
public powAsyncSlow(base: number, exponent: number, cb : (result : number) => void) {
setTimeout(() => {
var result = this.pow(base, exponent);
cb(result);
}, 45);
}

// simulate reelly slow function > 100ms
public powAsyncReallySlow(base: number, exponent: number, cb : (result : number) => void) {
var result = base ^ exponent;
setTimeout(() => {
var result = this.pow(base, exponent);
cb(result);
}, 101);
}

// simulate too slow > 2000ms (breaks build)
public powAsyncTooSlow(base: number, exponent: number, cb : (result : number) => void) {
var result = base ^ exponent;
setTimeout(() => {
var result = this.pow(base, exponent);
cb(result);
}, 2001);
}

// used to showcase how to assert that an error is thrown
public bad(foo : any) {
if(foo == null){
throw new Error("Error!");
}
else {
//...
}
}


}

export { MathDemo };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface MathInterface {
PI : number;
pow(base: number, exponent: number);
powAsync(base: number, exponent: number, cb : (result : number) => void);
powAsyncSlow(base: number, exponent: number, cb : (result : number) => void);
powAsyncReallySlow(base: number, exponent: number, cb : (result : number) => void);
powAsyncTooSlow(base: number, exponent: number, cb : (result : number) => void);
bad(foo : any) : void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<fileSet>
<includes>
<file>coffee/*.js</file>
<file>ts/*.js</file>
</includes>
</fileSet>
<fileSet>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Animal {
constructor(public name: string) { }
move(meters: number) {
alert(this.name + " moved " + meters + "m.");
}
}

class Snake extends Animal {
constructor(name: string) { super(name); }
move() {
alert("Slithering...");
super.move(5);
}
}

class Horse extends Animal {
constructor(name: string) { super(name); }
move() {
alert("Galloping...");
super.move(45);
}
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ assertThat(output).isFile();
content = FileUtils.readFileToString(output);
assertThat(content).contains("var math;math={root:Math.sqrt")
.contains("function log(n){return Math.log(n)};")
.contains("sam")

// -- Check un-filtered extensions
output = new File(project.target(), "classes/assets/unfiltered/stuff.nf");
Expand Down
Loading

0 comments on commit 51ece68

Please sign in to comment.