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

Codestarts testing #11474

Merged
merged 1 commit into from
Aug 21, 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
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: maven
type: buildtool
fallback: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: config-properties
type: config
fallback: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: config-yaml
type: config
language:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: commandmode-example
ref: commandmode
type: example
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: java
type: language
fallback: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: kotlin
type: language
language:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: scala
type: language
language:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: quarkus
type: project
fallback: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: dockerfiles
type: tooling
preselected: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: qute-example
ref: qute
type: example
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
name: resteasy-example
ref: resteasy
type: example
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

public class CodestartException extends RuntimeException {

public CodestartException(String message, Throwable cause) {
super(message, cause);
}

public CodestartException(Throwable cause) {
super(null, cause);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@
import io.quarkus.devtools.codestarts.reader.CodestartFileReader;
import io.quarkus.devtools.codestarts.strategy.CodestartFileStrategy;
import io.quarkus.devtools.codestarts.strategy.CodestartFileStrategyHandler;
import io.quarkus.devtools.codestarts.strategy.DefaultCodestartFileStrategyHandler;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -82,9 +83,8 @@ void processCodestartDir(final Path sourceDirectory, final Map<String, Object> f
final boolean hasFileStrategyHandler = getStrategy(relativeTargetPath.toString()).isPresent();
try {
if (!possibleReader.isPresent() && !hasFileStrategyHandler) {
// Copy static files
final Path targetPath = targetDirectory.resolve(relativeTargetPath.toString());
processStaticFile(sourcePath, targetPath);
getSelectedDefaultStrategy().copyStaticFile(sourcePath, targetPath);
continue;
}
final Optional<String> content = reader.read(sourceDirectory, relativeSourcePath,
Expand All @@ -111,11 +111,6 @@ private List<Path> findSources(Path sourceDirectory) {
}
}

private static void processStaticFile(Path path, Path targetPath) throws IOException {
Files.createDirectories(targetPath.getParent());
Files.copy(path, targetPath, StandardCopyOption.REPLACE_EXISTING);
}

void checkTargetDir() throws IOException {
if (!Files.exists(targetDirectory)) {
boolean mkdirStatus = targetDirectory.toFile().mkdirs();
Expand All @@ -137,12 +132,25 @@ public void writeFiles() throws IOException {
for (Map.Entry<String, List<CodestartFile>> e : files.entrySet()) {
final String relativePath = e.getKey();
Files.createDirectories(targetDirectory.resolve(relativePath).getParent());
getStrategy(relativePath).orElse(CodestartFileStrategyHandler.DEFAULT_STRATEGY)
getStrategy(relativePath).orElse(getSelectedDefaultStrategy())
.process(targetDirectory, relativePath, e.getValue(), data);
}
}

private Optional<CodestartFileStrategyHandler> getStrategy(final String key) {
DefaultCodestartFileStrategyHandler getSelectedDefaultStrategy() {
for (CodestartFileStrategy codestartFileStrategy : strategies) {
if (Objects.equals(codestartFileStrategy.getFilter(), "*")) {
ia3andy marked this conversation as resolved.
Show resolved Hide resolved
if (codestartFileStrategy.getHandler() instanceof DefaultCodestartFileStrategyHandler) {
return (DefaultCodestartFileStrategyHandler) codestartFileStrategy.getHandler();
}
throw new CodestartDefinitionException(
codestartFileStrategy.getHandler().name() + " can't be used as '*' file strategy");
}
}
return CodestartFileStrategyHandler.DEFAULT_STRATEGY;
}

Optional<CodestartFileStrategyHandler> getStrategy(final String key) {
for (CodestartFileStrategy codestartFileStrategy : strategies) {
if (codestartFileStrategy.test(key)) {
return Optional.of(codestartFileStrategy.getHandler());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
public class Codestarts {

public static CodestartProject prepareProject(final CodestartInput input) throws IOException {
final Set<String> selectedCodestartNames = new HashSet<>(input.getCodestarts());

final List<Codestart> allCodestarts = loadAllCodestarts(input);
return prepareProject(input, loadAllCodestarts(input));
}

public static CodestartProject prepareProject(final CodestartInput input, final List<Codestart> allCodestarts) {
final Set<String> selectedCodestartNames = new HashSet<>(input.getCodestarts());
final Collection<Codestart> baseCodestarts = resolveSelectedBaseCodestarts(allCodestarts, selectedCodestartNames);
final String languageName = baseCodestarts.stream().filter(c -> c.getType() == LANGUAGE).findFirst()
.orElseThrow(() -> new CodestartDefinitionException("Language codestart is required")).getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static String readQuteFile(Path sourceDirectory, Path relativeSourcePath,
try {
return engine.parse(content).render(data);
} catch (TemplateException e) {
throw new IOException("Error while rendering template: " + sourcePath.toString(), e);
throw new CodestartException("Error while rendering template: " + sourcePath.toString(), e);
}
}

Expand Down Expand Up @@ -103,7 +103,7 @@ public boolean appliesTo(TemplateNode.Origin origin, Object result) {
}

public String map(Object result, Expression expression) {
throw new CodestartException("Missing required data: {" + expression.toOriginalString() + "}");
throw new TemplateException("Missing required data: {" + expression.toOriginalString() + "}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ public CodestartFileStrategy(String filter, CodestartFileStrategyHandler handler
this.handler = handler;
}

public String getFilter() {
return filter;
}

@Override
public boolean test(String t) {
if (Objects.equals(filter, t)) {
return true;
}
if (Objects.equals("*", t)) {
return true;
}
// TODO SUPPORT FOR GLOB
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

public interface CodestartFileStrategyHandler {

FailOnDuplicateCodestartFileStrategyHandler DEFAULT_STRATEGY = new FailOnDuplicateCodestartFileStrategyHandler();
DefaultCodestartFileStrategyHandler DEFAULT_STRATEGY = new FailOnDuplicateCodestartFileStrategyHandler();

Map<String, CodestartFileStrategyHandler> BY_NAME = Stream
.of(DEFAULT_STRATEGY,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.quarkus.devtools.codestarts.strategy;

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

public interface DefaultCodestartFileStrategyHandler extends CodestartFileStrategyHandler {

void copyStaticFile(Path sourcePath, Path targetPath) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.List;
import java.util.Map;

final class FailOnDuplicateCodestartFileStrategyHandler implements CodestartFileStrategyHandler {
final class FailOnDuplicateCodestartFileStrategyHandler implements DefaultCodestartFileStrategyHandler {
@Override
public String name() {
return "fail-on-duplicate";
Expand All @@ -18,12 +18,21 @@ public String name() {
public void process(Path targetDirectory, String relativePath, List<CodestartFile> codestartFiles, Map<String, Object> data)
throws IOException {
checkNotEmptyCodestartFiles(codestartFiles);
if (codestartFiles.size() > 1) {
final Path targetPath = targetDirectory.resolve(relativePath);
if (codestartFiles.size() > 1 || Files.exists(targetPath)) {
throw new CodestartDefinitionException(
"Multiple files found for path with 'fail-on-duplicate' FileStrategy: " + relativePath);
}
final Path targetPath = targetDirectory.resolve(relativePath);
checkTargetDoesNotExist(targetPath);
Files.write(targetPath, codestartFiles.get(0).getContent().getBytes());
}

@Override
public void copyStaticFile(Path sourcePath, Path targetPath) throws IOException {
if (Files.exists(targetPath)) {
throw new CodestartDefinitionException(
"Multiple files found for path with 'fail-on-duplicate' FileStrategy: " + targetPath);
}
Files.createDirectories(targetPath.getParent());
Files.copy(sourcePath, targetPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.Map;

final class ReplaceCodestartFileStrategyHandler implements CodestartFileStrategyHandler {
final class ReplaceCodestartFileStrategyHandler implements DefaultCodestartFileStrategyHandler {

@Override
public String name() {
return "replace";
}

@Override
public void copyStaticFile(Path sourcePath, Path targetPath) throws IOException {
Files.createDirectories(targetPath.getParent());
ia3andy marked this conversation as resolved.
Show resolved Hide resolved
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}

@Override
public void process(Path targetDirectory, String relativePath, List<CodestartFile> codestartFiles, Map<String, Object> data)
throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import io.quarkus.devtools.codestarts.CodestartException;
import io.quarkus.devtools.codestarts.NestedMaps;
import io.quarkus.devtools.codestarts.reader.CodestartFile;
Expand All @@ -16,7 +17,8 @@

final class SmartConfigMergeCodestartFileStrategyHandler implements CodestartFileStrategyHandler {

private static final ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory());
private static final ObjectMapper YAML_MAPPER = new ObjectMapper(
new YAMLFactory().configure(YAMLGenerator.Feature.WRITE_DOC_START_MARKER, false));

@Override
public String name() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import static io.quarkus.devtools.codestarts.CodestartSpec.Type.EXAMPLE;
import static io.quarkus.devtools.codestarts.CodestartSpec.Type.PROJECT;
import static org.apache.commons.io.IOUtils.resourceToString;
import static org.assertj.core.api.Assertions.as;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Set;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.mockito.internal.util.collections.Sets;

class CodestartLoaderTest {

Expand Down Expand Up @@ -62,24 +66,46 @@ void testReadCodestartSpecDefault() throws IOException {
void testLoadBundledCodestarts() throws IOException {
final CodestartInput input = CodestartInput.builder(new TestCodestartResourceLoader()).build();
final Collection<Codestart> codestarts = CodestartLoader.loadBundledCodestarts(input);
assertThat(codestarts).extracting(Codestart::getSpec).extracting(CodestartSpec::getName)
.containsExactlyInAnyOrder("y", "z", "config-properties", "config-yaml", "foo", "a", "b", "replace", "t");
assertThat(codestarts).extracting(Codestart::getName)
.containsExactlyInAnyOrder("y", "maven", "config-properties", "config-yaml", "foo", "a", "b", "replace", "t",
"example-with-b");

checkLanguages(codestarts, Sets.newSet("y", "z"), "a", "b");
checkLanguages(codestarts, Sets.newSet("config-properties", "config-yaml", "foo", "a", "b", "replace"));
checkLanguages(codestarts, Sets.newSet("t"), "a");
}

private void checkLanguages(Collection<Codestart> codestarts, Set<String> names, String... languages) {
assertThat(codestarts)
.filteredOn(c -> names.contains(c.getName()))
.allSatisfy((c) -> assertThat(c)
.extracting(Codestart::getImplementedLanguages, as(InstanceOfAssertFactories.ITERABLE))
.containsExactlyInAnyOrder(languages));
}

@Test
void testLoadCodestartsFromExtensions() throws IOException {
final CodestartInput input = CodestartInput.builder(new TestCodestartResourceLoader()).build();
final Collection<Codestart> codestarts = CodestartLoader.loadCodestartsFromExtensions(input);
assertThat(codestarts).extracting(Codestart::getSpec).extracting(CodestartSpec::getName)
assertThat(codestarts).extracting(Codestart::getName)
.containsExactlyInAnyOrder("example1", "example2", "example-forbidden");
checkLanguages(codestarts, Sets.newSet("example1"), "a");
checkLanguages(codestarts, Sets.newSet("example2"), "b");
checkLanguages(codestarts, Sets.newSet("example-forbidden"));
}

@Test
void testLoadCodestartsFail() throws IOException {
final CodestartInput input = CodestartInput.builder(new TestCodestartResourceLoader()).build();
assertThatExceptionOfType(CodestartDefinitionException.class)
.isThrownBy(() -> CodestartLoader.loadCodestarts(input.getResourceLoader(), "codestarts-with-error"))
.isThrownBy(() -> CodestartLoader.loadCodestarts(input.getResourceLoader(), "codestarts-with-error-1"))
.withMessageContaining("codestart-1");
assertThatExceptionOfType(CodestartDefinitionException.class)
.isThrownBy(() -> CodestartLoader.loadCodestarts(input.getResourceLoader(), "codestarts-with-error-2"))
.withMessageContaining("codestart-2");
assertThatExceptionOfType(CodestartDefinitionException.class)
.isThrownBy(() -> CodestartLoader.loadCodestarts(input.getResourceLoader(), "codestarts-with-error-3"))
.withMessageContaining("codestart-3");
}

}
Loading