Python 构建工具 zc.buildout

Reproduced from:

  • python项目构建工具zc.buildout
  • 用Buildout来构建Python项目
  • Python 构建工具 buildout 的介绍与使用

Introduction

Buildout 是一个基于 Python 的自动化构建工具,由 Zope 团队开发维护,包名为 zc.buildout。

Buildout 主要是为了解决两个问题:

  • 中心化的应用组装和部署
  • 重复的从 Python 软件发布中组装项目

通过配置文件 buildout.cfg,可以从多个部分创建,组装,并部署你的应用,能够构建一个封闭隔离的开发环境。(封闭隔离的特性类似于 virtualenv,但二者不同,Buildout 支持的功能更便于自动化构建。)(即使应用包含了非 Python 的组建,Buildout 也能胜任。)

Install

pip3 install zc.buildout

Initialization

创建一个项目目录后,在项目目录中,使用 Buildout 初始化:

buildout init

使用 tree 查看 buildout 后的目录结构:创建了目录 binpartseggsdevelop-eggs,在 bin 目录下生成了 buildout 脚本。

Python 构建工具 zc.buildout_第1张图片
buildout 后的目录结构

├── bin
│   └── buildout
├── buildout.cfg
├── develop-eggs
│   ├── zc.buildout.egg-link
├── eggs
└── parts
  • bin 目录用来存放生成的脚本文件;
  • parts 目录存放生成的数据,大多用不上;
  • develop-eggs 存放指向开发目录的链接文件,和 buildout.cfgdevelop 选项相关;
  • eggs 是存放从网络上下载下来的包,并打包成 egg,这些包一般在 buildout.cfg 中的 egg 选项里定义。

Configuration

配置 buildout.cfg 文件

[buildout] # 脚本入口
develop = .
# index = 
newest = false
update-versions-file = versions.cfg
extends = versions.cfg
relative-paths = true
show-picked-versions = true  # 显示所安装的版本
versions = versions
parts = app
  test
  gen-thrift

[app] # 编写子函数app的逻辑
recipe = zc.recipe.egg  # 除了 recipe 其他都是选项都被认为是 recipe 的参数
interpreter = python
eggs =  pandas #需要安装的依赖
  ipython
extra-paths = ${buildout:directory}/gen-py

[test]
recipe = pbp.recipe.noserunner
eggs = ${app:eggs}
       coverage
       boring
defaults = -vd --with-coverage --with-xunit --cover-xml --cover-package=my_project --boring
extra-paths = ${buildout:directory}/gen-py

配置使用的是 INI file format。

  • [buildout] 这是个必须的 section 块
    • develop 用来管理开发库的,一般不需要配置。这里配置 . 符号,在执行 buildout 命令的时候生成的 develop-eggs 文件夹将会是一个空的。
    • newest 这个参数默认是 true,如果是 true,那么会在 buildout 的时候总是检查最新版本,如果为 false 只有在包不满足需求的时候才会去更新版本。
    • update-version-file 指定一个包依赖的更新文件,一般使用 versions.cfg 来保存需要的依赖。
    • extended 扩展配置的指定
    • relative-path 启用相对路径
    • show-picked-versions 默认是 false,如果为 true,当 buildout 在找到一个最新的发布版本而且满足 requirement 申明的时候,将会重新写一条配置进 versions.cfg 文件,也就是说 update-versions-file 配置的文件中,格式类似于这种:
      # Required by:
      # opentracing==1.0rc3
      futures = 3.0.5
      
    • versions 默认就是 versions,更详细参考 Pinned versions
    • parts parts 用来指定构建什么。每个 buildout 都要有一个 parts 列表,也可以为空。如果 parts 中指定的段中还有 parts 的话,会递归构建。
  • [app]
    • recipes 每个 section 都必须包含一个 recipe 的项目,这个项目用来声明自己使用了什么工具,各种其他的包在 pypi 上都能下载到,各有不同的用处。也许可以将它理解成使用不用的插件。最常使用的是 zc.recipe.egg 这个 recipe,它可以被用来安装各种各样的包,并且打包成 egg 放到 eggs 目录中;
    • interpreter 安装解释器,会创建一个包含 eggs 和依赖关系的环境在 bin 目录下;
    • eggs 一个需要被安装的依赖的 list;
    • extra-paths 需要编译出应用之后应该被加入 sys.path 的路径。

Buildout

buildout 的流程,先调用 [buildout],然后发现 parts 中的 app 这个子函数逻辑,app 中除了 recipe,其他都被认为是 recipe 的参数,当调用 eggs 时,buildout 发现这些包没有被安装,于是自动安装包并存放在 eggs 目录下。

  • buildout 会在 eggs 目录下安装 pandas, ipython
  • bin 目录下生成一系列可执行文件,此时如果想解释任务 python 脚本,都必须执行 bin/python xxx.py(即当前 buildout 的 bin 目录中的 python 解释器)
  • 每个可执行文件中的 sys 路径都发生改变,都会优先读取 eggs 下的三方包

Buildout With setup.py

将 setup.py 中填写的 name 项对应的值,填写到 eggs 中,在 buildout 时会自动加载 setup.py 中的配置。

Create setup.py

setup.py 中填写的 name 项对应的值,填写的 eggs 中,则在 buildout 时会自动加载 setup.py 中的配置。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

fromsetuptoolsimportsetup, find_packages
 
setup(
    name='credit',  # 此处填写包名
    version='0.0.1',
    author='Roy Tien',
    author_email='[email protected]',
    description='This is just a test',
    license='PRIVATE',
    keyword='credit',
    packages=find_packages('apps'),
    install_requires=[
        'redis',  # 此处填写需要的包
        'arrow',
    ],
)

更新 buildout.cfg 文件

[buildout]
develop = .
show-picked-versions = true
parts = app

[app]
recipe = zc.recipe.egg
interpreter = python
eggs = ipython
    credit

再次执行 buildout,会解析 setup.py 的数据,并安装 install_requires 中填写的所有包,并且会通过 packages=find_packages 将目前目录加入到 sys.path

之后需要使用当前目录 bin 下的可执行文件 python 来运行代码 bin/python show_path.py

# show_path.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

if__name__ =='__main__':
    print(sys.path)

通过运行结果可以看到:

  1. 首先会搜索当前目录下的包(使用当前路径下的解释钱,自然排在最前面);
  2. 然后会搜索 eggs 目录下由 buildout 安装的包,这就是 buildout 的作用:优先加载当前目录 eggs 下的包(当前路径的包排在前面);
  3. 最后会搜索系统中的包,可以看到并没有完全隔离系统中的包

开发环境 + 生产环境

可以创建多个配置文件,将 prod.cfg 作为生产环境的配置,将 dev.cfg 作为开发环境的配置,使用 extends 来区分。

[buildout] 
extends = dev.cfg 

开发环境 VS 生产环境
我们可以创建多个配置文件, 比如把buildout.cfg作为生产环境的配置, 把develop的配置从buildout.cfg删除, 创建一个development.cfg作为开发环境的配置:

完全隔离的开发环境

工具:

  • setuptools
  • zc.buildout
  • virtualenv / pipenv

创建完全隔离的开发环境

  • 创建空的项目文件
  • virtualenv / pipenv 创建一个虚拟环境;
  • 使用 buildout 配置开发需求;
  • setup.py 集成测试,开发,发布于一体。

你可能感兴趣的:(Python 构建工具 zc.buildout)