Skip to content

Commit

Permalink
Hack Ginevra: Copy static resources
Browse files Browse the repository at this point in the history
  • Loading branch information
nipafx committed Apr 15, 2024
1 parent bc47132 commit 25fd985
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.nipafx.ginevra.execution;

import dev.nipafx.ginevra.execution.Step.FilterStep;
import dev.nipafx.ginevra.execution.Step.GenerateResourcesStep;
import dev.nipafx.ginevra.execution.Step.MergeSteps;
import dev.nipafx.ginevra.execution.Step.SourceStep;
import dev.nipafx.ginevra.execution.Step.StoreResourceStep;
Expand Down Expand Up @@ -148,6 +149,11 @@ void generate(Template<DATA> template) {
createStepListFor(next);
}

public void generateStaticResources(Path folder, String... resources) {
var next = new GenerateResourcesStep(folder, List.of(resources));
createStepListFor(next);
}

// misc

private void createStepListFor(SourceStep<?> step) {
Expand All @@ -162,6 +168,12 @@ private void createStepListFor(TemplateStep<?> step) {
throw new IllegalArgumentException("This template was already registered");
}

private void createStepListFor(GenerateResourcesStep step) {
var previous = stepMap.put(step, List.of());
if (previous != null)
throw new IllegalArgumentException("This resource generation was already registered");
}

private void appendStep(StepKey<?> previous, Step step) {
stepMap.putIfAbsent(step, new ArrayList<>());
switch (previous) {
Expand Down
73 changes: 56 additions & 17 deletions ginevra/src/main/java/dev/nipafx/ginevra/execution/MapOutline.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.nipafx.ginevra.execution;

import dev.nipafx.ginevra.execution.Step.FilterStep;
import dev.nipafx.ginevra.execution.Step.GenerateResourcesStep;
import dev.nipafx.ginevra.execution.Step.MergeStepOne;
import dev.nipafx.ginevra.execution.Step.MergeStepTwo;
import dev.nipafx.ginevra.execution.Step.SourceStep;
Expand Down Expand Up @@ -58,6 +59,7 @@ class MapOutline implements Outline {
public void run() {
runOutlineUntilStorage();
renderTemplates();
generateResources();
}

private void runOutlineUntilStorage() {
Expand All @@ -69,21 +71,6 @@ private void runOutlineUntilStorage() {
sourceSteps.forEach(step -> step.source().loadAll());
}

private void renderTemplates() {
try {
paths.createFolders();
stepMap
.keySet().stream()
.mapMulti(keepOnly(TemplateStep.class))
.flatMap(this::generateFromTemplate)
// TODO: find out why this cast is needed
.forEach((Consumer<TemplatedFile>) this::writeTemplatedFile);
} catch (IOException | UncheckedIOException ex) {
// TODO: handle error
ex.printStackTrace();
}
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private void processRecursively(Step origin, Document<?> doc) {
var steps = stepMap.get(origin);
Expand Down Expand Up @@ -117,10 +104,26 @@ case StoreResourceStep(var naming) -> {
store.storeResource(name, fileDoc);
}
case TemplateStep _ -> throw new IllegalStateException("No step should map to a template");
case GenerateResourcesStep _ -> throw new IllegalStateException("No step should map to resource generation");
}
});
}

private void renderTemplates() {
try {
paths.createFolders();
stepMap
.keySet().stream()
.mapMulti(keepOnly(TemplateStep.class))
.flatMap(this::generateFromTemplate)
// TODO: find out why this cast is needed
.forEach((Consumer<TemplatedFile>) this::writeTemplatedFile);
} catch (IOException | UncheckedIOException ex) {
// TODO: handle error
ex.printStackTrace();
}
}

private <DATA extends Record & Data> Stream<TemplatedFile> generateFromTemplate(TemplateStep<DATA> templateStep) {
var template = templateStep.template();
var results = switch (template.query()) {
Expand Down Expand Up @@ -158,6 +161,8 @@ private void writeTemplatedFile(TemplatedFile file) {
private void copyFile(CopiedFile copiedFile) {
var target = paths.siteFolder().resolve(copiedFile.target());
try {
// copied files have a hashed name, so if a target file of that name already exists
// it can be assumed to be up-to-date and nothing needs to be done
if (!Files.exists(target))
Files.copy(copiedFile.source(), target);
} catch (IOException ex) {
Expand All @@ -167,12 +172,17 @@ private void copyFile(CopiedFile copiedFile) {
}

private void writeCssFile(CssFile cssFile) {
var file = paths.siteFolder().resolve(cssFile.file()).toAbsolutePath();
writeToFile(file, cssFile.content());
var targetFile = paths.siteFolder().resolve(cssFile.file()).toAbsolutePath();
// CSS files have a hashed name, so if a target file of that name already exists
// it can be assumed to be up-to-date and nothing needs to be done
if (!Files.exists(targetFile))
writeToFile(targetFile, cssFile.content());
}

private static void writeToFile(Path filePath, String fileContent) {
try {
// some files can change without Ginevra noticing,
// so they need to be deleted and recreated
Files.createDirectories(filePath.getParent());
Files.deleteIfExists(filePath);
Files.writeString(filePath, fileContent);
Expand All @@ -182,6 +192,35 @@ private static void writeToFile(Path filePath, String fileContent) {
}
}

private void generateResources() {
stepMap
.keySet().stream()
.mapMulti(keepOnly(GenerateResourcesStep.class))
.forEach(step -> copyStaticFiles(step.folder(), step.resourceNames()));
}

private void copyStaticFiles(Path folder, List<String> resourceNames) {
try {
var folderPath = paths.siteFolder().resolve(folder).toAbsolutePath();
Files.createDirectories(folderPath);
for (String resourceName : resourceNames) {
var source = store
.getResource(resourceName)
.orElseThrow(() -> new IllegalArgumentException(STR."No resource with name '\{resourceName}'."))
.data()
.file();
var target = folderPath.resolve(resourceName);
// these files can change without Ginevra noticing,
// so they need to be deleted and recreated
Files.deleteIfExists(target);
Files.copy(source, target);
}
} catch (IOException ex) {
// TODO: handle error
ex.printStackTrace();
}
}

private record TemplatedFile(Path file, String content, Set<ResourceFile> referencedResources) { }

}
3 changes: 3 additions & 0 deletions ginevra/src/main/java/dev/nipafx/ginevra/execution/Step.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import dev.nipafx.ginevra.outline.Template;
import dev.nipafx.ginevra.outline.Transformer;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -100,4 +101,6 @@ record StoreResourceStep<DATA extends Record & FileData>(Function<DATA, String>

record TemplateStep<DATA extends Record & Data>(Template<DATA> template) implements Step { }

record GenerateResourcesStep(Path folder, List<String> resourceNames) implements Step { }

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ void storeResource(StepKey<DATA_IN> previous) {
<DATA extends Record & Data>
void generate(Template<DATA> template);

void generateStaticResources(Path folder, String... resources);

// build

Outline build();
Expand Down

0 comments on commit 25fd985

Please sign in to comment.