japanese/docs/history/CONFIG_SIMPLIFICATION.md
panli ef3df73166 refactor: 三层架构重构 + 配置文件 + 项目目录整理
清洗管线重构为严格三层架构:
- tango_analyser.py(底层:单词分析)
- task_processor.py(中层:文件 I/O、桶管理)
- workflow.py(顶层:状态机、任务推进)
- 移除旧的 batch_processor.py

新增配置文件系统:
- config.py:TOML 配置,相对路径相对配置文件目录解析
- 查找优先级 --config > cwd > 项目根 > ~ > 默认值
- count=None 语义为处理到文件末尾

项目目录整理:
- 根脚本归档到 scripts/analysis 与 scripts/legacy
- 文档归档到 docs/{design,history,analysis}
- 临时报告移到 reports/(已 gitignore)

文档质量:
- 新增 .markdownlint.json 与 scripts/mdlint.cmd
- 修复全部 14 个 md 文件的 markdownlint 警告

测试:74 passed(8 cleaner + 31 workflow + 6 tango + 15 validator + 14 config)
2026-08-19 19:40:02 +08:00

7.3 KiB
Raw Permalink Blame History

配置文件简化总结

按用户要求移除不必要的配置项,简化配置文件和任务创建逻辑。

变更内容

1. 移除的配置项

JCleanConfig 和配置文件移除

  • sources_dir — 数据源路径应在创建任务时显式指定(--source 必需参数)
  • default_start_line — 不指定时默认 1硬编码
  • default_count — 不指定时默认 None(处理整个文件)

理由

  • 数据源必须每次任务显式指定,不应有全局默认路径
  • 起始行 99% 的情况是 1不需要配置
  • count 默认"全部处理"比硬编码 300 更合理

2. 核心逻辑变更

count 的语义

  • 之前count: int = 300(必须指定条数)
  • 现在count: Optional[int] = NoneNone = 处理到文件末尾)

处理范围解析

# TaskConfig
count: Optional[int] = None  # None 表示从 start_line 处理到文件末尾

# _read_source_lines
if count is not None and len(lines) >= count:
    break  # count=None 时不限行数,读到文件末尾
```text

#### **CLI create 命令**

```bash
# 不指定 --count处理整个文件
jclean create task1 --source data.txt

# 指定 --count处理指定条数
jclean create task2 --source data.txt --count 100

# 指定 --start从指定行开始
jclean create task3 --source data.txt --start 500
```text

#### **输出信息**

```text
范围: L1 起到文件末尾全部        # count=None
范围: L1  300                     # count=300
范围: L500 起到文件末尾全部      # start=500, count=None
```text

---

### 3. 配置文件对比

#### **之前(冗余)**

```toml
[paths]
tasks_root = "tasks"
vocabulary = "data/db/vocabulary.txt"
skipped = "data/db/skipped.txt"
sources_dir = "data/sources"  # 不必要

[defaults]
start_line = 1    # 不必要
count = 300       # 不必要
backup_before_merge = true
backup_dir = "data/backup"

[logging]
level = "INFO"
```text

#### **现在(精简)**

```toml
[paths]
tasks_root = "tasks"
vocabulary = "data/db/vocabulary.txt"
skipped = "data/db/skipped.txt"

[defaults]
backup_before_merge = true
backup_dir = "data/backup"

[logging]
level = "INFO"
```text

---

### 4. 文件变更清单

#### **核心代码**

- `src/pl_japanese/cleaner/config.py`
  - 移除 `sources_dir`、`default_start_line`、`default_count`
  - `load_config` 不再解析这些字段
  - `generate_sample_config` 模板已精简
- `src/pl_japanese/cleaner/task.py`
  - `TaskConfig.count: Optional[int] = None`
  - `Task.create()` 参数 `count: Optional[int] = None`
  - 文档更新`count=None` 表示处理到文件末尾
- `src/pl_japanese/cleaner/task_processor.py`
  - `_read_source_lines(count: Optional[int])`  支持 `count=None`
  - 循环逻辑`if count is not None and len(lines) >= count: break`
- `src/pl_japanese/cleaner/task_manager.py`
  - `create_task()` 参数 `count: Optional[int] = None`
- `src/pl_japanese/cleaner/cli.py`
  - `--start` help: "起始行号(默认 1"
  - `--count` help: "处理条数(默认处理到文件末尾)"
  - `_cmd_create`: `start_line = args.start if args.start else 1`
  - `_cmd_create`: `count = args.count` (None = 全部)
  - `_cmd_show_config`: 移除 `sources_dir`、`start_line`、`count` 显示

#### **配置文件**

- `jclean.toml`  已更新为精简版本

#### **测试**

- `tests/test_config.py`  移除 `default_start_line`、`default_count` 断言
- 所有测试通过74 

---

### 5. 端到端验证

#### **测试用例**

```bash
# 创建 5 行测试文件
日本:にほん:
中国:ちゅうごく:
美国:べいこく:
英国:えいこく:
法国:ふらんす:

# 测试 1不指定 count应处理全部 5 行)
jclean create test1 --source source.txt
jclean run test1
# 结果3 行 auto_done + 2 行 review_split = 5 行全部处理 ✅

# 测试 2指定 count=3应处理前 3 行)
jclean create test2 --source source.txt --count 3
jclean run test2
# 结果2 行 auto_done + 1 行 review_split = 3 行 ✅

# 测试 3创建时的输出信息
jclean create test3 --source source.txt
# 输出:"范围: L1 起到文件末尾(全部)" ✅
```text

#### **JSON 序列化**

```json
// count=None 时的 task.json
{
  "config": {
    "source": "source.txt",
    "start_line": 1,
    "count": null   // null  None 往返正确 
  }
}

// count=3 时的 task.json
{
  "config": {
    "count": 3
  }
}
```text

---

### 6. 兼容性

#### **旧任务**

-  `task.json`  `count: 300`  加载后仍为 300行为不变 
- 旧任务可正常运行无需迁移

#### **旧配置文件**

- 如果旧 `jclean.toml` 包含 `sources_dir`/`start_line`/`count`
  - 加载时**静默忽略**不报错
  - 但不再使用这些值
- 建议用户重新生成`jclean init-config`

---

### 7. 设计原则确认

用户原话
> "数据源目录是不必要的,我认为创建任务时必须提供数据源"
> "起始行和count也是没必要的如果创建任务时没指定起始行就是1如果没有指定count就是整个文件所有行都处理"

 **完全符合要求**

- `--source` 必需参数无全局默认
- `--start` 默认 1硬编码不可配置
- `--count` 默认 None全部处理不限行数

---

### 8. 测试结果

```text
============================= 74 passed in 12.23s ==============================

tests/test_config.py           14 passed  (配置管理已移除 count/start_line 相关)
tests/test_cleaner.py           8 passed  (底层单元)
tests/test_cleaner_workflow.py 31 passed  (三层集成)
tests/test_tango.py             6 passed  (下游模型)
tests/test_validator.py        15 passed  (格式校验)
```text

---

## 影响总结

### **用户体验改进**

1. **配置文件更简洁**  只保留真正需要配置的路径和备份选项
2. **默认行为更合理**  `count=None` 处理全部比硬编码 300 更直观
3. **必需参数更明确**  `--source` 必需避免路径混乱

### **代码质量改进**

1. **职责更清晰**  配置文件不管任务级别的参数start/count
2. **类型更准确**  `count: Optional[int]` 明确表达"可以不限"
3. **文档更简单**  减少需要解释的配置项

### **兼容性保证**

1. **旧任务正常运行**  `count=300` 的旧任务行为不变
2. **旧配置不报错**  多余字段静默忽略
3. **迁移成本低**  建议重新生成配置但不强制

---

## 完成文件

- `config.py` 
- `task.py` 
- `task_processor.py` 
- `task_manager.py` 
- `cli.py` 
- `jclean.toml` 
- `tests/test_config.py` 
- 74 个测试全部通过 

---

## 后续建议

用户可以考虑进一步简化

- `backup_before_merge` 是否默认 `true` 就够了不需要配置
- `backup_dir` 是否默认 `data/backup` 就够了

如果这两个也不需要配置`[defaults]` 整个段都可以删掉配置文件只剩

```toml
[paths]
tasks_root = "tasks"
vocabulary = "data/db/vocabulary.txt"
skipped = "data/db/skipped.txt"

[logging]
level = "INFO"
```text

甚至 `[logging]` 也可以考虑移除命令行 `--verbose`/`--quiet` 覆盖)。

最终极简版配置文件

```toml
[paths]
tasks_root = "tasks"
vocabulary = "data/db/vocabulary.txt"
skipped = "data/db/skipped.txt"
```text

**是否需要进一步简化由用户决定**