Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/applied-logic #1

Draft
wants to merge 3 commits into
base: feat/checkout-remote-branch-locally
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 57 additions & 52 deletions apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ({
Expand Down Expand Up @@ -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,
Expand All @@ -132,34 +160,13 @@ export async function applyIfNeedsToApply({
autoApplyIfNeeded: boolean; //
config: Git.Config;
}): Promise<ReturnOfApplyIfNeedsToApply> {
/**
* 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,
};
}

Expand All @@ -181,7 +188,7 @@ export async function applyIfNeedsToApply({
return {
neededToApply: true,
userAllowedToApplyAndWeApplied: false,
markThatNeedsToApply,
markThatNeedsToApply: _markThatNeedsToApply,
};
}

Expand All @@ -196,13 +203,11 @@ export async function applyIfNeedsToApply({
pathToStackedRebaseDirInsideDotGit, //
...rest,
});

unmarkThatNeedsToApply(pathToStackedRebaseDirInsideDotGit);
}

return {
neededToApply: true,
userAllowedToApplyAndWeApplied: true, //
markThatNeedsToApply,
markThatNeedsToApply: _markThatNeedsToApply,
};
}
10 changes: 1 addition & 9 deletions branchSequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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<void>;
Expand All @@ -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) =>
Expand Down
3 changes: 2 additions & 1 deletion filenames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
*/
export const filenames = {
rewrittenList: "rewritten-list",
rewrittenListApplied: "rewritten-list.applied",
needsToApply: "needs-to-apply",
applied: "applied",
//
gitRebaseTodo: "git-rebase-todo",
//
Expand Down
1 change: 0 additions & 1 deletion forcePush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,4 @@ export const forcePush: BranchSequencerBase = (argsBase) =>
execSyncInRepo(`${argsBase.gitCmd} push --force`);
},
delayMsBetweenCheckouts: 0,
rewrittenListFile: "rewritten-list.applied",
});
7 changes: 3 additions & 4 deletions parse-todo-of-stacked-rebase/parseNewGoodCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand Down