/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.gradle.plugins.css.builder; import com.liferay.css.builder.CSSBuilderArgs; import com.liferay.gradle.util.FileUtil; import com.liferay.gradle.util.GradleUtil; import com.liferay.gradle.util.Validator; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.gradle.api.Project; import org.gradle.api.file.FileCollection; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputDirectories; import org.gradle.api.tasks.OutputFiles; import org.gradle.api.tasks.SkipWhenEmpty; import org.gradle.util.CollectionUtils; import org.gradle.util.GUtil; /** * @author Andrea Di Giorgi */ public class BuildCSSTask extends JavaExec { public BuildCSSTask() { setDefaultCharacterEncoding(StandardCharsets.UTF_8.toString()); setDirNames("/"); setMain("com.liferay.css.builder.CSSBuilder"); } public BuildCSSTask dirNames(Iterable<Object> dirNames) { GUtil.addToCollection(_dirNames, dirNames); return this; } public BuildCSSTask dirNames(Object... dirNames) { return dirNames(Arrays.asList(dirNames)); } @Override public void exec() { setArgs(_getCompleteArgs()); super.exec(); } @InputFiles @SkipWhenEmpty public FileCollection getCSSFiles() { Project project = getProject(); List<String> dirNames = getDirNames(); File docrootDir = getDocrootDir(); if (dirNames.isEmpty() || (docrootDir == null)) { return project.files(); } Map<String, Object> args = new HashMap<>(); args.put("dir", docrootDir); args.put("exclude", "**/" + _addTrailingSlash(getOutputDirName())); for (String dirName : dirNames) { dirName = dirName.replace('\\', '/'); if (dirName.equals("/")) { dirName = ""; } else { dirName = _removeLeadingSlash(dirName); dirName = _removeTrailingSlash(dirName); dirName += "/"; } List<String> includes = new ArrayList<>(2); includes.add(dirName + "**/*.css"); includes.add(dirName + "**/*.scss"); args.put("includes", includes); } return project.fileTree(args); } public List<String> getDirNames() { return GradleUtil.toStringList(_dirNames); } public File getDocrootDir() { return GradleUtil.toFile(getProject(), _docrootDir); } @Input public String getOutputDirName() { return GradleUtil.toString(_outputDirName); } @OutputDirectories public FileCollection getOutputDirs() { Project project = getProject(); Set<File> outputDirs = new HashSet<>(); FileCollection cssFiles = getCSSFiles(); String outputDirName = _removeTrailingSlash(getOutputDirName()); for (File cssFile : cssFiles) { File outputDir = project.file(cssFile + "/../" + outputDirName); outputDirs.add(outputDir); } return project.files(outputDirs); } @InputDirectory @Optional public File getPortalCommonDir() { return GradleUtil.toFile(getProject(), _portalCommonDir); } @InputFile @Optional public File getPortalCommonFile() { return GradleUtil.toFile(getProject(), _portalCommonFile); } @Input public File getPortalCommonPath() { File portalCommonPath = getPortalCommonDir(); if (portalCommonPath == null) { portalCommonPath = getPortalCommonFile(); } return portalCommonPath; } @Input public int getPrecision() { return GradleUtil.toInteger(_precision); } @Input public List<String> getRtlExcludedPathRegexps() { return GradleUtil.toStringList(_rtlExcludedPathRegexps); } @Input @Optional public String getSassCompilerClassName() { return GradleUtil.toString(_sassCompilerClassName); } @OutputFiles public FileCollection getSourceMapFiles() { Project project = getProject(); List<File> sourceMapFiles = new ArrayList<>(); if (isGenerateSourceMap()) { FileCollection cssFiles = getCSSFiles(); for (File cssFile : cssFiles) { File sourceMapFile = project.file(cssFile + ".map"); sourceMapFiles.add(sourceMapFile); } } return project.files(sourceMapFiles); } @Input public boolean isGenerateSourceMap() { return _generateSourceMap; } public BuildCSSTask rtlExcludedPathRegexps( Iterable<Object> rtlExcludedPathRegexps) { GUtil.addToCollection(_rtlExcludedPathRegexps, rtlExcludedPathRegexps); return this; } public BuildCSSTask rtlExcludedPathRegexps( Object... rtlExcludedPathRegexps) { return rtlExcludedPathRegexps(Arrays.asList(rtlExcludedPathRegexps)); } public void setDirNames(Iterable<Object> dirNames) { _dirNames.clear(); dirNames(dirNames); } public void setDirNames(Object... dirNames) { setDirNames(Arrays.asList(dirNames)); } public void setDocrootDir(Object docrootDir) { _docrootDir = docrootDir; } public void setGenerateSourceMap(boolean generateSourceMap) { _generateSourceMap = generateSourceMap; } public void setOutputDirName(Object outputDirName) { _outputDirName = outputDirName; } public void setPortalCommonDir(Object portalCommonDir) { _portalCommonDir = portalCommonDir; } public void setPortalCommonFile(Object portalCommonFile) { _portalCommonFile = portalCommonFile; } public void setPrecision(Object precision) { _precision = precision; } public void setRtlExcludedPathRegexps( Iterable<Object> rtlExcludedPathRegexps) { _rtlExcludedPathRegexps.clear(); rtlExcludedPathRegexps(rtlExcludedPathRegexps); } public void setRtlExcludedPathRegexps(Object... rtlExcludedPathRegexps) { setRtlExcludedPathRegexps(Arrays.asList(rtlExcludedPathRegexps)); } public void setSassCompilerClassName(Object sassCompilerClassName) { _sassCompilerClassName = sassCompilerClassName; } private String _addTrailingSlash(String path) { if (Validator.isNull(path)) { return path; } path = path.replace('\\', '/'); if (path.charAt(path.length() - 1) != '/') { path += '/'; } return path; } private List<String> _getCompleteArgs() { List<String> args = new ArrayList<>(getArgs()); List<String> dirNames = getDirNames(); if (dirNames.size() == 1) { args.add("sass.dir=/" + _removeLeadingSlash(dirNames.get(0))); } else { for (int i = 0; i < dirNames.size(); i++) { String dirName = dirNames.get(i); args.add("sass.dir." + i + "=/" + _removeLeadingSlash(dirName)); } } String docrootDirName = FileUtil.getAbsolutePath(getDocrootDir()); args.add("sass.docroot.dir=" + _removeTrailingSlash(docrootDirName)); args.add("sass.generate.source.map=" + isGenerateSourceMap()); args.add("sass.output.dir=" + _addTrailingSlash(getOutputDirName())); String portalCommonPath = FileUtil.getAbsolutePath( getPortalCommonPath()); args.add("sass.portal.common.path=" + portalCommonPath); args.add("sass.precision=" + getPrecision()); String rtlExcludedPathRegexps = CollectionUtils.join( ",", getRtlExcludedPathRegexps()); args.add("sass.rtl.excluded.path.regexps=" + rtlExcludedPathRegexps); String sassCompilerClassName = getSassCompilerClassName(); if (Validator.isNotNull(sassCompilerClassName)) { args.add("sass.compiler.class.name=" + sassCompilerClassName); } return args; } private String _removeLeadingSlash(String path) { if (Validator.isNull(path)) { return path; } path = path.replace('\\', '/'); if (path.charAt(0) == '/') { path = path.substring(1); } return path; } private String _removeTrailingSlash(String path) { if (Validator.isNull(path)) { return path; } path = path.replace('\\', '/'); if (path.charAt(path.length() - 1) == '/') { path = path.substring(0, path.length() - 1); } return path; } private final Set<Object> _dirNames = new LinkedHashSet<>(); private Object _docrootDir; private boolean _generateSourceMap; private Object _outputDirName = CSSBuilderArgs.OUTPUT_DIR_NAME; private Object _portalCommonDir; private Object _portalCommonFile; private Object _precision = CSSBuilderArgs.PRECISION; private final Set<Object> _rtlExcludedPathRegexps = new LinkedHashSet<>(); private Object _sassCompilerClassName; }