簡體   English   中英

從源文件中獲取 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-build-3.16.1 (2018 年 11 月)開始,這里是在 conda 配方中以編程方式設置version的方法。

這些例子的一部分meta.yaml你傳遞給conda-build ,作為解釋在這里

A. 進入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

B. Git 環境變量

如果您的項目在 git 中標記,並且您使用 conda 接受作為有效版本號的標記格式(例如2.5.1v2.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 文檔使用后者。


這不起作用

請注意,如果這在過去有效,如 2016 年的一個答案中所述,現在就行不通了。

package:
  name: mypkg
build:
  script_env:
    - VERSION

$ VERSION=`script-to-get-mypkg-version` conda-build conda-recipe

在這種情況下, conda-build忽略 env var VERSION

來源

有很多方法可以到達終點。 這就是 conda 本身所做的......

__version__版本信息的真實來源是__version__ conda/__init__.py 它可以按照您的建議在 python 代碼中以編程方式加載,如from conda import __version__ 它也被硬連接到setup.py此處(也請注意此代碼),因此從命令行python setup.py --version是獲取該信息的規范方式。

在 conda-build 的 1.x 版本中,放置一行

$PYTHON setup.py --version > __conda_version__.txt

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設置__version__變量...

在源代碼中看到的是對auxlib.packaging.get_version()函數的調用。 此函數按順序執行以下操作

  1. 首先查找文件conda/.version ,如果找到則返回內容作為版本標識符
  2. 接下來查找VERSION環境變量,如果設置,則返回值作為版本標識符
  3. 最后查看git describe --tags輸出,並在可能的情況下返回版本標識符(必須安裝 git,必須是 git repo 等)
  4. 如果以上都沒有產生版本標識符,則返回None

現在還有一個最后的技巧。 在康達的setup.py文件中,我們設置cmdclassbuild_pysdist到規定的那些auxlib.packaging 基本上我們有

from auxlib import packaging
setup(
    cmdclass={
        'build_py': packaging.BuildPyCommand,
        'sdist': packaging.SDistCommand,
    }
)

這些特殊的命令類實際上會修改內置/安裝包中的__version__ conda/__init__.py文件,因此__version__變量被硬編碼為字符串文字,並且不使用auxlib.packaging.get_version()函數。


在您的情況下,不想標記每個版本,您可以使用上述所有內容,並從命令行使用VERSION環境變量設置版本。 類似的東西

VERSION=1.0.0alpha1 conda build conda.recipe

在您的build部分 meta.yaml 配方中,您需要添加一個script_env鍵來告訴script_env -build 將VERSION環境變量一直傳遞到構建環境。

build:
  script_env:
    - 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導入版本的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

我已經嘗試了很多東西,有和沒有符合pyproject.toml等等,但最終,這對我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.cfg的其余setup()元數據和選項。 需要存在的一個是:

[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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM