ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Kubectl 国际化(i18n)翻译工作流完全指南:从 PO 文件到二进制内嵌

Kubectl 国际化(i18n)翻译工作流完全指南:从 PO 文件到二进制内嵌 Kubectl 国际化i18n翻译工作流完全指南从 PO 文件到二进制内嵌【免费下载链接】kubesphereThe container platform tailored for Kubernetes multi-cloud, datacenter, and edge management ⎈ ☁️项目地址: https://gitcode.com/GitHub_Trending/ku/kubespherekubectl 作为 Kubernetes 生态中使用频率最高的命令行工具其提示信息、错误消息与帮助文本都通过一套完整的 gettext 国际化i18n体系实现多语言支持。本指南以 kubectl 翻译工作流文档为核心结合当前仓库中 kubectl 的源码实现与翻译资源文件系统讲解新增语言、包裹字符串、提取翻译、生成 MO 文件以及代码中调用翻译 API 的完整流程读者学完后可以独立为 kubectl 系工具新增一种语言或维护既有翻译。翻译体系全景从 PO 到内嵌二进制kubectl 的 i18n 体系遵循 GNU gettext 标准翻译文件按语言目录组织。在当前仓库中完整资源位于 vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/每个语言目录下都遵循LC_MESSAGES/子目录结构包含成对的k8s.po可编辑的翻译源文件与k8s.mo编译后的机器码文件translations/kubectl/ ├── de_DE/LC_MESSAGES/k8s.po, k8s.mo ├── default/LC_MESSAGES/k8s.po, k8s.mo # 兜底语言 ├── en_US/LC_MESSAGES/k8s.po, k8s.mo # 英语msgid 源语言 ├── fr_FR/LC_MESSAGES/k8s.po, k8s.mo ├── it_IT/LC_MESSAGES/k8s.po, k8s.mo ├── ja_JP/LC_MESSAGES/k8s.po, k8s.mo ├── ko_KR/LC_MESSAGES/k8s.po, k8s.mo ├── pt_BR/LC_MESSAGES/k8s.po, k8s.mo ├── zh_CN/LC_MESSAGES/k8s.po, k8s.mo # 简体中文 ├── zh_TW/LC_MESSAGES/k8s.po, k8s.mo # 繁体中文 ├── OWNERS └── template.pot # 待翻译消息模板以 zh_CN/LC_MESSAGES/k8s.po 为例其头部包含标准的 gettext 元信息随后的每个翻译条目由#:注释标注源码位置、msgid英文原文与msgstr目标语言译文组成例如#: staging/src/k8s.io/kubectl/pkg/cmd/top/top_node.go:62 msgid \n \t\t # Show metrics for all nodes\n \t\t kubectl top node\n \n \t\t # Show metrics for a given node\n \t\t kubectl top node NODE_NAME msgstr \n \t\t # 显示所有节点的指标\n \t\t kubectl top node\n \n \t\t # 显示指定节点的指标\n \t\t kubectl top node NODE_NAME一个值得注意的细节是不同语言目录的翻译完成度并不一致。统计当前仓库中的msgid条目数可以发现en_US与default为 337 条zh_CN、ja_JP、it_IT、pt_BR为 102 条de_DE为 93 条而zh_TW与ko_KR仅 8 条template.pot模板则包含 339 条待翻译消息。这说明翻译工作是渐进式的——新增语言可以先完成核心消息后续再通过模板补全。新增一种语言目录、注册与语言探测创建语言目录与 PO 文件为 kubectl 新增一种语言只需在translations/kubectl/下创建对应语言目录及 PO 文件translations/kubectl/language/LC_MESSAGES/k8s.po其中language使用 locale 命名规范例如法语为fr_FR。无需改动translations/test/...目录——该目录default与en_US两个子集仅用于单元测试。注册到 knownTranslations 映射创建语言文件后必须将其注册到 vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go 的knownTranslations映射中var knownTranslations map[string][]string{ kubectl: { default, en_US, fr_FR, zh_CN, ja_JP, zh_TW, it_IT, de_DE, ko_KR, pt_BR, }, // only used for unit tests. test: { default, en_US, }, }从源码可以清楚地看到语言注册的两层结构knownTranslations[kubectl]对应正式二进制使用的语言集合而knownTranslations[test]仅为单元测试保留default与en_US。findLanguage()函数i18n.go会遍历该列表若系统语言不在列表中则回退到default。系统语言探测优先级loadSystemLanguage()i18n.go按 GNU gettext 标准实现 locale 环境变量优先级LC_ALL→LC_MESSAGES→LANG。三个环境变量都未设置时记录日志并回退到default即en_US。它还会按.切分语言字符串以剥离字符集部分例如zh_CN.UTF-8→zh_CN格式异常同样回退到default。包裹字符串extract.py 的正则改造脚本翻译的前提是源码中的用户可见字符串被i18n.T()包裹。目录下的 extract.py 是一个简单正则包装脚本它并不追求完美但能自动化处理 kubectl 命令中最常见的几类字符串匹配器正则目标改造效果SHORT_MATCHShort: ...命令短描述替换为i18n.T(...)IMPORT_MATCHk8s.io/kubectl/pkg/cmd/util导入行在其后追加k8s.io/kubectl/pkg/util/i18n导入STRING_FLAG_MATCHcmd.Flags().String(...)字符串 flag 默认值替换为i18n.T(...)LONG_DESC_MATCHLongDesc(...)反引号长描述包裹进i18n.T()EXAMPLE_MATCHExamples(...)反引号示例包裹进i18n.T()脚本按行处理Short:、导入与 flag 三类单行匹配再用正则搜索替换LongDesc与Examples多行块最后调用goimports -w重新格式化文件。其用法为在仓库根目录执行python3 extract.py pkg/kubectl/cmd/apply.go从脚本注释可知其定位是始终可以通过改进来识别更多字符串——如果你需要包裹其他模式的字符串可以扩展MatchHandler列表。提取字符串go-xgettext 与 update-translations.sh安装 go-xgettext字符串包裹完成后从 Go 文件提取可翻译消息需要go-xgettext命令go get github.com/gosexy/gettext/go-xgettext运行更新脚本安装后运行./hack/update-translations.sh该脚本会提取并排序所有新增字符串同步更新template.pot模板、各语言k8s.po与k8s.mo文件。它承担两阶段职责提取调用go-xgettext扫描被i18n.T()/i18n.Errorf()包裹的字符串生成或更新 POT 模板编译将各语言的po文件编译为mo二进制格式POEdit 保存时也会自动完成这一步骤。新增翻译与复数形式处理使用 POEdit 编辑 PO 文件编辑对应的k8s.po文件时推荐使用开源工具 POEdit。它可以加载 template.pot 模板来找出缺失的翻译消息——该模板包含 339 条带源码位置注释#:的条目是核对翻译覆盖率的权威清单。英文原文作为 msgidkubectl 约定始终使用英文原文作为msgid因此所有语言共享同一套消息键翻译工作只填充各语言的msgstr。完成 PO 编辑后生成对应的k8s.mo文件——POEdit 会在保存时自动完成也可以运行./hack/update-translations.sh执行 PO 到 MO 的转换。复数形式的翻译处理msgid是英文原文的同时复数形式通过特殊的.plural后缀约定实现。翻译 API 调用i18n.T(You had %d items, items)时代码内部会查找You had %d items.plural对应的复数条目。因此 PO 文件中需要同时提供单数与复数两种msgstr并正确声明Plural-Forms规则——以 zh_CN 为例其头部声明为Plural-Forms: nplurals2; plural(n 1);。生成内嵌数据从 go-bindata 到编译期内嵌历史上 PO/MO 文件需要先通过go-bindata转换为 Go 代码再打包进 Kubernetes 二进制go get github.com/go-bindata/go-bindata/... ./hack/generate-bindata.sh重要变更从 Kubernetes 1.22 起这一步已不再必要——翻译资源改为在编译期直接内嵌进二进制。当前仓库的 i18n.go 正是这一演进的直接证据//go:embed translations var translations embed.FS//go:embed translations指令将整个translations/目录树嵌入编译产物彻底取代了运行时读取文件或 bindata 代码生成的方式。运行时加载机制LoadTranslations()i18n.go的实现展示了内嵌资源如何被消费它从embed.FS中读取选中语言的k8s.po与k8s.mo将两者打包进一个内存 ZIP 归档再通过gettext.BindLocale绑定 locale、gettext.SetDomain(k8s)设置域、gettext.SetLanguage(langStr)设置语言。整个加载过程由sync.Once保证只执行一次懒加载加载失败仅记录 warning 日志而不中断程序。在代码中使用翻译 API翻译体系对外暴露的 API 集中在 i18n.go使用前导入包import k8s.io/kubectl/pkg/util/i18n四种调用形式// 翻译普通字符串 translated : i18n.T(Your message in english here) // 翻译复数字符串第二个参数为数量 translated : i18n.T(You had %d items, items) // 翻译错误消息 return i18n.Error(Something bad happened) // 翻译复数错误消息 return i18n.Error(%d bad things happened)从 i18n.go 的实现可以看到T()在无附加参数时调用gettext.PGettext(, defaultValue)做普通查询有参数时调用gettext.PNGettext(, defaultValue, defaultValue.plural, args[0])查询复数形式再用fmt.Sprintf填充%d占位符文档中提到的i18n.Error()在源码中的实际实现为Errorf()它直接基于T()构造errors.New()错误消息同样参与翻译。自定义翻译加载可选对于希望接入自定义翻译的集成方SetLoadTranslationsFunc()提供了扩展点它必须在任何i18n.T()调用之前、通过独立的包在init()中注册。注册函数在首次调用翻译 API 时懒加载执行且一旦翻译已加载则拒绝重复注册返回错误。当前仓库的 kubectl 工具链内翻译调用已出现在 vendor/k8s.io/kubectl/pkg/cmd/util/override_options.go 等命令实现文件中。全流程串联与适用说明将上述步骤串联起来一个完整的为 kubectl 新增语言工作流如下创建translations/kubectl/language/LC_MESSAGES/k8s.po无需改动translations/test/在 i18n.go 的knownTranslations[kubectl]中注册新语言代码用 extract.py 包裹源码中未国际化的字符串Short:、flag、LongDesc、Examples安装go-xgettext运行./hack/update-translations.sh提取并排序新字符串、更新template.pot用 POEdit 加载template.pot对照补全k8s.po的msgstr英文原文为msgid复数条目使用.plural后缀由 POEdit 或更新脚本生成k8s.moKubernetes 1.22 无需再运行./hack/generate-bindata.sh翻译由//go:embed在编译期内嵌在代码中以i18n.T()/i18n.Errorf()消费翻译系统 localeLC_ALL→LC_MESSAGES→LANG决定实际加载的语言未注册或未设置时回退default。需要说明的适用前提本文所述目录与脚本路径以当前仓库 vendor 树中的 kubectl 组件为准如 vendor/k8s.io/kubectl/pkg/util/i18n/在 Kubernetes 上游主仓库中对应路径为staging/src/k8s.io/kubectl/。仓库为只读状态上述文件仅用于阅读与参照实际新增语言或修改翻译应在可写副本如 fork中按流程执行。【免费下载链接】kubesphereThe container platform tailored for Kubernetes multi-cloud, datacenter, and edge management ⎈ ☁️项目地址: https://gitcode.com/GitHub_Trending/ku/kubesphere创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表