package org.kravemir.gradle.sass; import com.vaadin.sass.internal.ScssStylesheet; import com.vaadin.sass.internal.resolver.FilesystemResolver; import org.gradle.api.DefaultTask; import org.gradle.api.file.ConfigurableFileTree; import org.gradle.api.file.FileCollection; import org.gradle.api.tasks.*; import org.gradle.api.tasks.incremental.IncrementalTaskInputs; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.nio.file.Path; import java.nio.file.Paths; /** * Abstract and reusable Sass Compilation Task * @author Miroslav Kravec */ @CacheableTask public abstract class AbstractSassCompileTask extends DefaultTask { @InputFiles @PathSensitive(PathSensitivity.RELATIVE) FileCollection getSassFiles() { if(getSrcDir().exists() == false) throw new RuntimeException("srcDir doesn't exists"); if(getSrcDir().isDirectory() == false) throw new RuntimeException("srcDir isn't directory"); ConfigurableFileTree fileTree = getProject().fileTree(getSrcDir()); if(getInclude() != null) fileTree.include(getInclude()); if(getExclude() != null) fileTree.exclude(getExclude()); return fileTree; } @Internal FileCollection getInputFiles() { if(getSrcDir().exists() == false) throw new RuntimeException("srcDir doesn't exists"); if(getSrcDir().isDirectory() == false) throw new RuntimeException("srcDir isn't directory"); ConfigurableFileTree fileTree = getProject().fileTree(getSrcDir()); return fileTree; } @TaskAction void compile(IncrementalTaskInputs incrementalTaskInputs) throws Exception { File outputDir = getOutputDirectory(); outputDir.mkdirs(); Path srcDirPath = getSrcDir().toPath(); // only delete removed files if(incrementalTaskInputs.isIncremental()) { incrementalTaskInputs.outOfDate(inputFileDetails -> {}); incrementalTaskInputs.removed(inputFileDetails -> { File outputFile = getOutputFile(srcDirPath,outputDir,inputFileDetails.getFile()); if(outputFile.exists()) outputFile.delete(); }); } for(File f : getSassFiles()) { File outputFile = getOutputFile(srcDirPath,outputDir,f); outputFile.getParentFile().mkdirs(); try(OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outputFile))) { ScssStylesheet sass = ScssStylesheet.get(f.getAbsolutePath()); sass.setFile(f); sass.setCharset("UTF-8"); // TODO: inteligent sass.addResolver(new FilesystemResolver(getSrcDir().getAbsolutePath())); sass.compile(); sass.write(out,getMinify()); } } } private File getOutputFile(Path srcDirPath, File outputDir, File f) { Path relativePath = srcDirPath.relativize(f.toPath()); return new File(outputDir,relativePath.toString().replaceAll("\\.scss",".css")); } /** * @return directory, where compiled CSS files are written */ @OutputDirectory protected abstract File getOutputDirectory(); /** * @return source directory, where SASS files are searched */ @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) protected abstract File getSrcDir(); /** * @return pattern defining files to include in compilation as SASS root file */ @Internal protected abstract String getInclude(); /** * @return pattern defining to exclude files as SASS root */ @Internal protected abstract String getExclude(); /** * @return boolean, defines whether CSS files should be minified */ @Input protected abstract boolean getMinify(); }