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> { @Override public void accept(Pipeline pipeline, Consumer 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 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 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); } } }