Skip to content

Commit 48d136f

Browse files
Makes metadata parsing more modular. (#1547)
* Implements code suggestions. * Makes metadata parsing more modular.
1 parent e93d554 commit 48d136f

File tree

11 files changed

+314
-148
lines changed

11 files changed

+314
-148
lines changed

buildSrc/src/main/groovy/io/micronaut/guides/GuideProjectGenerator.groovy

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import io.micronaut.core.annotation.Nullable
1010
import io.micronaut.guides.core.App
1111
import io.micronaut.guides.core.CopyFileVisitor
1212
import io.micronaut.guides.core.Guide
13+
import io.micronaut.guides.core.GuideParser
1314
import io.micronaut.guides.core.GuideUtils
1415
import io.micronaut.guides.core.GuidesOption
15-
import io.micronaut.guides.core.JsonSchemaProvider
16-
import io.micronaut.json.JsonMapper
1716
import io.micronaut.starter.api.TestFramework
1817
import io.micronaut.starter.options.BuildTool
1918
import io.micronaut.starter.options.JdkVersion
@@ -54,13 +53,12 @@ class GuideProjectGenerator implements AutoCloseable {
5453

5554
private final ApplicationContext applicationContext
5655
private final GuidesGenerator guidesGenerator
57-
private final JsonSchema jsonSchema;
58-
private final JsonMapper jsonMapper;
56+
private final GuideParser guideParser;
57+
5958
GuideProjectGenerator() {
6059
applicationContext = ApplicationContext.run()
6160
guidesGenerator = applicationContext.getBean(GuidesGenerator)
62-
this.jsonSchema = applicationContext.getBean(JsonSchemaProvider.class).getSchema();
63-
this.jsonMapper = applicationContext.getBean(JsonMapper.class)
61+
guideParser = applicationContext.getBean(GuideParser)
6462
}
6563

6664
@Override
@@ -83,7 +81,7 @@ class GuideProjectGenerator implements AutoCloseable {
8381
asciidocDir.mkdir()
8482
}
8583

86-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(guidesDir, metadataConfigName, jsonSchema, jsonMapper)
84+
List<Guide> metadatas = guideParser.parseGuidesMetadata(guidesDir, metadataConfigName)
8785
for (Guide metadata : metadatas) {
8886
File dir = new File(guidesDir, metadata.slug)
8987
try {

buildSrc/src/main/groovy/io/micronaut/guides/GuidesPlugin.groovy

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package io.micronaut.guides
22

33
import groovy.transform.CompileStatic
44
import io.micronaut.core.util.CollectionUtils
5+
import io.micronaut.guides.core.DefaultGuideParser
56
import io.micronaut.guides.core.DefaultJsonSchemaProvider
67
import io.micronaut.guides.core.Guide
7-
import io.micronaut.guides.core.GuideUtils
8+
import io.micronaut.guides.core.GuideParser
89
import io.micronaut.guides.core.GuidesOption
910
import io.micronaut.guides.core.JsonSchemaProvider
1011
import io.micronaut.guides.tasks.AsciidocGenerationTask
@@ -65,10 +66,10 @@ class GuidesPlugin implements Plugin<Project> {
6566

6667
JsonMapper jsonMapper = JsonMapper.createDefault();
6768
JsonSchemaProvider jsonSchemaProvider = new DefaultJsonSchemaProvider();
68-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(
69+
GuideParser guideParser = new DefaultGuideParser(jsonSchemaProvider, jsonMapper);
70+
List<Guide> metadatas = guideParser.parseGuidesMetadata(
6971
guidesDir.asFile,
70-
project.extensions.extraProperties.get("metadataConfigName").toString(),
71-
jsonSchemaProvider.getSchema(), jsonMapper)
72+
project.extensions.extraProperties.get("metadataConfigName").toString())
7273
List<Map<String, TaskProvider<Task>>> sampleTasks = metadatas
7374
.stream()
7475
.filter(guideMetadata -> Utils.process(guideMetadata, false))

buildSrc/src/main/groovy/io/micronaut/guides/IndexGenerator.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class IndexGenerator {
5757
//TODO. We should have an application context and get it from it.
5858
JsonMapper jsonMapper = JsonMapper.createDefault();
5959
JsonSchemaProvider jsonSchemaProvider = new DefaultJsonSchemaProvider()
60-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(guidesFolder, metadataConfigName, jsonSchemaProvider.getSchema(), jsonMapper)
60+
GuideParser guideParser = new DefaultGuideParser(jsonSchemaProvider, jsonMapper);
61+
List<Guide> metadatas = guideParser.parseGuidesMetadata(guidesFolder, metadataConfigName)
6162
.findAll { it.publish() }
6263
generateGuidesIndex(template, distDir, metadatas, indexgrid)
6364
GuidesConfiguration guidesConfiguration = new GuidesConfigurationProperties()
@@ -529,7 +530,8 @@ class IndexGenerator {
529530
//TOO get both from an application context
530531
JsonMapper jsonMapper = JsonMapper.createDefault();
531532
JsonSchemaProvider jsonSchemaProvider = new DefaultJsonSchemaProvider();
532-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(guidesFolder, metadataConfigName, jsonSchemaProvider.getSchema(), jsonMapper)
533+
GuideParser guideParser = new DefaultGuideParser(jsonSchemaProvider, jsonMapper);
534+
List<Guide> metadatas = guideParser.parseGuidesMetadata(guidesFolder, metadataConfigName)
533535
.findAll { it.publish() }
534536

535537
List<Map> result = metadatas

buildSrc/src/main/groovy/io/micronaut/guides/TestScriptGenerator.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package io.micronaut.guides
22

33
import groovy.transform.CompileStatic
44
import io.micronaut.guides.core.App
5+
import io.micronaut.guides.core.DefaultGuideParser
56
import io.micronaut.guides.core.DefaultJsonSchemaProvider
67
import io.micronaut.guides.core.Guide
8+
import io.micronaut.guides.core.GuideParser
79
import io.micronaut.guides.core.GuideUtils
810
import io.micronaut.guides.core.GuidesOption
911
import io.micronaut.guides.core.JsonSchemaProvider
@@ -81,7 +83,8 @@ exit 0
8183
//TODO. We should have an application context and get it from it.
8284
JsonMapper jsonMapper = JsonMapper.createDefault();
8385
JsonSchemaProvider jsonSchemaProvider = new DefaultJsonSchemaProvider();
84-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(guidesFolder, metadataConfigName, jsonSchemaProvider.getSchema(), jsonMapper);
86+
GuideParser guideParser = new DefaultGuideParser(jsonSchemaProvider, jsonMapper);
87+
List<Guide> metadatas = guideParser.parseGuidesMetadata(guidesFolder, metadataConfigName)
8588
metadatas = metadatas.stream()
8689
.filter(metadata -> !shouldSkip(metadata, slugsChanged, forceExecuteEveryTest))
8790
.collect(Collectors.toList())

buildSrc/src/main/groovy/io/micronaut/guides/ThemeProcessor.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package io.micronaut.guides
22

3+
import io.micronaut.guides.core.DefaultGuideParser
34
import io.micronaut.guides.core.DefaultJsonSchemaProvider
45
import io.micronaut.guides.core.Guide
5-
import io.micronaut.guides.core.GuideUtils
6+
import io.micronaut.guides.core.GuideParser
67
import io.micronaut.guides.core.GuidesOption
78
import io.micronaut.guides.core.JsonSchemaProvider
89
import io.micronaut.json.JsonMapper
@@ -24,7 +25,8 @@ class ThemeProcessor {
2425
//TODO. We should have an application context and get it from it.
2526
JsonMapper jsonMapper = JsonMapper.createDefault();
2627
JsonSchemaProvider jsonSchemaProvider = new DefaultJsonSchemaProvider();
27-
List<Guide> metadatas = GuideUtils.parseGuidesMetadata(guidesFolder, metadataConfigName, jsonSchemaProvider.getSchema(), jsonMapper)
28+
GuideParser guideParser = new DefaultGuideParser(jsonSchemaProvider, jsonMapper);
29+
List<Guide> metadatas = guideParser.parseGuidesMetadata(guidesFolder, metadataConfigName)
2830
for (Guide metadata : metadatas) {
2931
if (!Utils.process(metadata, false)) {
3032
continue
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package io.micronaut.guides.core;
2+
3+
import com.networknt.schema.InputFormat;
4+
import com.networknt.schema.ValidationMessage;
5+
import groovy.json.JsonSlurper;
6+
import io.micronaut.core.annotation.NonNull;
7+
import io.micronaut.json.JsonMapper;
8+
import io.micronaut.starter.options.BuildTool;
9+
import io.micronaut.starter.options.Language;
10+
import jakarta.inject.Singleton;
11+
import jakarta.validation.constraints.NotNull;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.nio.file.Files;
18+
import java.nio.file.Paths;
19+
import java.util.*;
20+
21+
import static io.micronaut.guides.core.GuideUtils.mergeMetadataList;
22+
23+
@Singleton
24+
public class DefaultGuideParser implements GuideParser {
25+
26+
private static final Logger LOG = LoggerFactory.getLogger(DefaultGuideParser.class);
27+
28+
private final JsonSchemaProvider jsonSchemaProvider;
29+
private final JsonMapper jsonMapper;
30+
31+
public DefaultGuideParser(JsonSchemaProvider jsonSchemaProvider, JsonMapper jsonMapper) {
32+
this.jsonSchemaProvider = jsonSchemaProvider;
33+
this.jsonMapper = jsonMapper;
34+
35+
}
36+
37+
@Override
38+
@NonNull
39+
public List<Guide> parseGuidesMetadata(@NonNull @NotNull File guidesDir, @NonNull @NotNull String metadataConfigName) {
40+
List<Guide> metadatas = new ArrayList<>();
41+
42+
File dirs[] = guidesDir.listFiles(File::isDirectory);
43+
if(dirs == null) {
44+
return metadatas;
45+
}
46+
for (File dir : dirs) {
47+
parseGuideMetadata(dir, metadataConfigName).ifPresent(metadatas::add);
48+
}
49+
50+
mergeMetadataList(metadatas);
51+
52+
return metadatas;
53+
}
54+
55+
@Override
56+
@NonNull
57+
public Optional<Guide> parseGuideMetadata(@NonNull @NotNull File guidesDir, @NonNull @NotNull String metadataConfigName) {
58+
File configFile = new File(guidesDir, metadataConfigName);
59+
if (!configFile.exists()) {
60+
LOG.warn("metadata file not found for {}", guidesDir.getName());
61+
return Optional.empty();
62+
}
63+
64+
String content;
65+
try {
66+
content = Files.readString(Paths.get(configFile.toString()));
67+
} catch (IOException e) {
68+
LOG.warn("metadata file not found for {}", guidesDir.getName());
69+
return Optional.empty();
70+
}
71+
72+
Map<String, Object> config = (Map<String,Object>) new JsonSlurper().parse(configFile);
73+
boolean publish = config.get("publish") == null || (Boolean) config.get("publish");
74+
75+
if(publish) {
76+
Set<ValidationMessage> assertions = jsonSchemaProvider.getSchema().validate(content, InputFormat.JSON);
77+
78+
if (!assertions.isEmpty()) {
79+
LOG.trace("Guide metadata {} does not validate the JSON Schema. Skipping guide.", configFile);
80+
return Optional.empty();
81+
}
82+
}
83+
84+
Guide raw;
85+
try {
86+
raw = jsonMapper.readValue(content, Guide.class);
87+
} catch (IOException e) {
88+
LOG.trace("Error parsing guide metadata {}. Skipping guide.", configFile, e);
89+
return Optional.empty();
90+
}
91+
92+
List<App> apps = new LinkedList<>();
93+
94+
for (App app : raw.apps()) {
95+
apps.add(new App(
96+
app.name(),
97+
app.packageName(),
98+
app.applicationType(),
99+
app.framework(),
100+
app.features() != null ? app.features() : new ArrayList<>(),
101+
app.invisibleFeatures() != null ? app.invisibleFeatures() : new ArrayList<>(),
102+
app.kotlinFeatures() != null ? app.kotlinFeatures() : new ArrayList<>(),
103+
app.javaFeatures() != null ? app.javaFeatures() : new ArrayList<>(),
104+
app.groovyFeatures() != null ? app.groovyFeatures() : new ArrayList<>(),
105+
app.testFramework(),
106+
app.excludeTest(),
107+
app.excludeSource(),
108+
app.validateLicense()
109+
));
110+
}
111+
112+
return Optional.of(new Guide(
113+
raw.title(),
114+
raw.intro(),
115+
raw.authors(),
116+
raw.categories(),
117+
publish ? raw.publicationDate() : null,
118+
raw.minimumJavaVersion(),
119+
raw.maximumJavaVersion(),
120+
raw.cloud(),
121+
raw.skipGradleTests(),
122+
raw.skipMavenTests(),
123+
publish ? guidesDir.getName() + ".adoc" : null,
124+
raw.languages() != null ? raw.languages() : List.of(Language.JAVA, Language.GROOVY, Language.KOTLIN),
125+
raw.tags() != null ? raw.tags() : Collections.emptyList(),
126+
raw.buildTools() != null ? raw.buildTools() : List.of(BuildTool.GRADLE, BuildTool.MAVEN),
127+
raw.testFramework(),
128+
raw.zipIncludes() != null ? raw.zipIncludes() : new ArrayList<>(),
129+
guidesDir.getName(),
130+
publish,
131+
raw.base(),
132+
raw.env() != null ? raw.env() : new HashMap<>(),
133+
apps
134+
));
135+
}
136+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.micronaut.guides.core;
2+
3+
import io.micronaut.core.annotation.NonNull;
4+
import jakarta.validation.constraints.NotNull;
5+
6+
import java.io.File;
7+
import java.util.List;
8+
import java.util.Optional;
9+
10+
public interface GuideParser {
11+
@NonNull
12+
List<Guide> parseGuidesMetadata(@NonNull @NotNull File guidesDir,
13+
@NonNull @NotNull String metadataConfigName);
14+
15+
@NonNull
16+
Optional<Guide> parseGuideMetadata(@NonNull @NotNull File guidesDir,
17+
@NonNull @NotNull String metadataConfigName);
18+
}

0 commit comments

Comments
 (0)