当前位置: 首页 > news >正文

Vscode/Code-Server 安装中文包——CI/CD

前言

啊好多人问我怎么还不更新,其实本月是已经写了一篇测评的,但是鉴于过于超前会给产品带来不好的影响,所以就没有公开。那么既然这样本月就再更新一篇。

首先 声明 一点,安装中文包的初衷不是看不懂英文,也不是对某些语言有偏见,既然它存在必然有其存在的理由,所以本文仅从技术的角度分析如何安装。

由于 Code-server 是基于 Vscode 的二开版本,本文将以 Code-server 为例来讲解。

项目链接

https://github.com/microsoft/vscodehttps://github.com/coder/code-server

问题初现

可能有人看到这个标题会很好奇,Vscode 安装中文语言包?那不是几秒钟的事?

啊确实,但是那是基于在 GUI 环境下,但是如果是在运行之前就将其设定为中文启动呢?

你可能又会说,这有何难,安装中文语言包不就行了,再改个配置文件,不一样可以实现?

那么问题就出在了这里,Vscode 上游有 BUG !

根据 Vscode 官网文档:我们是可以通过修改 .vscode/argv.json 的内容来实现修改为中文的(对于 Code-server 来说是 $HOME/.local/share/code-server/User/argv.json)。

那么查看一下手动修改中文后的 argv.json 文件是什么样的:

{"locale": "zh-cn"
}

啊🤔,秒了?这好像没难度,那么我就这么写?

curl -fsSL https://code-server.dev/install.sh | sh && \code-server --install-extension ms-ceintl.vscode-language-pack-zh-hanscat >> $HOME/.local/share/code-server/User/argv.json << EOF
{"locale": "zh-cn"
}
EOF

测试运行!

好好好。。。有问题 🤣👉🤡

那么我都文档操作都有问题,想必也不是个例,看看 issue 吧

显然许多人也遇到了同样的问题,通过查看 issue,发现这似乎与 languagepacks.json 文件有关

验证猜想

但是毕竟这条回答来源于 2021 年,其问题是否被修复难以确认,根据这个提示,我就尝试在 $HOME/.local/share/code-server/ 文件夹下起了一个 git 来查看是否确实是这个原因

切换语言,发现确实生成了 languagepacks.json ,那么 issue 中提到的手动复制 languagepacks.json 的办法应该确实可行,

进阶实现

但是 languagepacks.json 里是存在插件版本信息的,每次手动本地生成复制也不是办法,那么有没有办法手动用脚本生成 languagepacks.json 呢,这样就只需要安装插件后执行脚本生成就好了。

translations

观察 languagepacks.json 中的数据,动态变化的应该是 hash uuid translations 这几个值了,先看看插件包里是否存在

大概可以看出来 translations 是用语言包里 package.json 的相对路径改成绝对路径即可。

uuid

uuid 应该也是有的,全局搜索下先:

不错不错,$HOME/.local/share/code-server/extensions/extensions.json 就有,直接拿过来就好。

hash

这应该是得算了,翻翻源码看看是怎么算的

就在这里了,看看实现:

private updateHash(languagePack: ILanguagePack): void {if (languagePack) {const md5 = createHash('md5'); // CodeQL [SM04514] Used to create an hash for language pack extension version, which is not a security issuefor (const extension of languagePack.extensions) {md5.update(extension.extensionIdentifier.uuid || extension.extensionIdentifier.id).update(extension.version); // CodeQL [SM01510] The extension UUID is not sensitive info and is not manually created by a user}languagePack.hash = md5.digest('hex');}
}

原来是拼接了 UUID 和 VERSION,那就好说,一句话解决:

HASH=$(echo -n "$LANGUAGE_PACK_UUID$LANGUAGE_PACK_VERSION" | md5sum | awk '{print $1}')

那就来个脚本

https://cnb.cool/Anyexyz/DevEnv/default-dev-env/-/blob/main/create_languagepacks

#!/bin/bash# 定义路径
EXTENSIONS_DIR="$HOME/.local/share/code-server/extensions"
OUTPUT_DIR="$HOME/.local/share/code-server"
LANGUAGE_PACK_PREFIX="ms-ceintl.vscode-language-pack-"# 定义输出文件
LANGUAGEPACKS_FILE="$OUTPUT_DIR/languagepacks.json"
ARGV_FILE="$OUTPUT_DIR/User/argv.json"
EXTENSIONS_JSON="$EXTENSIONS_DIR/extensions.json"# 创建 User 目录(如果不存在)
mkdir -p "$(dirname "$ARGV_FILE")"# 查找语言包目录
LANGUAGE_PACK_FOLDER=$(find "$EXTENSIONS_DIR" -type d -name "${LANGUAGE_PACK_PREFIX}*" | head -n 1)# 检查语言包文件夹是否存在
if [ -z "$LANGUAGE_PACK_FOLDER" ]; thenecho "未找到语言包文件夹,请确保路径正确。"exit 1
fi# 从 package.json 中提取数据
PACKAGE_JSON="$LANGUAGE_PACK_FOLDER/package.json"
if [ ! -f "$PACKAGE_JSON" ]; thenecho "未找到 package.json 文件,请检查语言包目录。"exit 1
fi# 从 extensions.json 中提取 UUID
if [ ! -f "$EXTENSIONS_JSON" ]; thenecho "未找到 extensions.json 文件,请检查路径。"exit 1
fiLANGUAGE_PACK_NAME=$(jq -r '.name' "$PACKAGE_JSON")
echo "找到语言包: $LANGUAGE_PACK_NAME"
LANGUAGE_PACK_UUID=$(jq -r --arg id "ms-ceintl.$LANGUAGE_PACK_NAME" '.[] | select(.identifier.id == $id) | .identifier.uuid' "$EXTENSIONS_JSON")if [ -z "$LANGUAGE_PACK_UUID" ]; thenecho "未能在 extensions.json 中找到对应语言包的 UUID"exit 1
fi# 提取其他必要信息
LANGUAGE_ID=$(jq -r '.contributes.localizations[0].languageId' "$PACKAGE_JSON")
LANGUAGE_LABEL=$(jq -r '.contributes.localizations[0].localizedLanguageName' "$PACKAGE_JSON")
LANGUAGE_PACK_VERSION=$(jq -r '.version' "$PACKAGE_JSON")# 动态生成 translations
TRANSLATIONS=$(jq -n --arg dir "$LANGUAGE_PACK_FOLDER" --argjson translations "$(jq '.contributes.localizations[0].translations' "$PACKAGE_JSON")" 'reduce $translations[] as $item ({}; . + {($item.id): "\($dir)/\($item.path)"})
')# 生成 languagepacks.json
HASH=$(echo -n "$LANGUAGE_PACK_UUID$LANGUAGE_PACK_VERSION" | md5sum | awk '{print $1}')
cat > "$LANGUAGEPACKS_FILE" <<EOL
{"${LANGUAGE_ID}": {"hash": "${HASH}","extensions": [{"extensionIdentifier": {"id": "${LANGUAGE_PACK_NAME}","uuid": "${LANGUAGE_PACK_UUID}"},"version": "${LANGUAGE_PACK_VERSION}"}],"translations": ${TRANSLATIONS},"label": "${LANGUAGE_LABEL}"}
}
EOL# 格式化 languagepacks.json
jq '.' "$LANGUAGEPACKS_FILE" > "$LANGUAGEPACKS_FILE.tmp" && mv "$LANGUAGEPACKS_FILE.tmp" "$LANGUAGEPACKS_FILE"
echo "languagepacks.json 已生成并格式化: $LANGUAGEPACKS_FILE"# 生成 argv.json
cat > "$ARGV_FILE" <<EOL
{"locale": "${LANGUAGE_ID}"
}
EOL# 格式化 argv.json
jq '.' "$ARGV_FILE" > "$ARGV_FILE.tmp" && mv "$ARGV_FILE.tmp" "$ARGV_FILE"
echo "argv.json 已生成并格式化: $ARGV_FILE"

调用

https://cnb.cool/Anyexyz/DevEnv/default-dev-env/-/blob/main/Dockerfile

http://www.xdnf.cn/news/265069.html

相关文章:

  • PCIe | TLP 报头 / 包格式 / 地址转换 / 配置空间 / 命令寄存器 / 配置类型
  • JMM 与 JVM 运行时数据区有什么区别和联系?
  • 数字化转型进阶:26页华为数字化转型实践分享【附全文阅读】
  • 传奇各职业/战士/法师/道士/头盔爆率及出处产出地/圣战/法神/天尊/祈祷/斗笠/精灵
  • 面向对象编程简介
  • list的两种设计
  • MySQL 比较运算符详解
  • 穿越数据森林与网络迷宫:树与图上动态规划实战指南
  • 深拷贝与浅拷贝的核心区别
  • 【unity游戏开发——Animator动画】Animation动画资源节约、优化、编辑修改小技巧
  • 人工智能:如何快速筛选出excel中某列存在跳号的单元格位置?
  • Manus联合创始人:公司产品基于Claude和阿里千问大模型开发
  • Java开发经验——ali编码规范经验总结
  • java面向对象编程【高级篇】之特殊类
  • 【Java多线程】计时器Timer/ScheduledExecutorService的使用
  • mysql主从复制搭建,并基于‌Keepalived + VIP实现高可用
  • MARM:推荐系统中的记忆增强突破
  • C++ - 数据容器之 forward_list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)
  • Python爬虫实战:获取企信网指定公司基本工商数据并分析,为客户选择公司做参考
  • 封装pinia并引入pinia持久化工具(pinia-plugin-persistedstate)
  • HarmonyOS NEXT——DevEco Studio的使用(还没写完)
  • 如何基于HAL库进行STM32开发
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3商用服务开通教程
  • Python 学习
  • 4.29-4.30 Maven+单元测试
  • 【LeetCode Hot100】二分查找篇
  • Swift:重构开发范式的现代编程语言
  • 《高性能MySQL》第1讲:MySQL架构
  • 音视频开发技术总结报告
  • 对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础