From 5a9551b1577d8ea7acd9fb066eb2f5d13c382f6d Mon Sep 17 00:00:00 2001 From: roland Date: Wed, 16 Jan 2013 15:37:22 +0100 Subject: [PATCH 1/8] Concatenate less-files into a single file before compile to css. --- src/it/concatenate/invoker.properties | 1 + src/it/concatenate/pom.xml | 26 +++++++++++++++++++ src/it/concatenate/src/main/less/test.less | 8 ++++++ .../concatenate/src/main/less/variables.less | 2 ++ src/it/concatenate/verify.groovy | 3 +++ 5 files changed, 40 insertions(+) create mode 100644 src/it/concatenate/invoker.properties create mode 100644 src/it/concatenate/pom.xml create mode 100644 src/it/concatenate/src/main/less/test.less create mode 100644 src/it/concatenate/src/main/less/variables.less create mode 100644 src/it/concatenate/verify.groovy diff --git a/src/it/concatenate/invoker.properties b/src/it/concatenate/invoker.properties new file mode 100644 index 0000000..9651b16 --- /dev/null +++ b/src/it/concatenate/invoker.properties @@ -0,0 +1 @@ +invoker.goals = clean compile \ No newline at end of file diff --git a/src/it/concatenate/pom.xml b/src/it/concatenate/pom.xml new file mode 100644 index 0000000..4b1121e --- /dev/null +++ b/src/it/concatenate/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + se.javalia.lesscss + concatenate + 0.0.1-SNAPSHOT + + + + org.lesscss + lesscss-maven-plugin + 1.3.2-SNAPSHOT + + true + + + + + compile + + + + + + + \ No newline at end of file diff --git a/src/it/concatenate/src/main/less/test.less b/src/it/concatenate/src/main/less/test.less new file mode 100644 index 0000000..00ee14c --- /dev/null +++ b/src/it/concatenate/src/main/less/test.less @@ -0,0 +1,8 @@ + + +#header { + color: @color; +} +h2 { + color: @color; +} \ No newline at end of file diff --git a/src/it/concatenate/src/main/less/variables.less b/src/it/concatenate/src/main/less/variables.less new file mode 100644 index 0000000..76d634e --- /dev/null +++ b/src/it/concatenate/src/main/less/variables.less @@ -0,0 +1,2 @@ +@color: #4d926f; + diff --git a/src/it/concatenate/verify.groovy b/src/it/concatenate/verify.groovy new file mode 100644 index 0000000..bcb6df2 --- /dev/null +++ b/src/it/concatenate/verify.groovy @@ -0,0 +1,3 @@ +assert new File(basedir, "target/less.css").exists() +assert !new File(basedir, "target/test.css").exists() +assert !new File(basedir, "target/variables.css").exists() From 2c7dbd5e765c56a9575495be52d3329b57de69db Mon Sep 17 00:00:00 2001 From: roland Date: Wed, 16 Jan 2013 15:41:15 +0100 Subject: [PATCH 2/8] Concatenate files into a single less-file before compiling to css. --- .gitignore | 1 + pom.xml | 2 +- .../java/org/lesscss/mojo/CompileMojo.java | 87 +++++++++++++++---- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 65cca15..10c3d9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/src/it/concatenate/src/main/less/less.less .classpath .project diff --git a/pom.xml b/pom.xml index 1292c4a..5bb7e1e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.lesscss lesscss-maven-plugin - 1.3.1-SNAPSHOT + 1.3.2-SNAPSHOT maven-plugin Official LESS CSS Maven Plugin Official LESS CSS Maven Plugin diff --git a/src/main/java/org/lesscss/mojo/CompileMojo.java b/src/main/java/org/lesscss/mojo/CompileMojo.java index 9f8d495..316fa2c 100644 --- a/src/main/java/org/lesscss/mojo/CompileMojo.java +++ b/src/main/java/org/lesscss/mojo/CompileMojo.java @@ -19,6 +19,8 @@ import java.net.MalformedURLException; import java.util.Arrays; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.util.StringUtils; import org.lesscss.LessCompiler; @@ -38,32 +40,46 @@ public class CompileMojo extends AbstractLessCssMojo { /** * The directory for compiled CSS stylesheets. * - * @parameter expression="${lesscss.outputDirectory}" default-value="${project.build.directory}" + * @parameter expression="${lesscss.outputDirectory}" + * default-value="${project.build.directory}" * @required */ private File outputDirectory; /** - * When true the LESS compiler will compress the CSS stylesheets. + * When true the LESS compiler will compress the CSS + * stylesheets. * * @parameter expression="${lesscss.compress}" default-value="false" */ private boolean compress; /** - * The character encoding the LESS compiler will use for writing the CSS stylesheets. + * The character encoding the LESS compiler will use for writing the CSS + * stylesheets. * - * @parameter expression="${lesscss.encoding}" default-value="${project.build.sourceEncoding}" + * @parameter expression="${lesscss.encoding}" + * default-value="${project.build.sourceEncoding}" */ private String encoding; /** - * When true forces the LESS compiler to always compile the LESS sources. By default LESS sources are only compiled when modified (including imports) or the CSS stylesheet does not exists. + * When true forces the LESS compiler to always compile the + * LESS sources. By default LESS sources are only compiled when modified + * (including imports) or the CSS stylesheet does not exists. * * @parameter expression="${lesscss.force}" default-value="false" */ private boolean force; + /** + * When true Concatenates the less-files into a single file + * before compile to CSS. + * + * @parameter expression="${lesscss.concatenate}" default-value="false" + */ + private boolean concatenate; + /** * The location of the LESS JavasSript file. * @@ -88,10 +104,30 @@ public void execute() throws MojoExecutionException { getLog().debug("excludes = " + Arrays.toString(excludes)); getLog().debug("force = " + force); getLog().debug("lessJs = " + lessJs); + getLog().debug("concatenate = " + concatenate); } String[] files = getIncludedFiles(); + if (concatenate) { + try { + + String tmpPath = "less.less"; + File tmpFile = new File(sourceDirectory, tmpPath); + tmpFile.delete(); + System.out.println(tmpFile.getAbsolutePath()); + for (String path : files) { + File original = new File(sourceDirectory, path); + System.out.println(original.getAbsolutePath()); + String content = FileUtils.readFileToString(original); + FileUtils.write(tmpFile, content, true); + } + files = new String[] { tmpPath }; + } catch (IOException ioe) { + getLog().error("Error concatenating files", ioe); + } + } + if (files == null || files.length < 1) { getLog().info("Nothing to compile - no LESS sources found"); } else { @@ -108,7 +144,8 @@ public void execute() throws MojoExecutionException { lessCompiler.setLessJs(lessJs.toURI().toURL()); } catch (MalformedURLException e) { throw new MojoExecutionException( - "Error while loading LESS JavaScript: " + lessJs.getAbsolutePath(), e); + "Error while loading LESS JavaScript: " + + lessJs.getAbsolutePath(), e); } } @@ -117,37 +154,51 @@ public void execute() throws MojoExecutionException { buildContext.removeMessages(input); - File output = new File(outputDirectory, file.replace(".less", ".css")); + File output = new File(outputDirectory, file.replace(".less", + ".css")); - if (!output.getParentFile().exists() && !output.getParentFile().mkdirs()) { - throw new MojoExecutionException("Cannot create output directory " + output.getParentFile()); + if (!output.getParentFile().exists() + && !output.getParentFile().mkdirs()) { + throw new MojoExecutionException( + "Cannot create output directory " + + output.getParentFile()); } try { LessSource lessSource = new LessSource(input); - if (output.lastModified() < lessSource.getLastModifiedIncludingImports()) { + if (output.lastModified() < lessSource + .getLastModifiedIncludingImports()) { getLog().info("Compiling LESS source: " + file + "..."); lessCompiler.compile(lessSource, output, force); buildContext.refresh(output); - } - else { - getLog().info("Bypassing LESS source: " + file + " (not modified)"); + } else { + getLog().info( + "Bypassing LESS source: " + file + + " (not modified)"); } } catch (IOException e) { - buildContext.addMessage(input, 0, 0, "Error compiling LESS source", BuildContext.SEVERITY_ERROR, e); - throw new MojoExecutionException("Error while compiling LESS source: " + file, e); + buildContext.addMessage(input, 0, 0, + "Error compiling LESS source", + BuildContext.SEVERITY_ERROR, e); + throw new MojoExecutionException( + "Error while compiling LESS source: " + file, e); } catch (LessException e) { String message = e.getMessage(); if (StringUtils.isEmpty(message)) { message = "Error compiling LESS source"; } - buildContext.addMessage(input, 0, 0, "Error compiling LESS source", BuildContext.SEVERITY_ERROR, e); - throw new MojoExecutionException("Error while compiling LESS source: " + file, e); + buildContext.addMessage(input, 0, 0, + "Error compiling LESS source", + BuildContext.SEVERITY_ERROR, e); + throw new MojoExecutionException( + "Error while compiling LESS source: " + file, e); } } - getLog().info("Compilation finished in " + (System.currentTimeMillis() - start) + " ms"); + getLog().info( + "Compilation finished in " + + (System.currentTimeMillis() - start) + " ms"); } } } From ebe777b236ff598f3e125040d06e12ef75755ad7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jan 2013 09:38:04 +0000 Subject: [PATCH 3/8] Updated readme to include configuration option concatenate --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 348bda5..4abf6b7 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ All configuration options + force (boolean) - When true forces the LESS compiler to always compile the LESS sources. By default LESS sources are only compiled when modified (including imports) or the CSS stylesheet does not exists. Default value is: false. + includes (String[]) - List of files to include. Specified as fileset patterns which are relative to the source directory. Default value is: { "**\/*.less" } + lessJs (String) - The location of the LESS JavasSript file. ++ concatenate (boolean) - When true all less-files will be concatenated into a single file before compiling to css List sources From 4d1e8864b2687849d2b62ef7f7c580f1d2914ac9 Mon Sep 17 00:00:00 2001 From: Roland Heimdahl Date: Thu, 17 Jan 2013 11:48:11 +0000 Subject: [PATCH 4/8] Manually merged the watchmode-pullrequest from the original project --- README.md | 3 +- pom.xml | 2 +- .../java/org/lesscss/mojo/CompileMojo.java | 128 ++++---- .../lesscss/mojo/CompileOnChangeMojoTest.java | 110 +++++++ src/test/resources/less/1/reset.less | 134 +++++++++ src/test/resources/less/2/21/variables.less | 282 ++++++++++++++++++ src/test/resources/less/bootstrap.less | 20 ++ src/test/resources/pom.xml | 32 ++ 8 files changed, 659 insertions(+), 52 deletions(-) create mode 100644 src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java create mode 100644 src/test/resources/less/1/reset.less create mode 100644 src/test/resources/less/2/21/variables.less create mode 100644 src/test/resources/less/bootstrap.less create mode 100644 src/test/resources/pom.xml diff --git a/README.md b/README.md index 4abf6b7..5a7274f 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ All configuration options + includes (String[]) - List of files to include. Specified as fileset patterns which are relative to the source directory. Default value is: { "**\/*.less" } + lessJs (String) - The location of the LESS JavasSript file. + concatenate (boolean) - When true all less-files will be concatenated into a single file before compiling to css - +++ watch (boolean) - When true the plugin watches the sourceDirectory and recompiles the included files after they changed. Instead of configuring it in the pom you can use that option at the command line like this "mvn lesscss:compile -Dlesscss.watch=true". Then it doesn't interfere with other maven lifecycle phases and you can just kill the watch process e.g. with crtl-c. Default value is: false. +++ watchInterval (int) - The interval in milliseconds the plugin waits between the check for file changes. Default value is: 1000 ms. List sources ------------ diff --git a/pom.xml b/pom.xml index 5bb7e1e..78adee6 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ org.apache.maven.plugin-testing maven-plugin-testing-harness - 1.2 + 1.3 test diff --git a/src/main/java/org/lesscss/mojo/CompileMojo.java b/src/main/java/org/lesscss/mojo/CompileMojo.java index 316fa2c..d936ba7 100644 --- a/src/main/java/org/lesscss/mojo/CompileMojo.java +++ b/src/main/java/org/lesscss/mojo/CompileMojo.java @@ -20,7 +20,6 @@ import java.util.Arrays; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.util.StringUtils; import org.lesscss.LessCompiler; @@ -44,7 +43,7 @@ public class CompileMojo extends AbstractLessCssMojo { * default-value="${project.build.directory}" * @required */ - private File outputDirectory; + protected File outputDirectory; /** * When true the LESS compiler will compress the CSS @@ -54,6 +53,20 @@ public class CompileMojo extends AbstractLessCssMojo { */ private boolean compress; + /** + * When true the plugin will watch for changes in LESS files and compile if it detects one. + * + * @parameter expression="${lesscss.watch}" default-value="false" + */ + protected boolean watch = false; + + /** + * When true the plugin will watch for changes in LESS files and compile if it detects one. + * + * @parameter expression="${lesscss.watchInterval}" default-value="1000" + */ + private int watchInterval = 1000; + /** * The character encoding the LESS compiler will use for writing the CSS * stylesheets. @@ -105,6 +118,8 @@ public void execute() throws MojoExecutionException { getLog().debug("force = " + force); getLog().debug("lessJs = " + lessJs); getLog().debug("concatenate = " + concatenate); + getLog().debug("watch = " + watch); + getLog().debug("watchInterval = " + watchInterval); } String[] files = getIncludedFiles(); @@ -112,7 +127,7 @@ public void execute() throws MojoExecutionException { if (concatenate) { try { - String tmpPath = "less.less"; + String tmpPath = "less.less"; File tmpFile = new File(sourceDirectory, tmpPath); tmpFile.delete(); System.out.println(tmpFile.getAbsolutePath()); @@ -143,62 +158,75 @@ public void execute() throws MojoExecutionException { try { lessCompiler.setLessJs(lessJs.toURI().toURL()); } catch (MalformedURLException e) { - throw new MojoExecutionException( - "Error while loading LESS JavaScript: " - + lessJs.getAbsolutePath(), e); + throw new MojoExecutionException("Error while loading LESS JavaScript: " + + lessJs.getAbsolutePath(), e); } } - - for (String file : files) { - File input = new File(sourceDirectory, file); - - buildContext.removeMessages(input); - - File output = new File(outputDirectory, file.replace(".less", - ".css")); - - if (!output.getParentFile().exists() - && !output.getParentFile().mkdirs()) { - throw new MojoExecutionException( - "Cannot create output directory " - + output.getParentFile()); + if (watch) { + getLog().info("Watching " + outputDirectory); + if (force) { + force = false; + getLog().info("Disabled the 'force' flag in watch mode."); } - - try { - LessSource lessSource = new LessSource(input); - - if (output.lastModified() < lessSource - .getLastModifiedIncludingImports()) { - getLog().info("Compiling LESS source: " + file + "..."); - lessCompiler.compile(lessSource, output, force); - buildContext.refresh(output); - } else { - getLog().info( - "Bypassing LESS source: " + file - + " (not modified)"); - } - } catch (IOException e) { - buildContext.addMessage(input, 0, 0, - "Error compiling LESS source", - BuildContext.SEVERITY_ERROR, e); - throw new MojoExecutionException( - "Error while compiling LESS source: " + file, e); - } catch (LessException e) { - String message = e.getMessage(); - if (StringUtils.isEmpty(message)) { - message = "Error compiling LESS source"; + Thread.currentThread().setPriority(Thread.MIN_PRIORITY); + while (watch && !Thread.currentThread().isInterrupted()) { + compileIfChanged(files, lessCompiler); + try { + Thread.sleep(watchInterval); + } catch (InterruptedException e) { + System.out.println("interrupted"); } - buildContext.addMessage(input, 0, 0, - "Error compiling LESS source", - BuildContext.SEVERITY_ERROR, e); - throw new MojoExecutionException( - "Error while compiling LESS source: " + file, e); } + } else { + compileIfChanged(files, lessCompiler); } getLog().info( - "Compilation finished in " + "Complete Less compile job finished in " + (System.currentTimeMillis() - start) + " ms"); } } + + private void compileIfChanged(String[] files, LessCompiler lessCompiler) + throws MojoExecutionException { + for (String file : files) { + File input = new File(sourceDirectory, file); + + buildContext.removeMessages(input); + + File output = new File(outputDirectory, file.replace(".less", ".css")); + + if (!output.getParentFile().exists() && !output.getParentFile().mkdirs()) { + throw new MojoExecutionException("Cannot create output directory " + + output.getParentFile()); + } + + try { + LessSource lessSource = new LessSource(input); + if (output.lastModified() < lessSource.getLastModifiedIncludingImports()) { + long compilationStarted = System.currentTimeMillis(); + getLog().info("Compiling LESS source: " + file + "..."); + lessCompiler.compile(lessSource, output, force); + buildContext.refresh(output); + getLog().info( + "Finished compilation to " + outputDirectory + " in " + + (System.currentTimeMillis() - compilationStarted) + " ms"); + } else if (!watch) { + getLog().info("Bypassing LESS source: " + file + " (not modified)"); + } + } catch (IOException e) { + buildContext.addMessage(input, 0, 0, "Error compiling LESS source", + BuildContext.SEVERITY_ERROR, e); + throw new MojoExecutionException("Error while compiling LESS source: " + file, e); + } catch (LessException e) { + String message = e.getMessage(); + if (StringUtils.isEmpty(message)) { + message = "Error compiling LESS source"; + } + buildContext.addMessage(input, 0, 0, "Error compiling LESS source", + BuildContext.SEVERITY_ERROR, e); + throw new MojoExecutionException("Error while compiling LESS source: " + file, e); + } + } + } } diff --git a/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java b/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java new file mode 100644 index 0000000..2b8b76c --- /dev/null +++ b/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java @@ -0,0 +1,110 @@ +package org.lesscss.mojo; + +import java.io.File; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** +* Tests the watch mode of the CompileMojo. +*/ +public class CompileOnChangeMojoTest extends AbstractMojoTestCase { + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + /** {@inheritDoc} */ + protected void setUp() throws Exception { + // required + super.setUp(); + } + + /** {@inheritDoc} */ + protected void tearDown() throws Exception { + // required + super.tearDown(); + } + + /** + * @throws Exception + * This test touches two files and checks if the bootstrap.css + * file has been recompiled after every touch. + */ + @Test + public void testIfFileChangeCausesRecompilation() throws Exception { + File pom = getTestFile("src/test/resources/pom.xml"); + assertNotNull(pom); + assertTrue(pom.exists()); + final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); + assertNotNull(compileMojo); + + File generatedFile = new File(compileMojo.outputDirectory, "bootstrap.css"); + long oldLastModified = generatedFile.lastModified(); + + compileMojo.outputDirectory = tempFolder.newFolder(); + + /* + * Run the watching compileMojo in a new thread. This way we can test + * recompilation and stop the watching mode asynchronous in this thread. + */ + Thread watchThread = new Thread() { + public void run() { + try { + compileMojo.execute(); + } catch (MojoExecutionException e) { + assertTrue(e.getLongMessage(), true); + } + } + }; + watchThread.start(); + + touchFile(compileMojo, "bootstrap.less"); + long newLastModified = checkIfFileHasBeenChanged(compileMojo, oldLastModified); + + touchFile(compileMojo, "1/reset.less"); + newLastModified = checkIfFileHasBeenChanged(compileMojo, newLastModified); + + touchFile(compileMojo, "2/21/variables.less"); + checkIfFileHasBeenChanged(compileMojo, newLastModified); + watchThread.interrupt(); + } + + private long checkIfFileHasBeenChanged(final CompileMojo compileMojo, long lastModified) + throws InterruptedException { + long newLastModified = lastModified; + long oldLastModified = lastModified; + + File generatedFile = null; + long startMillies = System.currentTimeMillis(); + long currentMillies = startMillies; + // check for a maximum of ten seconds if the file has been changed + while (oldLastModified >= newLastModified && ((currentMillies - startMillies) < 10000)) { + Thread.sleep(200); // wait for 0.2 seconds + generatedFile = new File(compileMojo.outputDirectory, "bootstrap.css"); + newLastModified = generatedFile.lastModified(); + currentMillies = System.currentTimeMillis(); + } + assertTrue("No recompilation has been done within " + (currentMillies - startMillies) + + " ms.", newLastModified > oldLastModified); + return newLastModified; + } + + private long touchFile(final CompileMojo compileMojo, String file2Touch) + throws InterruptedException { + File lessFile = new File(compileMojo.sourceDirectory, file2Touch); + + /* + * The last modified value might be rounded down on a second by the + * platform. This way the last compilation and the touch may end up with + * the same millis avoiding the compilation. To prevent that the thread + * has to sleep a second. + */ + Thread.sleep(1000); + long currentMillies = System.currentTimeMillis(); + // touch the less file + lessFile.setLastModified(currentMillies); + return currentMillies; + } +} \ No newline at end of file diff --git a/src/test/resources/less/1/reset.less b/src/test/resources/less/1/reset.less new file mode 100644 index 0000000..3dd9031 --- /dev/null +++ b/src/test/resources/less/1/reset.less @@ -0,0 +1,134 @@ +// +// Modals +// Adapted from http://github.com/necolas/normalize.css +// -------------------------------------------------- + + +// Display in IE6-9 and FF3 +// ------------------------- + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +// Display block in IE6-9 and FF3 +// ------------------------- + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +// Prevents modern browsers from displaying 'audio' without controls +// ------------------------- + +audio:not([controls]) { + display: none; +} + +// Base settings +// ------------------------- + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +// Hover & Active +a:hover, +a:active { + outline: 0; +} + +// Prevents sub and sup affecting line-height in all browsers +// ------------------------- + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} + +// Img border in a's and image quality +// ------------------------- + +img { + /* Responsive images (ensure images don't scale beyond their parents) */ + max-width: 100%; /* Part 1: Set a maxium relative to the parent */ + width: auto\9; /* IE7-8 need help adjusting responsive images */ + height: auto; /* Part 2: Scale the height according to the width, otherwise you get stretching */ + + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +// Prevent max-width from affecting Google Maps +#map_canvas img { + max-width: none; +} + +// Forms +// ------------------------- + +// Font size in all browsers, margin changes, misc consistency +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; // Inner spacing ie IE6/7 + line-height: normal; // FF3/4 have !important on line-height in UA stylesheet +} +button::-moz-focus-inner, +input::-moz-focus-inner { // Inner padding and border oddities in FF3/4 + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; // Cursors on all buttons applied consistently + -webkit-appearance: button; // Style clickable inputs in iOS +} +input[type="search"] { // Appearance in Safari/Chrome + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5 +} +textarea { + overflow: auto; // Remove vertical scrollbar in IE6-9 + vertical-align: top; // Readability and alignment cross-browser +} \ No newline at end of file diff --git a/src/test/resources/less/2/21/variables.less b/src/test/resources/less/2/21/variables.less new file mode 100644 index 0000000..cd37886 --- /dev/null +++ b/src/test/resources/less/2/21/variables.less @@ -0,0 +1,282 @@ +// Variables +// -------------------------------------------------- + + +// Global values +// -------------------------------------------------- + + +// Grays +// ------------------------- +@black: #000; +@grayDarker: #222; +@grayDark: #333; +@gray: #555; +@grayLight: #999; +@grayLighter: #eee; +@white: #fff; + + +// Accent colors +// ------------------------- +@blue: #049cdb; +@blueDark: #0064cd; +@green: #46a546; +@red: #9d261d; +@yellow: #ffc40d; +@orange: #f89406; +@pink: #c3325f; +@purple: #7a43b6; + + +// Scaffolding +// ------------------------- +@bodyBackground: yellow; +@textColor: yellow; +//#c0c0c0; + + +// Links +// ------------------------- +@linkColor: #c0c0c0; +@linkColorHover: darken(@linkColor, 15%); + + +// Typography +// ------------------------- +@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; +@serifFontFamily: Georgia, "Times New Roman", Times, serif; +@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; + +@baseFontSize: 14px; +@baseFontFamily: @sansFontFamily; +@baseLineHeight: 20px; +@altFontFamily: @serifFontFamily; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: bold; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + + +// Tables +// ------------------------- +@tableBackground: transparent; // overall background-color +@tableBackgroundAccent: #f9f9f9; // for striping +@tableBackgroundHover: #f5f5f5; // for hover +@tableBorder: #ddd; // table and cell border + + +// Buttons +// ------------------------- +@btnBackground: @white; +@btnBackgroundHighlight: darken(@white, 10%); +@btnBorder: #bbb; + +@btnPrimaryBackground: @linkColor; +@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%); + +@btnInfoBackground: #5bc0de; +@btnInfoBackgroundHighlight: #2f96b4; + +@btnSuccessBackground: #62c462; +@btnSuccessBackgroundHighlight: #51a351; + +@btnWarningBackground: lighten(@orange, 15%); +@btnWarningBackgroundHighlight: @orange; + +@btnDangerBackground: #ee5f5b; +@btnDangerBackgroundHighlight: #bd362f; + +@btnInverseBackground: #444; +@btnInverseBackgroundHighlight: @grayDarker; + + +// Forms +// ------------------------- +@inputBackground: @white; +@inputBorder: #ccc; +@inputBorderRadius: 3px; +@inputDisabledBackground: @grayLighter; +@formActionsBackground: #f5f5f5; + +// Dropdowns +// ------------------------- +@dropdownBackground: @white; +@dropdownBorder: rgba(0,0,0,.2); +@dropdownDividerTop: #e5e5e5; +@dropdownDividerBottom: @white; + +@dropdownLinkColor: @grayDark; + +@dropdownLinkColorHover: @white; +@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; + +@dropdownLinkColorActive: @dropdownLinkColor; +@dropdownLinkBackgroundActive: @linkColor; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexPopover: 1010; +@zindexTooltip: 1030; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; + + +// Sprite icons path +// ------------------------- +@iconSpritePath: "../img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; + + +// Input placeholder text color +// ------------------------- +@placeholderText: @grayLight; + + +// Hr border color +// ------------------------- +@hrBorder: @grayLighter; + + +// Horizontal forms & lists +// ------------------------- +@horizontalComponentOffset: 180px; + + +// Wells +// ------------------------- +@wellBackground: #f5f5f5; + + +// Navbar +// ------------------------- +@navbarCollapseWidth: 979px; + +@navbarHeight: 40px; +@navbarBackground: darken(@navbarBackgroundHighlight, 5%); +@navbarBackgroundHighlight: #ffffff; +@navbarBorder: darken(@navbarBackground, 12%); + +@navbarText: @gray; +@navbarLinkColor: @gray; +@navbarLinkColorHover: @grayDark; +@navbarLinkColorActive: @gray; +@navbarLinkBackgroundHover: transparent; +@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); + +@navbarBrandColor: @navbarLinkColor; + +// Inverted navbar +@navbarInverseBackground: #111111; +@navbarInverseBackgroundHighlight: #222222; +@navbarInverseBorder: #252525; + +@navbarInverseText: @grayLight; +@navbarInverseLinkColor: @grayLight; +@navbarInverseLinkColorHover: @white; +@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; +@navbarInverseLinkBackgroundHover: transparent; +@navbarInverseLinkBackgroundActive: @navbarInverseBackground; + +@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); +@navbarInverseSearchBackgroundFocus: @white; +@navbarInverseSearchBorder: @navbarInverseBackground; +@navbarInverseSearchPlaceholderColor: #ccc; + +@navbarInverseBrandColor: @navbarInverseLinkColor; + + +// Pagination +// ------------------------- +@paginationBackground: #fff; +@paginationBorder: #ddd; +@paginationActiveBackground: #f5f5f5; + + +// Hero unit +// ------------------------- +@heroUnitBackground: @grayLighter; +@heroUnitHeadingColor: inherit; +@heroUnitLeadColor: inherit; + + +// Form states and alerts +// ------------------------- +@warningText: #c09853; +@warningBackground: #fcf8e3; +@warningBorder: darken(spin(@warningBackground, -10), 3%); + +@errorText: #b94a48; +@errorBackground: #f2dede; +@errorBorder: darken(spin(@errorBackground, -10), 3%); + +@successText: #468847; +@successBackground: #dff0d8; +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: #3a87ad; +@infoBackground: #d9edf7; +@infoBorder: darken(spin(@infoBackground, -10), 7%); + + +// Tooltips and popovers +// ------------------------- +@tooltipColor: #fff; +@tooltipBackground: #000; +@tooltipArrowWidth: 5px; +@tooltipArrowColor: @tooltipBackground; + +@popoverBackground: #fff; +@popoverArrowWidth: 10px; +@popoverArrowColor: #fff; +@popoverTitleBackground: darken(@popoverBackground, 3%); + +// Special enhancement for popovers +@popoverArrowOuterWidth: @popoverArrowWidth + 1; +@popoverArrowOuterColor: rgba(0,0,0,.25); + + + +// GRID +// -------------------------------------------------- + + +// Default 940px grid +// ------------------------- +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 20px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// 1200px min +@gridColumnWidth1200: 70px; +@gridGutterWidth1200: 30px; +@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); + +// 768px-979px +@gridColumnWidth768: 42px; +@gridGutterWidth768: 20px; +@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); + + +// Fluid grid +// ------------------------- +@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); +@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); + +// 1200px min +@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); +@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); + +// 768px-979px +@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); +@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); \ No newline at end of file diff --git a/src/test/resources/less/bootstrap.less b/src/test/resources/less/bootstrap.less new file mode 100644 index 0000000..c11f3d1 --- /dev/null +++ b/src/test/resources/less/bootstrap.less @@ -0,0 +1,20 @@ +/*! + * Bootstrap v2.1.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +/* +Attention: +Any changes of this file will be lost on the next compile run of the .less files! + */ + +// CSS Reset +@import "1/reset.less"; + +// Core variables and mixins +@import "2/21/variables.less"; // Modify this for custom colors, font-sizes, etc \ No newline at end of file diff --git a/src/test/resources/pom.xml b/src/test/resources/pom.xml new file mode 100644 index 0000000..abc103f --- /dev/null +++ b/src/test/resources/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + org.lesscss.it + includes + testing + + + + org.lesscss + lesscss-maven-plugin + @project.version@ + + src/test/resources/less + true + + bootstrap.less + + + + + + compile + + + + + + + + \ No newline at end of file From e6b64154b8efaff8b848c6ebde4a2bdf44f3301e Mon Sep 17 00:00:00 2001 From: Roland Heimdahl Date: Fri, 18 Jan 2013 08:55:27 +0000 Subject: [PATCH 5/8] Added configuration option to run several compile-runs with there own settings. --- pom.xml | 2 +- src/it/concatenate/pom.xml | 8 +- src/it/multiple-config/invoker.properties | 1 + src/it/multiple-config/pom.xml | 38 ++++ .../src/main/less1/firstTest.less | 8 + .../src/main/less2/secondTest.less | 8 + src/it/multiple-config/verify.groovy | 2 + .../org/lesscss/mojo/AbstractLessCssMojo.java | 27 ++- .../java/org/lesscss/mojo/CompileMojo.java | 207 ++++++++++++------ .../org/lesscss/mojo/ConfigurationItem.java | 112 ++++++++++ src/main/java/org/lesscss/mojo/ListMojo.java | 45 +++- .../lesscss/mojo/AbstractLessCssMojoTest.java | 19 +- .../org/lesscss/mojo/CompileMojoTest.java | 15 ++ .../lesscss/mojo/CompileOnChangeMojoTest.java | 2 +- .../mojo/MultipleConfigurationTest.java | 124 +++++++++++ src/test/resources/change-pom.xml | 32 +++ src/test/resources/multiple-pom.xml | 38 ++++ 17 files changed, 597 insertions(+), 91 deletions(-) create mode 100644 src/it/multiple-config/invoker.properties create mode 100644 src/it/multiple-config/pom.xml create mode 100644 src/it/multiple-config/src/main/less1/firstTest.less create mode 100644 src/it/multiple-config/src/main/less2/secondTest.less create mode 100644 src/it/multiple-config/verify.groovy create mode 100644 src/main/java/org/lesscss/mojo/ConfigurationItem.java create mode 100644 src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java create mode 100644 src/test/resources/change-pom.xml create mode 100644 src/test/resources/multiple-pom.xml diff --git a/pom.xml b/pom.xml index 78adee6..c32d266 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.lesscss lesscss-maven-plugin - 1.3.2-SNAPSHOT + 1.3.3-SJV-SNAPSHOT maven-plugin Official LESS CSS Maven Plugin Official LESS CSS Maven Plugin diff --git a/src/it/concatenate/pom.xml b/src/it/concatenate/pom.xml index 4b1121e..94bc782 100644 --- a/src/it/concatenate/pom.xml +++ b/src/it/concatenate/pom.xml @@ -1,15 +1,15 @@ 4.0.0 - se.javalia.lesscss - concatenate - 0.0.1-SNAPSHOT + org.lesscss.it + concatenate + testing org.lesscss lesscss-maven-plugin - 1.3.2-SNAPSHOT + @project.version@ true diff --git a/src/it/multiple-config/invoker.properties b/src/it/multiple-config/invoker.properties new file mode 100644 index 0000000..9651b16 --- /dev/null +++ b/src/it/multiple-config/invoker.properties @@ -0,0 +1 @@ +invoker.goals = clean compile \ No newline at end of file diff --git a/src/it/multiple-config/pom.xml b/src/it/multiple-config/pom.xml new file mode 100644 index 0000000..87d8ff2 --- /dev/null +++ b/src/it/multiple-config/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + org.lesscss.it + basic + testing + + + + + org.lesscss + lesscss-maven-plugin + @project.version@ + + + + ${project.basedir}/src/main/less1 + ${project.build.directory}/css1 + + + ${project.basedir}/src/main/less2 + ${project.build.directory}/css2 + + + + + + + compile + + + + + + + + diff --git a/src/it/multiple-config/src/main/less1/firstTest.less b/src/it/multiple-config/src/main/less1/firstTest.less new file mode 100644 index 0000000..49618d9 --- /dev/null +++ b/src/it/multiple-config/src/main/less1/firstTest.less @@ -0,0 +1,8 @@ +@color: #4d926f; + +#header { + color: @color; +} +h2 { + color: @color; +} \ No newline at end of file diff --git a/src/it/multiple-config/src/main/less2/secondTest.less b/src/it/multiple-config/src/main/less2/secondTest.less new file mode 100644 index 0000000..49618d9 --- /dev/null +++ b/src/it/multiple-config/src/main/less2/secondTest.less @@ -0,0 +1,8 @@ +@color: #4d926f; + +#header { + color: @color; +} +h2 { + color: @color; +} \ No newline at end of file diff --git a/src/it/multiple-config/verify.groovy b/src/it/multiple-config/verify.groovy new file mode 100644 index 0000000..b3e0e9e --- /dev/null +++ b/src/it/multiple-config/verify.groovy @@ -0,0 +1,2 @@ +assert new File(basedir, "target/css1/firstTest.css").exists() +assert new File(basedir, "target/css2/secondTest.css").exists() \ No newline at end of file diff --git a/src/main/java/org/lesscss/mojo/AbstractLessCssMojo.java b/src/main/java/org/lesscss/mojo/AbstractLessCssMojo.java index 420d82b..20ee803 100644 --- a/src/main/java/org/lesscss/mojo/AbstractLessCssMojo.java +++ b/src/main/java/org/lesscss/mojo/AbstractLessCssMojo.java @@ -15,6 +15,7 @@ package org.lesscss.mojo; import java.io.File; +import java.util.List; import org.apache.maven.plugin.AbstractMojo; import org.codehaus.plexus.util.Scanner; @@ -30,6 +31,13 @@ public abstract class AbstractLessCssMojo extends AbstractMojo { /** @component */ protected BuildContext buildContext; + /** + * Using configurationItems allows you to have several different compilations on a single project + * + * @parameter + */ + protected List configurationItems; + /** * The source directory containing the LESS sources. * @@ -43,7 +51,7 @@ public abstract class AbstractLessCssMojo extends AbstractMojo { * * @parameter */ - protected String[] includes = new String[] { "**/*.less" }; + protected String[] includes = new String[] { INCLUDES_DEFAULT_VALUE }; /** * List of files to exclude. Specified as fileset patterns which are relative to the source directory. @@ -52,16 +60,25 @@ public abstract class AbstractLessCssMojo extends AbstractMojo { */ protected String[] excludes = new String[] {}; + static final String INCLUDES_DEFAULT_VALUE = "**/*.less"; + /** * Scans for the LESS sources that should be compiled. * * @return The list of LESS sources. */ - protected String[] getIncludedFiles() { - Scanner scanner = buildContext.newScanner(sourceDirectory, true); - scanner.setIncludes(includes); - scanner.setExcludes(excludes); + protected String[] getIncludedFiles(ConfigurationItem configurationItem) { + Scanner scanner = buildContext.newScanner(configurationItem.getSourceDirectory(), true); + scanner.setIncludes(configurationItem.getIncludes()); + scanner.setExcludes(configurationItem.getExcludes()); scanner.scan(); return scanner.getIncludedFiles(); } + + /** + * Get configuration + * + * @return a list of ConfigurationItems read from the plugin-configuration + */ + protected abstract List getConfiguration(); } diff --git a/src/main/java/org/lesscss/mojo/CompileMojo.java b/src/main/java/org/lesscss/mojo/CompileMojo.java index d936ba7..996e3df 100644 --- a/src/main/java/org/lesscss/mojo/CompileMojo.java +++ b/src/main/java/org/lesscss/mojo/CompileMojo.java @@ -17,7 +17,9 @@ import java.io.File; import java.io.IOException; import java.net.MalformedURLException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.MojoExecutionException; @@ -36,6 +38,8 @@ */ public class CompileMojo extends AbstractLessCssMojo { + private static final int WATCH_INTERVAL_DEFAULT = 1000; + /** * The directory for compiled CSS stylesheets. * @@ -65,7 +69,7 @@ public class CompileMojo extends AbstractLessCssMojo { * * @parameter expression="${lesscss.watchInterval}" default-value="1000" */ - private int watchInterval = 1000; + private int watchInterval = WATCH_INTERVAL_DEFAULT; /** * The character encoding the LESS compiler will use for writing the CSS @@ -110,91 +114,100 @@ public void execute() throws MojoExecutionException { long start = System.currentTimeMillis(); - if (getLog().isDebugEnabled()) { - getLog().debug("sourceDirectory = " + sourceDirectory); - getLog().debug("outputDirectory = " + outputDirectory); - getLog().debug("includes = " + Arrays.toString(includes)); - getLog().debug("excludes = " + Arrays.toString(excludes)); - getLog().debug("force = " + force); - getLog().debug("lessJs = " + lessJs); - getLog().debug("concatenate = " + concatenate); - getLog().debug("watch = " + watch); - getLog().debug("watchInterval = " + watchInterval); - } - - String[] files = getIncludedFiles(); - - if (concatenate) { - try { + List configurationItems = getConfiguration(); - String tmpPath = "less.less"; - File tmpFile = new File(sourceDirectory, tmpPath); - tmpFile.delete(); - System.out.println(tmpFile.getAbsolutePath()); - for (String path : files) { - File original = new File(sourceDirectory, path); - System.out.println(original.getAbsolutePath()); - String content = FileUtils.readFileToString(original); - FileUtils.write(tmpFile, content, true); - } - files = new String[] { tmpPath }; - } catch (IOException ioe) { - getLog().error("Error concatenating files", ioe); - } + if (configurationItems.size() == 0) { + return; } - if (files == null || files.length < 1) { - getLog().info("Nothing to compile - no LESS sources found"); - } else { + for (ConfigurationItem item : configurationItems) { if (getLog().isDebugEnabled()) { - getLog().debug("included files = " + Arrays.toString(files)); + getLog().debug("sourceDirectory = " + item.getSourceDirectory()); + getLog().debug("outputDirectory = " + item.getOutputDirectory()); + getLog().debug("includes = " + Arrays.toString(item.getIncludes())); + getLog().debug("excludes = " + Arrays.toString(item.getExcludes())); + getLog().debug("force = " + item.isForce()); + getLog().debug("lessJs = " + item.getLessJs()); + getLog().debug("concatenate = " + item.isConcatenate()); + getLog().debug("watch = " + item.isWatch()); + getLog().debug("watchInterval = " + item.getWatchInterval()); + getLog().debug("compress = " + item.isCompress()); } - LessCompiler lessCompiler = new LessCompiler(); - lessCompiler.setCompress(compress); - lessCompiler.setEncoding(encoding); + String[] files = getIncludedFiles(item); - if (lessJs != null) { + if (item.isConcatenate()) { try { - lessCompiler.setLessJs(lessJs.toURI().toURL()); - } catch (MalformedURLException e) { - throw new MojoExecutionException("Error while loading LESS JavaScript: " - + lessJs.getAbsolutePath(), e); + + String tmpPath = "less.less"; + File tmpFile = new File(item.getSourceDirectory(), tmpPath); + tmpFile.delete(); + System.out.println(tmpFile.getAbsolutePath()); + for (String path : files) { + File original = new File(item.getSourceDirectory(), path); + System.out.println(original.getAbsolutePath()); + String content = FileUtils.readFileToString(original); + FileUtils.write(tmpFile, content, true); + } + files = new String[] { tmpPath }; + } catch (IOException ioe) { + getLog().error("Error concatenating files", ioe); } } - if (watch) { - getLog().info("Watching " + outputDirectory); - if (force) { - force = false; - getLog().info("Disabled the 'force' flag in watch mode."); + + if (files == null || files.length < 1) { + getLog().info("Nothing to compile - no LESS sources found"); + } else { + if (getLog().isDebugEnabled()) { + getLog().debug("included files = " + Arrays.toString(files)); } - Thread.currentThread().setPriority(Thread.MIN_PRIORITY); - while (watch && !Thread.currentThread().isInterrupted()) { - compileIfChanged(files, lessCompiler); + + LessCompiler lessCompiler = new LessCompiler(); + lessCompiler.setCompress(item.isCompress()); + lessCompiler.setEncoding(item.getEncoding()); + + if (item.getLessJs() != null) { try { - Thread.sleep(watchInterval); - } catch (InterruptedException e) { - System.out.println("interrupted"); + lessCompiler.setLessJs(item.getLessJs().toURI().toURL()); + } catch (MalformedURLException e) { + throw new MojoExecutionException("Error while loading LESS JavaScript: " + + item.getLessJs().getAbsolutePath(), e); } } - } else { - compileIfChanged(files, lessCompiler); - } + if (item.isWatch()) { + getLog().info("Watching " + item.getOutputDirectory()); + if (item.isForce()) { + force = false; + getLog().info("Disabled the 'force' flag in watch mode."); + } + Thread.currentThread().setPriority(Thread.MIN_PRIORITY); + while (item.isWatch() && !Thread.currentThread().isInterrupted()) { + compileIfChanged(files, lessCompiler, item); + try { + Thread.sleep(item.getWatchInterval()); + } catch (InterruptedException e) { + System.out.println("interrupted"); + } + } + } else { + compileIfChanged(files, lessCompiler, item); + } - getLog().info( - "Complete Less compile job finished in " - + (System.currentTimeMillis() - start) + " ms"); + getLog().info( + "Complete Less compile job finished in " + + (System.currentTimeMillis() - start) + " ms"); + } } } - private void compileIfChanged(String[] files, LessCompiler lessCompiler) - throws MojoExecutionException { + private void compileIfChanged(String[] files, LessCompiler lessCompiler, + ConfigurationItem item) throws MojoExecutionException { for (String file : files) { - File input = new File(sourceDirectory, file); + File input = new File(item.getSourceDirectory(), file); buildContext.removeMessages(input); - File output = new File(outputDirectory, file.replace(".less", ".css")); + File output = new File(item.getOutputDirectory(), file.replace(".less", ".css")); if (!output.getParentFile().exists() && !output.getParentFile().mkdirs()) { throw new MojoExecutionException("Cannot create output directory " @@ -229,4 +242,70 @@ private void compileIfChanged(String[] files, LessCompiler lessCompiler) } } } + + + public List getConfiguration() { + if (this.configurationItems == null) { + configurationItems = new ArrayList(); + }else{ + //TODO: Should not need to do this but somehow an extra configuration + //TODO: is included... + return configurationItems; + } + + + ConfigurationItem configurationItem = new ConfigurationItem(); + boolean configured = false; + if (sourceDirectory != null) { + configurationItem.setSourceDirectory(sourceDirectory); + configured = true; + } + if (outputDirectory != null) { + configurationItem.setOutputDirectory(outputDirectory); + configured = true; + } + if (excludes.length > 0) { + configurationItem.setExcludes(excludes); + configured = true; + } + if (includes[0] != INCLUDES_DEFAULT_VALUE) { + configurationItem.setIncludes(includes); + configured = true; + } + if (compress) { + configurationItem.setCompress(compress); + configured = true; + } + if (watch) { + configurationItem.setWatch(watch); + if (watchInterval != WATCH_INTERVAL_DEFAULT) { + configurationItem.setWatchInterval(watchInterval); + }else{ + configurationItem.setWatchInterval(WATCH_INTERVAL_DEFAULT); + } + configured = true; + } + if (encoding != null) { + configurationItem.setEncoding(encoding); + configured = true; + } + if (force) { + configurationItem.setForce(force); + configured = true; + } + if (lessJs != null) { + configurationItem.setLessJs(lessJs); + configured = true; + } + if (concatenate) { + configurationItem.setConcatenate(concatenate); + configured = true; + } + + if (configured) { + configurationItems.add(configurationItem); + } + + return configurationItems; + } } diff --git a/src/main/java/org/lesscss/mojo/ConfigurationItem.java b/src/main/java/org/lesscss/mojo/ConfigurationItem.java new file mode 100644 index 0000000..ca66c89 --- /dev/null +++ b/src/main/java/org/lesscss/mojo/ConfigurationItem.java @@ -0,0 +1,112 @@ +package +org.lesscss.mojo; + +import java.io.File; + +/** + * A configurationItem is a complete set of configuration-parameters + * needed for the LessCss to compile a set of .less-files to .css. + * + * @author Roland Heimdahl + * + */ +public class ConfigurationItem { + private File sourceDirectory; + private File outputDirectory; + private String[] includes; + private String[] excludes; + private boolean compress; + private boolean watch; + private int watchInterval; + private String encoding; + private boolean force; + private File lessJs; + private boolean concatenate; + + public File getSourceDirectory() { + return sourceDirectory; + } + + public File getOutputDirectory() { + return outputDirectory; + } + + public String[] getIncludes() { + return includes; + } + + public String[] getExcludes() { + return excludes; + } + + public void setSourceDirectory(final File sourceDirectory) { + this.sourceDirectory = sourceDirectory; + } + + public void setOutputDirectory(final File outputDirectory){ + this.outputDirectory = outputDirectory; + } + + public void setIncludes(final String[] includes){ + this.includes = includes; + } + + public void setExcludes(final String[] excludes){ + this.excludes = excludes; + } + + public boolean isCompress() { + return compress; + } + + public void setCompress(boolean compress) { + this.compress = compress; + } + + public boolean isWatch() { + return watch; + } + + public void setWatch(boolean watch) { + this.watch = watch; + } + + public int getWatchInterval() { + return watchInterval; + } + + public void setWatchInterval(int watchInterval) { + this.watchInterval = watchInterval; + } + + public String getEncoding() { + return encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public File getLessJs() { + return lessJs; + } + + public void setLessJs(File lessJs) { + this.lessJs = lessJs; + } + + public boolean isConcatenate() { + return concatenate; + } + public void setConcatenate(final boolean concatenate){ + this.concatenate = concatenate; + } +} diff --git a/src/main/java/org/lesscss/mojo/ListMojo.java b/src/main/java/org/lesscss/mojo/ListMojo.java index e51556e..d61b391 100644 --- a/src/main/java/org/lesscss/mojo/ListMojo.java +++ b/src/main/java/org/lesscss/mojo/ListMojo.java @@ -17,8 +17,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.List; import java.util.Map.Entry; import org.apache.maven.plugin.MojoExecutionException; @@ -44,8 +46,15 @@ public void execute() throws MojoExecutionException { getLog().debug("includes = " + Arrays.toString(includes)); getLog().debug("excludes = " + Arrays.toString(excludes)); } + + List configurationItems = getConfiguration(); - String[] files = getIncludedFiles(); + if (configurationItems.size() == 0) { + return; + } + ConfigurationItem item = configurationItems.get(0); + + String[] files = getIncludedFiles(item); if (files == null || files.length < 1) { getLog().info("No LESS sources found"); @@ -58,9 +67,11 @@ public void execute() throws MojoExecutionException { LessSource lessSource = new LessSource(lessFile); listLessSource(lessSource, file, 0, false); } catch (FileNotFoundException e) { - throw new MojoExecutionException("Error while loading LESS source: " + lessFile.getAbsolutePath(), e); + throw new MojoExecutionException("Error while loading LESS source: " + + lessFile.getAbsolutePath(), e); } catch (IOException e) { - throw new MojoExecutionException("Error while loading LESS source: " + lessFile.getAbsolutePath(), e); + throw new MojoExecutionException("Error while loading LESS source: " + + lessFile.getAbsolutePath(), e); } } } @@ -88,4 +99,32 @@ private void listLessSource(LessSource lessSource, String path, int level, boole listLessSource(entry.getValue(), entry.getKey(), level + 1, !it.hasNext()); } } + + public List getConfiguration() { + if(this.configurationItems == null){ + configurationItems = new ArrayList(); + } + + ConfigurationItem configurationItem = new ConfigurationItem(); + boolean configured = false; + if (sourceDirectory != null) { + configurationItem.setSourceDirectory(sourceDirectory); + configured = true; + } + + if(excludes.length > 0){ + configurationItem.setExcludes(excludes); + configured = true; + } + if(includes[0] != INCLUDES_DEFAULT_VALUE){ + configurationItem.setIncludes(includes); + configured = true; + } + + if (configured) { + configurationItems.add(configurationItem); + } + + return configurationItems; + } } diff --git a/src/test/java/org/lesscss/mojo/AbstractLessCssMojoTest.java b/src/test/java/org/lesscss/mojo/AbstractLessCssMojoTest.java index 7f0fde5..6b52858 100644 --- a/src/test/java/org/lesscss/mojo/AbstractLessCssMojoTest.java +++ b/src/test/java/org/lesscss/mojo/AbstractLessCssMojoTest.java @@ -20,6 +20,7 @@ import static org.powermock.api.mockito.PowerMockito.when; import java.io.File; +import java.util.List; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.testing.AbstractMojoTestCase; @@ -59,6 +60,11 @@ public void setUp() throws Exception { mojo = new AbstractLessCssMojo() { public void execute() throws MojoExecutionException { } + + @Override + protected List getConfiguration() { + return null; + } }; setVariableValueToObject(mojo, "buildContext", buildContext); @@ -67,19 +73,6 @@ public void execute() throws MojoExecutionException { setVariableValueToObject(mojo, "excludes", excludes); } - @Test - public void testGetFiles() throws Exception { - when(buildContext.newScanner(sourceDirectory, true)).thenReturn(scanner); - when(scanner.getIncludedFiles()).thenReturn(files); - - assertSame(files, mojo.getIncludedFiles()); - - verify(buildContext).newScanner(same(sourceDirectory), eq(true)); - verify(scanner).setIncludes(same(includes)); - verify(scanner).setExcludes(same(excludes)); - verify(scanner).scan(); - } - @After public void tearDown() { } diff --git a/src/test/java/org/lesscss/mojo/CompileMojoTest.java b/src/test/java/org/lesscss/mojo/CompileMojoTest.java index 37118e5..dd47b15 100644 --- a/src/test/java/org/lesscss/mojo/CompileMojoTest.java +++ b/src/test/java/org/lesscss/mojo/CompileMojoTest.java @@ -30,6 +30,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.List; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.logging.Log; @@ -472,6 +473,20 @@ public void testExecutionMakeDirsFailsWhenOutputDirectoryDoesNotExists() throws verify(parent).exists(); verify(parent).mkdirs(); } + + @Test + public void testGetFiles() throws Exception { + when(buildContext.newScanner(sourceDirectory, true)).thenReturn(scanner); + when(scanner.getIncludedFiles()).thenReturn(files); + + List items = mojo.getConfiguration(); + assertSame(files, mojo.getIncludedFiles(items.get(0))); + + verify(buildContext).newScanner(same(sourceDirectory), eq(true)); + verify(scanner).setIncludes(same(includes)); + verify(scanner).setExcludes(same(excludes)); + verify(scanner).scan(); + } @After public void tearDown() { diff --git a/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java b/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java index 2b8b76c..7048967 100644 --- a/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java +++ b/src/test/java/org/lesscss/mojo/CompileOnChangeMojoTest.java @@ -34,7 +34,7 @@ protected void tearDown() throws Exception { */ @Test public void testIfFileChangeCausesRecompilation() throws Exception { - File pom = getTestFile("src/test/resources/pom.xml"); + File pom = getTestFile("src/test/resources/change-pom.xml"); assertNotNull(pom); assertTrue(pom.exists()); final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); diff --git a/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java b/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java new file mode 100644 index 0000000..76a9634 --- /dev/null +++ b/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java @@ -0,0 +1,124 @@ +package org.lesscss.mojo; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.junit.Test; + +public class MultipleConfigurationTest extends AbstractMojoTestCase { + + private CompileMojo mojo; + + private File sourceDirectory = new File("./source"); + private File outputDirectory = new File("./output"); + private String[] includes = new String[] { "include" }; + private String[] excludes = new String[] { "exclude" }; + private boolean compress = true; + private boolean watch = true; + private int watchInterval = 3600; + private String encoding = "UTF-8"; + private boolean force = true; + private File lessJs = new File("./lessJs"); + private boolean concatenate = true; + + private String[] files = new String[] { "file" }; + + @Test + public void testNeverReturnNullConfigurations() { + mojo = new CompileMojo(); + List configurationItems = mojo.getConfiguration(); + assertNotNull(configurationItems); + assertEquals(0, configurationItems.size()); + } + + @Test + public void testGetSimpleSingleConfiguration() throws IllegalAccessException { + mojo = new CompileMojo(); + + setVariableValueToObject(mojo, "sourceDirectory", sourceDirectory); + setVariableValueToObject(mojo, "outputDirectory", outputDirectory); + setVariableValueToObject(mojo, "includes", includes); + setVariableValueToObject(mojo, "excludes", excludes); + setVariableValueToObject(mojo, "compress", compress); + setVariableValueToObject(mojo, "watch", watch); + setVariableValueToObject(mojo, "watchInterval", watchInterval); + setVariableValueToObject(mojo, "force", force); + setVariableValueToObject(mojo, "lessJs", lessJs); + setVariableValueToObject(mojo, "concatenate", concatenate); + + List configurationItems = mojo.getConfiguration(); + assertEquals(1, configurationItems.size()); + + ConfigurationItem item = configurationItems.get(0); + assertEquals(sourceDirectory.getAbsolutePath(), item.getSourceDirectory() + .getAbsolutePath()); + assertEquals(outputDirectory.getAbsolutePath(), item.getOutputDirectory() + .getAbsolutePath()); + assertEquals(includes, item.getIncludes()); + assertEquals(excludes, item.getExcludes()); + assertEquals(compress, item.isCompress()); + assertEquals(watch, item.isWatch()); + assertEquals(watchInterval, item.getWatchInterval()); + assertEquals(force, item.isForce()); + assertEquals(lessJs, item.getLessJs()); + assertEquals(concatenate, item.isConcatenate()); + } + + @Test + public void testSingleConfigurationItem() throws IllegalAccessException { + ConfigurationItem configurationItem = new ConfigurationItem(); + configurationItem.setExcludes(excludes); + configurationItem.setIncludes(includes); + configurationItem.setOutputDirectory(outputDirectory); + configurationItem.setSourceDirectory(sourceDirectory); + List original = new ArrayList(); + original.add(configurationItem); + + mojo = new CompileMojo(); + setVariableValueToObject(mojo, "configurationItems", original); + + List actual = mojo.getConfiguration(); + assertEquals(1, actual.size()); + + ConfigurationItem item = actual.get(0); + assertEquals(sourceDirectory.getAbsolutePath(), item.getSourceDirectory() + .getAbsolutePath()); + assertEquals(outputDirectory.getAbsolutePath(), item.getOutputDirectory() + .getAbsolutePath()); + assertEquals(includes, item.getIncludes()); + assertEquals(excludes, item.getExcludes()); + } + + @Test + public void testTwoConfigurationItems() throws IllegalAccessException { + ConfigurationItem configurationItem = new ConfigurationItem(); + configurationItem.setExcludes(excludes); + configurationItem.setIncludes(includes); + configurationItem.setOutputDirectory(outputDirectory); + configurationItem.setSourceDirectory(sourceDirectory); + List original = new ArrayList(); + original.add(configurationItem); + original.add(configurationItem); // add twice + + mojo = new CompileMojo(); + setVariableValueToObject(mojo, "configurationItems", original); + + List actual = mojo.getConfiguration(); + assertEquals(2, actual.size()); + } + + @Test + public void testReadConfigurationFromPom() throws Exception { + File pom = getTestFile("src/test/resources/multiple-pom.xml"); + assertNotNull(pom); + assertTrue(pom.exists()); + final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); + assertNotNull(compileMojo); + List config = compileMojo.getConfiguration(); + assertEquals(2, config.size()); + assertTrue(config.get(0).getOutputDirectory().getAbsolutePath().endsWith("css1")); + assertTrue(config.get(1).getOutputDirectory().getAbsolutePath().endsWith("css2")); + } +} diff --git a/src/test/resources/change-pom.xml b/src/test/resources/change-pom.xml new file mode 100644 index 0000000..abc103f --- /dev/null +++ b/src/test/resources/change-pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + org.lesscss.it + includes + testing + + + + org.lesscss + lesscss-maven-plugin + @project.version@ + + src/test/resources/less + true + + bootstrap.less + + + + + + compile + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/multiple-pom.xml b/src/test/resources/multiple-pom.xml new file mode 100644 index 0000000..b275304 --- /dev/null +++ b/src/test/resources/multiple-pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + org.lesscss.it + basic + testing + + + + + org.lesscss + lesscss-maven-plugin + @project.version@ + + + + ${project.basedir}/src/main/less1 + ${project.build.directory}/css1 + + + ${project.basedir}src/main/less2 + ${project.build.directory}/css2 + + + + + + + compile + + + + + + + + From 127f4d4bb1a9fcf23e5702db37aab3eb36d438cb Mon Sep 17 00:00:00 2001 From: Roland Heimdahl Date: Fri, 18 Jan 2013 09:28:04 +0000 Subject: [PATCH 6/8] Fixed text and example, removed unused file. --- README.md | 61 +++++++++++++++++++++++++------------- src/test/resources/pom.xml | 32 -------------------- 2 files changed, 40 insertions(+), 53 deletions(-) delete mode 100644 src/test/resources/pom.xml diff --git a/README.md b/README.md index 5a7274f..3e01b4d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -Official LESS CSS Maven Plugin -============================== +LESS CSS Maven Plugin - SJV +=========================== +For official versoin see: https://github.com/marceloverdijk/lesscss-maven-plugin Usage ----- @@ -9,7 +10,7 @@ Declare the plugin and its goals. The process-sources phase is bound to by defau org.lesscss lesscss-maven-plugin - 1.3.0 + 1.3.3-SJV @@ -28,7 +29,7 @@ Example configuration for web project org.lesscss lesscss-maven-plugin - 1.3.0 + 1.3.3-SJV ${project.basedir}/src/main/webapp/less ${project.build.directory}/${project.build.finalName}/css @@ -45,6 +46,37 @@ Example configuration for web project + +Exmple configuration with two configurations.... +------------------------------------------------ + + org.lesscss + lesscss-maven-plugin + 1.3.3-SJV + + + + + ${project.basedir}/src/main/less/common + ${project.build.directory}/${project.build.finalName}/css/common + true + + + ${project.basedir}/src/main/webapp/less/project + ${project.build.directory}/${project.build.finalName}/css/project + false + + + + + + + + compile + + + + All configuration options @@ -59,8 +91,10 @@ All configuration options + includes (String[]) - List of files to include. Specified as fileset patterns which are relative to the source directory. Default value is: { "**\/*.less" } + lessJs (String) - The location of the LESS JavasSript file. + concatenate (boolean) - When true all less-files will be concatenated into a single file before compiling to css -++ watch (boolean) - When true the plugin watches the sourceDirectory and recompiles the included files after they changed. Instead of configuring it in the pom you can use that option at the command line like this "mvn lesscss:compile -Dlesscss.watch=true". Then it doesn't interfere with other maven lifecycle phases and you can just kill the watch process e.g. with crtl-c. Default value is: false. -++ watchInterval (int) - The interval in milliseconds the plugin waits between the check for file changes. Default value is: 1000 ms. ++ watch (boolean) - When true the plugin watches the sourceDirectory and recompiles the included files after they changed. Instead of configuring it in the pom you can use that option at the command line like this "mvn lesscss:compile -Dlesscss.watch=true". Then it doesn't interfere with other maven lifecycle phases and you can just kill the watch process e.g. with crtl-c. Default value is: false. ++ watchInterval (int) - The interval in milliseconds the plugin waits between the check for file changes. Default value is: 1000 ms. ++ configurationItems - a list of configurationItem. ++ configurationItem - a custom class. Holds a separate configuration, eg all of the above. List sources ------------ @@ -68,21 +102,6 @@ List sources To list the LESS sources in your project the lesscss:list goal can be used. It lists the LESS sources and it's imports based on sourceDirectory and optionally includes and excludes configuration options. -Support -------- - -Have a question, or found an issue? Just create a issue: https://github.com/marceloverdijk/lesscss-maven-plugin/issues - - -Authors -------- - -**Marcel Overdijk** - -+ marcel@overdijk.me -+ http://twitter.com/marceloverdijk -+ http://github.com/marceloverdijk - Copyright and License --------------------- diff --git a/src/test/resources/pom.xml b/src/test/resources/pom.xml deleted file mode 100644 index abc103f..0000000 --- a/src/test/resources/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - org.lesscss.it - includes - testing - - - - org.lesscss - lesscss-maven-plugin - @project.version@ - - src/test/resources/less - true - - bootstrap.less - - - - - - compile - - - - - - - - \ No newline at end of file From a2f1178011541aeb18f7300d7db3efcf6976478d Mon Sep 17 00:00:00 2001 From: Roland Heimdahl Date: Fri, 18 Jan 2013 13:20:19 +0000 Subject: [PATCH 7/8] Don't compile if nothing is changed when concatenating files --- .gitignore | 1 + .../java/org/lesscss/mojo/CompileMojo.java | 15 +++++++- .../org/lesscss/mojo/ConcatenateTest.java | 33 +++++++++++++++++ src/test/resources/concatenate-pom.xml | 37 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/lesscss/mojo/ConcatenateTest.java create mode 100644 src/test/resources/concatenate-pom.xml diff --git a/.gitignore b/.gitignore index 10c3d9a..07fc93e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .project .settings/ target/ +.svn \ No newline at end of file diff --git a/src/main/java/org/lesscss/mojo/CompileMojo.java b/src/main/java/org/lesscss/mojo/CompileMojo.java index 996e3df..e67bc88 100644 --- a/src/main/java/org/lesscss/mojo/CompileMojo.java +++ b/src/main/java/org/lesscss/mojo/CompileMojo.java @@ -141,8 +141,21 @@ public void execute() throws MojoExecutionException { String tmpPath = "less.less"; File tmpFile = new File(item.getSourceDirectory(), tmpPath); + + boolean updated = false; + for(String path: files){ + File original = new File(item.getSourceDirectory(), path); + if(original.lastModified() > tmpFile.lastModified()){ + updated = true; + } + } + + if(!updated){ + getLog().info("No files updated since last build"); + return; + } + tmpFile.delete(); - System.out.println(tmpFile.getAbsolutePath()); for (String path : files) { File original = new File(item.getSourceDirectory(), path); System.out.println(original.getAbsolutePath()); diff --git a/src/test/java/org/lesscss/mojo/ConcatenateTest.java b/src/test/java/org/lesscss/mojo/ConcatenateTest.java new file mode 100644 index 0000000..9806007 --- /dev/null +++ b/src/test/java/org/lesscss/mojo/ConcatenateTest.java @@ -0,0 +1,33 @@ +package org.lesscss.mojo; + +import java.io.File; + +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.junit.Test; + +public class ConcatenateTest extends AbstractMojoTestCase { + + @Test + public void testDontUpdateIfNotChanged() throws Exception { + File pom = getTestFile("src/test/resources/concatenate-pom.xml"); + final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); + + File expected = new File(compileMojo.sourceDirectory, "less.less"); + if(expected.exists()){ + expected.delete(); + } + + compileMojo.execute(); + expected = new File(compileMojo.sourceDirectory, "less.less"); + + compileMojo.execute(); + File actual = new File(compileMojo.sourceDirectory, "less.less"); + + assertEquals(expected.lastModified(), actual.lastModified()); + + + + + + } +} diff --git a/src/test/resources/concatenate-pom.xml b/src/test/resources/concatenate-pom.xml new file mode 100644 index 0000000..b6f8a19 --- /dev/null +++ b/src/test/resources/concatenate-pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + org.lesscss.it + basic + testing + + + + + org.lesscss + lesscss-maven-plugin + @project.version@ + + true + src/test/resources/less + ${project.build.directory}/css1 + + **/*.less + + + less.less + + + + + + compile + + + + + + + + From 84cd1a867101b50b3d6b20e403368e145492f555 Mon Sep 17 00:00:00 2001 From: Roland Heimdahl Date: Wed, 23 Jan 2013 08:05:34 +0000 Subject: [PATCH 8/8] Changed parameter concatenate(boolean) to concatenateTo(String)to be able to control the name of the output. --- pom.xml | 2 +- src/it/concatenate/pom.xml | 2 +- src/it/concatenate/verify.groovy | 2 +- .../java/org/lesscss/mojo/CompileMojo.java | 68 ++++++++++++------- .../org/lesscss/mojo/ConfigurationItem.java | 10 +-- .../org/lesscss/mojo/ConcatenateTest.java | 19 ++++-- .../mojo/MultipleConfigurationTest.java | 6 +- src/test/resources/concatenate-pom.xml | 2 +- 8 files changed, 67 insertions(+), 44 deletions(-) diff --git a/pom.xml b/pom.xml index c32d266..178cc37 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ org.lesscss lesscss - 1.3.0 + 1.3.3.SJV-SNAPSHOT org.mockito diff --git a/src/it/concatenate/pom.xml b/src/it/concatenate/pom.xml index 94bc782..ef6e736 100644 --- a/src/it/concatenate/pom.xml +++ b/src/it/concatenate/pom.xml @@ -11,7 +11,7 @@ lesscss-maven-plugin @project.version@ - true + concatenated.less diff --git a/src/it/concatenate/verify.groovy b/src/it/concatenate/verify.groovy index bcb6df2..dcf91bc 100644 --- a/src/it/concatenate/verify.groovy +++ b/src/it/concatenate/verify.groovy @@ -1,3 +1,3 @@ -assert new File(basedir, "target/less.css").exists() +assert new File(basedir, "target/concatenated.css").exists() assert !new File(basedir, "target/test.css").exists() assert !new File(basedir, "target/variables.css").exists() diff --git a/src/main/java/org/lesscss/mojo/CompileMojo.java b/src/main/java/org/lesscss/mojo/CompileMojo.java index e67bc88..f984070 100644 --- a/src/main/java/org/lesscss/mojo/CompileMojo.java +++ b/src/main/java/org/lesscss/mojo/CompileMojo.java @@ -90,12 +90,11 @@ public class CompileMojo extends AbstractLessCssMojo { private boolean force; /** - * When true Concatenates the less-files into a single file - * before compile to CSS. + * If set concatenates the less files and outputs to the filename given * - * @parameter expression="${lesscss.concatenate}" default-value="false" + * @parameter expression="${lesscss.concatenateTo}" */ - private boolean concatenate; + private String concatenateTo; /** * The location of the LESS JavasSript file. @@ -128,7 +127,7 @@ public void execute() throws MojoExecutionException { getLog().debug("excludes = " + Arrays.toString(item.getExcludes())); getLog().debug("force = " + item.isForce()); getLog().debug("lessJs = " + item.getLessJs()); - getLog().debug("concatenate = " + item.isConcatenate()); + getLog().debug("concatenate = " + item.getConcateanteTo()); getLog().debug("watch = " + item.isWatch()); getLog().debug("watchInterval = " + item.getWatchInterval()); getLog().debug("compress = " + item.isCompress()); @@ -136,33 +135,21 @@ public void execute() throws MojoExecutionException { String[] files = getIncludedFiles(item); - if (item.isConcatenate()) { + if (item.getConcateanteTo() != null) { try { - String tmpPath = "less.less"; + String tmpPath = item.getConcateanteTo(); File tmpFile = new File(item.getSourceDirectory(), tmpPath); - boolean updated = false; - for(String path: files){ - File original = new File(item.getSourceDirectory(), path); - if(original.lastModified() > tmpFile.lastModified()){ - updated = true; - } - } - + boolean updated = isFilesUpdated(item, files, tmpFile); if(!updated){ getLog().info("No files updated since last build"); return; } - tmpFile.delete(); - for (String path : files) { - File original = new File(item.getSourceDirectory(), path); - System.out.println(original.getAbsolutePath()); - String content = FileUtils.readFileToString(original); - FileUtils.write(tmpFile, content, true); - } - files = new String[] { tmpPath }; + deleteTemporaryFile(tmpFile); + buildConcatenatedFile(item, files, tmpFile); + files = setTemporaryAsFileToCompile(tmpPath); } catch (IOException ioe) { getLog().error("Error concatenating files", ioe); } @@ -213,6 +200,37 @@ public void execute() throws MojoExecutionException { } } + private String[] setTemporaryAsFileToCompile(String tmpPath) { + String[] files; + files = new String[] { tmpPath }; + return files; + } + + private void buildConcatenatedFile(ConfigurationItem item, String[] files, File tmpFile) + throws IOException { + for (String path : files) { + File original = new File(item.getSourceDirectory(), path); + System.out.println(original.getAbsolutePath()); + String content = FileUtils.readFileToString(original); + FileUtils.write(tmpFile, content, true); + } + } + + private void deleteTemporaryFile(File tmpFile) { + tmpFile.delete(); + } + + private boolean isFilesUpdated(ConfigurationItem item, String[] files, File tmpFile) { + boolean updated = false; + for(String path: files){ + File original = new File(item.getSourceDirectory(), path); + if(original.lastModified() > tmpFile.lastModified()){ + updated = true; + } + } + return updated; + } + private void compileIfChanged(String[] files, LessCompiler lessCompiler, ConfigurationItem item) throws MojoExecutionException { for (String file : files) { @@ -310,8 +328,8 @@ public List getConfiguration() { configurationItem.setLessJs(lessJs); configured = true; } - if (concatenate) { - configurationItem.setConcatenate(concatenate); + if (concatenateTo != null) { + configurationItem.setConcatenateTo(concatenateTo); configured = true; } diff --git a/src/main/java/org/lesscss/mojo/ConfigurationItem.java b/src/main/java/org/lesscss/mojo/ConfigurationItem.java index ca66c89..093f6c7 100644 --- a/src/main/java/org/lesscss/mojo/ConfigurationItem.java +++ b/src/main/java/org/lesscss/mojo/ConfigurationItem.java @@ -21,7 +21,7 @@ public class ConfigurationItem { private String encoding; private boolean force; private File lessJs; - private boolean concatenate; + private String concatenateTo; public File getSourceDirectory() { return sourceDirectory; @@ -103,10 +103,10 @@ public void setLessJs(File lessJs) { this.lessJs = lessJs; } - public boolean isConcatenate() { - return concatenate; + public String getConcateanteTo() { + return concatenateTo; } - public void setConcatenate(final boolean concatenate){ - this.concatenate = concatenate; + public void setConcatenateTo(final String concatenate){ + this.concatenateTo = concatenate; } } diff --git a/src/test/java/org/lesscss/mojo/ConcatenateTest.java b/src/test/java/org/lesscss/mojo/ConcatenateTest.java index 9806007..8620250 100644 --- a/src/test/java/org/lesscss/mojo/ConcatenateTest.java +++ b/src/test/java/org/lesscss/mojo/ConcatenateTest.java @@ -12,22 +12,27 @@ public void testDontUpdateIfNotChanged() throws Exception { File pom = getTestFile("src/test/resources/concatenate-pom.xml"); final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); - File expected = new File(compileMojo.sourceDirectory, "less.less"); + File expected = new File(compileMojo.sourceDirectory, "concatenated.less"); if(expected.exists()){ expected.delete(); } compileMojo.execute(); - expected = new File(compileMojo.sourceDirectory, "less.less"); + expected = new File(compileMojo.sourceDirectory, "concatenated.less"); compileMojo.execute(); - File actual = new File(compileMojo.sourceDirectory, "less.less"); + File actual = new File(compileMojo.sourceDirectory, "concatenated.less"); assertEquals(expected.lastModified(), actual.lastModified()); + } + + @Test + public void testProducesCssFile() throws Exception{ + File pom = getTestFile("src/test/resources/concatenate-pom.xml"); + final CompileMojo compileMojo = (CompileMojo) lookupMojo("compile", pom); + compileMojo.execute(); - - - - + File expected = new File(compileMojo.outputDirectory, "concatenated.css"); + assertTrue(expected.exists()); } } diff --git a/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java b/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java index 76a9634..b95480d 100644 --- a/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java +++ b/src/test/java/org/lesscss/mojo/MultipleConfigurationTest.java @@ -21,7 +21,7 @@ public class MultipleConfigurationTest extends AbstractMojoTestCase { private String encoding = "UTF-8"; private boolean force = true; private File lessJs = new File("./lessJs"); - private boolean concatenate = true; + private String concatenateTo = "test.css"; private String[] files = new String[] { "file" }; @@ -46,7 +46,7 @@ public void testGetSimpleSingleConfiguration() throws IllegalAccessException { setVariableValueToObject(mojo, "watchInterval", watchInterval); setVariableValueToObject(mojo, "force", force); setVariableValueToObject(mojo, "lessJs", lessJs); - setVariableValueToObject(mojo, "concatenate", concatenate); + setVariableValueToObject(mojo, "concatenateTo", concatenateTo); List configurationItems = mojo.getConfiguration(); assertEquals(1, configurationItems.size()); @@ -63,7 +63,7 @@ public void testGetSimpleSingleConfiguration() throws IllegalAccessException { assertEquals(watchInterval, item.getWatchInterval()); assertEquals(force, item.isForce()); assertEquals(lessJs, item.getLessJs()); - assertEquals(concatenate, item.isConcatenate()); + assertEquals(concatenateTo, item.getConcateanteTo()); } @Test diff --git a/src/test/resources/concatenate-pom.xml b/src/test/resources/concatenate-pom.xml index b6f8a19..f4b97f1 100644 --- a/src/test/resources/concatenate-pom.xml +++ b/src/test/resources/concatenate-pom.xml @@ -13,7 +13,7 @@ lesscss-maven-plugin @project.version@ - true + concatenated.less src/test/resources/less ${project.build.directory}/css1