编程语言镜像源

本文探索不同编程语言都是如何管理其依赖包的,如何做到快速安装使用?如何为其构建的源做贡献?以及,如果想自定义一个第三方包管理,怎么做?

python

自定义包上传官方源

自定义包上传到pypi的教程:Packaging Python Projects — Python Packaging User Guide

通过twine命令。

有两点需要注意:

1、需要设置2FA验证后才能生成token。

什么是2FA验证:类似一种动态口令,需要手机扫二维码,获得口令码,再输入验证。

腾讯小程序有一个比较好用的: Authentic

2、如果遇到上传失败,提示403的情况,检查包名是否跟其他人重复:

1
2
3
4
ERROR    HTTPError: 403 Forbidden from https://test.pypi.org/legacy/               
The user 'wutengda' isn't allowed to upload to project
'example-package-testing'. See https://test.pypi.org/help/#project-name
for more information.

上传成功后,就可以使用该命令安装:

1
2
3
4
5
6
(venv) wutengda@wutengda:~/packaging_tutorial$ pip install example-package-wutengda

Collecting example-package-wutengda
Downloading example_package_wutengda-0.0.1-py3-none-any.whl (2.7 kB)
Installing collected packages: example-package-wutengda
Successfully installed example-package-wutengda-0.0.1

场景思考:

对于pytorch,在arm上直接使用报没有和cuda联合编译,导致运行失败的情况。此时我们手动编译构建了一个可用的联合编译版本,如何提交到pypi?

方式1:理想的,推动pytorch社区合入发布联合编译版本

方式2:在pypi上开一个新账号,提交新包到该账号下。该方式弊端是,你没法用pytorch命名,而使用者想用的话,只能去适配你的名称

方式3:新建一个私有pypi,将联合编译版本提交到这里。该方式需考虑:

  • 是否允许采用pytorch命名?
  • 当联合编译版本依赖其他包时,是否允许跨仓库关联解决?

自定义私有源

参考:Setting up a Private PyPI Server

安装pypiserver

1
2
3
pip install pypiserver
cd <dir-for-host-pypi>
pypi-server run -a . -P .

拉起成功后,可登录:localhost:8080

-a . -P .表示不需要登录就可以上传包,只要在上传时保持账号密码为空即可。

在没有指定目录时,上传的包会自动放到$HOME/packages目录下,如果该目录没有提前创建,上传会失败。

上传成功后,即可访问http://localhost:8080/simple查看已上传的包。

如果A包在自定义的仓库,B包在官方pypi源,此时pip install的行为是什么样的?示例:

1
2
3
# requirements.txt
example-package-wutengda==0.0.1 # 在官方pypi源
use-example-priv==0.0.1 # 在本地localhost:8080/simple私有源

安装前清理cache:

1
pip cache purge

此时执行:

1
2
3
4
5
6
7
8
9
(venv) wutengda@wutengda:~/test$ pip install --index-url http://localhost:8080 --trusted-host=localhost:8080 -r requirements.txt
Looking in indexes: http://localhost:8080
Collecting example-package-wutengda==0.0.1
Downloading example_package_wutengda-0.0.1-py3-none-any.whl (2.7 kB)
DEPRECATION: The HTML index page being used (http://localhost:8080/simple/use-example-priv/) is not a proper HTML 5 document. This is in violation of PEP 503 which requires these pages to be well-formed HTML 5 documents. Please reach out to the owners of this index page, and ask them to update this index page to a valid HTML 5 document. pip 22.2 will enforce this behaviour change. Discussion can be found at https://github.com/pypa/pip/issues/10825
Collecting use-example-priv==0.0.1
Downloading http://localhost:8080/packages/use_example_priv-0.0.1-py3-none-any.whl (2.7 kB)
Installing collected packages: use-example-priv, example-package-wutengda
Successfully installed example-package-wutengda-0.0.1 use-example-priv-0.0.1

可以正常安装, 不过会有一个DEPRECATION。

兼容性结论:

私有pypi源内如果有包依赖到官方源,则pip能够处理这种关系,pip将首先在当前配置的私有源中查找,如果未找到,则默认回退到官方源中查找。

java

自定义包上传maven源

参考:Maven – Maven Central Repository (apache.org)

为jar包生成gpgkey:Working with PGP Signatures - The Central Repository Documentation (sonatype.org)

提交jar包到中央仓库:

对于自定义的包,一般往OSSRH提交。该提交必须首先要持有一个JIRA账号和项目ticket(也就是新建一个group id)

对于私人项目,groupid可基于github命名,比如:io.github.stavewu(其他命名方式参考:Choosing your Coordinates - The Central Repository Documentation (sonatype.org))。提交new project后,还必须在自己的github下创建一个名为OSSRH-xxxxxx的仓库,完成后在对应OSSRH申请单下评论知会工作人员,通常是由机器人秒批的。

这部分细节处理可参考:发布 Jar 包到 Maven 中央仓库 – LOFFER – 一个可以fork的博客 (gitee.io)

image-20230929231952522

现在就可以通过jira账号登录OSSRH包管理网站:https://s01.oss.sonatype.org/

准备jar包,pom.xml文件按照以下两个指南编写:

准备好后,使能编译:

1
mvn clean deploy

java17版本在deploy阶段存在编译错误:selenium webdriver - Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: java.base doesn’t “opens java.util” to unnamed module - Stack Overflow

可采用降版本为java8规避。

如成功,将在OOSRH包管理网站上查询到staging profile信息:

image-20230930004122812

虽然官网写了:Upon release, your component will be published to Central: this typically occurs within 30 minutes, though updates to search can take up to four hours.

实际同步花个更长时间,可能大概两天,终于查到了我们要上传的包:

image-20231001174057638

兼容性结论:

  1. maven central对group id有严格控制,必须要得到group id管理员许可才能够提交进去
  2. 如果想基于已有开源软件(如spark)合入问题修复的版本,如做了兼容性适配完善等,想提交到maven central的话,必定会收到group id权限限制,也即需要社区同意后才能合入,无法自行处理。

自定义maven源

自定义maven源可以使用sonatypes nexus:Nexus!最受欢迎的仓库管理软件 - 知乎 (zhihu.com)

从上一章节讨论:

  1. nexus是介于maven central和本地之间的中转仓库,所有提交的包都会先存在于nexus这里
  2. 有很多包管理网站基于nexus搭建,如OSSRH、apache基金会等

该软件提供了图形化界面来上传包,支持除java以外的各种包类型,如npm等,详细包类型支持见Uploading Components (sonatype.com)

nexus本身是开源的:GitHub - sonatype/nexus-public: Sonatype Nexus Repository Manager; Open-source codebase mirror

go

参考:Using Go Modules - The Go Programming Language

类似maven这种包管理工具在go里面是go mod

go没有像maven一样有统一的中央仓库,go引入mod完全是靠各个包所在的网络链接来include

以k8s为例,k8s仓库中存在一份go.mod,打开可以看到其require方式为url:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// This is a generated file. Do not edit directly.
// Ensure you've carefully read
// https://git.k8s.io/community/contributors/devel/sig-architecture/vendor.md
// Run hack/pin-dependency.sh to change pinned dependency versions.
// Run hack/update-vendor.sh to update go.mod files and the vendor directory.

module k8s.io/kubernetes

go 1.20

require (
bitbucket.org/bertimus9/systemstat v0.5.0
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.29
github.com/Azure/go-autorest/autorest/adal v0.9.23
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab
github.com/Microsoft/go-winio v0.6.0
github.com/Microsoft/hcsshim v0.8.25
...

兼容性结论:

对于兼容性来说,因为go本身没有中央仓库管理,因此如有定制的patch等,在合入go mod官方仓库前是可以通过rpm等系统包管理机制来承载。go本身最终编译生成的文件也是一个标准系统二进制文件。

js

参考:

js的包发布通过npm即可完成,js的包也分两种,私人的和组织的,通过scope的表达方式进行(示例:@xxx/hello-world),这里的scope其实等价于namespace,用于预防和其他同名包冲突。不是所有的包都需要声明scope,比如vue。私人也可以发一些不带scope的包,比如shanglv-utils。

因为在npm发布时要求必须要首先登录npm:npm login,所以不会出现私人包覆盖官方包的情况。

兼容性结论:

npm发布包的机制和python基本一致,对于官方包,当官方包已经占位的情况下,我们无法去覆盖它,如有类型兼容性的patch需要合入,只有一种方式,就是通过包官方仓库接纳。

rust

rust是有中央仓库的:crates.io: Rust Package Registry

ruby

ruby也有中央仓库托管各种包:RubyGems.org

评论