From 16ca6a283ec3a174aea7bb56cd0a44265b552a1f Mon Sep 17 00:00:00 2001 From: paperbox <7126454+lego37yoon@users.noreply.github.com> Date: Sun, 9 Aug 2026 21:15:59 +0900 Subject: [PATCH 1/5] Add warning at delete contents for Linux users --- packages/init/src/ask/dir.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/init/src/ask/dir.ts b/packages/init/src/ask/dir.ts index 513de170c..bb132855b 100644 --- a/packages/init/src/ask/dir.ts +++ b/packages/init/src/ask/dir.ts @@ -46,12 +46,42 @@ const moveDirToTrash = (dir: string) => pipe(dir, askMoveToTrash, when(identity, moveToTrash(dir))); const askMoveToTrash = (dir: string) => + pipe( + getOsType(), + getDeleteAction, + (fn) => fn(dir), + ); + +const getDeleteAction = (os: NodeJS.Platform) => { + if ( + trashSupported[os as keyof typeof trashSupported] ?? trashSupported.linux + ) return moveToTrashAction; + return deletePermanentlyAction; +}; + +const trashSupported: Record< + Extract, + boolean +> = { + "darwin": true, + "win32": true, + "linux": false, +}; + +const moveToTrashAction = (dir: string) => toggle.default({ message: `Do you want to move the contents of "${dir}" to the trash? If you choose "No", you should choose another directory.`, default: false, }); +const deletePermanentlyAction = (dir: string) => + toggle.default({ + message: `Do you really want to delete all contents of "${dir}" PERMANENTLY? +If you choose "No", you should choose another directory.`, + default: false, + }); + const moveToTrash = (dir: string) => () => pipe( getOsType(), From e50f6ab3dec6c0bbc761ea503749d5a145d23191 Mon Sep 17 00:00:00 2001 From: paperbox <7126454+lego37yoon@users.noreply.github.com> Date: Sun, 9 Aug 2026 23:33:07 +0900 Subject: [PATCH 2/5] Refactor the meaning of each functions --- packages/init/src/ask/dir.ts | 107 +++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/packages/init/src/ask/dir.ts b/packages/init/src/ask/dir.ts index bb132855b..0ed270c30 100644 --- a/packages/init/src/ask/dir.ts +++ b/packages/init/src/ask/dir.ts @@ -1,10 +1,10 @@ import { identity, pipe, when } from "@fxts/core"; import { input } from "@inquirer/prompts"; -import { message } from "@optique/core/message"; +import { type Message, message } from "@optique/core/message"; import { printError } from "@optique/run"; import toggle from "inquirer-toggle"; -import { getCwd, getOsType, runSubCommand } from "../utils.ts"; import { isDirectoryEmpty, logger } from "../lib.ts"; +import { getCwd, getOsType, runSubCommand } from "../utils.ts"; /** * Fills in the project directory by prompting the user if not provided. @@ -26,12 +26,14 @@ const fillDir: ( export default fillDir; +type DirActionMode = "trash" | "permanent"; + const askDir = (cwd: string) => input({ message: "Project directory:", default: cwd }); const askIfNonEmpty = async (dir: string) => { if (await isDirectoryEmpty(dir)) return true; - if (await askNonEmpty(dir)) return await moveDirToTrash(dir); + if (await askNonEmpty(dir)) return await moveOrDeleteDir(dir); return false; }; @@ -42,77 +44,91 @@ Do you want to use it anyway?`, default: false, }); -const moveDirToTrash = (dir: string) => - pipe(dir, askMoveToTrash, when(identity, moveToTrash(dir))); +const moveOrDeleteDir = (dir: string) => + pipe( + dir, + buildMoveOrDelete, + (action) => + pipe( + action.confirm, + when(identity, runAction(action.command, action.error)), + ), + ); -const askMoveToTrash = (dir: string) => +const buildMoveOrDelete = (dir: string) => pipe( getOsType(), - getDeleteAction, - (fn) => fn(dir), + detectSupportedAction, + (fn) => { + return { + confirm: fn.confirmAction(dir), + command: fn.actionPlan.command(dir), + error: errorMessages[fn.actionPlan.mode](dir), + }; + }, ); -const getDeleteAction = (os: NodeJS.Platform) => { - if ( - trashSupported[os as keyof typeof trashSupported] ?? trashSupported.linux - ) return moveToTrashAction; - return deletePermanentlyAction; -}; +const detectSupportedAction = (os: NodeJS.Platform) => { + const actionPlan = + trashOrDeleteCommands[os as keyof typeof trashOrDeleteCommands] ?? + trashOrDeleteCommands.linux; -const trashSupported: Record< - Extract, - boolean -> = { - "darwin": true, - "win32": true, - "linux": false, + return { + confirmAction: (actionPlan.mode === "trash") + ? moveToTrashConfirm + : deletePermanentlyConfirm, + actionPlan, + }; }; -const moveToTrashAction = (dir: string) => +const moveToTrashConfirm = (dir: string) => toggle.default({ message: `Do you want to move the contents of "${dir}" to the trash? If you choose "No", you should choose another directory.`, default: false, }); -const deletePermanentlyAction = (dir: string) => +const deletePermanentlyConfirm = (dir: string) => toggle.default({ message: `Do you really want to delete all contents of "${dir}" PERMANENTLY? If you choose "No", you should choose another directory.`, default: false, }); -const moveToTrash = (dir: string) => () => +const runAction = (command: string[], error: Message) => () => pipe( - getOsType(), - getTrashCommand, - (fn) => fn(dir), + command, (cmd) => runSubCommand(cmd, { stdio: "ignore" }), () => true, ).catch((e) => { logger.error(e); - printError(message`Failed to move ${dir} to trash. -Please move it manually.`); + printError(error); return false; }); -const getTrashCommand = (os: NodeJS.Platform) => - trashCommands[os as keyof typeof trashCommands] ?? trashCommands.linux; - -const trashCommands: Record< +const trashOrDeleteCommands: Record< Extract, - (dir: string) => string[] + { mode: DirActionMode; command: (dir: string) => string[] } > = { // mac - darwin: (dir: string) => ["trash", dir], + darwin: { + mode: "trash", + command: (dir: string) => ["trash", dir], + }, // windows - win32: (dir: string) => [ - "powershell", - "-Command", - getPowershellTrashCommand(dir), - ], + win32: { + mode: "trash", + command: (dir: string) => [ + "powershell", + "-Command", + getPowershellTrashCommand(dir), + ], + }, // other unix - linux: (dir: string) => ["rm", "-rf", dir], + linux: { + mode: "permanent", + command: (dir: string) => ["rm", "-rf", dir], + }, }; const getPowershellTrashCommand = (dir: string) => @@ -126,3 +142,12 @@ const getPowershellTrashCommand = (dir: string) => "'OnlyErrorDialogs',", "'SendToRecycleBin')", ].join(" "); + +const errorMessages: Record Message> = { + "trash": (dir: string) => + message`Failed to move ${dir} to trash. +Please move it manually.`, + "permanent": (dir: string) => + message`Failed to delete ${dir} permanently. +Please remove it manually.`, +}; From 99212fe9c4f5684a9309e8e718a73d8d674df9e1 Mon Sep 17 00:00:00 2001 From: paperbox <7126454+lego37yoon@users.noreply.github.com> Date: Sun, 9 Aug 2026 23:47:57 +0900 Subject: [PATCH 3/5] Edited changelog with Sacho --- changes.d/init/permanent-delete.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changes.d/init/permanent-delete.md diff --git a/changes.d/init/permanent-delete.md b/changes.d/init/permanent-delete.md new file mode 100644 index 000000000..84c2e1b9a --- /dev/null +++ b/changes.d/init/permanent-delete.md @@ -0,0 +1,3 @@ + - Added permanent delete warning for Linux or other UNIX-like system users + before delete the existing content in the project directory. + [[#989] by Jungmin Yoon\] From 7f7a6c4add6c76979bc149482f950da68082683a Mon Sep 17 00:00:00 2001 From: paperbox <7126454+lego37yoon@users.noreply.github.com> Date: Mon, 10 Aug 2026 00:06:41 +0900 Subject: [PATCH 4/5] Edit word of changelog to improve grammar --- changes.d/init/permanent-delete.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes.d/init/permanent-delete.md b/changes.d/init/permanent-delete.md index 84c2e1b9a..16b6fd4a1 100644 --- a/changes.d/init/permanent-delete.md +++ b/changes.d/init/permanent-delete.md @@ -1,3 +1,3 @@ - - Added permanent delete warning for Linux or other UNIX-like system users + - Added permanent removal warning for Linux or other UNIX-like system users before delete the existing content in the project directory. [[#989] by Jungmin Yoon\] From 690fe345257d77320148f8c1e03481dc58ba9b35 Mon Sep 17 00:00:00 2001 From: paperbox <7126454+lego37yoon@users.noreply.github.com> Date: Sat, 15 Aug 2026 00:36:18 +0900 Subject: [PATCH 5/5] Add changes about recheck file delete --- CHANGES.md | 8 ++++++++ changes.d/init/permanent-delete.md | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 8964d5f04..f867258b2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,14 @@ Version 2.0.25 To be released. +### @fedify/init + + - Added permanent removal warning for Linux or other UNIX-like system users + before delete the existing content in the project directory. + [[#989] by Jungmin Yoon\] + +[#989]: https://github.com/fedify-dev/fedify/issues/989 + Version 2.0.24 -------------- diff --git a/changes.d/init/permanent-delete.md b/changes.d/init/permanent-delete.md index 16b6fd4a1..93c66b6d0 100644 --- a/changes.d/init/permanent-delete.md +++ b/changes.d/init/permanent-delete.md @@ -1,3 +1,5 @@ - Added permanent removal warning for Linux or other UNIX-like system users before delete the existing content in the project directory. - [[#989] by Jungmin Yoon\] + [[#989] by Jungmin Yoon] + +[#989]: https://github.com/fedify-dev/fedify/issues/989