努力和上进,不是为了做给别人看,是为了不辜负自己,不辜负此生。
pbr库是一个使用统一方式管理setuptools包的库。pbr库通过一个setup钩子函数读取并过滤setup.cfg中的数据,以填充默认值并提供更多合理的操作;然后将结果作为参数返回给setup.py。因此,处理Python包安装的大量繁重工作仍然交给setuptools包处理,pbr只为setuptools读取和过滤所需要的参数即可。需要注意的是,pbr并不支持setuptools的easy_install功能,尽管pbr依赖setup_requires,但对于install_requires还是需要手动或使用pip进行安装。本文将详细分析pbr的实现原理和使用方法。
pbr的使用场景
目前,pbr可以实现很多功能,主要包括以下几个方面:
- version:基于git的修订版本和标签来管理版本号;
- AUTHORS:从git log命令生成AUTHORS文件;
- ChangeLog:从git log命令生成ChangeLog文件;
- Manifest:从git文件和一些标准文件中生成一个合理的Manifest清单;
- Sphinx Autodoc:为整个模块生成autodoc存根文件;
- Requirements:将依赖库保存在一个pip的requirements文件中;
- long_description:使用README文件作为一个库的描述信息;
- Smart find_packages:在根目录下智能找到相应的软件包。
pbr的实现原理
hook的实现
本文开始介绍pbr会通过一个setup钩子函数读取并过滤setup.cfg文件中的数据,因此本文首先就来介绍一下pbr的hook函数的实现。pbr的hook函数的实现都放在pbr.hooks中,首先pbr创建了一个配置基类BaseConfig,该类中首先定义了一个钩子方法hook()的空实现,然后定义了一个save()方法保存配置信息,最后定义了一个模板方法run()。在这个模板方法中,首先调用hook()方法过滤读取到的配置信息,然后调用save()方法保存过滤后的配置信息。因此,在实现具体的配置实体时,需要重写hook()和save()方法。而pbr的hook函数的实现主要包括以下几个:
- MetadataConfig类:该类获取setup.cfg文件中section为metadata的配置信息,即获取待安装的包的元数据,包括其名称、版本、描述等信息;
- CommandsConfig类:该类获取setup.cfg文件中section为global的配置信息,即获取一些安装命令对应的程序;
- FilesConfig类:该类获取setup.cfg文件中section为files的配置信息,即获取对应的包与配置文件路径等;
- BackwardsCompatConfig类:该类获取setup.cfg文件中section为backwards_compat的配置信息,即获取依赖相关的配置信息。
为了使用这些钩子函数获取对应的配置信息,pbr在pbr.hooks模块下定义了setup_hooks()方法调用了上述这些钩子函数。
1 | from pbr.hooks import backwards |
pbr的实现
上面介绍了pbr中定义的钩子函数,接下来将会结合钩子函数讨论pbr的实现。使用pbr安装包的实现主要放在pbr.core模块中,在该模块中主要定义了一个pbr(dist, attr, value)方法来获取安装时所需要的参数。在使用中,除了setup_requires外,pbr方法应该是setup()方法的唯一参数。该方法首先获取setup.cfg文件的路径,然后会调用pbr.util模块中的cfg_to_args(path=’setup.cfg’, script_args=())方法获取setuptools所需的配置参数。
cfg_to_args(path=’setup.cfg’, script_args=())方法则是通过配置的setup_hooks()方法读取setup.cfg文件中的配置信息,除了使用hook函数外,该方法还对一些可选配置项进行了读取,如entry_endpoints等,然后将结果作为参数返回给setup()方法进行软件包安装操作。
当然,除了实现pbr功能外,针对第1节中提到的使用场景,pbr库都有相应的实现,在此不再作过多分析,感兴趣的朋友可以参考 pbr官方文档。
pbr的使用
pbr的实现非常简单,这里以nova组件的setup为例简单介绍一下pbr的使用。通过上述分析,我们知道使用pbr,首先需要一个setup.cfg配置文件,nova组件的setup.cfg配置文件内容如下所示:
1 | [metadata] |
接下来,只需要添加一个setup.py安装脚本即可。
1 | import setuptools |
在这个脚本中,主要调用了setuptools.setup()方法,需要注意的是,在这个方法中,设置了pbr=True的参数,这就是说在使用setuptools进行安装时,会调用pbr.pbr()方法通过hook函数获取setup.cfg中的配置参数。
最后执行如下命令就可以执行安装了:
1 | python setup.py install |