001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.common.template.tool; 019 020import static dev.enola.common.io.resource.FileDescriptorResource.STDOUT_URI; 021 022import dev.enola.common.context.TLC; 023import dev.enola.common.function.MoreStreams; 024import dev.enola.common.io.iri.URIs; 025import dev.enola.common.io.mediatype.MediaTypeProviders; 026import dev.enola.common.io.mediatype.StandardMediaTypes; 027import dev.enola.common.io.mediatype.YamlMediaType; 028import dev.enola.common.io.object.ObjectReaderChain; 029import dev.enola.common.io.object.csv.CsvReader; 030import dev.enola.common.io.object.jackson.JacksonObjectReaderWriterChain; 031import dev.enola.common.io.object.template.TemplatedObjectReader; 032import dev.enola.common.io.resource.FileDescriptorResource; 033import dev.enola.common.io.resource.FileResource; 034import dev.enola.common.io.resource.ResourceProvider; 035import dev.enola.common.io.resource.ResourceProviders; 036import dev.enola.common.template.TemplateProvider; 037import dev.enola.common.template.handlebars.HandlebarsMediaType; 038import dev.enola.common.template.handlebars.HandlebarsTemplateProvider; 039 040import java.io.IOException; 041import java.net.URI; 042import java.nio.file.Paths; 043import java.util.Arrays; 044import java.util.List; 045 046// This is used by //MODULE.update.bash 047public class TemplyMain { 048 049 // TODO Expose this as an ./enola template CLI sub-command too 050 051 private final Temply temply; 052 private final ResourceProvider rp; 053 054 public TemplyMain(ResourceProvider rp, TemplateProvider templateProvider) { 055 this.rp = rp; 056 ObjectReaderChain delegateObjectReader = 057 new ObjectReaderChain(new JacksonObjectReaderWriterChain(), new CsvReader()); 058 this.temply = new Temply(new TemplatedObjectReader(delegateObjectReader), templateProvider); 059 } 060 061 private static ResourceProvider rp() { 062 var fileRP = new FileResource.Provider(); 063 var fdRP = new FileDescriptorResource.Provider(); 064 return new ResourceProviders(fileRP, fdRP); 065 } 066 067 private static final TemplyMain INSTANCE = 068 new TemplyMain(rp(), new HandlebarsTemplateProvider()); 069 070 public static void main(String[] args) throws IOException { 071 if (args.length < 1) { 072 var use = "USAGE: temply [data1.yaml data2.json data3.csv...] <template.handlebars>"; 073 System.err.println(use); 074 System.exit(1); 075 } 076 var dataURIs = Arrays.stream(args, 0, args.length - 1).map(URI::create).toList(); 077 var templateURI = URI.create(args[args.length - 1]); 078 079 MediaTypeProviders.set( 080 new HandlebarsMediaType(), new YamlMediaType(), new StandardMediaTypes()); 081 try (var ctx = TLC.open().push(URIs.ContextKeys.BASE, Paths.get("").toUri())) { 082 INSTANCE.run(dataURIs, templateURI, STDOUT_URI); 083 } 084 } 085 086 public void run(List<URI> dataURIs, URI templateURI, URI outURI) throws IOException { 087 var dataResources = MoreStreams.map(dataURIs.stream(), rp::getNonNull).toList(); 088 var templateResource = rp.getNonNull(templateURI); 089 var outResource = rp.getNonNull(outURI); 090 091 temply.convert(dataResources, templateResource, outResource); 092 } 093}