diff --git a/apply.ts b/apply.ts index 642f39e0..03bc8785 100644 --- a/apply.ts +++ b/apply.ts @@ -23,7 +23,7 @@ export const apply: BranchSequencerBase = (args) => // callbackAfterDone: defaultApplyCallback, delayMsBetweenCheckouts: 0, }).then( - (ret) => (unmarkThatNeedsToApply(args.pathToStackedRebaseDirInsideDotGit), ret) // + (ret) => (markThatApplied(args.pathToStackedRebaseDirInsideDotGit), ret) // ); const defaultApplyAction: ActionInsideEachCheckedOutBranch = async ({ @@ -82,44 +82,72 @@ const defaultApplyCallback__disabled: CallbackAfterDone = ({ }; noop(defaultApplyCallback__disabled); -export type ReturnOfApplyIfNeedsToApply = +export type ReturnOfApplyIfNeedsToApply = { + markThatNeedsToApply: () => void; +} & ( | { neededToApply: false; userAllowedToApplyAndWeApplied?: never; - markThatNeedsToApply: () => void; } | { neededToApply: true; userAllowedToApplyAndWeApplied: false; // markThatNeedsToApply?: never; // TODO TS infer auto - force code owner to exit - markThatNeedsToApply: () => void; } | { neededToApply: true; userAllowedToApplyAndWeApplied: true; - markThatNeedsToApply: () => void; - }; + } +); -const filenameOfNeedsToApply = "needs-to-apply" as const; +const getPaths = ( + pathToStackedRebaseDirInsideDotGit: string // +) => + ({ + rewrittenListPath: path.join(pathToStackedRebaseDirInsideDotGit, filenames.rewrittenList), + needsToApplyPath: path.join(pathToStackedRebaseDirInsideDotGit, filenames.needsToApply), + appliedPath: path.join(pathToStackedRebaseDirInsideDotGit, filenames.applied), + } as const); + +const markThatNeedsToApply = ( + pathToStackedRebaseDirInsideDotGit: string // +): void => + [getPaths(pathToStackedRebaseDirInsideDotGit)].map( + ({ rewrittenListPath, needsToApplyPath, appliedPath }) => ( + fs.existsSync(rewrittenListPath) + ? fs.copyFileSync(rewrittenListPath, needsToApplyPath) + : fs.writeFileSync(needsToApplyPath, ""), + fs.existsSync(appliedPath) && fs.unlinkSync(appliedPath), + void 0 + ) + )[0]; + +export const markThatApplied = (pathToStackedRebaseDirInsideDotGit: string): void => + [getPaths(pathToStackedRebaseDirInsideDotGit)].map( + ({ rewrittenListPath, needsToApplyPath, appliedPath }) => ( + fs.existsSync(needsToApplyPath) && fs.unlinkSync(needsToApplyPath), // + fs.copyFileSync(rewrittenListPath, appliedPath), + void 0 + ) + )[0]; + +const doesNeedToApply = (pathToStackedRebaseDirInsideDotGit: string): boolean => { + const { rewrittenListPath, needsToApplyPath, appliedPath } = getPaths(pathToStackedRebaseDirInsideDotGit); + + const needsToApplyPart1: boolean = fs.existsSync(needsToApplyPath); + if (needsToApplyPart1) { + return true; + } -const getPathOfFilenameOfNeedsToApply = (pathToStackedRebaseDirInsideDotGit: string): string => - path.join(pathToStackedRebaseDirInsideDotGit, filenameOfNeedsToApply); + const needsToApplyPart2: boolean = fs.existsSync(appliedPath) + ? /** + * check if has been applied, but that apply is outdated + */ + !fs.readFileSync(appliedPath).equals(fs.readFileSync(rewrittenListPath)) + : false; -/** - * TODO rename "markThatApplied" because we are _not_ reversing the action - * (undo-ing the file rename), - * we are invoking a new action of removing the files. - */ -export const unmarkThatNeedsToApply = ( - pathToStackedRebaseDirInsideDotGit: string, - mark = getPathOfFilenameOfNeedsToApply(pathToStackedRebaseDirInsideDotGit), - rewrittenListFile: string = path.join(pathToStackedRebaseDirInsideDotGit, filenames.rewrittenList), - rewrittenListAppliedFile: string = path.join(pathToStackedRebaseDirInsideDotGit, filenames.rewrittenListApplied) -): void => ( - fs.existsSync(mark) && fs.unlinkSync(mark), - fs.existsSync(rewrittenListFile) && fs.renameSync(rewrittenListFile, rewrittenListAppliedFile), - void 0 -); + return needsToApplyPart2; +}; export async function applyIfNeedsToApply({ repo, @@ -132,34 +160,13 @@ export async function applyIfNeedsToApply({ autoApplyIfNeeded: boolean; // config: Git.Config; }): Promise { - /** - * currently we're not saving the branch names - * & where they point to etc., - * so doing rebase after rebase without --apply - * will break the workflow after the 1st one. - * - * thus, until we have a more sophisticated solution, - * automatically --apply'ing (when needed) should do just fine. - * - */ - const pathToFileIndicatingThatNeedsToApply = getPathOfFilenameOfNeedsToApply(pathToStackedRebaseDirInsideDotGit); - const needsToApply: boolean = fs.existsSync(pathToFileIndicatingThatNeedsToApply); - - const pathToAppliedRewrittenListFile = path.join( - pathToStackedRebaseDirInsideDotGit, - filenames.rewrittenListApplied - ); - - const markThatNeedsToApply = (): void => ( - fs.writeFileSync(pathToFileIndicatingThatNeedsToApply, ""), - fs.existsSync(pathToAppliedRewrittenListFile) && fs.unlinkSync(pathToAppliedRewrittenListFile), - void 0 - ); + const needsToApply: boolean = doesNeedToApply(pathToStackedRebaseDirInsideDotGit); + const _markThatNeedsToApply = (): void => markThatNeedsToApply(pathToStackedRebaseDirInsideDotGit); if (!needsToApply) { return { neededToApply: false, - markThatNeedsToApply, + markThatNeedsToApply: _markThatNeedsToApply, }; } @@ -181,7 +188,7 @@ export async function applyIfNeedsToApply({ return { neededToApply: true, userAllowedToApplyAndWeApplied: false, - markThatNeedsToApply, + markThatNeedsToApply: _markThatNeedsToApply, }; } @@ -196,13 +203,11 @@ export async function applyIfNeedsToApply({ pathToStackedRebaseDirInsideDotGit, // ...rest, }); - - unmarkThatNeedsToApply(pathToStackedRebaseDirInsideDotGit); } return { neededToApply: true, userAllowedToApplyAndWeApplied: true, // - markThatNeedsToApply, + markThatNeedsToApply: _markThatNeedsToApply, }; } diff --git a/branchSequencer.ts b/branchSequencer.ts index 4e9a5d27..799d8908 100644 --- a/branchSequencer.ts +++ b/branchSequencer.ts @@ -3,8 +3,6 @@ import assert from "assert"; import Git from "nodegit"; -import { filenames } from "./filenames"; - import { createExecSyncInRepo } from "./util/execSyncInRepo"; import { Termination } from "./util/error"; @@ -54,7 +52,6 @@ export type BranchSequencerArgs = BranchSequencerArgsBase & { actionInsideEachCheckedOutBranch: ActionInsideEachCheckedOutBranch; delayMsBetweenCheckouts?: number; callbackAfterDone?: CallbackAfterDone; - rewrittenListFile?: typeof filenames.rewrittenList | typeof filenames.rewrittenListApplied; }; export type BranchSequencerBase = (args: BranchSequencerArgsBase) => Promise; @@ -70,18 +67,13 @@ export const branchSequencer: BranchSequencer = async ({ // callbackBeforeBegin, actionInsideEachCheckedOutBranch, callbackAfterDone = (): void => {}, - rewrittenListFile = filenames.rewrittenList, gitCmd, }) => { if (!fs.existsSync(pathToStackedRebaseDirInsideDotGit)) { throw new Termination(`\n\nno stacked-rebase in progress? (nothing to ${rootLevelCommandName})\n\n`); } - const stackedRebaseCommandsNew: GoodCommand[] = parseNewGoodCommands( - repo, - pathToStackedRebaseTodoFile, - rewrittenListFile - ); + const stackedRebaseCommandsNew: GoodCommand[] = parseNewGoodCommands(repo, pathToStackedRebaseTodoFile); // const remotes: Git.Remote[] = await repo.getRemotes(); // const remote: Git.Remote | undefined = remotes.find((r) => diff --git a/filenames.ts b/filenames.ts index 6a2cd143..ccc32479 100644 --- a/filenames.ts +++ b/filenames.ts @@ -3,7 +3,8 @@ */ export const filenames = { rewrittenList: "rewritten-list", - rewrittenListApplied: "rewritten-list.applied", + needsToApply: "needs-to-apply", + applied: "applied", // gitRebaseTodo: "git-rebase-todo", // diff --git a/forcePush.ts b/forcePush.ts index 171e3720..a7c0befa 100644 --- a/forcePush.ts +++ b/forcePush.ts @@ -38,5 +38,4 @@ export const forcePush: BranchSequencerBase = (argsBase) => execSyncInRepo(`${argsBase.gitCmd} push --force`); }, delayMsBetweenCheckouts: 0, - rewrittenListFile: "rewritten-list.applied", }); diff --git a/parse-todo-of-stacked-rebase/parseNewGoodCommands.ts b/parse-todo-of-stacked-rebase/parseNewGoodCommands.ts index f55ce234..12d8ad8f 100644 --- a/parse-todo-of-stacked-rebase/parseNewGoodCommands.ts +++ b/parse-todo-of-stacked-rebase/parseNewGoodCommands.ts @@ -14,14 +14,13 @@ import { GoodCommand, stackedRebaseCommands } from "./validator"; export function parseNewGoodCommands( repo: Git.Repository, - pathToStackedRebaseTodoFile: string, // - rewrittenListFile: typeof filenames.rewrittenList | typeof filenames.rewrittenListApplied + pathToStackedRebaseTodoFile: string // ): GoodCommand[] { const oldGoodCommands: GoodCommand[] = parseTodoOfStackedRebase(pathToStackedRebaseTodoFile); logGoodCmds(oldGoodCommands); - const pathOfRewrittenList: string = path.join(repo.path(), "stacked-rebase", rewrittenListFile); + const pathOfRewrittenList: string = path.join(repo.path(), "stacked-rebase", filenames.rewrittenList); const rewrittenList: string = fs.readFileSync(pathOfRewrittenList, { encoding: "utf-8" }); const rewrittenListLines: string[] = rewrittenList.split("\n").filter((line) => !!line); @@ -36,7 +35,7 @@ export function parseNewGoodCommands( const fromToSHA = line.split(" "); assert( fromToSHA.length === 2, - `from and to SHAs, coming from ${rewrittenListFile}, are written properly (1 space total).` + `from and to SHAs, coming from ${filenames.rewrittenList}, are written properly (1 space total).` ); const [oldSHA, newSHA] = fromToSHA;