feat(tui): delete working copies from move dialog (#31017)
This commit is contained in:
parent
025e1ac69f
commit
f591bf5f93
19 changed files with 337 additions and 117 deletions
|
|
@ -30,6 +30,7 @@ export class WorktreeError extends Schema.TaggedErrorClass<WorktreeError>()("Git
|
|||
operation: Schema.Literals(["create", "remove", "list"]),
|
||||
message: Schema.String,
|
||||
directory: Schema.optional(AbsolutePath),
|
||||
forceRequired: Schema.optional(Schema.Boolean),
|
||||
cause: Schema.optional(Schema.Defect),
|
||||
}) {}
|
||||
|
||||
|
|
@ -64,7 +65,11 @@ export interface Interface {
|
|||
readonly resetChanges: (directory: AbsolutePath) => Effect.Effect<void, PatchError>
|
||||
readonly softResetChanges: (directory: AbsolutePath) => Effect.Effect<void, PatchError>
|
||||
readonly worktreeCreate: (input: { repo: Repo; directory: AbsolutePath }) => Effect.Effect<void, WorktreeError>
|
||||
readonly worktreeRemove: (input: { repo: Repo; directory: AbsolutePath }) => Effect.Effect<void, WorktreeError>
|
||||
readonly worktreeRemove: (input: {
|
||||
repo: Repo
|
||||
directory: AbsolutePath
|
||||
force: boolean
|
||||
}) => Effect.Effect<void, WorktreeError>
|
||||
readonly worktreeList: (repo: Repo) => Effect.Effect<AbsolutePath[], WorktreeError>
|
||||
}
|
||||
|
||||
|
|
@ -335,10 +340,12 @@ export const layer = Layer.effect(
|
|||
),
|
||||
)
|
||||
if (result.exitCode === 0) return result.stdout.toString("utf8")
|
||||
const message = result.stderr.toString("utf8").trim() || result.stdout.toString("utf8").trim() || "Git failed"
|
||||
return yield* new WorktreeError({
|
||||
operation,
|
||||
directory: worktreeDirectory,
|
||||
message: result.stderr.toString("utf8").trim() || result.stdout.toString("utf8").trim() || "Git failed",
|
||||
message,
|
||||
forceRequired: operation === "remove" && /contains modified or untracked files|is dirty/i.test(message),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -346,11 +353,15 @@ export const layer = Layer.effect(
|
|||
yield* worktree("create", input.repo, ["worktree", "add", "--detach", input.directory, "HEAD"], input.directory)
|
||||
})
|
||||
|
||||
const worktreeRemove = Effect.fn("Git.worktreeRemove")(function* (input: { repo: Repo; directory: AbsolutePath }) {
|
||||
const worktreeRemove = Effect.fn("Git.worktreeRemove")(function* (input: {
|
||||
repo: Repo
|
||||
directory: AbsolutePath
|
||||
force: boolean
|
||||
}) {
|
||||
yield* worktree(
|
||||
"remove",
|
||||
input.repo,
|
||||
["worktree", "remove", "--force", input.directory],
|
||||
["worktree", "remove", ...(input.force ? ["--force"] : []), input.directory],
|
||||
input.directory,
|
||||
input.repo.store,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ export function makeStrategies(input: {
|
|||
yield* input.git.worktreeCreate({ repo: repo(options.sourceDirectory), directory: options.directory })
|
||||
return { directory: yield* input.canonical(options.directory) }
|
||||
}),
|
||||
remove: Effect.fn("ProjectCopy.GitWorktree.remove")(function* (directory) {
|
||||
const found = yield* input.git.find(directory)
|
||||
if (!found) return yield* new DirectoryUnavailableError({ directory })
|
||||
yield* input.git.worktreeRemove({ repo: found, directory })
|
||||
remove: Effect.fn("ProjectCopy.GitWorktree.remove")(function* (options) {
|
||||
const found = yield* input.git.find(options.directory)
|
||||
if (!found) return yield* new DirectoryUnavailableError({ directory: options.directory })
|
||||
yield* input.git.worktreeRemove({ repo: found, directory: options.directory, force: options.force })
|
||||
}),
|
||||
list: Effect.fn("ProjectCopy.GitWorktree.list")(function* (directory) {
|
||||
const found = yield* input.git.find(directory)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export type CreateInput = typeof CreateInput.Type
|
|||
export const RemoveInput = Schema.Struct({
|
||||
projectID: Project.ID,
|
||||
directory: AbsolutePath,
|
||||
force: Schema.Boolean,
|
||||
}).annotate({ identifier: "ProjectCopy.RemoveInput" })
|
||||
export type RemoveInput = typeof RemoveInput.Type
|
||||
|
||||
|
|
@ -82,7 +83,10 @@ export interface Strategy {
|
|||
sourceDirectory: AbsolutePath
|
||||
directory: AbsolutePath
|
||||
}) => Effect.Effect<Copy, Git.WorktreeError | DirectoryUnavailableError>
|
||||
readonly remove: (directory: AbsolutePath) => Effect.Effect<void, Git.WorktreeError | DirectoryUnavailableError>
|
||||
readonly remove: (input: {
|
||||
directory: AbsolutePath
|
||||
force: boolean
|
||||
}) => Effect.Effect<void, Git.WorktreeError | DirectoryUnavailableError>
|
||||
readonly list: (directory: AbsolutePath) => Effect.Effect<Copy[], Git.WorktreeError | DirectoryUnavailableError>
|
||||
readonly detect: (directory: AbsolutePath) => Effect.Effect<boolean>
|
||||
}
|
||||
|
|
@ -209,7 +213,7 @@ export const layer = Layer.effect(
|
|||
const copyDirectory = yield* canonical(input.directory)
|
||||
const id = yield* detect({ directory: copyDirectory })
|
||||
if (!id) return yield* new StrategyNotFoundError({ directory: copyDirectory })
|
||||
yield* strategy(id).remove(copyDirectory)
|
||||
yield* strategy(id).remove({ directory: copyDirectory, force: input.force })
|
||||
yield* changed(input.projectID, yield* removeStored(input.projectID, copyDirectory))
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue