我们有一个大型遗留项目,其中包含一些python代码,项目中所有组件的版本都是由构建项目的构建系统在运行时设置的。我们现在需要用其他组件使用的相同版本来打包python代码
包当前使用以下命令python setup.py bdist_wheel
存档,没有版本控制。
问题是如何在构建时将动态版本传递给setup.py命令。类似于:
python setup.py --version x.x.x bdist_wheel
有几个选项可以用新版本覆盖像version.py
或version.txt
这样的版本文件,然后在setup.py
文件中使用它,但假设我们不能在构建过程中添加更多步骤,只能修改构建命令和python文件,如何做到这一点?
附加要求:
- 如果没有传递版本,则应使用默认值
- 该版本应该在python代码中可用(就像在
__init__.py
中将其作为__version__
参数一样( - 如果可能,应支持使用
setup.cfg
或pyproject.toml
进行元数据配置
如果您选择只使用setup.py
并排除pyproject.toml
和setup.cfg
,您可以使用Python代码以任何您喜欢的方式检索包的版本。例如,您可以通过读取setup.py
脚本中的环境变量(例如EXAMPLE_VERSION
(来获得版本:
import os
import setuptools
from packaging.version import Version
# Try to read version string from env variable
# Default to 0.0.0.dev0 to allow for installs through `pip install -e .`
version_string = os.environ.get("EXAMPLE_VERSION", "0.0.0.dev0")
version = Version(version_string)
setuptools.setup(
name="package-name",
version=str(version),
description="description",
long_description="long_description",
install_requires=[],
)
代码来源于此要点。
运行
EXAMPLE_VERSION="0.1.0" python setup.py bdist_wheel
构建distpackage_name-0.1.0-py3-none-any.whl
但是,如果您希望该版本在模块的__init__.py
文件中的变量__version__
中可用,则在运行setup.py
脚本时需要动态更新此变量的值。这里有一个例子:
import os
import re
from pathlib import Path
import setuptools
from packaging.version import Version
init_file = Path(__file__).parent.absolute() / "src/my_module/__init__.py"
# Try to read version string from env variable
# Default to 0.0.0.dev0 to allow for installs through `pip install -e .`
version_string = os.environ.get("EXAMPLE_VERSION", "0.0.0.dev0")
version = Version(version_string)
print(f"### NEW_VERSION: {version} ###")
try:
# read __init__.py file
with open(init_file, "r") as f:
file_contents = f.read()
# replace __version__ = "0.0.0" string
new_version_string = f'__version__ = "{version}"'
new_contents = re.sub(r'^__version__ = ".+"$', new_version_string, file_contents)
# write content to __init__.py file again
with open(init_file, "w") as f:
f.write(new_contents)
setuptools.setup(
name="package-name",
package_dir={"": "src"},
packages=["my_module"],
version=str(version),
description="description",
long_description="long_description",
install_requires=[],
)
finally:
with open(init_file, "w") as f:
f.write(file_contents)
运行
EXAMPLE_VERSION="0.2.0" python setup.py bdist_wheel
将使用0.2.0版本构建bdist_wheel。在此之前,将更新__init__.py
中的__version__
变量。在执行setuptools.setup
命令之后,__init__.py
的内容被恢复。请注意,我假设这里是src布局。
我还没有玩过pyproject.toml
或setup.cfg
配置文件,但将自己限制为仅使用setup.py
可以编写您想要的代码。