Help us shape the future of Go! Take the 2026 Go Developer Survey

codei18n

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: GPL-3.0 Imports: 20 Imported by: 0

README

CodeI18n 技术文档

Code Comment Internationalization Infrastructure

CI Go Report Card License Release Go Version


1. 项目定位与问题定义

1.1 项目定位

CodeI18n 是一个面向工程团队的 代码注释国际化基础设施,目标是在不破坏 Git 语义、不污染源码、不影响编译与调试的前提下,实现:

  • 源码仓库统一语言(推荐英文)
  • 本地开发环境以母语阅读和编写注释
  • 注释语言在 Git 提交与 IDE 展示之间自动、可逆转换

CodeI18n 不是简单的“翻译插件”,而是一个 围绕 AST、Git、IDE 的完整工具链。


1.2 要解决的核心问题
问题 传统方案 CodeI18n
注释语言冲突 强制英文 / 中文 英文入库,本地多语言
diff / blame 污染 严重 不污染
多语言协作 成本高 零成本
IDE 体验 无 原生集成
可扩展性 无 AST + Adapter

2. 总体设计目标

2.1 功能目标
  • 支持 多自然语言

    • 默认:英文(en)、中文(zh-CN)
    • 识别候选:en、zh-Hans、zh-Hant、ja、ko、de、fr、es、ru(可通过 detectLanguages 配置),可翻译到任意语言
  • 支持 多编程语言

    • Go、Rust、Java、Kotlin、TypeScript、JavaScript、C#、Dart(扩展名见 §8.2;groovy / scala 按 Java 语法解析)
  • 支持 多 IDE

    • VS Code
    • JetBrains 家族(IntelliJ / GoLand / RustRover 等)

2.2 非功能目标(硬约束)
  1. Git 仓库中只存在一种注释语言
  2. IDE 展示不修改源码
  3. 所有注释解析必须基于 AST / PSI
  4. 注释翻译必须可逆、可定位
  5. Core 与 IDE 插件解耦

3. 核心设计原则

3.1 单一事实源(Single Source of Truth)
  • 英文注释源码 = 唯一事实源
  • 本地语言注释 = 派生视图

3.2 语义优先,而非文本优先
  • 注释必须绑定到:

    • 文件
    • 语义符号(函数 / 结构体 / 模块)
  • 禁止基于行号、正则处理注释


3.3 Core 与 IDE 解耦
  • Core(Go 实现)

    • 注释解析
    • ID 生成
    • 翻译与映射
  • IDE 插件

    • 只负责渲染
    • 不包含翻译、AST 逻辑

4. 整体系统架构

4.1 架构总览
┌────────────────────────────────────────────┐
│                   IDE Layer                │
│                                            │
│  ┌───────────────┐   ┌──────────────────┐ │
│  │ VS Code       │   │ JetBrains IDEs   │ │
│  │ Extension     │   │ Plugin           │ │
│  └──────▲────────┘   └────────▲─────────┘ │
│         │ Decorations / Inlay           │   │
└─────────┼────────────────────────────────┘
          │ JSON / CLI
┌─────────┴────────────────────────────────┐
│          CodeI18n Core (Go)               │
│  - AST Parsers                            │
│  - Comment Model                          │
│  - Comment ID Generator                   │
│  - Mapping Store                          │
│  - Translation Engine                     │
└─────────▲────────────────────────────────┘
          │ pre-commit
┌─────────┴────────────────────────────────┐
│          Git Hooks / CLI                  │
└─────────▲────────────────────────────────┘
          │
┌─────────┴────────────────────────────────┐
│          Git Remote Repository            │
│        (English-only Source Code)         │
└───────────────────────────────────────────┘

5. CodeI18n Core 设计

5.1 Core 职责
  • 扫描源码并提取注释
  • 为注释生成稳定 ID
  • 管理多语言注释映射
  • 执行注释语言转换(提交前)
  • 为 IDE 提供结构化注释数据

5.2 注释统一抽象模型
type Comment struct {
    ID         string      // 稳定 ID
    File       string      // 相对项目根的路径
    Language   string      // 编程语言标识:go / rust / ...
    Symbol     string      // 语义符号路径
    Range      TextRange
    SourceText string      // 原文
    Type       CommentType // line / block / doc
}

mappings.json 中以 comments[ID][语言码] = 文本 保存各语言文本,位置信息见 index.json。

5.3 作为库嵌入

模块路径为 github.com/CairnPack/codei18n,根包提供 codei18n.Open(root, opts...),同一进程可同时打开多个项目。详见 docs/library-api.md。

5.4 构建要求
  • Go 1.27.1
  • CGO_ENABLED=1:tree-sitter 通过 cgo 编译 C 源码;Windows 上需要 MinGW gcc(并保证在 PATH 中)。
CGO_ENABLED=1 go build ./cmd/codei18n

6. 注释 ID 设计(关键)

6.1 ID 生成原则

注释 ID 必须满足:

  • 稳定
  • 与代码语义绑定
  • 不依赖行号
6.2 ID 计算方式
ID = SHA1(
    file_path + "|" +
    language + "|" +
    parent_symbol + "|" +
    normalized_comment_text
)

📌 parent_symbol 示例:

  • Go:package.func
  • Rust:impl::fn
  • Java:Class#method

连续行注释合并后按一条注释计算 ID。消费方应把 ID 视为不透明字符串。



7. 多自然语言支持设计

7.1 映射文件结构
{
  "version": "1.0",
  "sourceLanguage": "en",
  "targetLanguage": "zh-CN",
  "comments": {
    "a8f9c3e2": {
      "en": "Calculate account balance",
      "zh-CN": "计算账户余额"
    }
  }
}
7.2 存储策略
  • 默认路径:.codei18n/(完整布局见 §14.3)
  • 映射文件 mappings.json 为本地使用,默认不提交 Git(.codei18n/ 会被加入 .gitignore)
  • 位置索引 index.json 记录每条注释的位置、类型与识别出的原语言,格式见 docs/index-format.md
  • 注释按识别出的原语言存放,规则见 §14.7

8. 多编程语言支持策略

8.1 编程语言适配器接口
type LanguageAdapter interface {
    Language() string
    Parse(file string, src []byte) ([]*domain.Comment, error)
}
8.2 已支持的编程语言

Go 使用 go/parser / go/ast;其余语言统一走 Tree-sitter 适配器。

语言 扩展名 说明
Go .go go/ast,支持 //、/* */、Doc comment
Rust .rs //、///、//!、/** */
Java .java groovy、scala 没有独立适配器,借用 Java 语法解析(符号可能不准)
Kotlin .kt .kts 独立 Kotlin 语法
TypeScript .ts .tsx .mts .cts .tsx 使用 tsx 语法
JavaScript .js .jsx .mjs .cjs 使用 javascript 语法
C# .cs /// 为文档注释
Dart .dart 内置 tree-sitter-dart(ABI 14),语法版本早于 Dart 3.10,新语法下注释仍可提取但符号可能不准
8.3 连续行注释的统一合并规则

所有语言统一:标记相同、相邻行、同列、独占一行的连续行注释合并为一条记录(记录 parts),整组为空时丢弃;行尾注释始终单独成条。完整规则见 docs/index-format.md §6.1。


9. IDE 支持设计

9.1 IDE 统一交互模式

IDE 插件通过调用 CLI 获取结构化数据:

codei18n scan --file xxx.go --lang zh-CN --format json

10. VS Code 插件设计

10.1 渲染方式
  • TextEditorDecorationType
  • 覆盖 / 附加显示中文注释
  • 不修改文档内容
after: {
  contentText: "计算账户余额"
}

11. JetBrains IDE 插件设计

11.1 插件类型
  • IntelliJ Platform Plugin
  • Kotlin 实现
  • 多 IDE 共用

11.2 渲染方案(推荐)
Inlay Hint
// Calculate account balance
// ↓ 计算账户余额
  • 使用 InlayModel
  • 官方推荐方式
  • 不影响 PSI / LSP

11.3 备选方案
  • Gutter icon + hover tooltip

12. Git 提交流程设计

12.1 pre-commit Hook

codei18n hook install 安装 pre-commit 与 commit-msg hook(hook uninstall 卸载)。pre-commit 的流程为:

git commit
 └─ pre-commit
    ├─ codei18n map update   更新映射与索引
    ├─ codei18n translate    翻译缺失条目(失败时跳过并提示检查 codei18n auth status)
    └─ codei18n convert --to en --file <暂存文件>   把暂存文件的注释改写为英文

hook 使用项目配置选用的 provider 和令牌(环境变量或凭据库),不再强制 --provider openai。升级后已安装的旧 hook 需重新执行 codei18n hook install 才会更新。

12.2 行为原则
  • 只处理 staged 文件(当前 hook 脚本只匹配暂存的 .go 文件)
  • 翻译失败不阻断提交(hook 中跳过并提示)

13. 翻译引擎设计

13.1 抽象接口
type Translator interface {
    Translate(ctx context.Context, text, from, to string) (string, error)
    TranslateBatch(ctx context.Context, texts []string, from, to string) ([]string, error)
}
13.2 实现策略
  • 本地缓存优先,优先复用已有翻译结果,减少对外部服务的调用频率。

  • 支持的翻译后端(通过 translationProvider 或配置档的 provider 选择):

    • openai / llm:基于 OpenAI 兼容协议的远程 LLM(如官方 OpenAI、DeepSeek 或自建代理),令牌见 §14.4,可选 OPENAI_BASE_URL。
    • ollama:本地 Ollama 服务,通过 REST API 调用本地模型(如 llama3、qwen3 等)。
    • mock:仅用于测试和集成测试场景,不用于生产环境。
  • 避免在 Git 提交路径上频繁同步调用大模型,可通过预翻译批量填充映射文件。

  • 所有长任务支持 context 取消(CLI 中 Ctrl+C 可取消),取消后已完成的结果已落盘。

13.3 翻译服务配置示例

CodeI18n 的翻译服务配置由两部分组成:

  1. 顶层字段:translationProvider(选择后端)
  2. 细节字段:translationConfig(不同后端的参数)
13.3.1 使用 OpenAI / DeepSeek / 兼容 LLM
{
  "sourceLanguage": "en",
  "localLanguage": "zh-CN",
  "translationProvider": "openai",
  "translationConfig": {
    "baseUrl": "https://api.openai.com/v1",
    "model": "gpt-4.1-mini"
  },
  "batchSize": 10
}

运行前需要提供 API 令牌,推荐保存到系统凭据库(见 §14.4):

codei18n auth set --profile default

也可以使用环境变量(优先级高于凭据库):

export CODEI18N_API_KEY="your-api-key"   # 或沿用 OPENAI_API_KEY
# 可选:自建代理或第三方 OpenAI 兼容服务
export OPENAI_BASE_URL="https://api.openai.com/v1"

如果 model 设置为 deepseek-chat 或 deepseek-coder,系统会自动将 baseUrl 设为 https://api.deepseek.com,也可以手动通过 baseUrl 显式指定其他兼容服务。

13.3.2 使用本地 Ollama
{
  "sourceLanguage": "en",
  "localLanguage": "zh-CN",
  "translationProvider": "ollama",
  "translationConfig": {
    "endpoint": "http://localhost:11434",
    "model": "qwen3:4b"
  },
  "batchSize": 5
}

说明:

  • endpoint:Ollama HTTP 服务地址,默认 http://localhost:11434。
  • model:本地已拉取的模型名称,例如 qwen3:4b、llama3 等。
  • CodeI18n 在调用 Ollama 时会显式设置 "think": false,关闭思维链模式,避免额外的延迟和算力消耗。

启用本地 Ollama 集成测试示例(非必须):

CODEI18N_OLLAMA_TEST=1 \
CODEI18N_OLLAMA_MODEL=qwen3:4b \
go test ./adapters/translator -run TestOllamaTranslator_Translate_Integration -v
13.3.3 通过 CLI 覆盖配置

在 .codei18n/config.json 配置好默认翻译服务后,也可以在命令行临时覆盖:

# 覆盖 provider 为 openai
codei18n translate --provider openai

# 覆盖 provider 为本地 ollama
codei18n translate --provider ollama

# 临时指定模型(会覆盖 translationConfig.model)
codei18n translate --model gpt-4.1-mini
13.3.4 从 Google / DeepL 迁移

历史版本中可能使用过 translationProvider: "google" 或 "deepl"。迁移建议:

  1. 打开 .codei18n/config.json,删除或重命名以下配置:
    • 将 "translationProvider": "google" 或 "deepl" 改为 "openai" 或 "ollama";
    • 如有旧的 google/deepl 相关字段,可以移除,仅保留 baseUrl/model 等通用字段。
  2. 为 openai 模式配置:
    • 设置 translationProvider: "openai";
    • 在 translationConfig 中指定 model,必要时指定 baseUrl;
    • 在环境中配置 OPENAI_API_KEY(以及可选的 OPENAI_BASE_URL)。
  3. 或者切换到本地 ollama 模式:
    • 设置 translationProvider: "ollama";
    • 在 translationConfig 中设置 endpoint 和本地模型名称;
  4. 运行:
codei18n translate

确认命令可以正常执行且不会再出现“翻译提供商 google/deepl 已不再支持”的错误提示。


14. 配置文件设计

14.1 分层规则

配置按以下优先级合并,后者覆盖前者:

内置默认  <  ~/.codei18n/config.json(全局)  <  <项目>/.codei18n/config.json(项目)  <  CLI 参数

库 API 的 Project.Config() 返回合并后的值,并标明每个字段来自哪一层(default / global / project / override)。项目显式选用了 profile 时,项目配置里旧版的 provider 字段(旧版 init 生成的快照)会被忽略,以免遮住所选配置档。

CLI 全局参数:--config <path> 指定配置文件,--verbose 显示详细日志。

14.2 全局配置档(profiles)与项目覆盖

全局配置 ~/.codei18n/config.json 中用 profiles 定义多个命名配置档,项目用 profile 选用其中一个,并可用 profileOverrides 覆盖单个字段。配置档支持的字段:provider、baseUrl、model、endpoint、batchSize、concurrency、apiKeyRef。

全局 ~/.codei18n/config.json:

{
  "sourceLanguage": "en",
  "localLanguage": "zh-CN",
  "detectLanguages": ["en", "zh-Hans", "zh-Hant", "ja", "ko", "de", "fr", "es", "ru"],
  "profiles": {
    "openai-mini": {
      "provider": "openai",
      "baseUrl": "https://api.openai.com/v1",
      "model": "gpt-4.1-mini",
      "batchSize": 10,
      "concurrency": 5
    },
    "local": {
      "provider": "ollama",
      "endpoint": "http://localhost:11434",
      "model": "qwen3:4b",
      "batchSize": 5
    }
  }
}

项目 <项目>/.codei18n/config.json:

{
  "projectId": "3f2b8c1e-0000-0000-0000-000000000000",
  "sourceLanguage": "en",
  "localLanguage": "zh-CN",
  "excludePatterns": [".git/**", "vendor/**", ".codei18n/**"],
  "detectLanguages": ["en", "zh-Hans", "ja"],
  "profile": "openai-mini",
  "profileOverrides": {
    "model": "gpt-4.1",
    "batchSize": 20
  }
}

说明:

  • projectId 由 codei18n init 生成,用于项目级令牌的凭据库账户名(见 §14.4)。
  • detectLanguages 是语种识别的候选集合,默认 en, zh-Hans, zh-Hant, ja, ko, de, fr, es, ru;识别结果不在候选集内时标为 unknown。
  • §13.3 中的 translationProvider / translationConfig 是旧版平铺字段,仍然可用。
14.3 .codei18n/ 目录布局
<项目根>/.codei18n/
├─ config.json      # 项目配置
├─ mappings.json    # 注释 ID → 语言 → 文本
├─ index.json       # 位置索引(格式见 docs/index-format.md)
├─ overrides.json   # 用户手动纠正的注释原语言,扫描不会覆盖
└─ cache/           # 增量扫描与语种识别缓存,可随时删除

所有 JSON 文件都以“写临时文件 + rename”的方式原子写入。库 API 的 EnsureGitignore 与 CLI 初始化流程会把 .codei18n/ 加入 .gitignore(如尚未包含)。

14.4 令牌存储

翻译 API 令牌不写入配置文件、日志、错误信息或进度事件,而是保存在系统凭据库中。

  • 存储后端:目前仅实现 Windows 凭据管理器(generic credential,TargetName 为 codei18n/<account>)。其它平台请使用环境变量。

  • account 命名:

    • 全局配置档令牌:profile/<name>
    • 项目级覆盖令牌:project/<projectId>/<name>
  • 单个令牌上限 2560 字节。

  • 读取优先级(先命中者生效):

    1. 环境变量 CODEI18N_API_KEY
    2. 环境变量 OPENAI_API_KEY
    3. 项目级覆盖令牌(project/<projectId>/<name>)
    4. 所选配置档的全局令牌(profile/<name>,全局配置中配置档的 apiKeyRef 可指向其它 account)
    5. 配置文件中的旧版明文字段(仍可使用,但会给出警告,应迁移)

    以上均未命中时报错,并提示设置方式。

  • 安全限制:项目配置会随仓库分发,因此不可信。

    • 项目文件中的 apiKeyRef 会被忽略。
    • 项目文件把 baseUrl / endpoint 改成与全局配置不同的地址时,不会使用全局令牌(auth status 中显示为已阻止)。这种情况下请用 codei18n auth set --project 为该项目保存专用令牌,或把地址写进全局配置的 profile。

命令:

# 保存全局令牌(只从标准输入或隐藏输入读取,不接受命令行参数)
codei18n auth set --profile openai-mini
echo "$KEY" | codei18n auth set --profile openai-mini

# 保存当前项目的覆盖令牌
codei18n auth set --profile openai-mini --project

# 查看是否已保存、末 4 位与生效来源层
codei18n auth status --profile openai-mini

# 删除令牌
codei18n auth delete --profile openai-mini --project

# 把配置文件中的旧版明文令牌迁入凭据库,并从文件中删除
codei18n auth migrate

--profile 省略时使用当前生效的配置档;status 只显示末 4 位。

14.5 扫描性能与增量缓存
  • 并行扫描:worker pool(默认 CPU 核数),每个 worker 持有自己的解析器。
  • 增量扫描:.codei18n/cache/scan.gob 记录每个文件的 size、mtime、内容 hash 与解析结果;未变化的文件直接复用,全部命中且映射/索引/覆盖文件都未变时直接返回。
  • 语种识别结果按文本 hash 缓存(cache/lang.gob)。
  • 翻译时方向相同、归一化原文相同的条目只请求一次;映射文件按批次节流保存,结束(含取消)时必定保存。
  • codei18n map update --no-cache 不使用缓存,重新解析所有文件。
  • codei18n map update --prune 删除源码中已不存在的映射条目;默认不删,只显示可清理的数量。只能在扫描整个项目时使用,指定 --scan-dir 子目录时会被拒绝。
14.6 文档注释结构化翻译

对 Javadoc、KDoc、JSDoc/TSDoc、Dartdoc、C# XML doc 等文档注释,翻译前先把代码引用、类型、参数名、标签、代码块等受保护片段替换为占位符 ⟦n⟧,只翻译剩余散文;翻译后还原,并校验占位符一个不少、一个不多、顺序不变,再按原注释的外框与缩进重新组装。

  • 校验失败重试 1 次,仍失败则标记为失败,不写入错误译文。
  • 正文全是受保护片段的注释不发请求,直接沿用原文。
  • 需要 index.json(据此选择格式);没有 index.json 时保持旧行为。
  • 已知限制:Markdown 缩进式代码块不受保护;a<b> 之类文本可能被当作 HTML 标签保护。
14.7 注释语种识别
  • 识别使用裁剪后内置的 lingua(third_party/lingua,仅保留 en/zh/ja/ko/de/fr/es/ru 模型),简繁中文按字表区分。
  • 识别前会剥掉注释符号、受保护片段、代码、标识符、URL、路径等;剩余文本过短时用字符集启发式。
  • 无法判断时标记为 unknown,不强行归类;识别结果不在 detectLanguages 候选集内时同样为 unknown。
  • 存放规则:与本地语言/源语言等价时用配置写法(如 zh-CN);无法识别时按源语言存放;第三种语言(如日文)按规范码(如 ja)存放。
  • 翻译目标为 {源语言, 本地语言} 中与原语言不等价且缺失的语言;第三种语言两者都补。
  • 用户可通过 overrides.json(库 API:SetCommentLanguage)纠正原语言,纠正优先于识别结果。
  • 限制:只含汉字的日文会被判为中文。

15. 项目目录结构

codei18n/
├─ cmd/codei18n        # CLI(库之上的薄壳)
├─ codei18n.go ...     # 根包:Open / Project / Global 等库 API
├─ core/               # 配置、映射、索引、工作流、语种识别、文档注释格式、凭据库等
├─ adapters/           # 各编程语言适配器(含 commentgroup、translator)
├─ third_party/        # 内置的第三方代码(裁剪版 lingua、tree-sitter-dart)
├─ docs/               # 文档(index-format.md、library-api.md 等)
└─ openspec/           # 变更提案与规范

16. 开发工作流与 Makefile

本项目提供了完整的 Makefile 来简化日常开发操作。

16.1 常用命令
# 查看所有可用命令
make help

# 构建可执行文件
make build

# 运行所有测试(跳过集成测试)
make test

# 运行所有测试(包括集成测试,需要有效的 API key)
make test-integration

# 生成测试覆盖率报告
make coverage

# 查看 HTML 格式的覆盖率报告
make coverage-html

# 格式化代码
make fmt

# 运行代码检查
make lint

# 运行所有质量检查(fmt + vet + lint)
make check

# 开发模式:快速检查
make dev

# 完整 CI 流程
make all

# CI/CD 模式(包含覆盖率验证)
make ci

# Pre-commit 检查
make pre-commit
16.2 代码质量要求

根据项目章程要求:

  • 总体测试覆盖率: ≥ 60%
  • 核心模块覆盖率: ≥ 80%(core/comment, core/mapping, core/translate)
  • 代码规范: 必须通过 gofmt 和 golint/staticcheck 检查

使用以下命令验证:

# 检查覆盖率是否达标
make coverage-check

# 运行完整的 CI 检查
make ci
16.3 开发工作流示例
日常开发
# 1. 编写代码
# 2. 快速验证
make dev

# 3. 提交前检查
make pre-commit

# 4. 构建
make build
提交前完整检查
# 运行完整 CI 流程
make ci
16.4 Docker 支持

项目支持 Docker 容器化部署:

# 构建 Docker 镜像
make docker-build

# 运行 Docker 容器
make docker-run

# 在 Docker 中运行测试
make docker-test

# 清理 Docker 镜像
make docker-clean
16.5 CI/CD 集成

项目配置了完整的 GitHub Actions CI/CD 流程:

自动化检查

每次 push 或 pull request 时自动运行:

  • ✅ 代码质量检查(gofmt、go vet、staticcheck)
  • ✅ 多平台构建测试(Linux、macOS、Windows)
  • ✅ 单元测试和覆盖率报告
  • ✅ 集成测试
  • ✅ 安全扫描(gosec、govulncheck)
  • ✅ 依赖审计
自动发布

推送版本 tag 时自动构建和发布:

# 创建版本 tag
git tag -a v0.1.0 -m "Release v0.1.0"
git push origin v0.1.0

# GitHub Actions 将自动:
# - 构建多平台二进制文件
# - 生成 Release Notes
# - 创建 GitHub Release
# - 构建并推送 Docker 镜像(如果配置)

更多详情请查看 CI/CD 工作流说明。


17. Roadmap

  • 已完成:Go / Rust / Java / Kotlin / TypeScript / JavaScript / C# / Dart 适配器,库化 API(codei18n.Open),位置索引 index.json,系统凭据库令牌,增量并行扫描,文档注释结构化翻译,多语种识别。
  • 进行中:桌面端与 IDE 插件基于 index.json 的精确匹配。
  • 计划:更多编程语言(如 Python)、非 Windows 平台的凭据库实现(目前请使用环境变量)。

18. 结论

CodeI18n 本质是一个“代码注释 i18n 基础设施”:

  • Git 负责事实
  • AST 负责语义
  • IDE 负责体验

这是一个 长期存在、但一直没人系统解决的问题。

Documentation

Overview

Package codei18n 是 CodeI18n 的库入口:以项目根目录为单位打开项目,执行扫描、映射更新、翻译、改写等长任务。

同一进程中可以同时打开多个 Project,彼此互不影响(没有全局可变状态)。库代码不打印、不调用 os.Exit, 日志通过 Logger 注入,进度通过 ProgressFunc 回调发出,所有长任务都接受 context.Context 并可取消。

p, err := codei18n.Open(root, codei18n.WithLogger(myLogger))
res, err := p.UpdateMappings(ctx, codei18n.MapOptions{Progress: onProgress})

Index

Constants

View Source
const (
	EnvAPIKey       = "CODEI18N_API_KEY"
	EnvLegacyAPIKey = "OPENAI_API_KEY"
)

环境变量名。

View Source
const (
	PhaseDiscover  = events.PhaseDiscover
	PhaseScan      = events.PhaseScan
	PhaseMap       = events.PhaseMap
	PhaseIndex     = events.PhaseIndex
	PhaseTranslate = events.PhaseTranslate
	PhaseSave      = events.PhaseSave
	PhaseConvert   = events.PhaseConvert
	PhaseDone      = events.PhaseDone
)

进度阶段。

Variables

View Source
var (
	ErrProfileExists   = errors.New("配置档已存在")
	ErrProfileNotFound = errors.New("配置档不存在")
)

ErrProfileExists / ErrProfileNotFound 用于配置档管理。

View Source
var ErrAlreadyInitialized = errors.New("配置文件已存在")

ErrAlreadyInitialized 表示项目已初始化且未要求覆盖。

View Source
var ErrBusy = errors.New("项目正在执行其他任务")

ErrBusy 表示该项目正在执行另一个会写入映射的长任务。

View Source
var ErrNoToken = errors.New("未找到 API 令牌")

ErrNoToken 表示找不到可用的令牌。

View Source
var ErrNotInitialized = errors.New("项目尚未初始化")

ErrNotInitialized 表示项目尚未初始化(没有 .codei18n/config.json)。

View Source
var ErrUnknownComment = errors.New("未知的注释 ID")

ErrUnknownComment 表示 mappings.json 中没有该 ID。

View Source
var Version = "dev"

Version 是库版本,写入 index.json 的 generator 字段;CLI 构建时可覆盖。

Functions

func ValidateProfileName

func ValidateProfileName(name string) error

ValidateProfileName 检查配置档名:非空,不含 / \ 与空白(它会成为凭据库 account 的一部分)。

Types

type CommentRecord

type CommentRecord struct {
	ID string `json:"id"`
	// File 相对于项目根目录;没有 index.json 时为空。
	File string `json:"file"`
	// Language 是编程语言标识。
	Language   string      `json:"language"`
	Type       string      `json:"type"`
	Range      index.Range `json:"range"`
	Parts      int         `json:"parts"`
	Symbol     string      `json:"symbol"`
	Lang       string      `json:"lang"`
	LangSource string      `json:"langSource"`
	// SourceKey 是原文所在的 mappings 语言键。
	SourceKey string `json:"sourceKey"`
	// Original 是原文。
	Original string `json:"original"`
	// Texts 是全部语言的文本(含原文)。
	Texts map[string]string `json:"texts"`
	// Error 是上次翻译失败的错误信息(已脱敏),没有失败时为空。
	Error string `json:"error,omitempty"`
}

CommentRecord 是注释浏览器中的一条记录:index.json 的位置信息 + mappings.json 的文本。

func (*CommentRecord) Translation

func (r *CommentRecord) Translation(lang string) string

Translation 返回该记录在 lang(按等价语言码查找)下的文本。

type ConvertOptions

type ConvertOptions struct {
	File     string
	Dir      string
	To       string
	DryRun   bool
	Progress ProgressFunc
}

ConvertOptions 配置源码改写。

type ConvertResult

type ConvertResult = workflow.ConvertResult

结果类型。

type Event

type Event = events.Event

Event 是结构化进度事件。

type Failure

type Failure = workflow.Failure

结果类型。

type Global

type Global struct {
	// contains filtered or unexported fields
}

Global 管理全局配置(~/.codei18n/config.json)中的 provider 配置档及其令牌,不依赖任何项目。

func OpenGlobal

func OpenGlobal(opts ...Option) (*Global, error)

OpenGlobal 打开全局配置。支持 WithGlobalDir、WithSecretStore、WithLogger、WithEnv。

func (*Global) CopyProfile

func (g *Global) CopyProfile(from, to string) error

CopyProfile 复制配置档的字段为新名称。令牌不复制(避免在凭据库中悄悄产生副本),需要单独保存。

func (*Global) DeleteProfile

func (g *Global) DeleteProfile(name string) error

DeleteProfile 删除配置档,并一并删除它在凭据库中的全局令牌与各项目覆盖令牌。

func (*Global) DeleteProfileToken

func (g *Global) DeleteProfileToken(profile string) error

DeleteProfileToken 删除配置档的全局令牌;不存在时返回 secrets.ErrNotFound。

func (*Global) File

func (g *Global) File() (*config.File, error)

File 读取全局配置文件。

func (*Global) MigratePlaintextTokens

func (g *Global) MigratePlaintextTokens() ([]MigratedToken, error)

MigratePlaintextTokens 把全局配置中的明文令牌迁入凭据库:顶层 / translationConfig 中的字段迁到 profile/default,profiles.<name>.* 迁到 profile/<name>;然后从文件中删除这些字段(原子写)。

func (*Global) Path

func (g *Global) Path() string

Path 返回全局配置文件路径。

func (*Global) PlaintextTokens

func (g *Global) PlaintextTokens() ([]PlaintextToken, error)

PlaintextTokens 列出全局配置中的明文令牌字段(不含值)。

func (*Global) ProfileTokenStatus

func (g *Global) ProfileTokenStatus(profile string) (saved bool, last4 string, err error)

ProfileTokenStatus 返回配置档全局令牌是否已保存及末 4 位。

func (*Global) Profiles

func (g *Global) Profiles() ([]string, error)

Profiles 返回所有配置档名(排序)。

func (*Global) RenameProfile

func (g *Global) RenameProfile(from, to string) error

RenameProfile 重命名配置档,并把全局令牌与各项目的覆盖令牌迁移到新名称;全局 profile 选择同步更新。 项目配置文件中对旧名称的 profile 引用无法枚举,需要由调用方(桌面端对已知项目)更新。

func (*Global) SaveProfile

func (g *Global) SaveProfile(name string, fields config.ProviderFields) error

SaveProfile 新建或覆盖一个配置档的字段(不涉及令牌)。

func (*Global) SetProfileToken

func (g *Global) SetProfileToken(profile string, s Secret) error

SetProfileToken 保存配置档的全局令牌到系统凭据库。保存后 CLI 与 git hook 立即可用。

func (*Global) Update

func (g *Global) Update(fn func(*config.File) error) error

Update 原子地修改全局配置文件(保留未识别字段)。

type InitOptions

type InitOptions struct {
	SourceLanguage  *string
	LocalLanguage   *string
	ExcludePatterns []string
	Profile         *string
	// Provider 写入旧版 translationProvider 字段(与 CLI --provider 一致)。
	Provider *string
	// Snapshot 非 nil 时把这份扁平配置的全部字段写入项目文件(旧版 CLI init 的行为)。
	Snapshot *config.Config
	// Force 覆盖已存在的配置文件(保留原有 projectId)。
	Force bool
}

InitOptions 配置项目初始化。nil / 空值表示不写该字段(继承全局或默认值)。

type Logger

type Logger = logging.Logger

Logger 是可注入的日志接口。

type MapOptions

type MapOptions struct {
	// ScanDir 为空时扫描项目根目录。
	ScanDir string
	DryRun  bool
	// Prune 删除源码中已不存在的条目(孤儿)。只能在扫描整个项目根目录时使用;默认只在结果中报告数量。
	Prune bool
	// NoCache 禁用增量扫描缓存。
	NoCache bool
	// Workers 并行解析的 worker 数,<=0 时为 CPU 核数。
	Workers  int
	Progress ProgressFunc
}

MapOptions 配置映射更新。

type MapUpdateResult

type MapUpdateResult = workflow.MapUpdateResult

结果类型。

type MigratedToken

type MigratedToken struct {
	PlaintextToken
	Account string `json:"account"`
}

MigratedToken 描述一次明文迁移。

type Option

type Option func(*settings)

Option 配置 Open。

func WithConfigFile

func WithConfigFile(path string) Option

WithConfigFile 只使用指定的配置文件(作为项目层),不读取全局与项目默认位置的配置。 对应 CLI 的 --config。

func WithEnv

func WithEnv(getenv func(string) string) Option

WithEnv 注入环境变量读取函数(测试用)。

func WithGlobalDir

func WithGlobalDir(dir string) Option

WithGlobalDir 指定全局配置目录(默认 ~/.codei18n)。

func WithLogger

func WithLogger(l Logger) Option

WithLogger 注入日志实现;默认丢弃日志。

func WithOverrides

func WithOverrides(ov config.Overrides) Option

WithOverrides 设置调用方覆盖(优先级最高,不写入文件)。

func WithSecretStore

func WithSecretStore(s SecretStore) Option

WithSecretStore 注入凭据库(测试用内存实现)。

func WithTranslator

func WithTranslator(t core.Translator) Option

WithTranslator 注入翻译后端(测试或自定义后端),忽略配置中的 provider。

type Phase

type Phase = events.Phase

Phase 是进度阶段。

type PlaintextToken

type PlaintextToken struct {
	// Layer 为 global 或 project。
	Layer    config.Layer `json:"layer"`
	Path     string       `json:"path"`
	Location string       `json:"location"`
	Profile  string       `json:"profile,omitempty"`
}

PlaintextToken 描述配置文件中发现的一个旧版明文令牌字段(不含值)。

type ProgressFunc

type ProgressFunc = events.Func

ProgressFunc 接收进度事件;可能在任意 goroutine 上被调用。

type Project

type Project struct {
	// contains filtered or unexported fields
}

Project 是一个已打开的项目。方法可以从多个 goroutine 调用;写映射的长任务在同一项目上互斥(返回 ErrBusy)。

func Open

func Open(root string, opts ...Option) (*Project, error)

Open 打开以 root 为根目录的项目。root 必须是已存在的目录;项目不必已初始化。

func (*Project) Comments

func (p *Project) Comments() ([]CommentRecord, error)

Comments 返回项目中全部注释记录,按文件与位置排序;不在 index.json 中的条目排在最后。

func (*Project) Config

func (p *Project) Config() (*config.Effective, error)

Config 每次重新读取配置文件并返回合并后的值及每个字段的来源层。

func (*Project) ConfigPath

func (p *Project) ConfigPath() string

ConfigPath 返回项目配置文件路径。

func (*Project) Convert

func (p *Project) Convert(ctx context.Context, opts ConvertOptions) (*ConvertResult, error)

Convert 在源码中原地改写注释为目标语言(源码改写逻辑与旧版一致)。

func (*Project) DataDir

func (p *Project) DataDir() string

DataDir 返回 <root>/.codei18n。

func (*Project) DeleteProjectToken

func (p *Project) DeleteProjectToken(profile string) error

DeleteProjectToken 删除项目级覆盖令牌;不存在时返回 secrets.ErrNotFound。

func (*Project) EnsureGitignore

func (p *Project) EnsureGitignore() (bool, error)

EnsureGitignore 确保 .gitignore 中忽略 .codei18n/;返回是否修改了文件。

func (*Project) Failures

func (p *Project) Failures() ([]Failure, error)

Failures 返回上次翻译留下的失败条目。

func (*Project) Files

func (p *Project) Files() (global, project *config.File, err error)

Files 返回全局与项目两层配置文件的内容(不存在时为空 File)。

func (*Project) GlobalConfigPath

func (p *Project) GlobalConfigPath() string

GlobalConfigPath 返回全局配置文件路径;使用 WithConfigFile 时为空。

func (*Project) HooksInstalled

func (p *Project) HooksInstalled() bool

HooksInstalled 判断 hook 是否已安装。

func (*Project) Init

func (p *Project) Init(opts InitOptions) error

Init 写入项目配置 .codei18n/config.json,并生成 projectId。

func (*Project) Initialized

func (p *Project) Initialized() bool

Initialized 判断项目是否已初始化(存在项目配置文件)。

func (*Project) InstallHooks

func (p *Project) InstallHooks() error

InstallHooks 安装 pre-commit 与 commit-msg hook。

func (*Project) IsGitRepo

func (p *Project) IsGitRepo() bool

IsGitRepo 判断项目根目录是否是 Git 仓库。

func (*Project) MigratePlaintextTokens

func (p *Project) MigratePlaintextTokens() ([]MigratedToken, error)

MigratePlaintextTokens 把项目配置中的明文令牌迁入系统凭据库(项目级覆盖令牌),并从文件中删除这些字段(原子写)。 同一位置有多个明文字段时取优先级最高的一个,其余一并删除。先写凭据库再改文件,失败时不会丢失令牌。

func (*Project) Root

func (p *Project) Root() string

Root 返回项目根目录(绝对路径)。

func (*Project) Scan

func (p *Project) Scan(ctx context.Context, opts ScanOptions) (*ScanResult, error)

Scan 只读地扫描注释,不写任何文件。

func (*Project) SetCommentLanguage

func (p *Project) SetCommentLanguage(id, lang string) error

SetCommentLanguage 纠正某条注释识别出的原语言。结果持久化到 overrides.json,下次扫描不会覆盖; 同时把原文移到新语言对应的 mappings 键下,并更新 index.json 中的条目。lang 为空表示撤销纠正 (撤销后的语言在下次 map update 时重新识别)。

func (*Project) SetProjectToken

func (p *Project) SetProjectToken(profile string, s Secret) error

SetProjectToken 把项目级覆盖令牌存入系统凭据库(项目没有 projectId 时生成并写入项目配置)。

func (*Project) SetTranslation

func (p *Project) SetTranslation(id, lang, text string) error

SetTranslation 手动设置某条注释某种语言的文本,原子写回 mappings.json。text 为空时删除该语言文本。

func (*Project) Status

func (p *Project) Status() (*Status, error)

Status 读取项目状态。

func (*Project) TokenStatus

func (p *Project) TokenStatus() (*TokenStatus, error)

TokenStatus 返回当前生效 profile 的令牌状态。

func (*Project) Translate

func (p *Project) Translate(ctx context.Context, opts TranslateOptions) (*TranslateResult, error)

Translate 翻译缺失的条目。取消后已完成的结果已落盘,返回的错误为 ctx.Err(),结果中 Canceled 为 true。

func (*Project) TranslateText

func (p *Project) TranslateText(ctx context.Context, text, from, to string) (string, error)

TranslateText 用项目配置的后端翻译一段文本;from/to 为空时为源语言 → 本地语言。

func (*Project) UpdateConfig

func (p *Project) UpdateConfig(fn func(*config.File) error) error

UpdateConfig 原子地修改项目配置文件(保留未识别字段)。

func (*Project) UpdateMappings

func (p *Project) UpdateMappings(ctx context.Context, opts MapOptions) (*MapUpdateResult, error)

UpdateMappings 扫描源码,把新注释加入 mappings.json,并原子写出 index.json。

type ScanOptions

type ScanOptions struct {
	// Dir 为空时扫描项目根目录。
	Dir      string
	Progress ProgressFunc
}

ScanOptions 配置只读扫描。

type ScanResult

type ScanResult = scanner.Result

结果类型。

type Secret

type Secret = secrets.Secret

Secret 持有令牌;打印、格式化、JSON 编码时只输出脱敏形式。

func NewSecret

func NewSecret(b []byte) Secret

NewSecret 从字节构造令牌(去掉首尾空白)。

type SecretStore

type SecretStore = secrets.Store

SecretStore 是凭据库接口(默认为系统凭据库)。

type Status

type Status struct {
	Initialized bool `json:"initialized"`
	HasMappings bool `json:"hasMappings"`
	HasIndex    bool `json:"hasIndex"`
	// Comments 是 mappings.json 中的注释条数。
	Comments int `json:"comments"`
	// Translated 是本地语言文本已存在的条数。
	Translated int `json:"translated"`
	// Pending 是待翻译任务数(与 Translate 的任务数一致)。
	Pending int `json:"pending"`
	// Failed 是上次翻译失败的条数。
	Failed int `json:"failed"`
	// Languages 统计 index.json 中各原语言的注释数。
	Languages map[string]int `json:"languages"`
	// IndexGeneratedAt 是 index.json 的生成时间。
	IndexGeneratedAt string `json:"indexGeneratedAt,omitempty"`
}

Status 是项目的"快速载入"状态:只读 mappings、index 与缓存,不触发扫描。

type TokenSource

type TokenSource string

TokenSource 表示最终生效的令牌来自哪一层。

const (
	TokenSourceEnv     TokenSource = "env"         // 环境变量
	TokenSourceProject TokenSource = "project"     // 系统凭据库中的项目级覆盖令牌
	TokenSourceGlobal  TokenSource = "global"      // 系统凭据库中所选 profile 的全局令牌
	TokenSourceFile    TokenSource = "config-file" // 配置文件中的旧版明文字段(应迁移)
	TokenSourceNone    TokenSource = "none"
)

type TokenStatus

type TokenStatus struct {
	Profile string `json:"profile"`
	// Required 表示当前 provider 需要令牌(ollama / mock 不需要)。
	Required bool        `json:"required"`
	Source   TokenSource `json:"source"`
	Last4    string      `json:"last4,omitempty"`
	// EnvVar 是生效的环境变量名(Source 为 env 时)。
	EnvVar string `json:"envVar,omitempty"`

	ProjectAccount string `json:"projectAccount,omitempty"`
	ProjectSaved   bool   `json:"projectSaved"`
	ProjectLast4   string `json:"projectLast4,omitempty"`
	GlobalAccount  string `json:"globalAccount"`
	GlobalSaved    bool   `json:"globalSaved"`
	GlobalLast4    string `json:"globalLast4,omitempty"`
	// GlobalBlocked 表示项目配置把 baseUrl / endpoint 改成了与全局配置不同的地址,因此不使用全局令牌,
	// 防止随仓库分发的配置把用户的令牌发往不受信任的主机。
	GlobalBlocked bool `json:"globalBlocked,omitempty"`

	Plaintext []PlaintextToken `json:"plaintext,omitempty"`
	// StoreError 是凭据库不可用时的错误(例如非 Windows 平台)。
	StoreError string `json:"storeError,omitempty"`
}

TokenStatus 描述某个 profile 的令牌状态。不包含任何明文,只有末 4 位。

type TranslateOptions

type TranslateOptions struct {
	// Concurrency <=0 时使用配置值。
	Concurrency int
	// OnlyIDs 非空时只翻译这些注释(失败重试)。
	OnlyIDs  []string
	Progress ProgressFunc
}

TranslateOptions 配置翻译。

type TranslateResult

type TranslateResult = workflow.TranslateResult

结果类型。

Directories

Path Synopsis
commentgroup
Package commentgroup 实现所有语言统一的"物理注释 → 注释记录"规则: 连续行注释合并、空注释丢弃、注释类型判定。
Package commentgroup 实现所有语言统一的"物理注释 → 注释记录"规则: 连续行注释合并、空注释丢弃、注释类型判定。
csharp
Package csharp 实现 C#(.cs)的注释提取 adapter。
Package csharp 实现 C#(.cs)的注释提取 adapter。
dart
Package dart 实现 Dart 语言的注释提取 adapter。
Package dart 实现 Dart 语言的注释提取 adapter。
dart/grammar
Package grammar 是 tree-sitter-dart 语法的 cgo 绑定,写法与 smacker/go-tree-sitter 自带的各语言子包(如 kotlin、csharp)一致:parser.c、scanner.c、parser.h 平铺在本目录, 由 cgo 自动编译。
Package grammar 是 tree-sitter-dart 语法的 cgo 绑定,写法与 smacker/go-tree-sitter 自带的各语言子包(如 kotlin、csharp)一致:parser.c、scanner.c、parser.h 平铺在本目录, 由 cgo 自动编译。
kotlin
Package kotlin 实现 Kotlin(.kt / .kts)的注释提取 adapter。
Package kotlin 实现 Kotlin(.kt / .kts)的注释提取 adapter。
cmd
codei18n command
docfmt
Package docfmt 实现文档注释的结构化翻译预处理与还原。
Package docfmt 实现文档注释的结构化翻译预处理与还原。
events
Package events 定义长任务发出的结构化进度事件。
Package events 定义长任务发出的结构化进度事件。
gitint
Package gitint 负责与 Git 的集成:安装 / 卸载 hook、维护 .gitignore。
Package gitint 负责与 Git 的集成:安装 / 卸载 hook、维护 .gitignore。
index
Package index 读写位置索引 .codei18n/index.json。
Package index 读写位置索引 .codei18n/index.json。
langcode
Package langcode 提供全项目统一的 BCP 47 语言码规范化与等价判断。
Package langcode 提供全项目统一的 BCP 47 语言码规范化与等价判断。
langdetect
Package langdetect 识别注释文本的原语言。
Package langdetect 识别注释文本的原语言。
logging
Package logging 定义库代码使用的可注入日志接口。
Package logging 定义库代码使用的可注入日志接口。
secrets
Package secrets 管理 API 令牌:只存系统凭据库(本次实现 Windows 凭据管理器),绝不写入配置文件或日志。
Package secrets 管理 API 令牌:只存系统凭据库(本次实现 Windows 凭据管理器),绝不写入配置文件或日志。
internal
atomicfile
Package atomicfile 提供"写临时文件 + rename"的原子写入,读方永远不会读到半截文件。
Package atomicfile 提供"写临时文件 + rename"的原子写入,读方永远不会读到半截文件。
benchgen
Package benchgen 生成用于性能基准的中型样例项目(确定性:相同参数生成相同内容)。
Package benchgen 生成用于性能基准的中型样例项目(确定性:相同参数生成相同内容)。
log
scripts
genbench command
genbench 生成性能基准用的中型样例项目。
genbench 生成性能基准用的中型样例项目。
specs
tests
third_party
lingua
Package lingua accurately detects the natural language of written text, be it long or short.
Package lingua accurately detects the natural language of written text, be it long or short.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL