support hide dependency and codeOnly dependency (#20)

* add custom doc

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* add custom doc

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* add custom doc

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* add custom doc

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* refactor docs

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* allow hidden dependency

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* support sample code write to project root

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* spell fix

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* spell fix

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* allow hidden dependency

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* support sample code write to project root

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* add codeOnly depencencies proeprty of dependency

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* support codeonly dependency

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* hide group

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* support dependency of dependency

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* bugfix && page label update

Signed-off-by: theonefx <chenxilzx1@gmail.com>

* misspelling

Signed-off-by: theonefx <chenxilzx1@gmail.com>

Signed-off-by: theonefx <chenxilzx1@gmail.com>
This commit is contained in:
TheoneFx
2022-12-15 20:09:05 +08:00
committed by GitHub
parent 5545232a02
commit e2be410267
24 changed files with 417 additions and 318 deletions

View File

@@ -16,17 +16,6 @@
package com.alibaba.initializer.configure;
import java.util.Enumeration;
import java.util.Map;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.initializer.controller.InitializerProjectMetadataController;
import com.alibaba.initializer.controller.InitializerProjectRequestToDescriptionConverter;
import com.alibaba.initializer.core.template.CodeTemplateRepoRenderer;
@@ -37,6 +26,7 @@ import com.alibaba.initializer.core.template.loader.LocalRepoTemplateLoader;
import com.alibaba.initializer.core.template.loader.RootRepoTemplateLoader;
import com.alibaba.initializer.generation.BootstrapProjectGenerator;
import com.alibaba.initializer.generation.InitializerProjectGenerationInvoker;
import com.alibaba.initializer.generation.extension.dependency.DependencyOfDependencyDescriptionCustomizer;
import com.alibaba.initializer.protocol.CodeGenerationProtocolFilter;
import com.alibaba.initializer.protocol.archive.ProjectArchiveHandler;
import com.alibaba.initializer.protocol.git.ProjectGenerationResolver;
@@ -48,9 +38,9 @@ import io.spring.initializr.generator.io.SimpleIndentStrategy;
import io.spring.initializr.metadata.DependencyMetadataProvider;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.start.site.project.JavaVersionProjectDescriptionCustomizer;
import static java.util.concurrent.TimeUnit.SECONDS;
import org.eclipse.jgit.http.server.GitFilter;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
@@ -59,7 +49,15 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import static java.util.concurrent.TimeUnit.SECONDS;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
@@ -223,4 +221,9 @@ public class BootstrapProjectGenerationConfigure {
.setStatisticsEnabled(true)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(duration)));
}
@Bean
public DependencyOfDependencyDescriptionCustomizer dependencyOfDependencyDescriptionCustomizer(InitializrMetadataProvider metadataProvider) {
return new DependencyOfDependencyDescriptionCustomizer(metadataProvider);
}
}

View File

@@ -16,20 +16,25 @@
package com.alibaba.initializer.controller;
import java.lang.reflect.Field;
import java.util.stream.Collectors;
import com.alibaba.initializer.metadata.ArchitectureCapability;
import com.alibaba.initializer.metadata.EnhancedDependency;
import com.alibaba.initializer.metadata.EnhancedDependencyGroup;
import com.alibaba.initializer.metadata.InitializerMetadata;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.DependenciesCapability;
import io.spring.initializr.metadata.DependencyGroup;
import io.spring.initializr.metadata.Describable;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.web.mapper.InitializrMetadataV2JsonMapper;
import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariables;
import java.lang.reflect.Field;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
@@ -59,7 +64,6 @@ public class InitializerMetadataV2JsonMapper extends InitializrMetadataV2JsonMap
}
}
@Override
public String write(InitializrMetadata metadata, String appUrl) {
InitializerMetadata initializerMetadata = (InitializerMetadata) metadata;
@@ -89,10 +93,51 @@ public class InitializerMetadataV2JsonMapper extends InitializrMetadataV2JsonMap
single.put("default", defaultType.getId());
}
ArrayNode values = nodeFactory().arrayNode();
values.addAll(capability.getContent().stream().map(this::mapValue)
.collect(Collectors.toList()));
values.addAll(capability.getContent().stream().map(this::mapValue).collect(Collectors.toList()));
single.set("values", values);
parent.set(capability.getId(), single);
}
@Override
protected void dependencies(ObjectNode parent, DependenciesCapability capability) {
ObjectNode dependencies = nodeFactory().objectNode();
dependencies.put("type", capability.getType().getName());
ArrayNode values = nodeFactory().arrayNode();
values.addAll(capability.getContent().stream().filter(group -> {
if (group instanceof EnhancedDependencyGroup) {
if (((EnhancedDependencyGroup) group).isHide()) {
// do not add hidden dependency group to json meta
return false;
}
}
return true;
}).map(this::mapDependencyGroup).collect(Collectors.toList()));
dependencies.set("values", values);
parent.set(capability.getId(), dependencies);
}
@Override
protected ObjectNode mapDependencyGroup(DependencyGroup group) {
ObjectNode result = nodeFactory().objectNode();
result.put("name", group.getName());
if ((group instanceof Describable) && ((Describable) group).getDescription() != null) {
result.put("description", ((Describable) group).getDescription());
}
ArrayNode items = nodeFactory().arrayNode();
group.getContent().forEach((it) -> {
if (it instanceof EnhancedDependency) {
if (((EnhancedDependency) it).isHide()) {
// do not add hidden dependency to json metadata
return;
}
}
JsonNode dependency = mapDependency(it);
if (dependency != null) {
items.add(dependency);
}
});
result.set("values", items);
return result;
}
}

View File

@@ -24,7 +24,7 @@ public interface BootstrapTemplateRenderConstants {
String KEY_BASE_VERSION = "version";
String KEY_SPRINGBOOT_VERSION = "spring-boot.version";
String KEY_JAVA_VERSION = "java.version";
String KEY_TARGET_MODULE = "targetModule";
String KEY_MODULE = "module";
String KEY_ARTIFACT_ID = "artifactId";
String KEY_GROUP_ID = "groupId";

View File

@@ -38,7 +38,7 @@ import com.alibaba.initializer.core.template.CodeTemplateRepoRenderer;
import com.alibaba.initializer.core.template.RepoRenderResult;
import com.alibaba.initializer.core.template.loader.RootRepoTemplateLoader;
import com.alibaba.initializer.generation.constants.BootstrapTemplateRenderConstants;
import com.alibaba.initializer.metadata.ArchedDependency;
import com.alibaba.initializer.metadata.EnhancedDependency;
import com.alibaba.initializer.metadata.Architecture;
import com.alibaba.initializer.metadata.DependencyArchConfig;
import com.alibaba.initializer.metadata.InitializerMetadata;
@@ -113,7 +113,11 @@ public class SampleCodeContributor implements ProjectContributor {
List<RepoRenderResult.TemplateRenderResult> resources = result.getResults("resources");
resources.forEach(res -> writeResources(res, language, projectRoot, structure));
// TODO write root, how to separate root resource from code & resource ?
// write root
if (module.isRoot()) {
List<RepoRenderResult.TemplateRenderResult> roots = result.getResults("root");
roots.forEach(res -> writeRoot(res, language, projectRoot, structure));
}
});
}
@@ -148,7 +152,7 @@ public class SampleCodeContributor implements ProjectContributor {
private boolean filterByModule(Map.Entry<String, Dependency> entry, Architecture arch) {
String id = entry.getKey();
ArchedDependency dep = getMetaDependency(id);
EnhancedDependency dep = getMetaDependency(id);
if (dep == null) {
return true;
@@ -181,12 +185,12 @@ public class SampleCodeContributor implements ProjectContributor {
}
}
private ArchedDependency getMetaDependency(String id) {
private EnhancedDependency getMetaDependency(String id) {
for (DependencyGroup group : meta.getDependencies().getContent()) {
for (io.spring.initializr.metadata.Dependency dependency : group.getContent()) {
if (StringUtils.equalsIgnoreCase(dependency.getId(), id)) {
return (ArchedDependency) dependency;
return (EnhancedDependency) dependency;
}
}
}
@@ -219,6 +223,17 @@ public class SampleCodeContributor implements ProjectContributor {
}
}
protected void writeRoot(RepoRenderResult.TemplateRenderResult result, Language language, Path projectRoot, SourceStructure structure) {
Path path = projectRoot.resolve(result.getPath().subpath(1, result.getPath().getNameCount()));
String content = result.getContent();
try {
doWirte(path, content, true);
} catch (IOException e) {
throw new BizRuntimeException(ErrorCodeEnum.SYSTEM_ERROR, "write code error", e);
}
}
protected Path reslovePackagePath(Path sourceRoot, String content) {
Path path = sourceRoot;
Matcher matcher = Pattern.compile(PACKAGE_PATTEN).matcher(content);

View File

@@ -81,16 +81,9 @@ public class ArchedMavenProjectGenerationConfiguration {
}
@Bean
@ConditionalOnArchitectured
public MulitModuleMavenBuildProjectContributor mulitModuleavenBuildProjectContributor(
MavenBuild build, IndentingWriterFactory indentingWriterFactory) {
return new MulitModuleMavenBuildProjectContributor(build, indentingWriterFactory);
MavenBuild build, IndentingWriterFactory indentingWriterFactory,InitializrMetadata metadata) {
return new MulitModuleMavenBuildProjectContributor(build, indentingWriterFactory, metadata);
}
@Bean
@ConditionalOnMissingBean
public MavenBuildProjectContributor mavenBuildProjectContributor(
MavenBuild build, IndentingWriterFactory indentingWriterFactory) {
return new MavenBuildProjectContributor(build, indentingWriterFactory);
}
}

View File

@@ -37,9 +37,11 @@ import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.spring.build.maven.MavenBuildProjectContributor;
import io.spring.initializr.generator.version.VersionProperty;
import io.spring.initializr.generator.version.VersionReference;
import io.spring.initializr.metadata.InitializrMetadata;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
@@ -53,11 +55,14 @@ public class MulitModuleMavenBuildProjectContributor extends MavenBuildProjectCo
private final MulitModuleMavenBuildWriter buildWriter;
public MulitModuleMavenBuildProjectContributor(MavenBuild build, IndentingWriterFactory indentingWriterFactory) {
private final InitializrMetadata metadata;
public MulitModuleMavenBuildProjectContributor(MavenBuild build, IndentingWriterFactory indentingWriterFactory, InitializrMetadata metadata) {
super(build, indentingWriterFactory);
this.build = build;
this.indentingWriterFactory = indentingWriterFactory;
this.buildWriter = new MulitModuleMavenBuildWriter();
this.metadata = metadata;
this.buildWriter = new MulitModuleMavenBuildWriter(metadata);
// use reflext to replace MavenBuildWriter
try {
@@ -90,58 +95,63 @@ public class MulitModuleMavenBuildProjectContributor extends MavenBuildProjectCo
builder.configuration(conf -> conf.add("mainClass", description.getPackageName() + "." + description.getApplicationName()).add("skip", "true"));
});
// add submodule in root dependencymanager
for (Module subModule : arch.getSubModules()) {
this.build.boms().add(subModule.getName(),
DependencyBillOfMaterials
.withCoordinates(description.getGroupId(), subModule.getName())
.type(null)
.scope(null)
.version(VersionReference.ofValue(description.getVersion()))
);
}
if (arch == null || CollectionUtils.isEmpty(arch.getSubModules())) {
super.contribute(projectRoot);
} else {
List<Module> modules = arch.getSubModules();
// create new pom.xml file
super.contribute(projectRoot);
// insert <modules /> to pom.xml
List<Module> modules = description.getArchitecture().getSubModules();
Path pomFile = projectRoot.resolve("pom.xml");
try (RandomAccessFile rw = new RandomAccessFile(pomFile.toFile(), "rw")) {
StringBuffer rewrited = new StringBuffer();
//not utf-8 but ISO-8859-1 encodng
String rawLine;
int index = -1;
int insetIndex = findModulesInsertLine(pomFile);
while ((rawLine = rw.readLine()) != null) {
index++;
//trans encoding style
String line = new String(rawLine.getBytes("ISO-8859-1"), "UTF-8");
rewrited.append(line).append("\n");
if (index == insetIndex) {
StringWriter sw = new StringWriter();
IndentingWriter writer = indentingWriterFactory
.createIndentingWriter("maven", sw);
writer.println();
writer.indented(() -> {
writer.println("<modules>");
writer.indented(() -> modules.stream()
.map(name -> "<module>" + name.getName() + "</module>")
.forEach(writer::println));
writer.println("</modules>\n");
});
rewrited.append(sw);
}
// add submodule in root dependencymanager
for (Module subModule : arch.getSubModules()) {
this.build.boms().add(subModule.getName(),
DependencyBillOfMaterials
.withCoordinates(description.getGroupId(), subModule.getName())
.type(null)
.scope(null)
.version(VersionReference.ofValue(description.getVersion()))
);
}
rw.seek(0);
rw.write(rewrited.toString().getBytes());
}
} else {
// create new pom.xml file
super.contribute(projectRoot);
// insert <modules /> to pom.xml
Path pomFile = projectRoot.resolve("pom.xml");
try (RandomAccessFile rw = new RandomAccessFile(pomFile.toFile(), "rw")) {
StringBuffer rewrited = new StringBuffer();
//not utf-8 but ISO-8859-1 encodng
String rawLine;
int index = -1;
int insetIndex = findModulesInsertLine(pomFile);
while ((rawLine = rw.readLine()) != null) {
index++;
//trans encoding style
String line = new String(rawLine.getBytes("ISO-8859-1"), "UTF-8");
rewrited.append(line).append("\n");
if (index == insetIndex) {
StringWriter sw = new StringWriter();
IndentingWriter writer = indentingWriterFactory
.createIndentingWriter("maven", sw);
writer.println();
writer.indented(() -> {
writer.println("<modules>");
writer.indented(() -> modules.stream()
.map(name -> "<module>" + name.getName() + "</module>")
.forEach(writer::println));
writer.println("</modules>\n");
});
rewrited.append(sw);
}
}
rw.seek(0);
rw.write(rewrited.toString().getBytes());
}
}
} else {
if (module.isMain()) {
// main module depend all other submodules
List<Module> subModules = arch.getSubModules();

View File

@@ -16,19 +16,8 @@
package com.alibaba.initializer.generation.extension.build.maven;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.alibaba.initializer.generation.extension.build.DependencyBillOfMaterials;
import com.alibaba.initializer.metadata.EnhancedDependency;
import io.spring.initializr.generator.buildsystem.BillOfMaterials;
import io.spring.initializr.generator.buildsystem.BomContainer;
import io.spring.initializr.generator.buildsystem.Dependency;
@@ -56,10 +45,23 @@ import io.spring.initializr.generator.buildsystem.maven.MavenScm;
import io.spring.initializr.generator.io.IndentingWriter;
import io.spring.initializr.generator.version.VersionProperty;
import io.spring.initializr.generator.version.VersionReference;
import io.spring.initializr.metadata.InitializrMetadata;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* copy from MavenBuildWriter to rewrite prvate methods
*
@@ -67,6 +69,12 @@ import org.springframework.util.StringUtils;
*/
public class MulitModuleMavenBuildWriter extends MavenBuildWriter {
private final InitializrMetadata metadata;
public MulitModuleMavenBuildWriter(InitializrMetadata metadata) {
this.metadata = metadata;
}
/**
* Write a {@linkplain MavenBuild pom.xml} using the specified
* {@linkplain IndentingWriter writer}.
@@ -94,15 +102,6 @@ public class MulitModuleMavenBuildWriter extends MavenBuildWriter {
});
}
/**
* Return the {@link Comparator} to use to sort dependencies.
*
* @return a dependency comparator
*/
protected Comparator<Dependency> getDependencyComparator() {
return DependencyComparator.INSTANCE;
}
private void writeProject(IndentingWriter writer, Runnable whenWritten) {
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
writer.println(
@@ -213,21 +212,24 @@ public class MulitModuleMavenBuildWriter extends MavenBuildWriter {
}
private void writeDependencies(IndentingWriter writer, DependencyContainer dependencies) {
if (dependencies.isEmpty()) {
List<Dependency> items = dependencies.ids()
.filter(this::isNotCodeOnly)
.map(dependencies::get)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(items)) {
return;
}
writeElement(writer, "dependencies", () -> {
Collection<Dependency> compiledDependencies = writeDependencies(writer, dependencies,
Collection<Dependency> compiledDependencies = writeDependencies(writer, items,
(scope) -> scope == null || scope == DependencyScope.COMPILE);
if (!compiledDependencies.isEmpty()) {
writer.println();
}
writeDependencies(writer, dependencies, hasScope(DependencyScope.RUNTIME));
writeDependencies(writer, dependencies, hasScope(DependencyScope.COMPILE_ONLY));
writeDependencies(writer, dependencies, hasScope(DependencyScope.ANNOTATION_PROCESSOR));
writeDependencies(writer, dependencies, hasScope(DependencyScope.PROVIDED_RUNTIME));
writeDependencies(writer, dependencies,
hasScope(DependencyScope.TEST_COMPILE, DependencyScope.TEST_RUNTIME));
writeDependencies(writer, items, hasScope(DependencyScope.RUNTIME));
writeDependencies(writer, items, hasScope(DependencyScope.COMPILE_ONLY));
writeDependencies(writer, items, hasScope(DependencyScope.ANNOTATION_PROCESSOR));
writeDependencies(writer, items, hasScope(DependencyScope.PROVIDED_RUNTIME));
writeDependencies(writer, items, hasScope(DependencyScope.TEST_COMPILE, DependencyScope.TEST_RUNTIME));
});
}
@@ -235,14 +237,27 @@ public class MulitModuleMavenBuildWriter extends MavenBuildWriter {
return (scope) -> Arrays.asList(validScopes).contains(scope);
}
private Collection<Dependency> writeDependencies(IndentingWriter writer, DependencyContainer dependencies,
private Collection<Dependency> writeDependencies(IndentingWriter writer, List<Dependency> items,
Predicate<DependencyScope> filter) {
Collection<Dependency> candidates = dependencies.items().filter((dep) -> filter.test(dep.getScope()))
.sorted(getDependencyComparator()).collect(Collectors.toList());
Collection<Dependency> candidates = items.stream()
.filter((dep) -> filter.test(dep.getScope()))
.sorted(getDependencyComparator())
.collect(Collectors.toList());
writeCollection(writer, candidates, this::writeDependency);
return candidates;
}
private boolean isNotCodeOnly(String id) {
io.spring.initializr.metadata.Dependency dep = metadata.getDependencies().get(id);
if (dep == null) {
return true;
}
if (dep instanceof EnhancedDependency edep) {
return !edep.isCodeOnly();
}
return true;
}
private void writeDependency(IndentingWriter writer, Dependency dependency) {
writeElement(writer, "dependency", () -> {
writeSingleElement(writer, "groupId", dependency.getGroupId());

View File

@@ -0,0 +1,75 @@
/*
* 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.dependency;
import com.alibaba.initializer.metadata.EnhancedDependency;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectDescriptionCustomizer;
import io.spring.initializr.metadata.DependenciesCapability;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.metadata.support.MetadataBuildItemMapper;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
/**
* auto add dependency of dependency
*
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
public class DependencyOfDependencyDescriptionCustomizer implements ProjectDescriptionCustomizer {
private final InitializrMetadataProvider provider;
public DependencyOfDependencyDescriptionCustomizer(InitializrMetadataProvider dependencyMetadataProvider) {
this.provider = dependencyMetadataProvider;
}
@Override
public void customize(MutableProjectDescription description) {
InitializrMetadata metadata = provider.get();
DependenciesCapability allDependency = metadata.getDependencies();
Set<String> ids = description.getRequestedDependencies().keySet();
ids.stream().map(allDependency::get).forEach(dep -> this.appendSubDep(dep, description, allDependency));
}
private void appendSubDep(Dependency dependency, MutableProjectDescription description, DependenciesCapability allDependency) {
if (!description.getRequestedDependencies().containsKey(dependency.getId())) {
description.addDependency(dependency.getId(), MetadataBuildItemMapper.toDependency(dependency));
}
if (!(dependency instanceof EnhancedDependency edep)) {
return;
}
List<String> subDeps = edep.getDependencies();
if (CollectionUtils.isEmpty(subDeps)) {
return;
}
subDeps.stream().map(allDependency::get).forEach(dep -> this.appendSubDep(dep, description, allDependency));
}
}

View File

@@ -1,52 +0,0 @@
/*
* 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.dependency;
import java.util.Set;
import com.alibaba.initializer.metadata.InitializerMetadata;
import com.alibaba.initializer.metadata.Module;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectDescriptionCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
/**
* filter dependency for multi-arch module
*
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
public class MultiArchModuleDependencyFilterDescriptionCustomizer implements ProjectDescriptionCustomizer {
@Autowired
private Module module;
@Autowired
private InitializerMetadata metadata;
@Override
public void customize(MutableProjectDescription description) {
Set<String> ids = description.getRequestedDependencies().keySet();
if (!module.isMain()) {
ids.forEach(id -> description.getRequestedDependencies().remove(id));
}
}
}

View File

@@ -16,16 +16,37 @@
package com.alibaba.initializer.metadata;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.spring.initializr.metadata.Dependency;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ArchedDependency extends Dependency {
public class EnhancedDependency extends Dependency {
/**
* whether display on web page or idea plugin
* if true, this dependency will hide from web page or idea plugin.
* default false.
*/
private boolean hide = false;
/**
* If true, this dependency will not add any gradle | maven dependency,
* but only attach corresponding sample code to generated project.
* default false.
*/
private boolean codeOnly = false;
/**
* The sub dependencies of current dependency is selected.
* default null.
*/
private List<String> dependencies;
private Map<String, DependencyArchConfig> archCfg;
@@ -36,4 +57,28 @@ public class ArchedDependency extends Dependency {
public void setArchCfg(Map<String, DependencyArchConfig> archCfg) {
this.archCfg = archCfg;
}
public boolean isHide() {
return hide;
}
public void setHide(boolean hide) {
this.hide = hide;
}
public boolean isCodeOnly() {
return codeOnly;
}
public void setCodeOnly(boolean codeOnly) {
this.codeOnly = codeOnly;
}
public List<String> getDependencies() {
return dependencies;
}
public void setDependencies(List<String> dependencies) {
this.dependencies = dependencies;
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.metadata;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.DependencyGroup;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
public class EnhancedDependencyGroup extends DependencyGroup {
private List<EnhancedDependency> content;
/**
* wheather display on web page or idea plugin
* if true, this dependency group will hide from web page or idea plugin
*/
@JsonIgnore
private boolean hide = false;
/**
* Return the {@link EnhancedDependency dependencies} of this group.
*
* @return the content
*/
public List<Dependency> getContent() {
return new ArrayList<>(this.content);
}
public void setContent(List<EnhancedDependency> content) {
this.content = content;
try {
// use reflect to set parent final field
Field parentContentField = DependencyGroup.class.getDeclaredField("content");
parentContentField.setAccessible(true);
parentContentField.set(this, this.content);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public boolean isHide() {
return hide;
}
public void setHide(boolean hide) {
this.hide = hide;
}
}

View File

@@ -1,128 +0,0 @@
/*
* 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.metadata;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.spring.initializr.metadata.DependencyGroup;
/**
* @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
*/
public class InitializerDependencyGroup {
private String name;
@JsonIgnore
private String compatibilityRange;
@JsonIgnore
private String bom;
@JsonIgnore
private String repository;
final List<ArchedDependency> content = new ArrayList<>();
/**
* Return the name of this group.
*
* @return the name of the group
*/
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
/**
* Return the default compatibility range to apply to all dependencies of this group
* unless specified otherwise.
*
* @return the compatibility range
*/
public String getCompatibilityRange() {
return this.compatibilityRange;
}
public void setCompatibilityRange(String compatibilityRange) {
this.compatibilityRange = compatibilityRange;
}
/**
* Return the default bom to associate to all dependencies of this group unless
* specified otherwise.
*
* @return the BOM
*/
public String getBom() {
return this.bom;
}
public void setBom(String bom) {
this.bom = bom;
}
/**
* Return the default repository to associate to all dependencies of this group unless
* specified otherwise.
*
* @return the repository
*/
public String getRepository() {
return this.repository;
}
public void setRepository(String repository) {
this.repository = repository;
}
/**
* Return the {@link ArchedDependency dependencies} of this group.
*
* @return the content
*/
public List<ArchedDependency> getContent() {
return this.content;
}
/**
* Create a new {@link DependencyGroup} instance with the given name.
*
* @param name the name of the group
* @return a new {@link DependencyGroup} instance
*/
public static DependencyGroup create(String name) {
DependencyGroup group = new DependencyGroup();
group.setName(name);
return group;
}
public DependencyGroup toDependencyGroup() {
DependencyGroup group = new DependencyGroup();
group.setName(name);
group.setBom(bom);
group.setRepository(repository);
group.setCompatibilityRange(compatibilityRange);
group.getContent().addAll(content);
return group;
}
}

View File

@@ -106,7 +106,7 @@ public class InitializerMetadataBuilder {
public void customize(InitializrMetadata metadata) {
InitializerMetadata initializerMetadata = (InitializerMetadata) metadata;
initializerMetadata.getArchitecture().merge(this.properties.getArchitecture());
initializerMetadata.getDependencies().merge(toDepGroup(this.properties.getDependencies()));
initializerMetadata.getDependencies().merge(new ArrayList<>(this.properties.getDependencies()));
metadata.getTypes().merge(this.properties.getTypes());
metadata.getBootVersions().merge(this.properties.getBootVersions());
metadata.getPackagings().merge(this.properties.getPackagings());
@@ -120,8 +120,5 @@ public class InitializerMetadataBuilder {
this.properties.getPackageName().apply(metadata.getPackageName());
}
private List<DependencyGroup> toDepGroup(List<InitializerDependencyGroup> adepg) {
return adepg.stream().map(InitializerDependencyGroup::toDependencyGroup).collect(Collectors.toList());
}
}
}

View File

@@ -44,7 +44,7 @@ public class InitializerProperties extends InitializrConfiguration {
* Dependencies, organized in groups (i.e. themes).
*/
@JsonIgnore
private final List<InitializerDependencyGroup> dependencies = new ArrayList<>();
private final List<EnhancedDependencyGroup> dependencies = new ArrayList<>();
/**
* Available project types.
@@ -116,11 +116,10 @@ public class InitializerProperties extends InitializrConfiguration {
return architecture;
}
public List<InitializerDependencyGroup> getDependencies() {
public List<EnhancedDependencyGroup> getDependencies() {
return dependencies;
}
public List<Type> getTypes() {
return this.types;
}

View File

@@ -1707,6 +1707,14 @@ initializr:
href: https://googlecloudplatform.github.io/spring-cloud-gcp/reference/html/index.html#cloud-storage
- rel: guide
href: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/main/spring-cloud-gcp-samples/spring-cloud-gcp-storage-resource-sample
- name: Hidden Group
id: hidden-group
hide: true
description: this is a hidden dependency group
content:
- name: cloudshell
id: cloudshell
codeOnly: true
types:
- name: Maven Project
id: maven-project