Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Make it possible to include the recipe.yaml inside a pyproject.toml #345

Merged
merged 2 commits into from
May 8, 2023

Conversation

moqmar
Copy link
Contributor

@moqmar moqmar commented May 5, 2023

Instead of having a separate recipe.yaml (which since boa is now valid YAML), this makes it possible to represent a recipe directly inside a pyproject.toml file, which makes it a lot more streamlined to build internal packages where code & recipe are not separated from each other.

This is further explained in and closes #323, and implements only the second example - a load_toml() function might be nice as well, but as there's currently AFAIK also not a ``load_yaml()` function anymore in boa due to the new spec, I decided not to pusue that approach further.

@wolfv
Copy link
Member

wolfv commented May 5, 2023

Wow, do you have an example file? Would love to see this :)

@moqmar
Copy link
Contributor Author

moqmar commented May 8, 2023

This would be a simple example for a package that builds with both pip and conda from a single pyproject.toml:

[project]
name = "example_package"
version = "1.1.0"
description = "Basic skeleton of a Conda package"
license = { file = "LICENSE" }
[project.urls]
documentation = "http://example.org"
[[project.maintainers]]
email = "someone@example.org"

[build-system]
requires = [ "setuptools >= 40.9.0", "wheel" ]
build-backend = "setuptools.build_meta"

[tool.setuptools]
packages = ["example_package"]

[tool.setuptools.package-data]
example_package = ["*.dll", "assets/**"]

[project.scripts]
example_package = "example_package.__main__:main"

# ↑↑↑ for "pip install" ↑↑↑
# ↓↓↓  for "boa build"  ↓↓↓

[tool.boa.package]
name = "{{ pyproject.project.name }}"
version = "{{ pyproject.project.version }}"

[tool.boa.about]
summary = "{{ pyproject.project.description }}"
dev_url = "mailto:{{ pyproject.project.maintainers[0].email }}"
doc_url = "{{ pyproject.project.urls.documentation }}"
license_file = "{{ pyproject.project.license.file }}"

[tool.boa.source]
path= "."

[tool.boa.build]
script = ["python -m pip install --ignore-installed --no-deps ."]
number = 0
noarch = "python"

[tool.boa.requirements]
host = [
    "python >=3.10",
    "pip"
]
run = [
    "python >=3.10",
    "numpy",
    "pyyaml"
]

[tool.boa.test]
imports = [
    "{{ pyproject.project.name }}",
]

@dhirschfeld
Copy link
Contributor

Just kicking the tyres on this one and running into:

Traceback (most recent call last):
  File "/opt/mambaforge/envs/bin/bin/boa", line 10, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/mambaforge/envs/bin/lib/python3.11/site-packages/boa/cli/boa.py", line 244, in main
    run_build(args)
  File "/opt/mambaforge/envs/bin/lib/python3.11/site-packages/boa/core/run_build.py", line 502, in run_build
    all_recipes = find_all_recipes(args.target, config, is_pyproject_recipe)  # [noqa]
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/mambaforge/envs/bin/lib/python3.11/site-packages/boa/core/run_build.py", line 53, in find_all_recipes
    yml = render(fn, config=config, is_pyproject_recipe=is_pyproject_recipe)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/mambaforge/envs/bin/lib/python3.11/site-packages/boa/core/render.py", line 177, in render
    ydoc = tomllib.load(fi)
           ^^^^^^^^^^^^^^^^
  File "/opt/mambaforge/envs/bin/lib/python3.11/tomllib/_parser.py", line 63, in load
    raise TypeError(
TypeError: File must be opened in binary mode, e.g. use `open('foo.toml', 'rb')`

...which looks like it's complaining about:

with open(recipe_path, "r") as fi:

@dhirschfeld
Copy link
Contributor

Out of interest I patched it to try and parse the dependencies:

[tool.boa.requirements]
host = "{{ pyproject.project.optional_dependencies.host }}"
run = "{{ pyproject.project.dependencies }}"
{
    'requirements': {'host': "['hatchling', 'hatch-vcs', 'pip']", 'run': "['click>=8.1.3', 'msgspec>=0.15.1', 'numpy', 'pandas>=1.5.3', 'sortedcontainers>=2.4']"},
}

But they get converted to a string, so I'm not sure if there's a way around that.

@moqmar
Copy link
Contributor Author

moqmar commented Jun 26, 2023

Yeah, I saw that error too with Python >= 3.11, will need to create another PR for that.

Regarding the dependencies: pip unfortunately as far as I know requires there to not be a space ("python>3.10"), while conda requires the space ("python >3.10"). So, it's not an easy task to re-use those.

Regarding the string conversion, I believe that is basically #329.

@dhirschfeld
Copy link
Contributor

The problem of variables always being interpreted as strings, even if they're supposed to be arrays - e.g.

host = "{{ pyproject.project.optional_dependencies.host }}"

Gets rendered as a string representation of an array:

{
  "host": "['hatchling', 'hatch-vcs', 'pip']"
}

could perhaps be solved similarly to GitHub actions where they use a fromJson function to convert a string to a structured data type.

i.e.

host = fromJson("{{ pyproject.project.optional_dependencies.host }}")

would get rendered as:

{
  "host": ["hatchling", "hatch-vcs", "pip"]
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: integration with pyproject.toml
3 participants