Woodpecker-Include/src/main/java/io/gitlab/jfronny/woodpecker/include/PipelineUnpacker.java

71 lines
2.9 KiB
Java

package io.gitlab.jfronny.woodpecker.include;
import com.amihaiemil.eoyaml.*;
import io.gitlab.jfronny.commons.HttpUtils;
import io.gitlab.jfronny.woodpecker.include.model.Pipeline;
import io.gitlab.jfronny.woodpecker.include.util.FilteringYamlMapping;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
record PipelineUnpacker(AtomicBoolean changed) implements BiConsumer<Pipeline, Consumer<Pipeline>> {
@Override
public void accept(Pipeline pipeline, Consumer<Pipeline> pipelineConsumer) {
try {
processPipeline(pipeline, pipelineConsumer);
} catch (URISyntaxException e) {
throw new UncheckedIOException(new IOException("Could not find URL", e));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void processPipeline(Pipeline pipeline, Consumer<Pipeline> pipelineConsumer) throws URISyntaxException, IOException {
YamlNode include = pipeline.data.value("include");
if (include == null) {
// Has no includes
pipelineConsumer.accept(pipeline);
return;
}
changed.set(true);
// Send included
switch (include) {
case Scalar str -> download(str.value(), null, pipelineConsumer);
case YamlMapping map -> {
for (YamlNode key : map.keys()) {
download(map.string(key), key.asScalar().value(), pipelineConsumer);
}
}
case YamlSequence seq -> {
for (YamlNode node : seq) {
download(node.asScalar().value(), null, pipelineConsumer);
}
}
default -> throw new IllegalStateException("Unexpected value: " + include);
}
// Remove include from original
Pipeline filtered = new Pipeline();
filtered.name = pipeline.name;
pipeline.data = new FilteringYamlMapping(pipeline.data, s -> !s.asScalar().value().equals("include"));
pipelineConsumer.accept(filtered);
}
private void download(String url, String fileName, Consumer<Pipeline> pipelineConsumer) throws URISyntaxException, IOException {
URI uri = new URI(url.replace(" ", "%20"));
if (!"http".equalsIgnoreCase(uri.getScheme()) && !"https".equalsIgnoreCase(uri.getScheme())) {
throw new URISyntaxException(url, "Could not find scheme");
}
try (InputStream is = HttpUtils.get(url).sendInputStream()) {
Pipeline pipeline = new Pipeline();
pipeline.name = fileName != null ? fileName : Paths.get(new URI(url.replace(" ", "%20")).getPath()).getFileName().toString();
pipeline.data = Yaml.createYamlInput(is).readYamlMapping();
processPipeline(pipeline, pipelineConsumer);
}
}
}