1 /*
  2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package org.openjdk.skara.gradle.images;
 25 
 26 import org.gradle.api.*;
 27 import org.gradle.api.file.Directory;
 28 import org.gradle.api.tasks.bundling.*;
 29 import org.gradle.api.artifacts.UnknownConfigurationException;
 30 
 31 import java.util.ArrayList;
 32 import java.io.File;
 33 
 34 public class ImagesPlugin implements Plugin<Project> {
 35     @Override
 36     public void apply(Project project) {
 37         NamedDomainObjectContainer<ImageEnvironment> imageEnvironmentContainer =
 38             project.container(ImageEnvironment.class, new NamedDomainObjectFactory<ImageEnvironment>() {
 39                 public ImageEnvironment create(String name) {
 40                     return new ImageEnvironment(name, project.getObjects());
 41                 }
 42             });
 43         project.getExtensions().add("images", imageEnvironmentContainer);
 44 
 45         var projectPath = project.getPath();
 46         var taskNames = new ArrayList<String>();
 47         var rootDir = project.getRootDir().toPath().toAbsolutePath();
 48         var buildDir = project.getBuildDir().toPath().toAbsolutePath();
 49 
 50         imageEnvironmentContainer.all(new Action<ImageEnvironment>() {
 51             public void execute(ImageEnvironment env) {
 52                 var name = env.getName();
 53                 var subName = name.substring(0, 1).toUpperCase() + name.substring(1);
 54 
 55                 var downloadTaskName = "download" + subName + "JDK";
 56                 project.getTasks().register(downloadTaskName, DownloadJDKTask.class, (task) -> {
 57                     task.getUrl().set(env.getUrl());
 58                     task.getSha256().set(env.getSha256());
 59                     task.getToDir().set(rootDir.resolve(".jdk"));
 60                 });
 61 
 62                 var linkTaskName = "link" + subName;
 63                 project.getTasks().register(linkTaskName, LinkTask.class, (task) -> {
 64                     for (var jarTask : project.getTasksByName("jar", true)) {
 65                         if (jarTask instanceof Jar) {
 66                             task.getModulePath().add(((Jar) jarTask).getArchiveFile());
 67                         }
 68                     }
 69 
 70                     try {
 71                         var runtimeClasspath = project.getConfigurations().getByName("runtimeClasspath");
 72                         task.getRuntimeModules().addAll(runtimeClasspath.getElements());
 73                         task.dependsOn(runtimeClasspath);
 74                     } catch (UnknownConfigurationException e) {
 75                         // ignored
 76                     }
 77 
 78                     task.dependsOn(projectPath + ":" + downloadTaskName);
 79                     task.getToDir().set(buildDir.resolve("images"));
 80                     task.getUrl().set(env.getUrl());
 81                     task.getOS().set(name);
 82                     task.getLaunchers().set(env.getLaunchers());
 83                     task.getModules().set(env.getModules());
 84                 });
 85 
 86                 var launchersTaskName = "launchers" + subName;
 87                 project.getTasks().register(launchersTaskName, LaunchersTask.class, (task) -> {
 88                     task.getLaunchers().set(env.getLaunchers());
 89                     task.getOptions().set(env.getOptions());
 90                     task.getToDir().set(buildDir.resolve("launchers"));
 91                     task.getOS().set(name);
 92                 });
 93 
 94                 var zipTaskName = "bundleZip" + subName;
 95                 project.getTasks().register(zipTaskName, Zip.class, (task) -> {
 96                     task.dependsOn(projectPath + ":" + linkTaskName);
 97                     task.dependsOn(projectPath + ":" + launchersTaskName);
 98 
 99                     task.setPreserveFileTimestamps(false);
100                     task.setReproducibleFileOrder(true);
101                     task.getArchiveBaseName().set(project.getName());
102                     task.getArchiveClassifier().set(name);
103                     task.getArchiveExtension().set("zip");
104 
105                     if (env.getMan().isPresent()) {
106                         var root = project.getRootProject().getRootDir().toPath().toAbsolutePath();
107                         task.from(root.resolve(env.getMan().get()).toString(), (s) -> {
108                             s.into("bin/man");
109                         });
110                     }
111 
112                     task.from(buildDir.resolve("images").resolve(name), (s) -> {
113                         s.into("image");
114                     });
115                     task.from(buildDir.resolve("launchers").resolve(name), (s) -> {
116                         s.into("bin");
117                     });
118                 });
119 
120                 var gzipTaskName = "bundleTarGz" + subName;
121                 project.getTasks().register(gzipTaskName, Tar.class, (task) -> {
122                     task.dependsOn(projectPath + ":" + linkTaskName);
123                     task.dependsOn(projectPath + ":" + launchersTaskName);
124 
125                     task.setPreserveFileTimestamps(false);
126                     task.setReproducibleFileOrder(true);
127                     task.getArchiveBaseName().set(project.getName());
128                     task.getArchiveClassifier().set(name);
129                     task.getArchiveExtension().set("tar.gz");
130                     task.setCompression(Compression.GZIP);
131 
132                     if (env.getMan().isPresent()) {
133                         var root = project.getRootProject().getRootDir().toPath().toAbsolutePath();
134                         task.from(root.resolve(env.getMan().get()).toString(), (s) -> {
135                             s.into("bin/man");
136                         });
137                     }
138 
139                     task.from(buildDir.resolve("images").resolve(name), (s) -> {
140                         s.into("image");
141                     });
142                     task.from(buildDir.resolve("launchers").resolve(name), (s) -> {
143                         s.into("bin");
144                     });
145                 });
146 
147                 var imageTaskName = "image" + subName;
148                 project.getTasks().register(imageTaskName, DefaultTask.class, (task) -> {
149                     for (var bundle : env.getBundles().get()) {
150                         if (bundle.equals("zip")) {
151                             task.dependsOn(projectPath + ":" + zipTaskName);
152                         } else if (bundle.equals("tar.gz")) {
153                             task.dependsOn(projectPath + ":" + gzipTaskName);
154                         }
155                     }
156                 });
157 
158                 taskNames.add(imageTaskName);
159             }
160         });
161 
162         project.getTasks().register("images", DefaultTask.class, (task) -> {
163             for (var name : taskNames) {
164                 task.dependsOn(projectPath + ":" + name);
165             }
166         });
167     }
168 }