All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jreleaser.engine.templates.TemplateEvaluator Maven / Gradle / Ivy

The newest version!
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2020-2024 The JReleaser authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jreleaser.engine.templates;

import org.apache.commons.io.IOUtils;
import org.jreleaser.bundle.RB;
import org.jreleaser.engine.changelog.Changelog;
import org.jreleaser.logging.JReleaserLogger;
import org.jreleaser.model.Constants;
import org.jreleaser.model.JReleaserException;
import org.jreleaser.model.internal.JReleaserContext;
import org.jreleaser.mustache.TemplateContext;
import org.jreleaser.templates.TemplateResource;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;
import static org.jreleaser.bundle.RB.$;
import static org.jreleaser.mustache.MustacheUtils.applyTemplate;
import static org.jreleaser.mustache.MustacheUtils.passThrough;
import static org.jreleaser.templates.TemplateUtils.resolveTemplate;
import static org.jreleaser.templates.TemplateUtils.resolveTemplates;
import static org.jreleaser.templates.TemplateUtils.trimTplExtension;
import static org.jreleaser.util.FileUtils.createDirectoriesWithFullAccess;
import static org.jreleaser.util.FileUtils.grantFullAccess;

/**
 * @author Andres Almiray
 * @since 1.5.0
 */
public class TemplateEvaluator {
    private TemplateEvaluator() {
        // noop
    }

    public static Path generateTemplate(JReleaserContext context, Path templatePath, Path targetDirectory, boolean overwrite) throws JReleaserException {
        if (!Files.exists(templatePath)) {
            throw fail(RB.$("validation_directory_not_exist", "templatePath", templatePath));
        }

        if (!Files.isRegularFile(templatePath)) {
            throw fail(RB.$("validation_is_not_a_file", "templatePath", templatePath));
        }


        try {
            context.getLogger().info(RB.$("templates.create.directory"), targetDirectory.toAbsolutePath());
            Files.createDirectories(targetDirectory);

            TemplateResource template = resolveTemplate(templatePath);
            TemplateContext props = setupTemplateContext(context);

            String key = templatePath.getFileName().toString();

            Path targetTemplate = targetDirectory.resolve(trimTplExtension(key));
            if (template.isReader()) {
                context.getLogger().info(RB.$("templates.evaluate"), key);
                String content = applyTemplate(template.getReader(), props, key);
                context.getLogger().info(RB.$("templates.writing.file"), targetTemplate);
                writeFile(context.getLogger(), content, targetTemplate, overwrite);
            } else {
                context.getLogger().info(RB.$("templates.writing.file"), targetTemplate);
                writeFile(context.getLogger(), IOUtils.toByteArray(template.getInputStream()), targetTemplate, overwrite);
            }

        } catch (IOException e) {
            throw fail(e);
        }

        context.getLogger().info(RB.$("templates.evaluate.single.done", templatePath, targetDirectory));
        return targetDirectory;
    }

    public static Path generateTemplates(JReleaserContext context, Path inputDirectory, Path targetDirectory, boolean overwrite) throws JReleaserException {
        if (!Files.exists(inputDirectory)) {
            throw fail(RB.$("validation_directory_not_exist", "inputDirectory", inputDirectory));
        }

        if (!Files.isDirectory(inputDirectory)) {
            throw fail(RB.$("validation_is_not_a_directory", "inputDirectory", inputDirectory));
        }

        try {
            File inputDirectoryFile = inputDirectory.toFile();
            if (null == inputDirectoryFile.listFiles() || inputDirectoryFile.listFiles().length == 0) {
                throw fail(RB.$("validation_directory_is_empty", "inputDirectory", inputDirectory));
            }

            context.getLogger().info(RB.$("templates.create.directory"), targetDirectory.toAbsolutePath());
            Files.createDirectories(targetDirectory);

            Map templates = resolveTemplates(inputDirectory);
            TemplateContext props = setupTemplateContext(context);

            for (Map.Entry entry : templates.entrySet()) {
                String key = entry.getKey();
                TemplateResource value = entry.getValue();

                Path targetTemplate = targetDirectory.resolve(trimTplExtension(key));
                if (value.isReader()) {
                    context.getLogger().info(RB.$("templates.evaluate"), key);
                    String content = applyTemplate(value.getReader(), props, key);
                    context.getLogger().info(RB.$("templates.writing.file"), targetTemplate);
                    writeFile(context.getLogger(), content, targetTemplate, overwrite);
                } else {
                    context.getLogger().info(RB.$("templates.writing.file"), targetTemplate);
                    writeFile(context.getLogger(), IOUtils.toByteArray(value.getInputStream()), targetTemplate, overwrite);
                }
            }
        } catch (IOException e) {
            throw fail(e);
        }

        context.getLogger().info(RB.$("templates.evaluate.multiple.done", inputDirectory, targetDirectory));
        return targetDirectory;
    }

    private static TemplateContext setupTemplateContext(JReleaserContext context) {
        TemplateContext props = context.fullProps();

        if (context.getMode() == org.jreleaser.model.api.JReleaserContext.Mode.ANNOUNCE ||
            context.getMode() == org.jreleaser.model.api.JReleaserContext.Mode.CHANGELOG ||
            context.getMode() == org.jreleaser.model.api.JReleaserContext.Mode.CONFIG ||
            context.getMode() == org.jreleaser.model.api.JReleaserContext.Mode.FULL) {
            String resolvedChangelog = Changelog.createChangelog(context);
            context.getChangelog().setResolvedChangelog(resolvedChangelog);
            props.set(Constants.KEY_CHANGELOG_CONTENT, passThrough(resolvedChangelog));
            props.set(Constants.KEY_CHANGELOG_CHANGES, passThrough(context.getChangelog().getFormattedChanges()));
            props.set(Constants.KEY_CHANGELOG_CONTRIBUTORS, passThrough(context.getChangelog().getFormattedContributors()));
        }

        return props;
    }

    private static void writeFile(JReleaserLogger logger, String content, Path outputFile, boolean overwrite) {
        try {
            createDirectoriesWithFullAccess(outputFile.getParent());
            Files.write(outputFile, content.getBytes(UTF_8), overwrite ? CREATE : CREATE_NEW, WRITE, TRUNCATE_EXISTING);
            grantFullAccess(outputFile);
        } catch (FileAlreadyExistsException e) {
            logger.error($("jreleaser.ERROR_file_exists"), outputFile.toAbsolutePath());
        } catch (IOException e) {
            throw fail(RB.$("ERROR_unexpected_error_writing_file", outputFile.toAbsolutePath()), e);
        }
    }

    private static void writeFile(JReleaserLogger logger, byte[] content, Path outputFile, boolean overwrite) {
        try {
            createDirectoriesWithFullAccess(outputFile.getParent());
            Files.write(outputFile, content, overwrite ? CREATE : CREATE_NEW, WRITE, TRUNCATE_EXISTING);
            grantFullAccess(outputFile);
        } catch (FileAlreadyExistsException e) {
            logger.error($("jreleaser.ERROR_file_exists"), outputFile.toAbsolutePath());
        } catch (IOException e) {
            throw fail(RB.$("ERROR_unexpected_error_writing_file", outputFile.toAbsolutePath()), e);
        }
    }

    private static JReleaserException fail(String msg) throws JReleaserException {
        throw new JReleaserException(msg);
    }

    private static JReleaserException fail(String msg, Exception e) throws JReleaserException {
        throw new JReleaserException(msg, e);
    }

    private static JReleaserException fail(Exception e) throws JReleaserException {
        throw new JReleaserException(RB.$("ERROR_unexpected_template_fail2"), e);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy