Skip to content

Commit

Permalink
Merge pull request #29 from chickenlj/add-dockerfile
Browse files Browse the repository at this point in the history
Add dockerfile support, update native support
  • Loading branch information
chickenlj authored Dec 26, 2023
2 parents e04dd4d + 4600fd4 commit 62a5546
Show file tree
Hide file tree
Showing 25 changed files with 1,805 additions and 180 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2022 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 com.alibaba.initializer.generation.extension;

import com.alibaba.initializer.metadata.Module;
import com.alibaba.initializer.project.InitializerProjectDescription;
import io.spring.initializr.generator.project.contributor.ProjectContributor;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Map;

public class DockerfileCodeContributor implements ProjectContributor {
private static final String DOCKERFILE_PATH = "/docker/Dockerfile";
public static final String PLACEHOLDER = "${JDK_IMAGE}";

private static final Map<String, String> JDK_IMAGE_VERSIONS = Map.of(
"1.8", "openjdk:8-jdk-alpine",
"11", "openjdk:11-jdk-alpine",
"17", "openjdk:17-jdk-alpine",
"21", "openjdk:21-jdk-alpine"
);

@Autowired
private Module module;

@Autowired
protected InitializerProjectDescription description;

@Override
public void contribute(Path projectRoot) throws IOException {
if (this.module.isRoot()) {
writeDockerfile(projectRoot, "Dockerfile");

if (description.getRequestedDependencies().containsKey("dubbo-feature-native")) {
writeDockerfile(projectRoot, "Dockerfile.native");
}
}
}

private void writeDockerfile(Path projectRoot, String dockerFileName) {
URL url = getClass().getResource(DOCKERFILE_PATH);
if (url == null) {
throw new IllegalArgumentException("Resource not found on classpath: " + DOCKERFILE_PATH);
}

try {
URI uri = url.toURI();
// Read the file content
String dockerFileTemplate = Files.readString(Paths.get(uri));

// Replace the placeholders
String dockerFileContent = dockerFileTemplate.replace(PLACEHOLDER, JDK_IMAGE_VERSIONS.get(description.getLanguage().jvmVersion()));

Path targetFile = Files.createFile(projectRoot.resolve(dockerFileName));

try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(targetFile))) {
writer.write(dockerFileContent);
}
} catch (Exception e) {
throw new FileSystemNotFoundException("Resource is not located in the file system: " + e.getMessage());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.alibaba.initializer.generation.extension.codes.sample;

import com.alibaba.initializer.generation.extension.DockerfileCodeContributor;
import com.alibaba.initializer.generation.extension.SampleCodeContributor;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;

Expand All @@ -32,4 +33,9 @@ public SampleCodeContributor sampleCodeContributor() {
return new SampleCodeContributor();
}

@Bean
public DockerfileCodeContributor dockerfileContributor() {
return new DockerfileCodeContributor();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2012-2023 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 io.spring.initializr.generator.spring.build.maven;

import io.spring.initializr.generator.buildsystem.BillOfMaterials;
import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.spring.build.BuildCustomizer;
import io.spring.initializr.generator.version.VersionProperty;
import io.spring.initializr.metadata.InitializrConfiguration.Env.Maven;
import io.spring.initializr.metadata.InitializrConfiguration.Env.Maven.ParentPom;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.support.MetadataBuildItemMapper;

/**
* The default {@link Maven} {@link BuildCustomizer}.
*
* @author Stephane Nicoll
*/
public class DefaultMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {

private final ProjectDescription description;

private final InitializrMetadata metadata;

public DefaultMavenBuildCustomizer(ProjectDescription description, InitializrMetadata metadata) {
this.description = description;
this.metadata = metadata;
}

@Override
public void customize(MavenBuild build) {
build.settings().name(this.description.getName()).description(this.description.getDescription());
build.properties().property("java.version", this.description.getLanguage().jvmVersion());
build.plugins().add("org.springframework.boot", "spring-boot-maven-plugin");

Maven maven = this.metadata.getConfiguration().getEnv().getMaven();
String springBootVersion = this.description.getPlatformVersion().toString();
ParentPom parentPom = maven.resolveParentPom(springBootVersion);
if (parentPom.isIncludeSpringBootBom()) {
String versionProperty = "spring-boot.version";
BillOfMaterials springBootBom = MetadataBuildItemMapper
.toBom(this.metadata.createSpringBootBom(springBootVersion, versionProperty));
if (!hasBom(build, springBootBom)) {
build.properties().version(VersionProperty.of(versionProperty, true), springBootVersion);
build.boms().add("spring-boot", springBootBom);
}
}
if (!maven.isSpringBootStarterParent(parentPom)) {
build.properties()
.property("project.build.sourceEncoding", "UTF-8")
.property("project.reporting.outputEncoding", "UTF-8");
}
build.settings()
.parent(parentPom.getGroupId(), parentPom.getArtifactId(), parentPom.getVersion(),
parentPom.getRelativePath());
}

private boolean hasBom(MavenBuild build, BillOfMaterials bom) {
return build.boms()
.items()
.anyMatch((candidate) -> candidate.getGroupId().equals(bom.getGroupId())
&& candidate.getArtifactId().equals(bom.getArtifactId()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2012-2019 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 io.spring.initializr.generator.spring.build.maven;

import io.spring.initializr.generator.buildsystem.BuildWriter;
import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildWriter;
import io.spring.initializr.generator.io.IndentingWriter;
import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.project.contributor.ProjectContributor;

import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* {@link ProjectContributor} to contribute the files for a {@link MavenBuild}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
public class MavenBuildProjectContributor implements BuildWriter, ProjectContributor {

private final MavenBuild build;

private final IndentingWriterFactory indentingWriterFactory;

private final MavenBuildWriter buildWriter;

public MavenBuildProjectContributor(MavenBuild build, IndentingWriterFactory indentingWriterFactory) {
this.build = build;
this.indentingWriterFactory = indentingWriterFactory;
this.buildWriter = new MavenBuildWriter();
}

@Override
public void contribute(Path projectRoot) throws IOException {
Path pomFile = Files.createFile(projectRoot.resolve("pom.xml"));
writeBuild(Files.newBufferedWriter(pomFile));
}

@Override
public void writeBuild(Writer out) throws IOException {
try (IndentingWriter writer = this.indentingWriterFactory.createIndentingWriter("maven", out)) {
this.buildWriter.writeTo(writer, this.build);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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 io.spring.initializr.generator.spring.build.maven;

import com.alibaba.initializer.generation.condition.ConditionalOnModule;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
import io.spring.initializr.generator.condition.ConditionalOnBuildSystem;
import io.spring.initializr.generator.condition.ConditionalOnPlatformVersion;
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
import org.springframework.context.annotation.Bean;

/**
* {@link ProjectGenerationConfiguration} for generation of projects that depend on Maven.
*
* @author Stephane Nicoll
*/
@ProjectGenerationConfiguration
@ConditionalOnBuildSystem(MavenBuildSystem.ID)
class MavenProjectGenerationConfiguration {

@Bean
@ConditionalOnPlatformVersion("[2.0.0.M1,3.1.0-RC1)")
@ConditionalOnModule(root = true)
public MavenWrapperContributor maven38WrapperContributor() {
return new MavenWrapperContributor("3.8");
}

@Bean
@ConditionalOnPlatformVersion("3.1.0-RC1")
@ConditionalOnModule(root = true)
public MavenWrapperContributor mavenWrapperContributor() {
return new MavenWrapperContributor("3");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2012-2023 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 io.spring.initializr.generator.spring.build.maven;

import io.spring.initializr.generator.project.contributor.MultipleResourcesProjectContributor;

/**
* A {@link MultipleResourcesProjectContributor} that contributes Maven's wrapper to a
* project.
*
* @author Andy Wilkinson
*/
class MavenWrapperContributor extends MultipleResourcesProjectContributor {

MavenWrapperContributor(String mavenVersion) {
super("classpath:maven/" + mavenVersion + "/wrapper",
(filename) -> filename.equals("mvnw") || filename.equals("mvnw.cmd"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2012-2023 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 io.spring.initializr.generator.spring.build.maven;

import io.spring.initializr.generator.buildsystem.Dependency;
import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.buildsystem.maven.MavenDependency;
import io.spring.initializr.generator.spring.build.BuildCustomizer;

/**
* Maven {@link BuildCustomizer} that sets the "optional" flag for a dependency.
*
* @author Stephane Nicoll
* @author Moritz Halbritter
*/
public class OptionalDependencyMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {

private final String dependencyId;

/**
* Create a new instance with the identifier for the dependency.
* @param dependencyId the id of the dependency
*/
public OptionalDependencyMavenBuildCustomizer(String dependencyId) {
this.dependencyId = dependencyId;
}

@Override
public void customize(MavenBuild build) {
Dependency dependency = build.dependencies().get(this.dependencyId);
if (dependency != null) {
build.dependencies().add(this.dependencyId, MavenDependency.from(dependency).optional(true));
}
}

}
Loading

0 comments on commit 62a5546

Please sign in to comment.