/** * 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.workspace.configurators; import com.liferay.gradle.plugins.workspace.WorkspaceExtension; import com.liferay.gradle.plugins.workspace.WorkspacePlugin; import com.liferay.gradle.plugins.workspace.internal.util.FileUtil; import com.liferay.gradle.plugins.workspace.internal.util.GradleUtil; import com.liferay.gradle.util.Validator; import com.liferay.gradle.util.copy.StripPathSegmentsAction; import de.undercouch.gradle.tasks.download.Download; import groovy.lang.Closure; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.CopySpec; import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCopyDetails; import org.gradle.api.file.RelativePath; import org.gradle.api.initialization.Settings; import org.gradle.api.logging.Logger; import org.gradle.api.plugins.ExtensionAware; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.Copy; import org.gradle.api.tasks.TaskOutputs; import org.gradle.api.tasks.bundling.AbstractArchiveTask; import org.gradle.api.tasks.bundling.Compression; import org.gradle.api.tasks.bundling.Tar; import org.gradle.api.tasks.bundling.Zip; import org.gradle.language.base.plugins.LifecycleBasePlugin; /** * @author Andrea Di Giorgi * @author David Truong */ public class RootProjectConfigurator implements Plugin<Project> { public static final String BUNDLE_CONFIGURATION_NAME = "bundle"; public static final String BUNDLE_GROUP = "bundle"; public static final String CLEAN_TASK_NAME = LifecycleBasePlugin.CLEAN_TASK_NAME; public static final String DIST_BUNDLE_TAR_TASK_NAME = "distBundleTar"; public static final String DIST_BUNDLE_TASK_NAME = "distBundle"; public static final String DIST_BUNDLE_ZIP_TASK_NAME = "distBundleZip"; public static final String DOWNLOAD_BUNDLE_TASK_NAME = "downloadBundle"; public static final String INIT_BUNDLE_TASK_NAME = "initBundle"; /** * @deprecated As of 1.4.0, replaced by {@link * #RootProjectConfigurator(Settings)} */ @Deprecated public RootProjectConfigurator() { } public RootProjectConfigurator(Settings settings) { _defaultRepositoryEnabled = GradleUtil.getProperty( settings, WorkspacePlugin.PROPERTY_PREFIX + ".default.repository.enabled", _DEFAULT_REPOSITORY_ENABLED); } @Override public void apply(Project project) { WorkspaceExtension workspaceExtension = GradleUtil.getExtension( (ExtensionAware)project.getGradle(), WorkspaceExtension.class); GradleUtil.applyPlugin(project, LifecycleBasePlugin.class); if (isDefaultRepositoryEnabled()) { GradleUtil.addDefaultRepositories(project); } Download downloadBundleTask = _addTaskDownloadBundle( project, workspaceExtension); Copy distBundleTask = _addTaskDistBundle( project, downloadBundleTask, workspaceExtension); Tar distBundleTarTask = _addTaskDistBundle( project, DIST_BUNDLE_TAR_TASK_NAME, Tar.class, distBundleTask, workspaceExtension); distBundleTarTask.setCompression(Compression.GZIP); distBundleTarTask.setExtension("tar.gz"); _addTaskDistBundle( project, DIST_BUNDLE_ZIP_TASK_NAME, Zip.class, distBundleTask, workspaceExtension); _addTaskInitBundle(project, downloadBundleTask, workspaceExtension); } public boolean isDefaultRepositoryEnabled() { return _defaultRepositoryEnabled; } public void setDefaultRepositoryEnabled(boolean defaultRepositoryEnabled) { _defaultRepositoryEnabled = defaultRepositoryEnabled; } private Copy _addTaskCopyBundle( Project project, String taskName, Download downloadBundleTask, final WorkspaceExtension workspaceExtension) { Copy copy = GradleUtil.addTask(project, taskName, Copy.class); _configureTaskCopyBundleFromConfig( copy, new Callable<File>() { @Override public File call() throws Exception { return new File( workspaceExtension.getConfigsDir(), workspaceExtension.getEnvironment()); } }); _configureTaskCopyBundleFromConfig( copy, new Callable<File>() { @Override public File call() throws Exception { return new File( workspaceExtension.getConfigsDir(), "common"); } }); _configureTaskCopyBundleFromDownload(copy, downloadBundleTask); _configureTaskCopyBundlePreserveTimestamps(copy); copy.dependsOn(downloadBundleTask); copy.doFirst( new Action<Task>() { @Override public void execute(Task task) { Copy copy = (Copy)task; Project project = copy.getProject(); project.delete(copy.getDestinationDir()); } }); copy.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); return copy; } private Copy _addTaskDistBundle( final Project project, Download downloadBundleTask, WorkspaceExtension workspaceExtension) { Copy copy = _addTaskCopyBundle( project, DIST_BUNDLE_TASK_NAME, downloadBundleTask, workspaceExtension); _configureTaskDisableUpToDate(copy); copy.into( new Callable<File>() { @Override public File call() throws Exception { return new File(project.getBuildDir(), "dist"); } }); copy.setDescription("Assembles the Liferay bundle."); return copy; } private <T extends AbstractArchiveTask> T _addTaskDistBundle( Project project, String taskName, Class<T> clazz, final Copy distBundleTask, final WorkspaceExtension workspaceExtension) { T task = GradleUtil.addTask(project, taskName, clazz); _configureTaskDisableUpToDate(task); task.into( new Callable<String>() { @Override public String call() throws Exception { String bundleDistRootDirName = workspaceExtension.getBundleDistRootDirName(); if (Validator.isNull(bundleDistRootDirName)) { bundleDistRootDirName = ""; } return bundleDistRootDirName; } }, new Closure<Void>(task) { @SuppressWarnings("unused") public void doCall(CopySpec copySpec) { copySpec.from(distBundleTask); } }); task.setBaseName(project.getName()); task.setDescription("Assembles the Liferay bundle and zips it up."); task.setDestinationDir(project.getBuildDir()); task.setGroup(BUNDLE_GROUP); return task; } private Download _addTaskDownloadBundle( Project project, final WorkspaceExtension workspaceExtension) { final Download download = GradleUtil.addTask( project, DOWNLOAD_BUNDLE_TASK_NAME, Download.class); File destinationDir = new File( System.getProperty("user.home"), ".liferay/bundles"); destinationDir.mkdirs(); download.dest(destinationDir); download.onlyIfNewer(true); download.setDescription("Downloads the Liferay bundle zip file."); project.afterEvaluate( new Action<Project>() { @Override public void execute(Project project) { Object src = download.getSrc(); if (src != null) { if (src instanceof List<?>) { List<?> srcList = (List<?>)src; if (!srcList.isEmpty()) { return; } } else { return; } } String bundleUrl = workspaceExtension.getBundleUrl(); bundleUrl = bundleUrl.replace(" ", "%20"); try { download.src(bundleUrl); } catch (MalformedURLException murle) { throw new GradleException(murle.getMessage(), murle); } } }); return download; } private Copy _addTaskInitBundle( Project project, Download downloadBundleTask, final WorkspaceExtension workspaceExtension) { Copy copy = _addTaskCopyBundle( project, INIT_BUNDLE_TASK_NAME, downloadBundleTask, workspaceExtension); copy.into( new Callable<File>() { @Override public File call() throws Exception { return workspaceExtension.getHomeDir(); } }); copy.setDescription("Downloads and unzips the bundle."); copy.setGroup(BUNDLE_GROUP); return copy; } private void _configureTaskCopyBundleFromConfig( Copy copy, Callable<File> dir) { copy.from( dir, new Closure<Void>(copy.getProject()) { @SuppressWarnings("unused") public void doCall(CopySpec copySpec) { copySpec.exclude("**/.touch"); } }); } private void _configureTaskCopyBundleFromDownload( Copy copy, final Download download) { final Project project = copy.getProject(); final Set<String> rootDirNames = new HashSet<>(); copy.dependsOn(download); copy.doLast( new Action<Task>() { @Override public void execute(Task task) { Copy copy = (Copy)task; File destinationDir = copy.getDestinationDir(); for (String rootDirName : rootDirNames) { FileUtil.moveTree( new File(destinationDir, rootDirName), destinationDir); } } }); copy.from( new Callable<FileCollection>() { @Override public FileCollection call() throws Exception { File dir = download.getDest(); URL url = (URL)download.getSrc(); String fileName = url.toString(); fileName = fileName.substring( fileName.lastIndexOf('/') + 1); File file = new File(dir, fileName); if (fileName.endsWith(".tar.gz")) { return project.tarTree(file); } else { return project.zipTree(file); } } }, new Closure<Void>(project) { @SuppressWarnings("unused") public void doCall(CopySpec copySpec) { copySpec.eachFile( new Action<FileCopyDetails>() { @Override public void execute( FileCopyDetails fileCopyDetails) { RelativePath relativePath = fileCopyDetails.getRelativePath(); String[] segments = relativePath.getSegments(); rootDirNames.add(segments[0]); } }); copySpec.eachFile(new StripPathSegmentsAction(1)); } }); } private void _configureTaskCopyBundlePreserveTimestamps(Copy copy) { final Set<FileCopyDetails> fileCopyDetailsSet = new HashSet<>(); copy.doLast( new Action<Task>() { @Override public void execute(Task task) { Copy copy = (Copy)task; Logger logger = copy.getLogger(); for (FileCopyDetails fileCopyDetails : fileCopyDetailsSet) { File file = new File( copy.getDestinationDir(), fileCopyDetails.getPath()); if (!file.exists()) { logger.error( "Unable to set last modified time of {}, it " + "has not been copied", file); return; } boolean success = file.setLastModified( fileCopyDetails.getLastModified()); if (!success) { logger.error( "Unable to set last modified time of {}", file); } } } }); copy.eachFile( new Action<FileCopyDetails>() { @Override public void execute(FileCopyDetails fileCopyDetails) { fileCopyDetailsSet.add(fileCopyDetails); } }); } private void _configureTaskDisableUpToDate(Task task) { TaskOutputs taskOutputs = task.getOutputs(); taskOutputs.upToDateWhen( new Spec<Task>() { @Override public boolean isSatisfiedBy(Task task) { return false; } }); } private static final boolean _DEFAULT_REPOSITORY_ENABLED = true; private boolean _defaultRepositoryEnabled; }