跳到主要内容

格雷斯库尔之力... 我获得了 Conda 配方!

·7 分钟阅读
Marcelo Duarte Trevisani
conda-forge/core 成员

Skeletonr 的主要目标是征服格雷斯库尔。

简介

抛开玩笑,新项目 grayskull 的创建目的是生成更好的 Conda 配方,以便能够正确打包在不同渠道(如 PyPI、CRAN、Conan、GitHub 注册表、GitHub 仓库等)中可用的项目。此外,Grayskull 也在开发中,以帮助 conda-forge 更新配方。

当前状态

目前,Grayskull(版本 0.2.1)能够仅通过查找 PyPI 上的软件包来生成配方,并且它在 PyPIconda-forge 上可用。此软件包的 GitHub 仓库是:marcelotrevisani/grayskull

在 Grayskull 之前,我们只有 conda-build skeleton 来为 PyPI 上的 Python 软件包生成配方。在所有其他方面,与 conda-build skeletongrayskull 相比,生成的配方质量差异很大,生成它们所花费的时间也差异很大。Grayskull 生成配方时会考虑平台、可用的 Python 版本、选择器、编译器(Fortran、C 和 C++)、软件包约束、许可证类型、许可证文件等等。它使用来自多个来源的元数据,力求创建最佳配方。

安装

您可以使用 pipconda 安装 grayskullGrayskull 并不依赖 conda 运行,并且可以使用最少的依赖项生成配方。

使用 conda

Grayskull 在 conda-forge 频道上可用。

conda install -c conda-forge grayskull

使用 pip

pip install grayskull

Grayskull 与 conda-build skeleton 对比

grayskull 和 conda skeleton 生成的配方之间存在一些差异。以 pytest 配方为例,它具有平台选择器、Python 版本约束,以及多个软件包约束。

Grayskull (0.2.1) - 花费 4 秒生成配方

{% set name = "pytest" %}
{% set version = "5.3.5" %}

package:
name: {{ name|lower }}
version: {{ version }}

source:
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
sha256: 0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d

build:
number: 0
skip: true # [py2k]
entry_points:
- pytest=pytest:main
- py.test=pytest:main
script: {{ PYTHON }} -m pip install . -vv

requirements:
host:
- pip
- python
- setuptools >=40.0
- setuptools_scm
run:
- atomicwrites >=1.0 # [win]
- attrs >=17.4.0
- colorama # [win]
- importlib-metadata >=0.12 # [py<38]
- more-itertools >=4.0.0
- packaging
- pathlib2 >=2.2.0 # [py<36]
- pluggy <1.0,>=0.12
- py >=1.5.0
- python
- wcwidth

test:
imports:
- pytest
commands:
- pip check
- pytest --help
- py.test --help
requires:
- pip

about:
home: https://pypi.ac.cn/project/pytest/
summary: 'pytest: simple powerful testing with Python'
dev_url: https://github.com/pytest-dev/pytest
license: MIT
license_file: LICENSE

extra:
recipe-maintainers:
- marcelotrevisani

Skeleton (3.18.11) - 花费 31 秒生成配方

{% set name = "pytest" %}
{% set version = "5.3.5" %}

package:
name: "{{ name|lower }}"
version: "{{ version }}"

source:
url: "https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz"
sha256: 0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d

build:
number: 0
script: "{{ PYTHON }} -m pip install . -vv"

requirements:
host:
- atomicwrites >=1.0
- attrs >=17.4.0
- colorama;sys_platform =="win32"
- importlib-metadata >=0.12
- more-itertools >=4.0.0
- packaging
- pathlib2 >=2.2.0
- pip
- pluggy >=0.12,<1.0
- py >=1.5.0
- python
- wcwidth
run:
- atomicwrites >=1.0
- attrs >=17.4.0
- colorama;sys_platform =="win32"
- importlib-metadata >=0.12
- more-itertools >=4.0.0
- packaging
- pathlib2 >=2.2.0
- pluggy >=0.12,<1.0
- py >=1.5.0
- python
- wcwidth

about:
home: The package home page
license: MIT
license_family: MIT
license_file:
summary: "pytest: simple powerful testing with Python"
doc_url:
dev_url:

extra:
recipe-maintainers:
- your-github-id-here

conda-forge 上 pytest 5.3.5 的原始配方

{% set version = "5.3.5" %}

package:
name: pytest
version: {{ version }}

source:
url: https://pypi.io/packages/source/p/pytest/pytest-{{ version }}.tar.gz
sha256: 0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d

build:
skip: True # [py27]
number: 1
script: "{{ PYTHON }} setup.py install --single-version-externally-managed --record record.txt"
entry_points:
- py.test = py.test:main
- pytest = py.test:main

requirements:
host:
- pip
- python
- setuptools >=40.0
- setuptools_scm
run:
- atomicwrites >=1.0 # [win]
- attrs >=17.4.0
- colorama # [win]
- importlib_metadata >=0.12 # [py<38]
- more-itertools >=4.0
- packaging
- pathlib2 >=2.2.0 # [py<36]
- pluggy >=0.12,<1.0
- py >=1.5.0
- python
- setuptools >=40.0
- wcwidth
run_constrained:
# pytest-faulthandler 2 is a dummy package.
# if an older version of fault-handler is installed, it will conflict with pytest >=5.
- pytest-faulthandler >=2

test:
commands:
- pytest -h
imports:
- pytest

about:
home: https://pytest.cn/en/latest/
license: MIT
license_file: LICENSE
summary: 'Simple and powerful testing with Python.'
description: |
The pytest framework makes it easy to write small tests, yet scales to
support complex functional testing for applications and libraries.
doc_url: https://pytest.cn/en/latest/
dev_url: https://github.com/pytest-dev/pytest/

extra:
recipe-maintainers:
- flub
- goanpeca
- nicoddemus
- ocefpaf
- mingwandroid

主要差异

属性Grayskull (0.2.1)Skeleton (3.18.11)
命令✅ grayskull pypi pytest✅ conda skeleton pypi pytest
时间✅ 4 秒❌ 31 秒
许可证✅ 正确添加了许可证文件和许可证类型❗️ 仅添加了许可证类型
主机需求✅ 正确添加了所有主机需求❌ 它没有正确添加主机依赖项。它添加了不必要的依赖项,并且缺少构建软件包所需的许多依赖项
运行需求✅ 仅从主机需求中缺少 setuptools(但此依赖项未在 pytest 软件包中定义)❌ 向项目添加了不正确的依赖项
选择器✅ 正确跳过 Python 2,并为 Windows 和 Python 版本添加了选择器❌ 它没有添加任何关于选择器的信息。实际上,conda-build 添加了错误的信息,这将导致配方损坏。例如,添加了 'sys_platform == win32',这是 conda 配方的错误格式
入口点✅ 正确添加了所有入口点❌ 没有入口点
可以构建吗?✅ 是❌ 否

noarch: python 的情况下,Grayskull 足够智能,可以检测到配方何时支持它,而 Skeleton 则无法做到这一点。重要的是要强调,Skeleton 也无法检测编译器。尽管如此,Grayskull 始终尝试检测它。

Grayskull (0.2.1) 的用法

项目选项

$ grayskull --help
usage: grayskull [-h] [--version] {pypi} ...

Grayskull - Conda recipe generator

positional arguments:
{pypi} Options to generate PyPI recipes
pypi Generate recipes based on PyPI

optional arguments:
-h, --help show this help message and exit
--version, -v Print Grayskull version and exit
$ grayskull pypi --help
usage: grayskull pypi [-h] [--maintainers MAINTAINERS [MAINTAINERS...]]
[--output OUTPUT]
pypi_packages [pypi_packages ...]

positional arguments:
pypi_packages Specify the PyPI package name.

optional arguments:
-h, --help show this help message and exit
--maintainers MAINTAINERS [MAINTAINERS ...], -m MAINTAINERS [MAINTAINERS...] List of maintainers which will be added to the recipe.
--output OUTPUT, -o OUTPUT Path to where the recipe will be created

要生成配方,您只需调用 grayskull 并传递频道(目前我们仅支持 PyPI,应为 pypi)和软件包名称。您还应该使用 --output-o 选项指定输出文件夹,它将在其中创建软件包文件夹和配方。重要的是要注意,用户可以使用 --maintainers 选项指定将添加到配方中的维护者列表。

pytest 示例

Grayskull CLI

如果您需要指定软件包版本,只需在软件包名称后加上等号,然后在等号后紧跟版本即可。例如

grayskull pypi requests=2.21.0

grayskull pypi requests==2.21.0

Grayskull pinned package -requests

如果您想生成多个配方,只需传递软件包列表,例如

grayskul pypi pytest requests=2.21.0 colorama

未来计划

  • 在下一个主要版本 (1.0.0) 中,计划添加能够加载配方并仅更新其中部分的功能;
  • 使用 CRAN (R) 频道生成 Conda 配方 (2.0.0);
  • 使用 Conan (C++) 频道生成 Conda 配方 (3.0.0);

问题

如有任何问题、疑问或建议,请随时在仓库中提出问题

非常欢迎贡献!:)


这项工作得益于 NumFOCUS 小型开发资助计划。