@tinymce/beehive-flow
Version:
A CLI tool implementing the beehive flow git branching process
131 lines • 5.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTags = exports.hasLocalChanges = exports.resolveGitUrl = exports.detectGitUrl = exports.checkoutMainBranch = exports.checkout = exports.branchShouldNotExist = exports.pushUnlessDryRun = exports.doesRemoteBranchExist = exports.remoteBranchNames = exports.currentRevisionShortSha = exports.pushOneTag = exports.push = exports.currentBranch = exports.checkoutNewBranch = exports.cloneInTempFolder = exports.cloneIn = exports.initInTempFolder = void 0;
const tslib_1 = require("tslib");
const O = tslib_1.__importStar(require("fp-ts/Option"));
const simple_git_1 = require("simple-git");
const BranchLogic_1 = require("../core/BranchLogic");
const Files = tslib_1.__importStar(require("./Files"));
const ObjUtils = tslib_1.__importStar(require("./ObjUtils"));
const PromiseUtils = tslib_1.__importStar(require("./PromiseUtils"));
const StringUtils = tslib_1.__importStar(require("./StringUtils"));
const ASSUMED_REMOTE = 'origin'; // This module assumes a single remote called 'origin'
const initInTempFolder = async (bare = false) => {
const dir = await Files.tempFolder();
const git = (0, simple_git_1.gitP)(dir);
await git.init(bare);
return { dir, git };
};
exports.initInTempFolder = initInTempFolder;
const cloneIn = async (gitUrl, dir) => {
console.log(`Cloning ${gitUrl} to ${dir}`);
const git = (0, simple_git_1.gitP)(dir);
await git.clone(gitUrl, dir);
return { dir, git };
};
exports.cloneIn = cloneIn;
const cloneInTempFolder = async (gitUrl, temp = O.none) => {
const dir = O.isSome(temp) ? temp.value : (await Files.tempFolder());
return await (0, exports.cloneIn)(gitUrl, dir);
};
exports.cloneInTempFolder = cloneInTempFolder;
const checkoutNewBranch = (git, branchName) => git.checkout(['-b', branchName]);
exports.checkoutNewBranch = checkoutNewBranch;
const currentBranch = (git) => git.branch().then((b) => b.current);
exports.currentBranch = currentBranch;
const push = async (git) => {
const cur = await (0, exports.currentBranch)(git);
return git.push(ASSUMED_REMOTE, cur, { '--set-upstream': null });
};
exports.push = push;
const pushOneTag = async (git, tagName) => git.push(ASSUMED_REMOTE, tagName);
exports.pushOneTag = pushOneTag;
const currentRevisionShortSha = (git) => git.revparse(['--short', 'HEAD']);
exports.currentRevisionShortSha = currentRevisionShortSha;
const remoteBranchNames = async (git) => {
const rbs = await git.branch();
return rbs.all
.filter((r) => r.startsWith('remotes/origin/'))
.map((r) => StringUtils.removeLeading(r, 'remotes/origin/'));
};
exports.remoteBranchNames = remoteBranchNames;
const doesRemoteBranchExist = async (git, branchName) => {
const b = await git.branch();
return ObjUtils.hasKey(b.branches, 'remotes/origin/' + branchName);
};
exports.doesRemoteBranchExist = doesRemoteBranchExist;
const dryRunMessage = async (dir, git) => {
const curBranch = await (0, exports.currentBranch)(git);
return `dry-run - not pushing. To complete, push "${curBranch}" branch from ${dir}`;
};
const pushUnlessDryRun = async (dir, git, dryRun) => {
if (dryRun) {
console.log(await dryRunMessage(dir, git));
}
else {
console.log('git push');
await (0, exports.push)(git);
}
};
exports.pushUnlessDryRun = pushUnlessDryRun;
const branchShouldNotExist = async (git, branchName) => {
if (await (0, exports.doesRemoteBranchExist)(git, branchName)) {
return PromiseUtils.fail(`Remote branch already exists: ${branchName}`);
}
};
exports.branchShouldNotExist = branchShouldNotExist;
const checkout = async (git, branchName) => {
console.log(`Checking out branch: ${branchName}`);
await git.checkout(branchName);
return branchName;
};
exports.checkout = checkout;
const checkoutMainBranch = (git) => (0, exports.checkout)(git, BranchLogic_1.mainBranchName);
exports.checkoutMainBranch = checkoutMainBranch;
const detectGitUrl = async (g) => {
const remotes = await g.getRemotes(true);
if (remotes.length === 1) {
return remotes[0].refs.fetch;
}
else if (remotes.length === 0) {
return PromiseUtils.fail('Could not detect git url - the repo has no remotes.');
}
else {
const res = remotes.find((r) => r.name === 'origin');
if (res !== undefined) {
return res.refs.fetch;
}
else {
return PromiseUtils.fail('Could not detect git url - there were multiple remotes and none were called "origin"');
}
}
};
exports.detectGitUrl = detectGitUrl;
const detectGitUrlFromDir = async (dir) => {
const g = (0, simple_git_1.gitP)(dir);
return await (0, exports.detectGitUrl)(g);
};
const resolveGitUrl = async (gitUrlArg, workingDirArg) => O.isSome(gitUrlArg) ? gitUrlArg.value : await detectGitUrlFromDir(workingDirArg);
exports.resolveGitUrl = resolveGitUrl;
const isWorkingDirDirty = async (git) => {
const diff = await git.diffSummary(['HEAD']);
return diff.changed > 0;
};
const isAheadOfRemote = async (git, branchName) => {
await git.fetch();
const log = await git.log({ from: `origin/${branchName}`, to: branchName, symmetric: false });
return log.total > 0;
};
const hasLocalChanges = async (workingDir, branchName) => {
const git = (0, simple_git_1.gitP)(workingDir);
const isAhead = await isAheadOfRemote(git, branchName);
const isDirty = await isWorkingDirDirty(git);
return isDirty || isAhead;
};
exports.hasLocalChanges = hasLocalChanges;
const getTags = async (g) => {
const tags = await g.tags();
return tags.all;
};
exports.getTags = getTags;
//# sourceMappingURL=Git.js.map