diff --git a/.gitignore b/.gitignore index a9ef82c..f5827b0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ *.iml *.ipr target/ +.idea +*.iml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9032b9f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: java +jdk: +- oraclejdk7 +script: ./travis_build.sh +env: + global: + - BUILD_NUMBER=$TRAVIS_BUILD_NUMBER + - secure: UAyyiISVgcPjVXGkChjWWjeoHTFC/Zml5PfJwxoRuIsq6XgKFO4HgvETTY0p+fD85rZpYXsIHUKJWvykTJBTK7P6m81HsFNsD7rV+lJDbDId7iSTwpHiBZT8Xlhi1LbUgJZ5Ew8eP8NOjNsEuxJ6D+pKac6b/XcWa2EcA7EUpYM= + - secure: DMEAtPoyYlMCU2woZ8m0ADFU71HlmG43q2Orf463MBDWfl2GpeEi+qZiPvJR7fodBRj0yJiTJpq9Ol1vsFtAhpSNq5iFbmwOvdb73/YoVyr7kyp/MUmj6YzfHdup79zlYYtnWJWKyVQFHp9J5eqrJ+TetGLJ5ePI0Oa8j8Bvlho= +deploy: + provider: s3 + access_key_id: $AWS_ACCESS_KEY + secret_access_key: $AWS_SECRET_KEY + bucket: repo.raymanoz.com + region: eu-west-1 + endpoint: repo.raymanoz.com.s3-website-eu-west-1.amazonaws.com + skip_cleanup: true + local-dir: target/s3 + upload-dir: net/spmiller/org/lesscss/lesscss-1.3.3/$BUILD_NUMBER diff --git a/README.md b/README.md index 357913f..16c406d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ Official LESS CSS Compiler for Java =================================== +---------- +This is a fork, and is built on travis [![Build Status](https://travis-ci.org/spmiller/lesscss-java.svg?branch=master)](https://travis-ci.org/spmiller/lesscss-java) +---------- + ---------- -> Important note: +> Important note: > Due to changed interesst I'm no longer maintaining this project. Based on the frequent questions I get by e-mail and requests for updates (including pull requests) I think this project would serve it's goal to be continued. Therefore if you are interested to take over and bring this project to the next level contact me. ---------- @@ -13,13 +17,13 @@ LESS CSS Compiler for Java is a library to compile LESS sources to CSS styleshee The compiler uses Rhino, Envjs (simulated browser environment written in JavaScript), and the official LESS JavaScript compiler. Look at the simple example below to compile LESS to CSS: - + // Instantiate the LESS compiler LessCompiler lessCompiler = new LessCompiler(); - + // Compile LESS input string to CSS output string String css = lessCompiler.compile("@color: #4D926F; #header { color: @color; }"); - + // Or compile LESS input file to CSS output file lessCompiler.compile(new File("main.less"), new File("main.css")); @@ -73,7 +77,7 @@ Can be built with [Maven 2.2.x](http://maven.apache.org) (or later?) by using th or, to install into your local Maven repository: mvn install - + You may also wish to build API Documentation: mvn javadoc:javadoc diff --git a/pom.xml b/pom.xml index b81b8fd..7be8e7e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,9 +1,9 @@ 4.0.0 - org.lesscss + net.spmiller.org.lesscss lesscss - 1.3.3 + 1.3.3-${env.version} jar Official LESS CSS Compiler for Java Official LESS CSS Compiler for Java @@ -19,8 +19,13 @@ UTF-8 UTF-8 - + + + org.mozilla + rhino + 1.7R4 + commons-io commons-io @@ -30,6 +35,13 @@ commons-logging commons-logging 1.1.1 + true + + + org.apache.commons + commons-lang3 + 3.1 + test junit @@ -37,11 +49,6 @@ 4.10 test - - org.apache.commons - commons-lang3 - 3.1 - org.mockito mockito-core @@ -66,13 +73,8 @@ 0.3.0 test - - org.mozilla - rhino - 1.7R4 - - + @@ -149,7 +151,37 @@ 1.0 - + + + org.apache.maven.plugins + maven-shade-plugin + 1.7.1 + + + package + + shade + + + + + commons-logging:commons-logging + org.mozilla:rhino + + + + + org.apache.commons.io + internaldeps.org.apache.commons.io + + + true + true + deps + + + + diff --git a/src/main/java/org/lesscss/FileResolver.java b/src/main/java/org/lesscss/FileResolver.java new file mode 100644 index 0000000..2ad5096 --- /dev/null +++ b/src/main/java/org/lesscss/FileResolver.java @@ -0,0 +1,54 @@ +package org.lesscss; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; + +/** + * @author Jackstf + */ +public class FileResolver implements LessResolver { + + private final File file; + + public FileResolver(File file) { + this.file = file; + } + + public FileResolver() { + this.file = null; + } + + public boolean exists(String filename) { + return file(filename).exists(); + } + + public String resolve(String filename) throws IOException { + return FileUtils.readFileToString(file(filename)); + } + + public long getLastModified(String filename) { + return file(filename).lastModified(); + } + + public FileResolver resolveImport(String parent) { + return new FileResolver(file(parent)); + } + + private File file(String path) { + if (new File(path).isAbsolute()) { + return new File(path); + } + else if (file.getParentFile() != null) { + return new File(file.getParentFile(), path); + } + else if (file.getAbsolutePath().equals(path)) { + return file; + } + else { + return new File(path); + } + } + +} diff --git a/src/main/java/org/lesscss/LessCompiler.java b/src/main/java/org/lesscss/LessCompiler.java index 6b71866..37797d1 100644 --- a/src/main/java/org/lesscss/LessCompiler.java +++ b/src/main/java/org/lesscss/LessCompiler.java @@ -14,6 +14,12 @@ */ package org.lesscss; +import org.apache.commons.io.FileUtils; +import org.lesscss.logger.CommonsLogger; +import org.lesscss.logger.Logger; +import org.mozilla.javascript.*; +import org.mozilla.javascript.tools.shell.Global; + import java.io.File; import java.io.IOException; import java.io.InputStreamReader; @@ -21,15 +27,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Function; -import org.mozilla.javascript.JavaScriptException; -import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.ScriptableObject; -import org.mozilla.javascript.tools.shell.Global; /** * The LESS compiler to compile LESS sources to CSS stylesheets. @@ -59,9 +56,9 @@ public class LessCompiler { private static final String COMPILE_STRING = "function doIt(input, compress) { var result; var parser = new less.Parser(); parser.parse(input, function(e, tree) { if (e instanceof Object) { throw e; } ; result = tree.toCSS({compress: compress}); }); return result; }"; - - private static final Log log = LogFactory.getLog(LessCompiler.class); - + + private Logger logger; + private URL envJs = LessCompiler.class.getClassLoader().getResource("META-INF/env.rhino.js"); private URL lessJs = LessCompiler.class.getClassLoader().getResource("META-INF/less.js"); private List customJs = Collections.emptyList(); @@ -76,8 +73,13 @@ public class LessCompiler { * Constructs a new LessCompiler. */ public LessCompiler() { + logger = new CommonsLogger(this.getClass()); } - + + public LessCompiler(Logger logger) { + this.logger = logger; + } + /** * Returns the Envjs JavaScript file used by the compiler. * @@ -221,6 +223,7 @@ public synchronized void init() { global.init(cx); scope = cx.initStandardObjects(global); + scope.put("logger", scope, Context.toObject(logger, scope)); List jsUrls = new ArrayList(2 + customJs.size()); jsUrls.add(envJs); @@ -239,15 +242,13 @@ public synchronized void init() { } catch (Exception e) { String message = "Failed to initialize LESS compiler."; - log.error(message, e); + logger.error(message, e); throw new IllegalStateException(message, e); }finally{ Context.exit(); } - - if (log.isDebugEnabled()) { - log.debug("Finished initialization of LESS compiler in " + (System.currentTimeMillis() - start) + " ms."); - } + + logger.debug("Finished initialization of LESS compiler in " + (System.currentTimeMillis() - start) + " ms."); } /** @@ -268,11 +269,10 @@ public String compile(String input) throws LessException { try { Context cx = Context.enter(); Object result = doIt.call(cx, scope, null, new Object[]{input, compress}); - - if (log.isDebugEnabled()) { - log.debug("Finished compilation of LESS source in " + (System.currentTimeMillis() - start) + " ms."); - } - + + + logger.debug("Finished compilation of LESS source in " + (System.currentTimeMillis() - start) + " ms."); + return result.toString(); } catch (Exception e) { diff --git a/src/main/java/org/lesscss/LessResolver.java b/src/main/java/org/lesscss/LessResolver.java new file mode 100644 index 0000000..43cf733 --- /dev/null +++ b/src/main/java/org/lesscss/LessResolver.java @@ -0,0 +1,18 @@ +package org.lesscss; + +import java.io.IOException; + +/** + * @author Jackstf + */ +public interface LessResolver { + + boolean exists(String filename); + + String resolve(String filename) throws IOException; + + long getLastModified(String filename); + + LessResolver resolveImport(String parent); + +} diff --git a/src/main/java/org/lesscss/LessSource.java b/src/main/java/org/lesscss/LessSource.java index bbf39f4..aa57b97 100644 --- a/src/main/java/org/lesscss/LessSource.java +++ b/src/main/java/org/lesscss/LessSource.java @@ -15,6 +15,7 @@ package org.lesscss; import static java.util.regex.Pattern.MULTILINE; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -22,7 +23,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.commons.io.FileUtils; /** * Represents the metadata and content of a LESS source. @@ -36,10 +36,11 @@ public class LessSource { */ private static final Pattern IMPORT_PATTERN = Pattern.compile("^(?!\\s*//\\s*)@import\\s+(url\\()?\\s*(\"|')(.+)\\s*(\"|')(\\))?\\s*;.*$", MULTILINE); - private File file; + private String filename; private String content; private String normalizedContent; private Map imports = new LinkedHashMap(); + private LessResolver resolver; /** * Constructs a new LessSource. @@ -58,9 +59,28 @@ public LessSource(File file) throws FileNotFoundException, IOException { if (!file.exists()) { throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found."); } - this.file = file; - this.content = this.normalizedContent = FileUtils.readFileToString(file); - resolveImports(); + init(file.getAbsolutePath(), new FileResolver(file)); + } + + public LessSource(String filename) throws FileNotFoundException, IOException { + if (filename == null) { + throw new IllegalArgumentException("Filename not be null."); + } + init(filename, new FileResolver()); + } + + public LessSource(String filename, LessResolver resolver) throws FileNotFoundException, IOException { + if (filename == null) { + throw new IllegalArgumentException("Filename not be null."); + } + init(filename, resolver); + } + + public void init(String filename, LessResolver resolver) throws FileNotFoundException, IOException { + this.resolver = resolver; + this.filename = filename; + this.content = this.normalizedContent = resolver.resolve(filename); + resolveImports(); } /** @@ -69,7 +89,7 @@ public LessSource(File file) throws FileNotFoundException, IOException { * @return The absolute pathname of the LESS source. */ public String getAbsolutePath() { - return file.getAbsolutePath(); + return filename; } /** @@ -101,7 +121,7 @@ public String getNormalizedContent() { * @return A long value representing the time the file was last modified, measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970). */ public long getLastModified() { - return file.lastModified(); + return resolver.getLastModified(filename); } /** @@ -142,7 +162,7 @@ private void resolveImports() throws FileNotFoundException, IOException { importedFile = importedFile.matches(".*\\.(le?|c)ss$") ? importedFile : importedFile + ".less"; boolean css = importedFile.matches(".*css$"); if (!css) { - LessSource importedLessSource = new LessSource(new File(file.getParentFile(), importedFile)); + LessSource importedLessSource = new LessSource(importedFile, resolver.resolveImport(filename)); imports.put(importedFile, importedLessSource); normalizedContent = normalizedContent.substring(0, importMatcher.start()) + importedLessSource.getNormalizedContent() + normalizedContent.substring(importMatcher.end()); importMatcher = IMPORT_PATTERN.matcher(normalizedContent); diff --git a/src/main/java/org/lesscss/logger/CommonsLogger.java b/src/main/java/org/lesscss/logger/CommonsLogger.java new file mode 100644 index 0000000..e18b675 --- /dev/null +++ b/src/main/java/org/lesscss/logger/CommonsLogger.java @@ -0,0 +1,25 @@ +package org.lesscss.logger; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class CommonsLogger implements Logger { + + private final Log log; + + public CommonsLogger(Class loggingClass) { + log = LogFactory.getLog(loggingClass); + } + + public void debug(Object message) { + log.debug(message); + } + + public void error(Object message) { + log.error(message); + } + + public void error(Object message, Throwable exception) { + log.error(message, exception); + } +} diff --git a/src/main/java/org/lesscss/logger/LastMessageLogger.java b/src/main/java/org/lesscss/logger/LastMessageLogger.java new file mode 100644 index 0000000..a69a8ee --- /dev/null +++ b/src/main/java/org/lesscss/logger/LastMessageLogger.java @@ -0,0 +1,32 @@ +package org.lesscss.logger; + +public class LastMessageLogger implements Logger { + private String lastDebug; + private String lastError; + private Throwable lastException; + + public void debug(Object message) { + lastDebug = message.toString(); + } + + public void error(Object message) { + lastError = message.toString(); + } + + public void error(Object message, Throwable exception) { + error(message); + lastException = exception; + } + + public String lastDebug() { + return lastDebug; + } + + public String lastError() { + return lastError; + } + + public Throwable lastException() { + return lastException; + } +} diff --git a/src/main/java/org/lesscss/logger/Logger.java b/src/main/java/org/lesscss/logger/Logger.java new file mode 100644 index 0000000..2a88702 --- /dev/null +++ b/src/main/java/org/lesscss/logger/Logger.java @@ -0,0 +1,7 @@ +package org.lesscss.logger; + +public interface Logger { + void debug(Object message); + void error(Object message); + void error(Object message, Throwable exception); +} diff --git a/src/main/java/org/lesscss/logger/StdLogger.java b/src/main/java/org/lesscss/logger/StdLogger.java new file mode 100644 index 0000000..0d8f24f --- /dev/null +++ b/src/main/java/org/lesscss/logger/StdLogger.java @@ -0,0 +1,15 @@ +package org.lesscss.logger; + +public class StdLogger implements Logger { + public void debug(Object message) { + System.out.println(message.toString()); + } + + public void error(Object message) { + System.err.println(message.toString()); + } + + public void error(Object message, Throwable exception) { + System.err.println(String.format("%s: %s", message, exception)); + } +} diff --git a/src/main/resources/META-INF/env.rhino.js b/src/main/resources/META-INF/env.rhino.js index 47ea2ee..0abe93a 100644 --- a/src/main/resources/META-INF/env.rhino.js +++ b/src/main/resources/META-INF/env.rhino.js @@ -1,6 +1,6 @@ -// Override the print function so that the messages go to commons logging +// Override the print function so that the messages go to the configured logger print = function(message) { - Packages.org.apache.commons.logging.LogFactory.getLog('rhino').debug(message); + logger.debug(message); }; /* diff --git a/src/test/java/org/lesscss/LessCompilerTest.java b/src/test/java/org/lesscss/LessCompilerTest.java index d5fd8cb..7e5a7c2 100644 --- a/src/test/java/org/lesscss/LessCompilerTest.java +++ b/src/test/java/org/lesscss/LessCompilerTest.java @@ -14,8 +14,7 @@ */ package org.lesscss; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.mockStatic; @@ -38,6 +37,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.lesscss.logger.LastMessageLogger; +import org.lesscss.logger.Logger; import org.mockito.Mock; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; @@ -59,7 +60,7 @@ public class LessCompilerTest { private LessCompiler lessCompiler; - @Mock private Log log; + private LastMessageLogger logger = new LastMessageLogger(); @Mock private Context cx; @Mock private Global global; @@ -87,10 +88,7 @@ public class LessCompilerTest { @Before public void setUp() throws Exception { - lessCompiler = new LessCompiler(); - - when(log.isDebugEnabled()).thenReturn(false); - FieldUtils.writeField(lessCompiler, "log", log, true); + lessCompiler = new LessCompiler(logger); } @Test @@ -201,7 +199,7 @@ public void testInitThrowsIllegalStateExceptionWhenNotAbleToInitilize() throws E verify(envJsFile).openConnection(); - verify(log).error(anyString()); + assertNotNull(logger.lastError()); } @Test diff --git a/src/test/java/org/lesscss/LessSourceTest.java b/src/test/java/org/lesscss/LessSourceTest.java index bd1ae18..e522565 100644 --- a/src/test/java/org/lesscss/LessSourceTest.java +++ b/src/test/java/org/lesscss/LessSourceTest.java @@ -18,11 +18,13 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.verifyStatic; import static org.powermock.api.mockito.PowerMockito.when; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; + import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Before; @@ -33,8 +35,6 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.lesscss.LessSource; - @PrepareForTest({FileUtils.class, LessSource.class}) @RunWith(PowerMockRunner.class) public class LessSourceTest { @@ -78,7 +78,7 @@ public void testNewLessSourceWithoutImports() throws Exception { @Test(expected = IllegalArgumentException.class) public void testNewLessSourceFileNull() throws Exception { - lessSource = new LessSource(null); + lessSource = new LessSource((File) null); } @Test(expected = FileNotFoundException.class) diff --git a/travis_build.sh b/travis_build.sh new file mode 100755 index 0000000..fb6e3a3 --- /dev/null +++ b/travis_build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +function moan(){ + echo -e "$1" 1>&2 + exit 1 +} + +cd "$( dirname "$0" )" + +export version=${BUILD_NUMBER:-'dev.build'} +mvn clean package + +function prepare_for_publish() { + cd target + mkdir s3 + cp *.jar s3 +} + +prepare_for_publish || moan 'Failed to prepare_for_publish' \ No newline at end of file