forked from spring-projects/spring-boot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Java implementation of the buildpacks.io specification allowing projects to be packaged into OCI containers. The `builder` class provides a Java equivalent of `pack build` command and is based on the `pack` CLI Go code published at https://github.com/buildpacks/pack. Closes spring-projectsgh-19828
- Loading branch information
Showing
152 changed files
with
14,613 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
spring-boot-project/spring-boot-tools/spring-boot-cloudnativebuildpack/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
plugins { | ||
id 'java-library' | ||
id 'org.springframework.boot.conventions' | ||
id 'org.springframework.boot.deployed' | ||
id 'org.springframework.boot.internal-dependency-management' | ||
} | ||
|
||
description = 'Spring Boot Cloud Native Buildpack' | ||
|
||
dependencies { | ||
api platform(project(':spring-boot-project:spring-boot-parent')) | ||
api 'com.fasterxml.jackson.core:jackson-databind' | ||
api 'com.fasterxml.jackson.module:jackson-module-parameter-names' | ||
api 'net.java.dev.jna:jna-platform' | ||
api 'org.apache.commons:commons-compress:1.19' | ||
api 'org.apache.httpcomponents:httpclient' | ||
api 'org.springframework:spring-core' | ||
|
||
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support') | ||
testImplementation 'com.jayway.jsonpath:json-path' | ||
testImplementation 'org.assertj:assertj-core' | ||
testImplementation 'org.testcontainers:testcontainers' | ||
testImplementation 'org.hamcrest:hamcrest' | ||
testImplementation 'org.junit.jupiter:junit-jupiter' | ||
testImplementation 'org.mockito:mockito-core' | ||
testImplementation 'org.mockito:mockito-junit-jupiter' | ||
testImplementation 'org.skyscreamer:jsonassert' | ||
} |
96 changes: 96 additions & 0 deletions
96
...k/src/main/java/org/springframework/boot/cloudnativebuildpack/build/AbstractBuildLog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright 2012-2020 the original author or authors. | ||
* | ||
* 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 | ||
* | ||
* https://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 org.springframework.boot.cloudnativebuildpack.build; | ||
|
||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
import org.springframework.boot.cloudnativebuildpack.docker.LogUpdateEvent; | ||
import org.springframework.boot.cloudnativebuildpack.docker.TotalProgressEvent; | ||
import org.springframework.boot.cloudnativebuildpack.docker.type.Image; | ||
import org.springframework.boot.cloudnativebuildpack.docker.type.ImageReference; | ||
import org.springframework.boot.cloudnativebuildpack.docker.type.VolumeName; | ||
|
||
/** | ||
* Base class for {@link BuildLog} implementations. | ||
* | ||
* @author Phillip Webb | ||
* @since 2.3.0 | ||
*/ | ||
public abstract class AbstractBuildLog implements BuildLog { | ||
|
||
@Override | ||
public void start(BuildRequest request) { | ||
log("Building image '" + request.getName() + "'"); | ||
log(); | ||
} | ||
|
||
@Override | ||
public Consumer<TotalProgressEvent> pullingBuilder(BuildRequest request, ImageReference imageReference) { | ||
return getProgressConsumer(" > Pulling builder image '" + imageReference + "'"); | ||
} | ||
|
||
@Override | ||
public void pulledBulder(BuildRequest request, Image image) { | ||
log(" > Pulled builder image '" + getDigest(image) + "'"); | ||
} | ||
|
||
@Override | ||
public Consumer<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference) { | ||
return getProgressConsumer(" > Pulling run image '" + imageReference + "'"); | ||
} | ||
|
||
@Override | ||
public void pulledRunImage(BuildRequest request, Image image) { | ||
log(" > Pulled run image '" + getDigest(image) + "'"); | ||
} | ||
|
||
@Override | ||
public void executingLifecycle(BuildRequest request, LifecycleVersion version, VolumeName buildCacheVolume) { | ||
log(" > Executing lifecycle version " + version); | ||
log(" > Using build cache volume '" + buildCacheVolume + "'"); | ||
} | ||
|
||
@Override | ||
public Consumer<LogUpdateEvent> runningPhase(BuildRequest request, String name) { | ||
log(); | ||
log(" > Running " + name); | ||
String prefix = String.format(" %-14s", "[" + name + "] "); | ||
return (event) -> log(prefix + event); | ||
} | ||
|
||
@Override | ||
public void executedLifecycle(BuildRequest request) { | ||
log(); | ||
log("Successfully built image '" + request.getName() + "'"); | ||
log(); | ||
} | ||
|
||
private String getDigest(Image image) { | ||
List<String> digests = image.getDigests(); | ||
return (digests.isEmpty() ? "" : digests.get(0)); | ||
} | ||
|
||
protected void log() { | ||
log(""); | ||
} | ||
|
||
protected abstract void log(String message); | ||
|
||
protected abstract Consumer<TotalProgressEvent> getProgressConsumer(String message); | ||
|
||
} |
135 changes: 135 additions & 0 deletions
135
...ildpack/src/main/java/org/springframework/boot/cloudnativebuildpack/build/ApiVersion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright 2012-2020 the original author or authors. | ||
* | ||
* 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 | ||
* | ||
* https://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 org.springframework.boot.cloudnativebuildpack.build; | ||
|
||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import org.springframework.util.Assert; | ||
|
||
/** | ||
* API Version number comprised a major and minor value. | ||
* | ||
* @author Phillip Webb | ||
*/ | ||
final class ApiVersion { | ||
|
||
/** | ||
* The platform API version supported by this release. | ||
*/ | ||
static final ApiVersion PLATFORM = new ApiVersion(0, 1); | ||
|
||
private static final Pattern PATTERN = Pattern.compile("^v?(\\d+)\\.(\\d*)$"); | ||
|
||
private final int major; | ||
|
||
private final int minor; | ||
|
||
private ApiVersion(int major, int minor) { | ||
this.major = major; | ||
this.minor = minor; | ||
} | ||
|
||
/** | ||
* Return the major version number. | ||
* @return the major version | ||
*/ | ||
int getMajor() { | ||
return this.major; | ||
} | ||
|
||
/** | ||
* Return the minor version number. | ||
* @return the minor version | ||
*/ | ||
int getMinor() { | ||
return this.minor; | ||
} | ||
|
||
/** | ||
* Assert that this API version supports the specified version. | ||
* @param other the version to check against | ||
* @see #supports(ApiVersion) | ||
*/ | ||
void assertSupports(ApiVersion other) { | ||
if (!supports(other)) { | ||
throw new IllegalStateException( | ||
"Version '" + other + "' is not supported by this version ('" + this + "')"); | ||
} | ||
} | ||
|
||
/** | ||
* Returns if this API version supports the given version. A {@code 0.x} matches only | ||
* the same version number. A 1.x or higher release matches when the versions have the | ||
* same major version and a minor that is equal or greater. | ||
* @param other the version to check against | ||
* @return of the specified API is supported | ||
* @see #assertSupports(ApiVersion) | ||
*/ | ||
boolean supports(ApiVersion other) { | ||
if (equals(other)) { | ||
return true; | ||
} | ||
if (this.major == 0 || this.major != other.major) { | ||
return false; | ||
} | ||
return this.minor >= other.minor; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null || getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
ApiVersion other = (ApiVersion) obj; | ||
return (this.major == other.major) && (this.minor == other.minor); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return this.major * 31 + this.minor; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "v" + this.major + "." + this.minor; | ||
} | ||
|
||
/** | ||
* Factory method to parse a string into an {@link ApiVersion} instance. | ||
* @param value the value to parse. | ||
* @return the corresponding {@link ApiVersion} | ||
* @throws IllegalArgumentException if the value could not be parsed | ||
*/ | ||
static ApiVersion parse(String value) { | ||
Assert.hasText(value, "Value must not be empty"); | ||
Matcher matcher = PATTERN.matcher(value); | ||
Assert.isTrue(matcher.matches(), "Malformed version number '" + value + "'"); | ||
try { | ||
int major = Integer.parseInt(matcher.group(1)); | ||
int minor = Integer.parseInt(matcher.group(2)); | ||
return new ApiVersion(major, minor); | ||
} | ||
catch (NumberFormatException ex) { | ||
throw new IllegalArgumentException("Malformed version number '" + value + "'", ex); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.