"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublishGit = void 0;
const PublishUtilities_1 = require("./PublishUtilities");
const Utilities_1 = require("../utilities/Utilities");
const DUMMY_BRANCH_NAME = '-branch-name-';
class PublishGit {
    constructor(git, targetBranch) {
        this._targetBranch = targetBranch;
        this._gitPath = git.getGitPathOrThrow();
        this._gitTagSeparator = git.getTagSeparator();
    }
    async checkoutAsync(branchName, createBranch = false) {
        const args = ['checkout'];
        if (createBranch) {
            args.push('-b');
        }
        args.push(branchName || DUMMY_BRANCH_NAME);
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args
        });
    }
    async mergeAsync(branchName, verify = false) {
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args: ['merge', branchName, '--no-edit', ...(verify ? [] : ['--no-verify'])]
        });
    }
    async deleteBranchAsync(branchName, hasRemote = true, verify = false) {
        if (!branchName) {
            branchName = DUMMY_BRANCH_NAME;
        }
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args: ['branch', '-d', branchName]
        });
        if (hasRemote) {
            await PublishUtilities_1.PublishUtilities.execCommandAsync({
                shouldExecute: !!this._targetBranch,
                command: this._gitPath,
                args: ['push', 'origin', '--delete', branchName, ...(verify ? [] : ['--no-verify'])]
            });
        }
    }
    async pullAsync(verify = false) {
        const args = ['pull', 'origin'];
        if (this._targetBranch) {
            args.push(this._targetBranch);
        }
        if (!verify) {
            args.push('--no-verify');
        }
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args
        });
    }
    async fetchAsync() {
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args: ['fetch', 'origin']
        });
    }
    async addChangesAsync(pathspec, workingDirectory) {
        const files = pathspec || '.';
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args: ['add', files],
            workingDirectory
        });
    }
    async addTagAsync(shouldExecute, packageName, packageVersion, commitId, preReleaseName) {
        // Tagging only happens if we're publishing to real NPM and committing to git.
        const tagName = PublishUtilities_1.PublishUtilities.createTagname(packageName, packageVersion, this._gitTagSeparator);
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch && shouldExecute,
            command: this._gitPath,
            args: [
                'tag',
                '-a',
                preReleaseName ? `${tagName}-${preReleaseName}` : tagName,
                '-m',
                preReleaseName
                    ? `${packageName} v${packageVersion}-${preReleaseName}`
                    : `${packageName} v${packageVersion}`,
                ...(commitId ? [commitId] : [])
            ]
        });
    }
    async hasTagAsync(packageConfig) {
        const tagName = PublishUtilities_1.PublishUtilities.createTagname(packageConfig.packageName, packageConfig.packageJson.version, this._gitTagSeparator);
        const tagOutput = (await Utilities_1.Utilities.executeCommandAndCaptureOutputAsync({
            command: this._gitPath,
            args: ['tag', '-l', tagName],
            workingDirectory: packageConfig.projectFolder,
            environment: PublishUtilities_1.PublishUtilities.getEnvArgs(),
            keepEnvironment: true
        })).replace(/(\r\n|\n|\r)/gm, '');
        return tagOutput === tagName;
    }
    async commitAsync(commitMessage, verify = false) {
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            args: ['commit', '-m', commitMessage, ...(verify ? [] : ['--no-verify'])]
        });
    }
    async pushAsync(branchName, verify = false, followTags = true) {
        await PublishUtilities_1.PublishUtilities.execCommandAsync({
            shouldExecute: !!this._targetBranch,
            command: this._gitPath,
            // We append "--no-verify" to prevent Git hooks from running.  For example, people may
            // want to invoke "rush change -v" as a pre-push hook.
            args: [
                'push',
                'origin',
                `HEAD:${branchName || DUMMY_BRANCH_NAME}`,
                ...(followTags ? ['--follow-tags'] : []),
                '--verbose',
                ...(verify ? [] : ['--no-verify'])
            ]
        });
    }
}
exports.PublishGit = PublishGit;
//# sourceMappingURL=PublishGit.js.map