feat(commands): open default editor upon footer/body writing (#24)
This commit is being made to implement an ability to create multi-line bodies and footers in RCZ. Default behavior is to present tje user with a prompt inquiring on whether they wish to write a body/footer; the initial value is false as both of these parts of the commit message are used rather rarely. Proposed an accepted during TD meeting 18.05.2024
This commit is contained in:
@@ -18,7 +18,11 @@ along with RCZ. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Command } from "commander";
|
||||
import { checkForUpdates, getConfig } from "../utils/functions";
|
||||
import {
|
||||
checkForUpdates,
|
||||
getConfig,
|
||||
getDefaultEditor,
|
||||
} from "../utils/functions";
|
||||
import {
|
||||
cancel,
|
||||
confirm,
|
||||
@@ -33,6 +37,32 @@ import {
|
||||
import { existsSync } from "fs";
|
||||
import { join } from "path";
|
||||
import simpleGit, { ResetMode } from "simple-git";
|
||||
import { readFile, writeFile } from "fs/promises";
|
||||
import { tmpdir } from "os";
|
||||
import { spawn } from "child_process";
|
||||
|
||||
const getEditorInput = async (defaultValue = "") => {
|
||||
const tempFilePath = join(tmpdir(), `io.resultium.rcz-${Date.now()}.txt`);
|
||||
await writeFile(tempFilePath, defaultValue);
|
||||
|
||||
const editor = spawn(getDefaultEditor(), [tempFilePath], {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
return await new Promise<string>((resolve) => {
|
||||
editor.on("exit", async (code) => {
|
||||
if (code !== 0) {
|
||||
throw new Error(`Editor exited with code ${code}`);
|
||||
}
|
||||
|
||||
resolve((await readFile(tempFilePath)).toString());
|
||||
});
|
||||
|
||||
editor.on("error", (err) => {
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const command = new Command("commit")
|
||||
.alias("c")
|
||||
@@ -224,27 +254,56 @@ const command = new Command("commit")
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const body = await text({
|
||||
message: `Insert a commit body (motivation or elaboration for the change), can be left empty`,
|
||||
placeholder:
|
||||
"improves regex for suspicious character check in router requests",
|
||||
let body: null | string = null;
|
||||
const writeBody = await confirm({
|
||||
message: `Would you like to insert a commit body (elaboration for the change)?`,
|
||||
initialValue: false,
|
||||
});
|
||||
|
||||
if (isCancel(body)) {
|
||||
if (isCancel(writeBody)) {
|
||||
cancel("Commit creation cancelled");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const footer = await text({
|
||||
message: `Insert commit footer, can be left empty, e.g. Acked-by: @johndoe`,
|
||||
placeholder: "Acked-by: @security",
|
||||
if (writeBody) {
|
||||
// Stop clack input
|
||||
process.stdin.pause();
|
||||
|
||||
body = await getEditorInput(
|
||||
`e.g.
|
||||
* Revert "Guard against SMTP smuggling", commit faf23f1, by restoring the setting to its default.
|
||||
* Revert "[security] SMTP smuggling: update short term fix (#2346)", commmit e931e10, by restoring the setting to its default.
|
||||
* Set smtpd_forbid_bare_newline=normalize.
|
||||
|
||||
Fixes #444
|
||||
`,
|
||||
);
|
||||
|
||||
// Resume clack input
|
||||
process.stdin.resume();
|
||||
}
|
||||
|
||||
let footer: null | string = null;
|
||||
const writeFooter = await confirm({
|
||||
message: `Would you like to insert a commit footer?`,
|
||||
initialValue: false,
|
||||
});
|
||||
|
||||
if (isCancel(footer)) {
|
||||
if (isCancel(writeFooter)) {
|
||||
cancel("Commit creation cancelled");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (writeFooter) {
|
||||
process.stdin.pause();
|
||||
footer = await getEditorInput(
|
||||
`e.g.
|
||||
Co-authored-by: @john
|
||||
`,
|
||||
);
|
||||
process.stdin.resume();
|
||||
}
|
||||
|
||||
const isBreaking = await confirm({
|
||||
message: "Does this commit have breaking changes?",
|
||||
initialValue: false,
|
||||
|
||||
@@ -23,7 +23,7 @@ import { join } from "path";
|
||||
import { cwd } from "process";
|
||||
import { Config } from "../types";
|
||||
import { request } from "http";
|
||||
import { tmpdir } from "os";
|
||||
import { platform, tmpdir } from "os";
|
||||
import { execSync } from "child_process";
|
||||
import { gt } from "semver";
|
||||
import { note } from "@clack/prompts";
|
||||
@@ -110,3 +110,20 @@ export const checkForUpdates = async () => {
|
||||
if (gt(cachedVersion, localVersion)) note(updateText);
|
||||
}
|
||||
};
|
||||
|
||||
export const getDefaultEditor = () => {
|
||||
if (process.env.EDITOR) {
|
||||
return process.env.EDITOR;
|
||||
}
|
||||
|
||||
if (process.env.VISUAL) {
|
||||
return process.env.VISUAL;
|
||||
}
|
||||
|
||||
// Windows as always being the special kid
|
||||
if (platform() === "win32") {
|
||||
return "notepad";
|
||||
} else {
|
||||
return "vi";
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user