背景
公司本来有两个模块:emei和pythoncommon。emei是个标准的pypi模块,它依赖了很多其他模块,在当初开发emei时,开发那边用pip安装和这些所依赖的模块(site-packages文件夹下)。然后把site-packages文件夹下这些东西都复制进了pythoncommon,当成了另一个模块。由于emei是标准模块,运维那边都是pip install安装它;pythoncommon不是标准模块,所以运维总是执行里面build.sh脚本,在linux上复制这些依赖到服务器的python下的site-packages。
对于项目标准化来说,这是割裂的行为。任何python模块的安装我们并不希望又是pip install,又是复制粘贴依赖。所以,需要改造一下pythoncommon。后续我们只要打包emei是设置好它依赖了pythoncommon,安装emei自然会拉取pythoncommon下来。
改造前
以这次要改造的pythoncommon模块为例,在gitlab上拉去下来的源码层级结构如下,里面的pythoncommon和pythoncommon2两个文件夹并不是子模块,而是存放了开发其他pypi模块时所安装的依赖,这些依赖也仅仅是但是开发那边直接从site-packages文件夹下直接复制的过来的,所以pythcommon模块并没有一个模块的结构,也无法在打包后正常拉取下来。
改造方式
打包的层级:所有源码都放在pythoncommon下
(1)源码根目录下(pythoncommon下)增加_init_.py,内容可以为空,以此来声明这是一个模块(必须的,不然拉取不下来,因为不认为是个模块)
(2)打包路径下(pythoncommon同级目录)增加MANIFEST.in,声明打包时需要额外打包进去的非py文件(因为打包默认会忽略非py文件)
global-include pythoncommon/* *
(3)打包路径下(pythoncommon同级目录)增加setup.py,声明打包的操作
from setuptools import setup, find_packages
setup(
name="rcos-pythoncommon",
version="2.0.0",
keywords=("test", "common"),
description="python common for rccp",
long_description="python common for rccp",
license="Licence",
url="http://test.com",
author="yehao",
author_email="yehao@ruijie.com.cn",
packages=find_packages(exclude=['rcos_pythoncommon.egg-info', 'dist','build']),
include_package_data=True, # 和MANIFEST.in配合使用
platforms="any",
install_requires=[]
)
打包并推送
因为改造后pythoncommon声明为一个模块,也有了模块的层级了。但是它内部结构仍然是site-packages复制过来的。所以,打包时达成tar就好,二进制包是打不了的。
python setup.py sdist
使用twine推送
twine upload dist/*
拉取
由于我们只推送了tar包,pip install在安装tar时除了会解压源码到site-packages,也会额外对这些源码进行编译生成二进制。所以在编译时会报错,但不影响安装,因为我们只需要拉取下来源码就好。
pip install rcos-pythoncommon==2.0.0
复制pth文件
最后我们安装完源码后,对于python来说,它认为pythoncommon是一个模块,但它其实是额外的一个site-packages(毕竟它是开发那边直接复制过来的)。所以我们需要把pythoncommon的路径添加到模块库路径下。
复制源码内的pythoncommon.pth到python的site-packages下(pth文件只会在site-packages下被读取生效)。文件内指定好pythcommon的路径,如下:
./pythoncommon./pythoncommon
./pythoncommon./pythoncommon/ovirt_provider_ovn
./pythoncommon./pythoncommon/docker-4.2.0-py3.6.egg
./pythoncommon./pythoncommon/chardet-3.0.4-py3.6.egg
./pythoncommon./pythoncommon/setproctitle
./pythoncommon./pythoncommon/etcd3-0.12.0-py3.6.egg
./pythoncommon./pythoncommon/six-1.15.0-py3.6.egg
./pythoncommon./pythoncommon/protobuf-4.0.0rc2-py3.6.egg
我们也可以执行如下,看看sys.path是否有新增的pythcommon路径
import sys
print(sys.path)
评论区