"use strict";
/*
 * Copyright © 2020 Atomist, Inc.
 *
 * 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
 *
 *     http://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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGitTag = exports.executeTag = void 0;
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const LoggingProgressLog_1 = require("../../../api-helper/log/LoggingProgressLog");
const child_process_1 = require("../../../api-helper/misc/child_process");
const projectVersioner_1 = require("./local/projectVersioner");
/**
 * Create and return an execute goal object that creates a Git tag,
 * suitable for use with the [[Tag]] goal.
 *
 * @param opts Options that determine the tag created
 * @return Success if successful, Failure otherwise
 */
function executeTag(opts = {}) {
    return async (goalInvocation) => {
        const { configuration, goalEvent, credentials, id, context, progressLog } = goalInvocation;
        return configuration.sdm.projectLoader.doWithProject({ credentials, id, context, readOnly: false }, async (project) => {
            try {
                let tag;
                let message;
                if (opts.message) {
                    message = opts.message;
                }
                else if (goalEvent.push.after && goalEvent.push.after.message) {
                    message = goalEvent.push.after.message.split("\n")[0];
                }
                if (opts.name) {
                    tag = opts.name;
                    message = message || `Tag ${opts.name}`;
                }
                else {
                    const version = await projectVersioner_1.goalInvocationVersion(goalInvocation);
                    if (opts.release) {
                        tag = version.replace(/[-+].*/, "");
                        message = message || `Release ${tag}`;
                    }
                    else {
                        tag = version;
                        message = message || `Prerelease ${tag}`;
                    }
                }
                if (opts.build) {
                    tag += "+" + opts.build;
                }
                await createGitTag({ project, tag, message, log: progressLog });
                return {
                    code: 0,
                    message: `Created tag '${tag}' for ${goalEvent.repo.owner}/${goalEvent.repo.name}`,
                };
            }
            catch (e) {
                const message = `Failed to create tag for ${goalEvent.repo.owner}/${goalEvent.repo.name}: ${e.message}`;
                logger_1.logger.error(message);
                progressLog.write(message);
                return { code: 1, message };
            }
        });
    };
}
exports.executeTag = executeTag;
/**
 * Create and push a Git tag with optional message.
 *
 * @param opts Options for creating a Git tag.
 */
async function createGitTag(opts) {
    if (!opts.tag) {
        throw new Error("You must provide a valid Git tag");
    }
    if (!opts.project) {
        throw new Error("You must provide a Git project");
    }
    if (!opts.log) {
        opts.log = new LoggingProgressLog_1.LoggingProgressLog("logger");
    }
    const remote = opts.project.remote || "origin";
    try {
        const spawnOpts = { cwd: opts.project.baseDir, log: opts.log };
        const tagArgs = ["tag", opts.tag];
        if (opts.message) {
            tagArgs.splice(1, 0, "-m", opts.message);
        }
        const tagResult = await child_process_1.spawnLog("git", tagArgs, spawnOpts);
        if (tagResult.code) {
            throw new Error(`git tag failed: ${tagResult.message}`);
        }
        const pushResult = await child_process_1.spawnLog("git", ["push", remote, opts.tag], spawnOpts);
        if (pushResult.code) {
            throw new Error(`git push failed: ${pushResult.message}`);
        }
    }
    catch (e) {
        e.message = `Failed to create and push git tag '${opts.tag}': ${e.message}`;
        throw e;
    }
}
exports.createGitTag = createGitTag;
//# sourceMappingURL=executeTag.js.map