Skip to content
Merged
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
60 changes: 60 additions & 0 deletions devel/0075.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# [0075] fmt 和 fix 工具支持自定义文件后缀名

## 1. 相关文档
- [dddd.md](dddd.md) - 任务文档模板

## 2. 任务相关的代码文件
- `tools/fmt/liii/goldfmt.scm` - fmt 工具主入口
- `tools/fix/liii/goldfix.scm` - fix 工具主入口
- `tools/common/liii/goldtool-changed.scm` - changed-scheme-files-since 通用函数

## 3. 如何测试

### 3.1 确定性测试(单元测试)
```bash
xmake b goldfish
bin/gf test tools/common/tests/liii/goldtool-changed/changed-files-since-test.scm
bin/gf test tools/fmt/tests/
bin/gf test tools/fix/tests/
```

### 3.2 非确定性测试(功能验证)
```bash
# 默认只处理 .scm 文件
bin/gf fmt /path/to/dir
bin/gf fix /path/to/dir

# 指定其他后缀名
bin/gf fmt -e sld /path/to/dir
bin/gf fix -e sld /path/to/dir

# 逗号分隔同时指定多个后缀名
bin/gf fmt -e scm,sld /path/to/dir
bin/gf fix -e scm,sld /path/to/dir
```

## 4. 如何提交

提交前执行以下最少步骤:

```bash
bin/gf test --changed-since=main
```

## 5. 2026-05-31 任务描述

### 5.1 What
1. `fmt` 和 `fix` 工具默认只允许文件后缀名为 `.scm`
2. 为两个工具添加 `-e, --extension EXT` 命令行选项,支持传入自定义文件后缀名
3. 扩展名参数不需要带 `.`,内部自动补全
4. `--extension` 支持逗号分隔多个后缀名,如 `scm,sld`

### 5.2 Why
项目中除了 `.scm` 文件外,还可能存在其他 Scheme 相关后缀的文件(如 `.sld`),需要格式化或修复括号时,硬编码的 `.scm` 过滤会遗漏这些文件。

### 5.3 How
1. 在 `goldfmt.scm` 和 `goldfix.scm` 的 `make-*-arg-parser` 中添加 `--extension` 选项(默认值为 `"scm"`)
2. 在 `main` 函数中通过 `parse-extensions` 将逗号分隔的原始扩展名解析为列表,并自动补全 `.`
3. 添加 `file-extension-match?` 辅助函数判断文件是否匹配任一扩展名
4. 将 `format-directory`、`fix-directory` 和 `format-changed-since` 中的硬编码 `".scm"` 替换为扩展名列表
5. 修改 `changed-scheme-files-since`,增加可选的扩展名列表参数(保持向后兼容)
30 changes: 24 additions & 6 deletions tools/common/liii/goldtool-changed.scm
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,30 @@
) ;define

(define (changed-scheme-files-since since . maybe-path)
(filter (lambda (file) (and (string-ends? file ".scm") (path-file? file)))
(if (null? maybe-path)
(changed-files-since since)
(changed-files-since since (car maybe-path))
) ;if
) ;filter
(let* ((has-extension-param? (and (not (null? maybe-path))
(not (null? (cdr maybe-path)))))
(extensions (if has-extension-param? (cadr maybe-path) '(".scm")))
(path (if has-extension-param? (car maybe-path)
(if (null? maybe-path) #f (car maybe-path)))))
(filter (lambda (file)
(and (path-file? file)
(let loop ((exts extensions))
(if (null? exts)
#f
(if (string-ends? file (car exts))
#t
(loop (cdr exts))
) ;if
) ;if
) ;let
) ;and
) ;lambda
(if path
(changed-files-since since path)
(changed-files-since since)
) ;if
) ;filter
) ;let*
) ;define

) ;begin
Expand Down
53 changes: 45 additions & 8 deletions tools/fix/liii/goldfix.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
(import (liii base)
(liii sys)
(liii path)
(liii string)
(liii argparse)
(liii hashlib)
(liii os)
Expand Down Expand Up @@ -54,6 +55,8 @@
(newline)
(display " --dry-run 预览模式(仅支持单个文件)")
(newline)
(display " -e, --extension EXT 指定文件后缀名(默认 scm,支持逗号分隔多个)")
(newline)
(newline)
(display "Arguments:")
(newline)
Expand All @@ -73,6 +76,12 @@
(display " gf fix /path/to/dir 递归修正目录下所有 .scm 文件"
) ;display
(newline)
(display " gf fix -e sld /path/to/dir 递归修正目录下所有 .sld 文件"
) ;display
(newline)
(display " gf fix -e scm,sld /path/to/dir 递归修正目录下所有 .scm 和 .sld 文件"
) ;display
(newline)
) ;define

(define (display-diagnostics diagnostics)
Expand Down Expand Up @@ -143,7 +152,19 @@
(fix-file-core path-str use-cache?)
) ;define*

(define (fix-directory dir-path)
(define (file-extension-match? filename extensions)
(let loop ((exts extensions))
(if (null? exts)
#f
(if (string-suffix? (car exts) filename)
#t
(loop (cdr exts))
) ;if
) ;if
) ;let
) ;define

(define (fix-directory dir-path extensions)
(let ((fmt-cmd (string-append (executable) " fmt " dir-path)))
(os-call fmt-cmd)
) ;let
Expand All @@ -155,7 +176,7 @@
(let ((entry (vector-ref entries i)))
(cond ((path-file? entry)
(let ((entry-str (path->string entry)))
(if (string-suffix? ".scm" entry-str)
(if (file-extension-match? entry-str extensions)
(let ((result (fix-file-core entry-str)))
(cond ((eq? result 'cached)
(loop (+ i 1) (+ total 1) updated (+ cached 1)))
Expand All @@ -172,7 +193,7 @@
) ;let
) ;
((path-dir? entry)
(call-with-values (lambda () (fix-directory (path->string entry)))
(call-with-values (lambda () (fix-directory (path->string entry) extensions))
(lambda (sub-total sub-updated sub-cached)
(loop (+ i 1) (+ total sub-total) (+ updated sub-updated) (+ cached sub-cached))
) ;lambda
Expand Down Expand Up @@ -202,6 +223,10 @@
(short . "h")
(action . store-true)))
(parser :add-argument '((name . "dry-run") (action . store-true)))
(parser :add-argument '((name . "extension")
(short . "e")
(type . string)
(default . "scm")))
parser
) ;let
) ;define
Expand All @@ -212,13 +237,25 @@
) ;let
) ;define

(define (normalize-extension ext)
(if (and (> (string-length ext) 0)
(char=? (string-ref ext 0) #\.))
ext
(string-append "." ext))
) ;define

(define (parse-extensions raw)
(map normalize-extension (string-split raw ","))
) ;define

(define (main)
(let ((parser (make-fix-arg-parser)))
(parser :parse-argv (argv))
(let ((help-flag (parser 'help))
(dry-run (parser 'dry-run))
(path-str (first-positional parser))
) ;
(let* ((help-flag (parser 'help))
(dry-run (parser 'dry-run))
(extensions (parse-extensions (parser 'extension)))
(path-str (first-positional parser))
) ;
(cond ((or help-flag (string=? path-str "")) (display-help) #t)
((path-file? (path path-str))
(if dry-run
Expand Down Expand Up @@ -246,7 +283,7 @@
(newline)
(exit 1)
) ;begin
(call-with-values (lambda () (fix-directory path-str))
(call-with-values (lambda () (fix-directory path-str extensions))
(lambda (total updated cached)
(display (string-append "Total files fixed: "
(number->string total)
Expand Down
66 changes: 51 additions & 15 deletions tools/fmt/liii/goldfmt.scm
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
(display " --dry-run 预览模式(不写回文件;目录路径不支持)"
) ;display
(newline)
(display " --changed-since REV 仅格式化自 REV 以来变更的 .scm 文件"
(display " -e, --extension EXT 指定文件后缀名(默认 scm,支持逗号分隔多个)")
(newline)
(display " --changed-since REV 仅格式化自 REV 以来变更的文件"
) ;display
(newline)
(newline)
Expand All @@ -114,7 +116,7 @@
(newline)
(display " gf fmt --dry-run file.scm 预览格式化结果")
(newline)
(display " gf fmt --changed-since=HEAD 格式化自 HEAD 以来变更的 .scm 文件"
(display " gf fmt --changed-since=HEAD 格式化自 HEAD 以来变更的文件"
) ;display
(newline)
(display " gf fmt --dry-run --changed-since=HEAD 预览变更文件的格式化结果"
Expand All @@ -123,6 +125,12 @@
(display " gf fmt /path/to/dir 递归格式化目录下所有 .scm 文件"
) ;display
(newline)
(display " gf fmt -e sld /path/to/dir 递归格式化目录下所有 .sld 文件"
) ;display
(newline)
(display " gf fmt -e scm,sld /path/to/dir 递归格式化目录下所有 .scm 和 .sld 文件"
) ;display
(newline)
) ;define

;; ; 格式化单个文件(dry-run 模式,输出到终端)
Expand Down Expand Up @@ -196,16 +204,28 @@
) ;let
) ;define

(define (format-changed-since since path-str dry-run)
(define (file-extension-match? filename extensions)
(let loop ((exts extensions))
(if (null? exts)
#f
(if (string-suffix? (car exts) filename)
#t
(loop (cdr exts))
) ;if
) ;if
) ;let
) ;define

(define (format-changed-since since path-str dry-run extensions)
(let ((scope (if (string=? path-str "") #f path-str)))
(cond ((and scope (not (or (path-file? (path scope)) (path-dir? (path scope)))))
(display (string-append "错误: 路径不存在 - " scope))
(newline)
(exit 1)
) ;
(else (let ((files (if scope
(changed-scheme-files-since since scope)
(changed-scheme-files-since since)
(changed-scheme-files-since since scope extensions)
(changed-scheme-files-since since extensions)
) ;if
) ;files
) ;
Expand Down Expand Up @@ -238,7 +258,7 @@

;; ; 递归格式化目录
;; ; 返回值: (values total updated cached) - 处理的文件总数、更新数、缓存命中数
(define (format-directory dir-path)
(define (format-directory dir-path extensions)
(let ((entries (path-list-path (path dir-path))))
(let loop
((i 0) (total 0) (updated 0) (cached 0))
Expand All @@ -247,7 +267,7 @@
(let ((entry (vector-ref entries i)))
(cond ((path-file? entry)
(let ((entry-str (path->string entry)))
(if (string-suffix? ".scm" entry-str)
(if (file-extension-match? entry-str extensions)
(let ((result (format-file entry-str)))
(cond ((eq? result 'cached)
(loop (+ i 1) (+ total 1) updated (+ cached 1))
Expand All @@ -267,7 +287,7 @@
) ;let
) ;
((path-dir? entry)
(call-with-values (lambda () (format-directory (path->string entry)))
(call-with-values (lambda () (format-directory (path->string entry) extensions))
(lambda (sub-total sub-updated sub-cached)
(loop (+ i 1) (+ total sub-total) (+ updated sub-updated) (+ cached sub-cached))
) ;lambda
Expand Down Expand Up @@ -297,6 +317,10 @@
(short . "h")
(action . store-true)))
(parser :add-argument '((name . "dry-run") (action . store-true)))
(parser :add-argument '((name . "extension")
(short . "e")
(type . string)
(default . "scm")))
(parser :add-argument '((name . "changed-since") (type . string)))
parser
) ;let
Expand All @@ -308,17 +332,29 @@
) ;let
) ;define

(define (normalize-extension ext)
(if (and (> (string-length ext) 0)
(char=? (string-ref ext 0) #\.))
ext
(string-append "." ext))
) ;define

(define (parse-extensions raw)
(map normalize-extension (string-split raw ","))
) ;define

;; ; 主入口函数
(define (main)
(let ((parser (make-fmt-arg-parser)))
(parser :parse-argv (argv))
(let ((help-flag (parser 'help))
(dry-run (parser 'dry-run))
(changed-since (parser 'changed-since))
(path-str (first-positional parser))
) ;
(let* ((help-flag (parser 'help))
(dry-run (parser 'dry-run))
(extensions (parse-extensions (parser 'extension)))
(changed-since (parser 'changed-since))
(path-str (first-positional parser))
) ;
(cond (help-flag (display-help) #t)
(changed-since (format-changed-since changed-since path-str dry-run))
(changed-since (format-changed-since changed-since path-str dry-run extensions))
((string=? path-str "") (display-help) #t)
((path-file? (path path-str))
(if dry-run
Expand Down Expand Up @@ -346,7 +382,7 @@
(newline)
(exit 1)
) ;begin
(call-with-values (lambda () (format-directory path-str))
(call-with-values (lambda () (format-directory path-str extensions))
(lambda (total updated cached)
(display (string-append "Total files formatted: "
(number->string total)
Expand Down
Loading