Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Spring boot extensions #31

Merged
merged 2 commits into from
Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions first-party/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ subprojects {
GRADLE_EXTENSION: '0.3.0',
MAVEN_EXTENSION: '0.3.0',

SPRING_BOOT: '2.3.1.RELEASE', // for Spring Boot Gradle extension
MAVEN_API: '3.5.2',

//test
Expand Down
75 changes: 75 additions & 0 deletions first-party/jib-spring-boot-extension-gradle/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
plugins {
id 'java-gradle-plugin'
id 'net.researchgate.release'
id 'maven-publish'
id 'eclipse'
}

repositories {
gradlePluginPortal()
}

dependencies {
compileOnly "com.google.cloud.tools:jib-gradle-plugin-extension-api:${dependencyVersions.GRADLE_EXTENSION}"
compileOnly "gradle.plugin.com.google.cloud.tools:jib-gradle-plugin:${dependencyVersions.JIB_GRADLE}"
compileOnly "com.google.guava:guava:${dependencyVersions.GUAVA}"
compileOnly "org.springframework.boot:spring-boot-gradle-plugin:${dependencyVersions.SPRING_BOOT}"

testImplementation "com.google.cloud.tools:jib-gradle-plugin-extension-api:${dependencyVersions.GRADLE_EXTENSION}"
testImplementation "gradle.plugin.com.google.cloud.tools:jib-gradle-plugin:${dependencyVersions.JIB_GRADLE}"
testImplementation "com.google.guava:guava:${dependencyVersions.GUAVA}"
testImplementation "junit:junit:${dependencyVersions.JUNIT}"
testImplementation "org.mockito:mockito-core:${dependencyVersions.MOCKITO_CORE}"
testImplementation "org.springframework.boot:spring-boot-gradle-plugin:${dependencyVersions.SPRING_BOOT}"
}

jar {
manifest {
attributes 'Implementation-Version': version
attributes 'Automatic-Module-Name': 'com.google.cloud.tools.jib.gradle.extension.springboot'

// OSGi metadata
attributes 'Bundle-SymbolicName': 'com.google.cloud.tools.jib.gradle.extension.springboot'
attributes 'Bundle-Name': 'Spring Boot Extension for Jib Gradle Plugin'
attributes 'Bundle-Vendor': 'Google LLC'
attributes 'Bundle-DocURL': 'https://github.com/GoogleContainerTools/jib-extensions'
attributes 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0'
attributes 'Export-Package': 'com.google.cloud.tools.jib.*'
}
}

/* RELEASE */
configureMavenRelease()

publishing {
publications {
mavenJava(MavenPublication) {
pom {
name = 'Spring Boot Extension for Jib Gradle Plugin'
description = 'Provides extended support for Spring Boot projects.'
}
from components.java
}
}
}

// Release plugin (git release commits and version updates)
release {
tagTemplate = 'v$version-jib-spring-boot-extension-gradle'
git {
requireBranch = /^jib-spring-boot-extension-gradle-release-v\d+.*$/ //regex
}
}
/* RELEASE */

/* ECLIPSE */
// TODO: remove after upgrading to Gradle 5.6. (https://github.com/eclipse/buildship/issues/689)
// Also remove the 'eclipse' plugin.
eclipse.classpath.file.whenMerged {
entries.findAll {
it.path in ['src/test/java', 'src/test/resources', 'src/integration-test/java', 'src/integration-test/resources']
}.each {
it.entryAttributes['test'] = 'true'
}
}
/* ECLIPSE */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = 0.1.0-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright 2020 Google LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.cloud.tools.jib.gradle.extension.springboot;

import com.google.cloud.tools.jib.api.JavaContainerBuilder;
import com.google.cloud.tools.jib.api.buildplan.ContainerBuildPlan;
import com.google.cloud.tools.jib.api.buildplan.FileEntriesLayer;
import com.google.cloud.tools.jib.api.buildplan.FileEntry;
import com.google.cloud.tools.jib.api.buildplan.LayerObject;
import com.google.cloud.tools.jib.gradle.extension.GradleData;
import com.google.cloud.tools.jib.gradle.extension.JibGradlePluginExtension;
import com.google.cloud.tools.jib.plugins.extension.ExtensionLogger;
import com.google.cloud.tools.jib.plugins.extension.ExtensionLogger.LogLevel;
import com.google.cloud.tools.jib.plugins.extension.JibPluginExtensionException;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.UnknownTaskException;
import org.gradle.api.tasks.TaskProvider;
import org.springframework.boot.gradle.tasks.bundling.BootJar;

public class JibSpringBootExtension implements JibGradlePluginExtension<Void> {

@Override
public Optional<Class<Void>> getExtraConfigType() {
return Optional.empty();
}

@Override
public ContainerBuildPlan extendContainerBuildPlan(
ContainerBuildPlan buildPlan,
Map<String, String> properties,
Optional<Void> config,
GradleData gradleData,
ExtensionLogger logger)
throws JibPluginExtensionException {
logger.log(LogLevel.LIFECYCLE, "Running Jib Spring Boot extension");

if (!shouldExcludeDevtools(gradleData.getProject(), properties, logger)) {
logger.log(LogLevel.INFO, "Keeping spring-boot-devtools (if any)");
return buildPlan;
}
logger.log(LogLevel.INFO, "Removing spring-boot-devtools (if any)");

List<LayerObject> newLayers =
buildPlan
.getLayers()
.stream()
.map(JibSpringBootExtension::filterOutDevtools)
.collect(Collectors.toList());
return buildPlan.toBuilder().setLayers(newLayers).build();
}

@VisibleForTesting
static boolean isDevtoolsJar(File file) {
return file.getName().startsWith("spring-boot-devtools-") && file.getName().endsWith(".jar");
}

@VisibleForTesting
static boolean shouldExcludeDevtools(
Project project, Map<String, String> extensionProperties, ExtensionLogger logger) {
try {
TaskProvider<Task> taskProvider = project.getTasks().named("bootJar");
loosebazooka marked this conversation as resolved.
Show resolved Hide resolved
if (taskProvider.getOrNull() instanceof BootJar) {
BootJar bootJar = ((BootJar) taskProvider.get());

boolean useDeprecatedExcludeDevtools =
Boolean.valueOf(
extensionProperties.getOrDefault("useDeprecatedExcludeDevtoolsOption", "false"));
if (useDeprecatedExcludeDevtools) {
return bootJar.isExcludeDevtools();
}

// Since Spring 2.3.0, "excludeDevtools" is deprecated and has no effect. (Also its default
// is no longer "true".) The new guide to include devtools is to explicitly add
// "developmentOnly" to "bootJar.classpath".
// https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-including-development-only-dependencies
boolean noDevtoolsJarOnClasspath =
loosebazooka marked this conversation as resolved.
Show resolved Hide resolved
bootJar.getClasspath().filter(JibSpringBootExtension::isDevtoolsJar).isEmpty();
return noDevtoolsJarOnClasspath;
}
} catch (UnknownTaskException ignored) { // fall through
}

logger.log(LogLevel.WARN, "Jib Spring Boot extension: project doesn't have bootJar task?");
return true;
}

@VisibleForTesting
static LayerObject filterOutDevtools(LayerObject layerObject) {
String dependencyLayerName = JavaContainerBuilder.LayerType.DEPENDENCIES.getName();
if (!dependencyLayerName.equals(layerObject.getName())) {
return layerObject;
}

FileEntriesLayer layer = (FileEntriesLayer) layerObject;
Predicate<FileEntry> notDevtoolsJar =
fileEntry -> !isDevtoolsJar(fileEntry.getSourceFile().toFile());
List<FileEntry> newEntries =
layer.getEntries().stream().filter(notDevtoolsJar).collect(Collectors.toList());
return layer.toBuilder().setEntries(newEntries).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.google.cloud.tools.jib.gradle.extension.springboot.JibSpringBootExtension
Loading