# RuyiSDK 软件源的软件包版本约定

RuyiSDK 包管理器对所有软件包都采用[语义化版本][semver]（SemVer）风格的版本号。而 RuyiSDK 打包的许多软件，其上游并未采用
SemVer 规范，这样便给打包者带来了“我在打包上游版本 X 时，应当采用怎样的 RuyiSDK 版本 Y”这样一个问题。

[semver]: https://semver.org/

下面按照软件包的上游性质进行分类讨论。

## 以 RuyiSDK 团队或相关方为上游的软件包

由于这些软件包的打包与发布过程为 RuyiSDK 团队所控制或影响，考虑到 RuyiSDK 包管理器这一分发渠道，RuyiSDK
团队一般会选择 SemVer 风格的版本。此时上游版本号与 RuyiSDK 软件包版本号始终保持一致。

对于工具链打包（涉及众多组件版本）、滚动打包（上游版本不更新或不清晰）等场景，此时可以附加 RuyiSDK
特定的日期时间戳，见“RuyiSDK 日期时间戳”一节。

## 不以 RuyiSDK 团队或相关方为上游的软件包

这些软件包的版本号规律 RuyiSDK 团队不能决定，因此对于它们向 RuyiSDK 软件包版本号的映射方式，存在几种情况。

* 上游采用 SemVer。
    * 可以直接采用上游版本号。
* 上游采用[日历化版本][calver]（CalVer）或其他版本方案，但与 SemVer 相对较为兼容；或上游尽管不采用 SemVer 但该软件的流行程度相当之高。
    * 当对应 SemVer 大版本号的位置发生变化时，用户必须或十分建议跟进升级；
    * 且当对应 SemVer 大版本号的位置不变时，用户不是那么需要跟进升级。
    * 或者，如果不满足上述任一条件，但由于用户群体的心智已经十分根深蒂固，以至于采用编造的
      SemVer 方案反而将对用户体验造成损失：例如 GCC、LLVM/Clang、QEMU 都不采用
      SemVer，它们的大版本变更不见得会影响所有项目，但想必很难说服用户使用不同的版本号称呼这些软件。
    * 在这些情况下，可以直接采用上游版本号。
* 上游采用 CalVer 或其他版本方案，且与 SemVer 相对不兼容，且相应软件不甚驰名。
    * 不满足前述 CalVer 情况的任一判断要件，将造成用户使用不便：要么无意中被卡在旧的版本，要么将收到“SemVer major”一致但与先前所用版本不兼容的新版本。
    * 需要维护者按照 SemVer 规范，编造一种映射。目前不对映射的具体方式进行强制规定。举例如下：
        * 上游版本 `23.10`，对应 RuyiSDK 版本 `1.2310.0`。
        * 与上述上游版本兼容的 `24.04`，对应 RuyiSDK 版本 `1.2404.0`。
        * 与上述上游版本不兼容的 `24.10`，对应 RuyiSDK 版本 `2.2410.0`。
* 上游采用其他版本方案。
    * 也需要维护者按照 SemVer 规范，编造一种映射。目前不对映射的具体方式进行强制规定。

在映射版本号的过程中，应尽量保持关键要素的对齐。例如：

* 为 Python 软件包所采用的 [PEP 440][pep-0440] 风格版本，其“prerelease”部分如果为
  `a` `b`，应被映射到 SemVer 的 `alpha` `beta` 写法。
* 如上游版本号中包含 Git commit hash，为减少对排序算法的影响，应将其表示为 SemVer build tag，并在必要时补充 RuyiSDK 日期时间戳等体现排序的信息。
    * 例如：`emulator/qemu-user-riscv-xthead` 的 `6.1.0-ruyi.20231207+g03813c9fe8` 版本。

[pep-0440]: https://peps.python.org/pep-0440/

## RuyiSDK 日期时间戳

RuyiSDK 包管理器会特殊对待形如 `-ruyi.YYYYMMDD` 的 SemVer prerelease 标签：如无其他
prerelease 标记，则不将其视作 prerelease 版本。

作为[日历化版本][calver]（CalVer）的实践，这使得 RuyiSDK 可以为相同的上游版本打出不同的包：如为了修复打包脚本中的错误或上游未修复的紧急问题等。或者对于那些
RuyiSDK 能够自行决定发版方式与节奏的包，发版日期即可直接成为版本，使得发版的心智负担更低。

[calver]: https://calver.org/

原则上，只要一个软件包的内容受到了源自 RuyiSDK 的影响，包括但不限于：

* RuyiSDK 团队对上游发行版本进行了重打包，且对文件内容进行了修改；
* 软件包是 RuyiSDK 基于上游提供的源码包自行编译构建的；

那么在该软件包的版本号中，就应体现一个 RuyiSDK 日期时间戳。

## 上游版本号与 RuyiSDK 版本号映射关系的记录

目前 RuyiSDK 软件源并未提供记录该信息的手段。后续需要在 RuyiSDK 软件源中对此进行支持。在此之前，需要开发者在下游工具中自行跟踪相关信息。
