Skip to content

Commit

Permalink
assets bugs
Browse files Browse the repository at this point in the history
* dont fail when asset pipeline is empty fix #392
* closure compiler attempt to process .css files (not .js) fix #391
* assets maven plugin is broken fix #390
  • Loading branch information
jknack committed Jun 2, 2016
1 parent eb6f668 commit 5216c44
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public class ClosureCompiler extends AssetProcessor {

@Override
public boolean matches(final MediaType type) {
return MediaType.css.matches(type);
return MediaType.js.matches(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.FileNotFoundException;
import java.util.Arrays;

import org.jooby.MediaType;
import org.junit.Test;

import com.typesafe.config.ConfigFactory;
Expand Down Expand Up @@ -69,4 +70,9 @@ public void error() throws Exception {
ConfigFactory.empty()));
}

@Test
public void ctype() throws Exception {
assertEquals(true, new ClosureCompiler().matches(MediaType.js));
}

}
41 changes: 27 additions & 14 deletions jooby-assets/src/main/java/org/jooby/assets/AssetCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,32 +147,35 @@ public List<String> styles(final String name) {
public List<AssetProcessor> pipeline(final String dist) {
List<AssetProcessor> chain = this.pipeline.get(dist);
if (chain == null) {
throw new IllegalArgumentException("No pipeline for: " + dist);
log.debug("no pipeline for: {}", dist);
return Collections.emptyList();
}
return chain;
}

public Map<String, List<File>> build(final String dist, final File dir) throws Exception {
Map<String, List<File>> output = new LinkedHashMap<>();
List<AssetProcessor> pipeline = pipeline(dist);
log.info("{} pipeline: {}", dist, pipeline);
for (String fset : keySet()) {
List<String> files = assets(fset);

log.info("compiling {}: ", fset);
log.info("compiling {}:", fset);

String css = compile(dist, files.stream().filter(styles).iterator(), MediaType.css, "");
String css = compile(pipeline, files.stream().filter(styles).iterator(), MediaType.css, "");
Path pcss = Paths.get(patterns(styles).findFirst().get(), fset + "." + sha1(css) + ".css");
File fcss = dir.toPath().resolve(pcss).toFile();
fcss.getParentFile().mkdirs();
Files.write(css, fcss, charset);

String js = compile(dist, files.stream().filter(scripts).iterator(), MediaType.js, ";");
String js = compile(pipeline, files.stream().filter(scripts).iterator(), MediaType.js, ";");
Path pjs = Paths.get(patterns(scripts).findFirst().get(), fset + "." + sha1(js) + ".js");
File fjs = dir.toPath().resolve(pjs).toFile();
fjs.getParentFile().mkdirs();
Files.write(js, fjs, charset);

log.info("{}", fcss);
log.info("{}", fjs);
log.info("{}.css {} ({})", fset, humanReadableByteCount(fcss.length()), fcss);
log.info("{}.js {} ({})", fset, humanReadableByteCount(fjs.length()), fjs);

output.put(fset, Arrays.asList(fcss, fjs));
}
Expand All @@ -196,7 +199,8 @@ public Asset build(final Asset asset) throws Exception {
return asset;
}

String output = compile("dev", filename, type, toString(asset.stream(), charset));
List<AssetProcessor> pipeline = pipeline("dev");
String output = compile(pipeline, filename, type, toString(asset.stream(), charset));

return new InMemoryAsset(asset, output.getBytes(charset));
}
Expand All @@ -214,22 +218,21 @@ private Stream<String> patterns(final Predicate<String> filter) {

}

private String compile(final String env, final Iterator<String> files, final MediaType type,
final String sep)
throws Exception {
private String compile(final List<AssetProcessor> pipeline, final Iterator<String> files,
final MediaType type, final String sep) throws Exception {
StringBuilder buff = new StringBuilder();
while (files.hasNext()) {
String file = files.next();
log.info(" {}", file);
buff.append(compile(env, file, type, readFile(loader, file, charset))).append(sep);
buff.append(compile(pipeline, file, type, readFile(loader, file, charset))).append(sep);
}
return buff.toString();
}

private String compile(final String env, final String filename, final MediaType type,
final String input) throws Exception {
private String compile(final List<AssetProcessor> pipeline, final String filename,
final MediaType type, final String input) throws Exception {

Iterator<AssetProcessor> it = pipeline(env).iterator();
Iterator<AssetProcessor> it = pipeline.iterator();
String contents = input;
while (it.hasNext()) {
AssetProcessor processor = it.next();
Expand Down Expand Up @@ -430,4 +433,14 @@ private static String spath(final String path) {
return path.startsWith("/") ? path : "/" + path;
}

private static String humanReadableByteCount(final long bytes) {
int unit = 1024;
if (bytes < unit) {
return bytes + "b";
}
int exp = (int) (Math.log(bytes) / Math.log(unit));
char pre = "kmgtpe".charAt(exp - 1);
return String.format("%.1f%sb", bytes / Math.pow(unit, exp), pre);
}

}
4 changes: 3 additions & 1 deletion jooby-assets/src/main/java/org/jooby/assets/Assets.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.jooby.assets;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

import org.jooby.Env;
import org.jooby.Jooby;
Expand Down Expand Up @@ -269,7 +270,8 @@ public void configure(final Env env, final Config config, final Binder binder) {
.lastModified(conf.getBoolean("assets.lastModified"));

if (conf.hasPath("assets.cache.maxAge")) {
handler.maxAge(Duration.parse(conf.getString("assets.cache.maxAge")));
handler.maxAge(Duration
.ofSeconds(conf.getDuration("assets.cache.maxAge", TimeUnit.SECONDS)));
}

compiler.patterns().forEach(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -176,12 +176,8 @@ public void pipeline() throws Exception {
assertEquals("foo", prod.iterator().next().get("foo"));
assertEquals("bar", prod.iterator().next().get("bar"));

try {
compiler.pipeline("prod");
fail("no pipeline");
} catch (IllegalArgumentException ex) {

}
List<AssetProcessor> pipeline = compiler.pipeline("prod");
assertEquals(Collections.emptyList(), pipeline);
}

private String compile(final AssetCompiler compiler, final String path) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public void configuredist() throws Exception {
.withValue("assets.etag", ConfigValueFactory.fromAnyRef(true))
.withValue("application.path", ConfigValueFactory.fromAnyRef("/"))
.withValue("assets.cdn", ConfigValueFactory.fromAnyRef(""))
.withValue("assets.cache.maxAge", ConfigValueFactory.fromAnyRef("P365D"))
.withValue("assets.cache.maxAge", ConfigValueFactory.fromAnyRef("365d"))
.withValue("assets.lastModified", ConfigValueFactory.fromAnyRef(true))
.withValue("assets.watch", ConfigValueFactory.fromAnyRef(false));
new MockUnit(Env.class, Config.class, Binder.class, Request.class, Response.class,
Expand Down
11 changes: 10 additions & 1 deletion jooby-assets/src/test/java/org/jooby/assets/Issue229.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package org.jooby.assets;

import static org.junit.Assert.assertEquals;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import com.google.common.collect.Sets;
import com.typesafe.config.ConfigFactory;

public class Issue229 {

@Test
public void wrongVars() throws Exception {
AssetCompiler compiler = new AssetCompiler(ConfigFactory.parseResources("issue.229.conf"));
Set<String> vars = new HashSet<>();
compiler.keySet().forEach(asset -> {
System.out.println(asset);
vars.add(asset);
});

assertEquals(Sets.newHashSet("form", "base"), vars);
}
}
16 changes: 10 additions & 6 deletions jooby-maven-plugin/src/main/java/org/jooby/AssetMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

@Mojo(name = "assets", requiresDependencyResolution = ResolutionScope.TEST,
defaultPhase = LifecyclePhase.PREPARE_PACKAGE)
@Execute(phase = LifecyclePhase.PREPARE_PACKAGE)
@Mojo(name = "assets", defaultPhase = LifecyclePhase.COMPILE,
requiresDependencyResolution = ResolutionScope.TEST)
@Execute(phase = LifecyclePhase.COMPILE)
public class AssetMojo extends AbstractMojo {

@SuppressWarnings("serial")
Expand Down Expand Up @@ -78,9 +78,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
System.setProperty("application.env", env);

new JoobyRunner(mavenProject)
.run(mainClass, (app, loader) -> {
app.on("*", compile(loader));
});
.run(mainClass, app -> {
app.on("*", compile(app.getClass().getClassLoader()));
});
} catch (CompilationDone ex) {
long end = System.currentTimeMillis();
getLog().info("compilation took " + (end - start) + "ms");
Expand All @@ -94,9 +94,13 @@ private Consumer<Config> compile(final ClassLoader loader) {
try {
output.mkdirs();

getLog().debug("claspath: " + loader);

Config assetConf = ConfigFactory.parseResources(loader, "assets.conf")
.withFallback(conf);

getLog().debug("assets.conf: " + assetConf.getConfig("assets"));

AssetCompiler compiler = new AssetCompiler(loader, assetConf);

Map<String, List<File>> fileset = compiler.build(env, output);
Expand Down
11 changes: 10 additions & 1 deletion jooby-maven-plugin/src/main/java/org/jooby/Classpath.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,16 @@ public List<URL> build() throws MalformedURLException {
}

public URLClassLoader toClassLoader() throws MalformedURLException {
return new URLClassLoader(build().toArray(new URL[0]), getClass().getClassLoader());
return toClassLoader(build(), getClass().getClassLoader());
}

private static URLClassLoader toClassLoader(final List<URL> cp, final ClassLoader parent) {
return new URLClassLoader(cp.toArray(new URL[cp.size()]), parent) {
@Override
public String toString() {
return cp.toString();
}
};
}

private List<URL> jars(final Iterable<Artifact> artifacts) throws MalformedURLException {
Expand Down
18 changes: 6 additions & 12 deletions jooby-maven-plugin/src/main/java/org/jooby/JoobyRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

import java.net.URLClassLoader;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import org.apache.maven.project.MavenProject;
Expand All @@ -56,19 +55,14 @@ public JoobyRunner with(final Consumer<List<Route.Definition>> callback) {

public void run(final String mainClass, final Consumer<Jooby> callback)
throws Throwable {
run(mainClass, (app, loader) -> callback.accept(app));
}

public void run(final String mainClass, final BiConsumer<Jooby, ClassLoader> callback)
throws Throwable {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try (URLClassLoader apploader = cp.toClassLoader()) {
Thread.currentThread().setContextClassLoader(apploader);
Jooby app = (Jooby) apploader.loadClass(mainClass).newInstance();
callback.accept(app, loader);
ClassLoader global = Thread.currentThread().getContextClassLoader();
try (URLClassLoader local = cp.toClassLoader()) {
Thread.currentThread().setContextClassLoader(local);
Jooby app = (Jooby) local.loadClass(mainClass).newInstance();
callback.accept(app);
app.start(routes);
} finally {
Thread.currentThread().setContextClassLoader(loader);
Thread.currentThread().setContextClassLoader(global);
}
}

Expand Down
18 changes: 18 additions & 0 deletions jooby-mongodb-rx/src/main/java/org/jooby/mongodb/MongoRx.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.jooby.mongodb;

import static java.util.Objects.requireNonNull;
Expand Down
4 changes: 2 additions & 2 deletions jooby/src/main/resources/org/jooby/jooby.conf
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ assets {

charset = ${application.charset}

# Either null or a string in the ISO 8601 format according to `java.time.Duration.parse(CharSequence)`.
cache.maxAge = null
# -1 to disable or HOCON duration value
cache.maxAge = -1

}

Expand Down

0 comments on commit 5216c44

Please sign in to comment.