mirror of
https://gitee.com/dcren/initializr.git
synced 2026-02-26 05:32:58 +08:00
Project documentation infrastructure
This commit adds support for an `HelpDocument` that can be generated alongside the project. Such document can hold an arbitrary number of sections with pre-defined sections such as "Getting Started" and "Next Steps". A default contributor retrieves the links for requested dependencies and add them to the document. Closes gh-353 Co-authored-by: Madhura Bhave <mbhave@pivotal.io>
This commit is contained in:
committed by
Madhura Bhave
parent
2746a3a6e7
commit
924a73310a
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 io.spring.initializr.generator.io.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.spring.initializr.generator.io.template.TemplateRenderer;
|
||||
|
||||
/**
|
||||
* {@link Section} for list of items using a {@link TemplateRenderer}.
|
||||
*
|
||||
* @param <T> the type of the item in the bullets
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class BulletedSection<T> implements Section {
|
||||
|
||||
private final TemplateRenderer templateRenderer;
|
||||
|
||||
private final String templateName;
|
||||
|
||||
private final String itemName;
|
||||
|
||||
private List<T> items = new ArrayList<>();
|
||||
|
||||
public BulletedSection(TemplateRenderer templateRenderer, String templateName) {
|
||||
this(templateRenderer, templateName, "items");
|
||||
}
|
||||
|
||||
public BulletedSection(TemplateRenderer templateRenderer, String templateName,
|
||||
String itemName) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.templateName = templateName;
|
||||
this.itemName = itemName;
|
||||
}
|
||||
|
||||
public BulletedSection addItem(T item) {
|
||||
this.items.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.items.isEmpty();
|
||||
}
|
||||
|
||||
public List<T> getItems() {
|
||||
return Collections.unmodifiableList(this.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PrintWriter writer) throws IOException {
|
||||
if (!isEmpty()) {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put(this.itemName, this.items);
|
||||
writer.println(this.templateRenderer.render(this.templateName, model));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 io.spring.initializr.generator.io.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import io.spring.initializr.generator.io.template.MustacheTemplateRenderer;
|
||||
|
||||
/**
|
||||
* {@link Section} that uses a {@link MustacheTemplateRenderer}. Renders the content with
|
||||
* a newline at the end.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class MustacheSection implements Section {
|
||||
|
||||
private final MustacheTemplateRenderer templateRenderer;
|
||||
|
||||
private final String templateName;
|
||||
|
||||
private final Map<String, Object> model;
|
||||
|
||||
public MustacheSection(MustacheTemplateRenderer templateRenderer, String templateName,
|
||||
Map<String, Object> model) {
|
||||
this.templateRenderer = templateRenderer;
|
||||
this.templateName = templateName;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PrintWriter writer) throws IOException {
|
||||
writer.println(this.templateRenderer.render(this.templateName,
|
||||
resolveModel(this.model)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the {@code model} prior to render the section.
|
||||
* @param model the current model
|
||||
* @return the model to use to render this section (never null)
|
||||
*/
|
||||
protected Map<String, Object> resolveModel(Map<String, Object> model) {
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 io.spring.initializr.generator.io.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import io.spring.initializr.generator.io.template.TemplateRenderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link BulletedSection}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BulletedSectionTests {
|
||||
|
||||
@Mock
|
||||
private TemplateRenderer renderer;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Map<String, Object>> modelCaptor;
|
||||
|
||||
@Test
|
||||
void bulletedSectionEmpty() {
|
||||
assertThat(new BulletedSection<String>(this.renderer, "test").isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bulletedSectionEmptyDoesNotInvokeRender() throws IOException {
|
||||
BulletedSection<String> section = new BulletedSection<>(this.renderer, "test");
|
||||
PrintWriter writer = mock(PrintWriter.class);
|
||||
section.write(writer);
|
||||
verifyNoMoreInteractions(writer, this.renderer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bulletedSectionWithItem() {
|
||||
BulletedSection<String> section = new BulletedSection<>(this.renderer, "test");
|
||||
section.addItem("test");
|
||||
assertThat(section.isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bulletedSectionWithDefaultItemName() throws IOException {
|
||||
given(this.renderer.render(eq("template"), any())).willReturn("output");
|
||||
BulletedSection<String> section = new BulletedSection<>(this.renderer,
|
||||
"template");
|
||||
section.addItem("test");
|
||||
section.write(new PrintWriter(new StringWriter()));
|
||||
verify(this.renderer).render(eq("template"), this.modelCaptor.capture());
|
||||
Map<String, Object> model = this.modelCaptor.getValue();
|
||||
assertThat(model).containsOnly(entry("items", Collections.singletonList("test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void bulletedSectionWithCustomItemName() throws IOException {
|
||||
given(this.renderer.render(eq("template"), any())).willReturn("output");
|
||||
BulletedSection<String> section = new BulletedSection<>(this.renderer, "template",
|
||||
"elements");
|
||||
section.addItem("test");
|
||||
section.write(new PrintWriter(new StringWriter()));
|
||||
verify(this.renderer).render(eq("template"), this.modelCaptor.capture());
|
||||
Map<String, Object> model = this.modelCaptor.getValue();
|
||||
assertThat(model)
|
||||
.containsOnly(entry("elements", Collections.singletonList("test")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 io.spring.initializr.generator.io.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.samskivert.mustache.MustacheException;
|
||||
import io.spring.initializr.generator.io.template.MustacheTemplateRenderer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link MustacheSection}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class MustacheSectionTests {
|
||||
|
||||
private final MustacheTemplateRenderer renderer = new MustacheTemplateRenderer(
|
||||
"classpath:/templates/mustache");
|
||||
|
||||
@Test
|
||||
void renderSection() throws IOException {
|
||||
MustacheSection section = new MustacheSection(this.renderer, "test",
|
||||
Collections.singletonMap("key", "hello"));
|
||||
StringWriter writer = new StringWriter();
|
||||
section.write(new PrintWriter(writer));
|
||||
assertThat(writer.toString()).isEqualTo(String.format("hello%n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void renderSectionWithMissingKey() {
|
||||
MustacheSection section = new MustacheSection(this.renderer, "test",
|
||||
Collections.singletonMap("another", "hello"));
|
||||
assertThatThrownBy(() -> section.write(new PrintWriter(new StringWriter())))
|
||||
.isInstanceOf(MustacheException.class).hasMessageContaining("key");
|
||||
}
|
||||
|
||||
@Test
|
||||
void renderSectionWithCustomModelResolution() throws IOException {
|
||||
MustacheSection section = new MustacheSection(this.renderer, "test",
|
||||
Collections.emptyMap()) {
|
||||
@Override
|
||||
protected Map<String, Object> resolveModel(Map<String, Object> model) {
|
||||
return Collections.singletonMap("key", "custom");
|
||||
}
|
||||
};
|
||||
StringWriter writer = new StringWriter();
|
||||
section.write(new PrintWriter(writer));
|
||||
assertThat(writer.toString()).isEqualTo(String.format("custom%n"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,13 +17,14 @@
|
||||
package io.spring.initializr.generator.test.project;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.spring.initializr.generator.io.IndentingWriterFactory;
|
||||
import io.spring.initializr.generator.io.SimpleIndentStrategy;
|
||||
import io.spring.initializr.generator.io.template.MustacheTemplateRenderer;
|
||||
import io.spring.initializr.generator.project.DefaultProjectAssetGenerator;
|
||||
import io.spring.initializr.generator.project.ProjectAssetGenerator;
|
||||
import io.spring.initializr.generator.project.ProjectDescription;
|
||||
@@ -49,8 +50,12 @@ public class ProjectGeneratorTester
|
||||
}
|
||||
|
||||
private static Map<Class<?>, Supplier<?>> defaultBeans() {
|
||||
return Collections.singletonMap(IndentingWriterFactory.class,
|
||||
Map<Class<?>, Supplier<?>> beans = new HashMap<>();
|
||||
beans.put(IndentingWriterFactory.class,
|
||||
() -> IndentingWriterFactory.create(new SimpleIndentStrategy(" ")));
|
||||
beans.put(MustacheTemplateRenderer.class,
|
||||
() -> new MustacheTemplateRenderer("classpath:/templates"));
|
||||
return beans;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user