从源文件获取 conda meta.yaml 的包版本
Get package version for conda meta.yaml from source file
我正在尝试重新组织我的 python 包版本控制,因此我只需要在一个地方更新版本,最好是 python 模块或文本文件。对于我需要我的版本的所有地方,似乎有一种方法可以从源 from mypkg import __version__
加载它,或者至少将它作为文本从文件中解析出来。我似乎无法找到一种方法来使用我的 conda meta.yaml 文件。有没有办法从 meta.yaml 文件中的外部源加载版本?
我知道有 git 环境变量,但我不想标记通过本地 conda 存储库测试的每个 alpha/beta/rc 提交。我可以在 pyyaml 中使用 !!python/object
加载 python 对象,但 conda 不支持任意 python 执行。我看不到任何其他 jinja2 功能可以做到这一点。我也可以写一个脚本来更新多个地方的版本号,但我真的希望只修改一个文件作为最终版本号。感谢您的帮助。
有很多方法可以到达您的端点。这是 conda 本身的作用...
conda 版本信息的真实来源是 conda/__init__.py
中的 __version__
。它可以按照您的建议在 python 代码中以编程方式加载为 from conda import __version__
。它也被硬连接到 setup.py
here (note this code),因此从命令行 python setup.py --version
是获取该信息的规范方式。
在 1.x 版本的 conda-build 中,放置一行
$PYTHON setup.py --version > __conda_version__.txt
in build.sh
将使用我们的真实来源设置构建包的版本。 __conda_version__.txt
文件已弃用,但是,它可能会随着 conda-build 2.0 的发布而被删除。在最新版本的 conda-build 中,执行此操作的首选方法是在 jinja2 上下文中使用 load_setup_py_data()
,这将使您可以访问 setup.py
中的所有元数据。具体来说,在 meta.yaml
文件中,我们会有这样的东西
package:
name: conda
version: "{{ load_setup_py_data().version }}"
现在,__version__
变量是如何在 conda/__init__.py
...
中设置的
你see in the source code is a call to the auxlib.packaging.get_version()
的功能。此函数按顺序执行以下操作
- 首先查找文件
conda/.version
,如果找到 return 则内容作为版本标识符
- 接下来寻找
VERSION
环境变量,如果将 return 值设置为版本标识符
- 最后查看
git describe --tags
输出,如果可能的话 return 版本标识符(必须安装 git,必须是 git 存储库,等等)
- 如果上面的 none 产生版本标识符,return
None
现在还有最后一招。在 conda 的 setup.py
file 中,我们将 build_py
的 cmdclass
和 sdist
设置为 auxlib.packaging
提供的那些。基本上我们有
from auxlib import packaging
setup(
cmdclass={
'build_py': packaging.BuildPyCommand,
'sdist': packaging.SDistCommand,
}
)
这些特殊命令 类 实际上修改了 built/installed 包中的 conda/__init__.py
文件,因此 __version__
变量被硬编码为字符串文字,而不是使用 auxlib.packaging.get_version()
函数。
在您的情况下,不想标记每个版本,您可以使用以上所有内容,并从命令行使用 VERSION
环境变量设置版本。像
VERSION=1.0.0alpha1 conda build conda.recipe
在你的 build
部分 meta.yaml 配方中,你需要添加一个 script_env
键来告诉 conda-build 一路传递 VERSION
环境变量通过构建环境。
build:
script_env:
- VERSION
截至 conda-build-3.16.1
(2018 年 11 月),这里是在 conda 配方中以编程方式设置 version
的有效方法。
这些示例是您传递给 conda-build
的 meta.yaml
的一部分,如 here 所述。
一个。点击 setup.py
的版本:
如果你构建一个 python 包,这个方法是完美的,因为 setup.py
无论如何都需要它,所以你一定已经想到了。
{% set data = load_setup_py_data() %}
package:
name: mypackage
version: {{ data.get('version') }}
请注意,有时您必须明确告诉 conda 配方在哪里可以找到它,如果它与 setup.py
:
不在同一目录中
{% set data = load_setup_py_data(setup_file='../setup.py', from_recipe_dir=True) %}
现在继续:
$ conda-build conda-recipe
乙。 Git 环境变量
如果您的项目在 git 中标记,并且您使用 conda 接受的标记格式作为有效版本号(例如 2.5.1
或 v2.5.1
),则此方法很好。
package:
name: hub
version: {{ GIT_DESCRIBE_TAG }}
现在继续:
$ conda-build conda-recipe
C。传递环境变量:
这个对于非python conda 包很有用,其中的版本来自各种不同的地方,您可以完善它的价值 - 例如将 v2.5.1
转换为 2.5.1
.
package:
name: mypkg
version: {{ environ.get('MYPKG_VERSION', '') }}
然后创建一个获取版本的可执行脚本,我们称之为script-to-get-mypkg-version
现在继续加载将设置版本的环境变量:
$ MYPKG_VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
根据 conda-build 版本,您可能必须使用 os.environ.get
而不是 environ.get
。 docs使用后者。
这行不通
请注意,如果这在过去曾经有效,如 2016 年的一个答案中所述,现在则无效。
package:
name: mypkg
build:
script_env:
- VERSION
$ VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
在这种情况下,conda-build
忽略环境变量 VERSION
。
手动__version__
如果您有单独的 _version.py
版本,则无需加载整个包即可导入。
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.9.post2+g6481728.d20200518.dirty'
在我的例子中,这是自动生成的,但下一步保持不变。
在 __init__.py
你有一行 from ._version import version as __version__
然后在 setup.py
你可以做这样的事情。
这也是我在 sphinx conf.py
中导入版本的方式
source_dir = Path("src/<my_package>")
sys.path.insert(0, str(source_dir))
from _version import version
setup(version=version)
...
或者,您可以尝试手动解析它,而不是导入 _version
文件,这样您就不必向 sys.path
添加任何内容
然后在 meta.yaml
{% set data = load_setup_py_data() %}
{% set version = data.get('version') %}
package:
name: <my_package>
version: {{ version }}
我有相反的问题。我忘记不时更新我的版本,所以一直在寻找一种方法将 git
存储库作为包版本的单一来源。我用了 setuptools_scm
我已经尝试了很多东西,有和没有 pep517 兼容 pyproject.toml
等等,但最终,这是适合我的。
这样做的好处是您不需要那么大 versioneer.py
,但它会在构建时写入 _version.py
setup.py
from setuptools import setup
import setuptools_scm
def my_local_scheme(version: setuptools_scm.version.ScmVersion) -> str:
"""My local node and date version."""
node_and_date = setuptools_scm.version.get_local_node_and_date(version)
dirty = ".dirty" if version.dirty else ""
return str(node_and_date) + dirty
version = setuptools_scm.get_version(
write_to="src/<my_package>/_version.py",
version_scheme="post-release",
local_scheme=my_local_scheme,
)
setup(version=version,)
其余 setup()
元数据和选项在 setup.cfg
中。需要的是:
[options]
package_dir=
=src
packages = <my_package>
install_requires = setuptools_scm
src/<my_package>/_version.py
生成:
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.3.post0+g887e418.d20200518.dirty'
然后我将它添加到我的 .gitignore
src/<my_package>/__init__.py
"""<package_description>"""
from ._version import version as __version__
meta.yaml
{% set data = load_setup_py_data() %}
{% set version = data.get('version') %}
package:
name: capacity_simulation
version: {{ version }}
source:
path: .
build:
noarch: python
number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }}
script: python -m pip install --no-deps --ignore-installed .
include_recipe: False
requirements:
build:
- setuptools_scm
...
pyproject.toml
也可以使用pip wheel .
您需要 pyproject.toml
中的此部分
[build-system]
requires = ["setuptools>=34.4", "wheel", "setuptools_scm"]
build-backend = "setuptools.build_meta"
我正在尝试重新组织我的 python 包版本控制,因此我只需要在一个地方更新版本,最好是 python 模块或文本文件。对于我需要我的版本的所有地方,似乎有一种方法可以从源 from mypkg import __version__
加载它,或者至少将它作为文本从文件中解析出来。我似乎无法找到一种方法来使用我的 conda meta.yaml 文件。有没有办法从 meta.yaml 文件中的外部源加载版本?
我知道有 git 环境变量,但我不想标记通过本地 conda 存储库测试的每个 alpha/beta/rc 提交。我可以在 pyyaml 中使用 !!python/object
加载 python 对象,但 conda 不支持任意 python 执行。我看不到任何其他 jinja2 功能可以做到这一点。我也可以写一个脚本来更新多个地方的版本号,但我真的希望只修改一个文件作为最终版本号。感谢您的帮助。
有很多方法可以到达您的端点。这是 conda 本身的作用...
conda 版本信息的真实来源是 conda/__init__.py
中的 __version__
。它可以按照您的建议在 python 代码中以编程方式加载为 from conda import __version__
。它也被硬连接到 setup.py
here (note this code),因此从命令行 python setup.py --version
是获取该信息的规范方式。
在 1.x 版本的 conda-build 中,放置一行
$PYTHON setup.py --version > __conda_version__.txt
in build.sh
将使用我们的真实来源设置构建包的版本。 __conda_version__.txt
文件已弃用,但是,它可能会随着 conda-build 2.0 的发布而被删除。在最新版本的 conda-build 中,执行此操作的首选方法是在 jinja2 上下文中使用 load_setup_py_data()
,这将使您可以访问 setup.py
中的所有元数据。具体来说,在 meta.yaml
文件中,我们会有这样的东西
package:
name: conda
version: "{{ load_setup_py_data().version }}"
现在,__version__
变量是如何在 conda/__init__.py
...
你see in the source code is a call to the auxlib.packaging.get_version()
的功能。此函数按顺序执行以下操作
- 首先查找文件
conda/.version
,如果找到 return 则内容作为版本标识符 - 接下来寻找
VERSION
环境变量,如果将 return 值设置为版本标识符 - 最后查看
git describe --tags
输出,如果可能的话 return 版本标识符(必须安装 git,必须是 git 存储库,等等) - 如果上面的 none 产生版本标识符,return
None
现在还有最后一招。在 conda 的 setup.py
file 中,我们将 build_py
的 cmdclass
和 sdist
设置为 auxlib.packaging
提供的那些。基本上我们有
from auxlib import packaging
setup(
cmdclass={
'build_py': packaging.BuildPyCommand,
'sdist': packaging.SDistCommand,
}
)
这些特殊命令 类 实际上修改了 built/installed 包中的 conda/__init__.py
文件,因此 __version__
变量被硬编码为字符串文字,而不是使用 auxlib.packaging.get_version()
函数。
在您的情况下,不想标记每个版本,您可以使用以上所有内容,并从命令行使用 VERSION
环境变量设置版本。像
VERSION=1.0.0alpha1 conda build conda.recipe
在你的 build
部分 meta.yaml 配方中,你需要添加一个 script_env
键来告诉 conda-build 一路传递 VERSION
环境变量通过构建环境。
build:
script_env:
- VERSION
截至 conda-build-3.16.1
(2018 年 11 月),这里是在 conda 配方中以编程方式设置 version
的有效方法。
这些示例是您传递给 conda-build
的 meta.yaml
的一部分,如 here 所述。
一个。点击 setup.py
的版本:
如果你构建一个 python 包,这个方法是完美的,因为 setup.py
无论如何都需要它,所以你一定已经想到了。
{% set data = load_setup_py_data() %}
package:
name: mypackage
version: {{ data.get('version') }}
请注意,有时您必须明确告诉 conda 配方在哪里可以找到它,如果它与 setup.py
:
{% set data = load_setup_py_data(setup_file='../setup.py', from_recipe_dir=True) %}
现在继续:
$ conda-build conda-recipe
乙。 Git 环境变量
如果您的项目在 git 中标记,并且您使用 conda 接受的标记格式作为有效版本号(例如 2.5.1
或 v2.5.1
),则此方法很好。
package:
name: hub
version: {{ GIT_DESCRIBE_TAG }}
现在继续:
$ conda-build conda-recipe
C。传递环境变量:
这个对于非python conda 包很有用,其中的版本来自各种不同的地方,您可以完善它的价值 - 例如将 v2.5.1
转换为 2.5.1
.
package:
name: mypkg
version: {{ environ.get('MYPKG_VERSION', '') }}
然后创建一个获取版本的可执行脚本,我们称之为script-to-get-mypkg-version
现在继续加载将设置版本的环境变量:
$ MYPKG_VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
根据 conda-build 版本,您可能必须使用 os.environ.get
而不是 environ.get
。 docs使用后者。
这行不通
请注意,如果这在过去曾经有效,如 2016 年的一个答案中所述,现在则无效。
package:
name: mypkg
build:
script_env:
- VERSION
$ VERSION=`script-to-get-mypkg-version` conda-build conda-recipe
在这种情况下,conda-build
忽略环境变量 VERSION
。
手动__version__
如果您有单独的 _version.py
版本,则无需加载整个包即可导入。
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.9.post2+g6481728.d20200518.dirty'
在我的例子中,这是自动生成的,但下一步保持不变。
在 __init__.py
你有一行 from ._version import version as __version__
然后在 setup.py
你可以做这样的事情。
这也是我在 sphinx conf.py
source_dir = Path("src/<my_package>")
sys.path.insert(0, str(source_dir))
from _version import version
setup(version=version)
...
或者,您可以尝试手动解析它,而不是导入 _version
文件,这样您就不必向 sys.path
然后在 meta.yaml
{% set data = load_setup_py_data() %}
{% set version = data.get('version') %}
package:
name: <my_package>
version: {{ version }}
我有相反的问题。我忘记不时更新我的版本,所以一直在寻找一种方法将 git
存储库作为包版本的单一来源。我用了 setuptools_scm
我已经尝试了很多东西,有和没有 pep517 兼容 pyproject.toml
等等,但最终,这是适合我的。
这样做的好处是您不需要那么大 versioneer.py
,但它会在构建时写入 _version.py
setup.py
from setuptools import setup
import setuptools_scm
def my_local_scheme(version: setuptools_scm.version.ScmVersion) -> str:
"""My local node and date version."""
node_and_date = setuptools_scm.version.get_local_node_and_date(version)
dirty = ".dirty" if version.dirty else ""
return str(node_and_date) + dirty
version = setuptools_scm.get_version(
write_to="src/<my_package>/_version.py",
version_scheme="post-release",
local_scheme=my_local_scheme,
)
setup(version=version,)
其余 setup()
元数据和选项在 setup.cfg
中。需要的是:
[options]
package_dir=
=src
packages = <my_package>
install_requires = setuptools_scm
src/<my_package>/_version.py
生成:
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.0.3.post0+g887e418.d20200518.dirty'
然后我将它添加到我的 .gitignore
src/<my_package>/__init__.py
"""<package_description>"""
from ._version import version as __version__
meta.yaml
{% set data = load_setup_py_data() %}
{% set version = data.get('version') %}
package:
name: capacity_simulation
version: {{ version }}
source:
path: .
build:
noarch: python
number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }}
script: python -m pip install --no-deps --ignore-installed .
include_recipe: False
requirements:
build:
- setuptools_scm
...
pyproject.toml
也可以使用pip wheel .
您需要 pyproject.toml
[build-system]
requires = ["setuptools>=34.4", "wheel", "setuptools_scm"]
build-backend = "setuptools.build_meta"