ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

仓颉中心仓制品包发布指南:cjpm bundle 与 publish 全解析

仓颉中心仓制品包发布指南:cjpm bundle 与 publish 全解析
  • 文档
  • 编程语言

【免费下载链接】cangjie_docs

仓颉编程语言开发者文档。

项目地址:https://gitcode.com/Cangjie/cangjie_docs
点击查看免费下载

本文基于仓颉开发者文档仓库(cangjie_docs)中的中心仓客户端文档,系统讲解如何把本地开发的仓颉源码模块通过cjpm打包为符合中心仓格式的制品源码包(.cjp),并完成cangjie-repo.tomltoken 配置、bundle/publish命令参数、include/exclude打包范围规则与元数据规格等全流程操作。读完本文,你可以独立完成一个模块从配置、打包、检查到成功发布到仓颉中心仓(Cangjie Central Repository)的完整发布链路,并理解每一步背后的校验逻辑与通信细节。

一、发布前提:环境准备与 token 配置

cjpm可以将开发的源码模块打包并发布到中心仓。发布前用户必须配置 token 以进行用户认证。

中心仓(Cangjie Central Repository)是仓颉语言的三方库托管平台,由三部分组成:中心仓官网(搜索、浏览制品、管理与组织操作)、中心仓客户端(集成在cjpm中的上传/使用命令行工具)、中心仓仓库(存放制品包及元数据),详见 概述。

cjpm通过配置文件cangjie-repo.toml完成中心仓相关配置,其格式如下(详见 中心仓客户端配置):

[repository.cache] path = "/path/to/repository/cache" # 本地存放路径 [repository.home] registry = "https://pkg.cangjie-lang.cn/registry" # 中心仓 url token = "user-token" # 用户个人 token

各字段含义:

  • repository.cache.path:本地缓存路径,用于存放从中心仓下载的制品包源码;支持绝对/相对路径(相对路径以该cangjie-repo.toml为基准);留空时Linux/macOS下最终生效路径为$HOME/.cjpm,Windows下为%USERPROFILE%\.cjpm。
  • repository.home.registry:中心仓仓库地址(https://pkg.cangjie-lang.cn/registry),用于上传下载通信。
  • repository.home.token:用户个人 token,在上传制品包时用于用户认证。

token 在中心仓官网"个人中心 → API Tokens"页面新建/刷新/作废(即上文配图所示页面)。cangjie-repo.toml的查找顺序为:模块内与cjpm.toml同级目录 → 用户目录.cjpm/cangjie-repo.toml→ 仓颉 SDK 中tools/config/cangjie-repo.toml(默认值),找到即停止。

二、cjpm.toml中与制品包制作和发布相关的配置项

cjpm.toml中与制品包创建和发布相关的字段如下(来自 制品包发布文档):

字段名字段描述是否必填
cjc-version仓颉 SDK 最低版本号是
name模块名,与模块内root包名一致是
organization组织名,为空则为无组织模块否
description描述信息仅打包时必填
version模块版本信息是
output-type编译输出产物类型,取值为静态库/动态库/可执行(static/dynamic/executable)是
authors作者 ID 列表否
repository制品代码仓 url否
homepage制品主页 url否
documentation制品文档页 url否
tag制品标签否
category官方提供的制品分类否
license协议列表,取值需遵循 SPDX Identifier 规范否
include指定打包范围否
exclude指定打包排除范围否
dependencies项目依赖,格式如aoo = "1.0.0"或"org::boo" = { version = "2.0.0" }否
test-dependencies测试依赖,格式与dependencies相同否
script-dependencies脚本依赖,格式与dependencies相同否

如下是一个具体的cjpm.toml示例:

[package] cjc-version = "1.0.0" name = "demo" organization = "cangjie" description = "demo of cangjie central repository" version = "1.0.0" output-type = "executable" authors = ["Tom", "Joan"] repository = "https://cangjie-demo.git" homepage = "https://cangjie-demo.com" documentation = "https://cangjie-demo.com/docs" tag = ["cangjie", "demo"] category = ["Network", "UI"] license = ["Apache-2.0"] include = ["src"] exclude = ["*.txt"] [dependencies] aoo = "1.0.0" [test-dependencies] boo = "2.0.0" [script-dependencies] "org::coo" = "3.0.0"

结合 cjpm 使用手册 可补充以下细节,方便配置时一次做对:

  • authors、repository、homepage、documentation均用于中心仓网页的制品信息展示,最终写入元数据(见 元数据规格)。
  • tag用于指定制品标签,上限 5 个;category用于指定制品分类,上限 5 个,且取值必须在中心仓提供的分类范围内(如Network、Utility、Logging、UI等共 26 个分类)。配置时大小写不敏感,但生成的元数据中会统一转换为标准格式。
  • 制品名/组织名的命名规范(见 中心仓制品规格):由大小写字母、数字和下划线组成,长度 [3, 64],必须以字母或若干个下划线开头,以下划线开头时第一个非下划线字符必须是字母(例如cangjie_demo_1、__Cangjie_Demo_2);不能是任何仓颉语法关键字(大小写不敏感);组织名不能为default。制品版本号格式为主版本号.次版本号.修订版本号,三级均为自然数(如0.1.2)。

三、bundle命令:制品包打包范围(include / exclude)

cjpm提供bundle命令,将本地开发的源码模块打包成符合中心仓制品包格式的制品包,用于后续上传。

bundle的常用可配置项(见 cjpm 手册 bundle 章节):

  • -V, --verbose:展示安装(打包)日志;
  • --skip-test:跳过单元测试阶段;
  • --skip-lint:跳过静态检查阶段。

打包范围由include和exclude两个字段决定,二者均为字符串数组,每个字符串代表一条匹配规则。匹配规则采用gitignore 风格的 glob 语法(*、?、**、行首/锚定、行尾/目录匹配等),规则相对于项目根目录匹配。配置时优先使用常规写法(如src、*.txt、src/**),不建议使用./前缀或.//等冗余路径写法。

支持的 glob 语法:

语法含义
*匹配除/外的任意字符(单路径段内)
?匹配单个非/字符
**匹配任意层级目录
[abc]匹配括号内任一字符
以/开头仅匹配项目根目录下的路径(如/src只匹配根目录src)
以/结尾匹配该目录及其下所有文件(如src/)
不含/的规则可在任意目录层级匹配(如*.txt)

匹配前规则会先做路径规范化:折叠多余的/和/./段、解析..段;以./开头的规则会先去掉./前缀。规则./或././表示匹配项目内全部文件。

与.gitignore的差异需要注意:

  • 不支持!否定规则;
  • 隐藏文件(以.开头的文件和目录)始终不会被打包;
  • 部分在.gitignore中无效的规则(如./src/**)在bundle中可用,但建议使用标准写法。

bundle只检查并打包当前项目目录下的文件。最终打包范围确定规则:

  • 无关配置,默认会被打包:项目根目录下的cjpm.toml、README.md、README_zh.md;
  • 无关配置,默认不会被打包:
    • 项目根目录下的cjpm.lock和cangjie-repo.toml;
    • 编译产物目录和构建脚本产物目录;
    • 所有二进制文件;
    • 所有隐藏文件(以.开头的文件和目录)。
  • 其余文件遵循:
    • 匹配任意include规则且不匹配任意exclude规则 → 打包;
    • 未配置include时 → 打包当前目录下所有不匹配任意exclude规则的文件。

以如下待打包模块demo为例:

demo ├── src │ ├── demo.cj │ ├── demo-config.txt │ └── aoo │ ├── aoo.cj │ └── aoo-config.txt ├── test │ ├── test.cj │ └── test-config.txt ├── README.md └── cjpm.toml

不同配置下的打包结果:

# 示例一:include = [],exclude = [] # 结果:打包上述文件列表中的所有文件
# 示例二:include = ["src"],exclude = [] # 结果:打包 cjpm.toml、README.md 和 src 目录
# 示例三:include = [],exclude = ["*.txt"] # 结果:排除所有 txt 文件,打包其余文件
# 示例四:include = ["src"],exclude = ["*.txt"] # 结果:打包 cjpm.toml、README.md 和 src 目录中除 txt 文件以外的其他文件

四、bundle打包流程:从模块检查到产出.cjp

bundle的完整打包流程分四步,任一步骤失败都会导致打包失败:

  1. 模块检查。一个可以被成功打包的cjpm模块需满足:
    • 模块名、组织名满足规格要求:长度 [3, 64] 且符合命名规格;不能为任何仓颉语法关键字(大小写不敏感);组织名不能为default;
    • cjpm.toml中包含模块说明description;
    • 根目录下包含中文文档README_zh.md或英文文档README.md;
    • 模块的依赖项均为中心仓形式(即不能依赖本地path依赖直接发布)。
  2. 编译检查:进行编译检查,确保模块能够编译通过;未配置--skip-test时会运行单元测试。编译和测试失败均导致打包失败。
  3. 代码静态检查:未配置--skip-lint时调用cjlint进行静态检查,出现error级别错误会导致打包失败。
  4. 打包:基于include/exclude将当前模块打包成tar.gz格式的制品源码包,文件名为模块名-版本号.cjp,位于编译产物目录;同时生成元数据文件meta-data.json。

继续以demo为例,假设version = "1.0.0",未配置编译产物目录时默认为target。执行cjpm bundle后,target目录中会有:

target ├── demo-1.0.0.cjp # 制品源码包 ├── meta-data.json # 制品元数据 └── 其他编译产物

demo-1.0.0.cjp可以按tar.gz格式解压,解压结果即打包范围内文件的内容。

注意:元数据文件记录了本地模块的关键信息,供中心仓网页进行制品信息展示,详见下一节。

五、元数据meta-data.json与索引规格

原文档说明:元数据文件记录了本地模块的关键信息,请参阅 中心仓元数据规格。

cjpm bundle生成的元数据用于仓库端入库检查和网页端制品展示,规格如下:

{ "organization": "cangjie", // 组织名,为空则为无组织 "name": "demo", // 模块名 "version": "1.0.0", // 版本号 "cjc-version": "1.0.0", // 仓颉 SDK 版本号 "description": "demo for cangjie central repository", // 模块描述 "artifact-type": "src", // 制品包类型,固定为源码包 src "executable": true, // 是否可以编译成可执行程序,package.output-type == executable 时为 true "authors": ["Tom", "Joan"], // 作者 ID 列表 "repository": "https://github.com/xxx", // 制品代码仓 "homepage": "https://xxx.com", // 制品主页 "documentation": "https://xxx.com/docs", // 制品文档页 "tag": ["cangjie", "cjpm"], // 制品标签 "category": ["Network"], // 制品分类 "license": ["Apache-2.0"], // 协议列表 "index": { ... }, // 制品包索引 "meta-version": 1 // 元数据规格版本号 }

其中index制品包索引记录了依赖信息,cjpm利用它做依赖解析;关键项包括:

{ "dependencies": [ { "name": "dep1", // 依赖项模块名 "require": "1.1.0", // 依赖项版本需求 "target": null, // 平台隔离标识,null 表示不区分平台 "type": null, // 编译模式标识,null 表示不区分编译模式 "output-type": null // 编译产物类型,null 表示遵循被依赖模块的 package.output-type } ], "test-dependencies": [], // 测试依赖项 "script-dependencies": [], // 构建脚本依赖项 "sha256sum": "...", // 对应制品包的 SHA-256 校验码,用于验证制品包完整性 "yanked": false, // 制品包弃用标识,true 表示已被弃用 "index-version": 1 // 索引规格版本号 }

这里的sha256sum正是后面publish校验制品包完整性所依据的校验码。

六、publish命令:把制品包发布到中心仓

cjpm提供publish命令,将bundle生成的制品源码包发布到中心仓。

执行publish时,cjpm会检查编译产物目录中是否存在模块名-版本号.cjp制品源码包与meta-data.json元数据文件。若任一文件不存在,或元数据中的制品包校验码与制品包不匹配,则重新执行默认bundle流程;随后将有效的制品源码包和元数据发布到中心仓。也就是说,cjpm publish在缺包或包被改动过(如手工修改了target下的.cjp)时会自动重新打包,保证上传内容与元数据一致。

publish发布成功需要满足以下条件:

  1. 已在cangjie-repo.toml中配置有效的用户 token;
  2. 上传的制品包唯一,即仓库中不存在另一个制品包与新上传制品包的组织名、制品名和版本号均相同;
  3. 若制品包隶属于某个组织,则 token 对应的用户必须是该组织的成员;
  4. 发布的制品包通过中心仓的安全扫描。

结合 中心仓通信规格,publish实际向repository.home.registry发起的请求为:

  • 方法:POST;
  • url:无组织模块为/pkg/${module-name},组织内模块为/pkg/${module-name}?organization=${org-name}(url 中不体现版本号);
  • header:Authorization=${token};
  • body:依次为元数据(1 byte 元数据版本 + 4 byte 长度 + m byte 元数据内容)与制品包(1 byte 制品包版本 + 4 byte 长度 + n byte 制品包内容)的序列化字节流。

返回码方面,排错时可参考:401用户认证失败(token 无效或过期,可到官网 API Tokens 页面刷新);403用户无权限或制品包名已被占用(制品包名不区分大小写);409上传的制品包与仓库已有制品包冲突;429每日请求频率超限。

发布成功后,制品即出现在中心仓官网的制品详情页,展示README、标签、版本、依赖、作者与分类等信息:

七、发布前自检清单

在动手执行cjpm publish之前,可对照以下清单自查(均可在上述文档与配置中验证):

  1. 命名合规:模块名/组织名满足长度 [3, 64]、字符集与关键字限制,组织名不为default;
  2. 必填字段齐全:cjc-version、name、version、output-type已配置,description已填写;
  3. 文档存在:根目录存在README.md或README_zh.md(注意两者都会被默认打包进制品包);
  4. 依赖形式:dependencies/test-dependencies/script-dependencies均为中心仓形式(path本地依赖不能直接发布);
  5. 打包范围符合预期:include/exclude规则按上文 glob 语义检查,确认不会把大文件、二进制文件(二进制会被强制排除)或密钥类文件误打包;
  6. 编译与测试通过:未加--skip-test时单元测试必须全部通过;
  7. 静态检查无 error:未加--skip-lint时cjlint不能有error级别问题;
  8. token 有效且权限足够:cangjie-repo.toml中 token 未过期,组织制品需为该组织成员;
  9. 版本号唯一:目标版本尚未发布过,避免409冲突。

完成以上检查后,在项目根目录依次执行cjpm bundle(可加-V观察过程)与cjpm publish,制品即可发布到仓颉中心仓,供其他开发者通过dependencies依赖或cjpm install(executable类型)安装使用。

  • 文档
  • 编程语言

【免费下载链接】cangjie_docs

仓颉编程语言开发者文档。

项目地址:https://gitcode.com/Cangjie/cangjie_docs
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进