feat: 新增 git.clean 清理工作区命令
This commit is contained in:
@@ -0,0 +1,92 @@
|
|||||||
|
package executor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// gitCleanOptions are the parsed arguments of `kopsc git clean`.
|
||||||
|
type gitCleanOptions struct {
|
||||||
|
DryRun bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// runGitClean removes untracked files and directories.
|
||||||
|
func runGitClean(ctx context.Context, req BuiltinRequest) error {
|
||||||
|
return runGitCleanWith(ctx, req, execGitRunner{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runGitCleanWith(ctx context.Context, req BuiltinRequest, runner gitRunner) error {
|
||||||
|
opts, confirmed, err := parseGitCleanArgs(req.Args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
confirmed = confirmed || req.Confirmed
|
||||||
|
|
||||||
|
// First, show what will be cleaned (dry-run)
|
||||||
|
dryOut, _, err := runner.Run(ctx, "clean", "-fd", "--dry-run")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("检查未跟踪文件失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
files := strings.TrimSpace(dryOut)
|
||||||
|
if files == "" {
|
||||||
|
fmt.Fprintf(req.Stdout, "没有未跟踪的文件或目录需要清理\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count files
|
||||||
|
lines := strings.Split(files, "\n")
|
||||||
|
count := 0
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "Would remove ") {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(req.Stdout, "将清理 %d 个未跟踪的文件/目录:\n\n", count)
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "Would remove ") {
|
||||||
|
fmt.Fprintf(req.Stdout, " %s\n", strings.TrimPrefix(line, "Would remove "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.DryRun {
|
||||||
|
fmt.Fprintf(req.Stdout, "\n(仅预览,未执行任何操作)\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !confirmed {
|
||||||
|
fmt.Fprintf(req.Stdout, "\n加 --yes 确认删除这些文件。\n")
|
||||||
|
return &ExitError{Code: 2, Err: errors.New("需要确认")}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute clean
|
||||||
|
if _, stderr, err := runner.Run(ctx, "clean", "-fd"); err != nil {
|
||||||
|
return fmt.Errorf("清理失败: %w\n%s", err, stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(req.Stdout, "\n✓ 已清理 %d 个未跟踪的文件/目录\n", count)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseGitCleanArgs(args []string) (gitCleanOptions, bool, error) {
|
||||||
|
var opts gitCleanOptions
|
||||||
|
var confirmed bool
|
||||||
|
|
||||||
|
for _, arg := range args {
|
||||||
|
switch arg {
|
||||||
|
case "--yes", "-y":
|
||||||
|
confirmed = true
|
||||||
|
case "--dry-run", "-n":
|
||||||
|
opts.DryRun = true
|
||||||
|
default:
|
||||||
|
if strings.HasPrefix(arg, "-") {
|
||||||
|
return opts, false, fmt.Errorf("未知选项 %q", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts, confirmed, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user