Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ and this project adheres to

### Added

- build::
- build:
- Support setuptools.packages.find.where directive in setup converter.
- Support setuptools.data-files directives in setup converter.

### Changed

- build: Make `authors` optional in setup converter (omit `author` and
`author_email` when not specified).

## [1.8.0] - 2026-05-22

### Added
Expand Down
6 changes: 4 additions & 2 deletions src/build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ arguments:
| Source | `setup()` argument |
|--------|-------------------|
| `[project]` `name`, `version` | `name`, `version` |
| `[project]` `authors[0]` | `author`, `author_email` |
| `[project]` `authors[0]` (optional) | `author`, `author_email` (each only when present) |
| `[project]` `scripts` | `entry_points["console_scripts"]` |
| `[project]` `dependencies` | `install_requires` |
| `[project]` `optional-dependencies` | `extras_require` |
Expand Down Expand Up @@ -116,7 +116,9 @@ The converter is intentionally minimal. It does **not** map many common
- `[tool.setuptools]` `package-dir` as an explicit pyproject key (only inferred from
`where`)

Only the first `[project]` author entry is used.
When `[project].authors` is present, only the first entry is used; `name` and
`email` are each passed to `setup()` only when specified. When `authors` is absent
or empty, no author metadata is passed.

The script must be executed from the directory that contains `pyproject.toml`. It
requires `tomllib` (Python 3.11+) or the `tomli` package on older Python versions.
Expand Down
9 changes: 7 additions & 2 deletions src/build/rfl/build/scripts/setup
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,16 @@ elif "file" in pyproject["project"]["license"]:
if "urls" in pyproject["project"]:
kwargs["url"] = pyproject["project"]["urls"]["Homepage"]

authors = pyproject["project"].get("authors") or []
if authors:
if "name" in authors[0]:
kwargs["author"] = authors[0]["name"]
if "email" in authors[0]:
kwargs["author_email"] = authors[0]["email"]

setup(
name=pyproject["project"]["name"],
version=pyproject["project"]["version"],
author=pyproject["project"]["authors"][0]["name"],
author_email=pyproject["project"]["authors"][0]["email"],
platforms=["GNU/Linux"],
**kwargs,
)
72 changes: 68 additions & 4 deletions src/build/rfl/tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,27 @@ def _run_setup_script():
exec(compile(code, str(path), "exec"), {"__name__": "__main__"})


def _minimal_pyproject(extra="", license_line='license = "LGPL-3.0-or-later"'):
def _minimal_pyproject(
extra="",
license_line='license = "LGPL-3.0-or-later"',
authors_block=textwrap.dedent(
"""\
authors = [
{name = "Test Author", email = "test@example.com"},
]
"""
),
):
content = textwrap.dedent(
f"""\
[project]
name = "test-pkg"
version = "1.0.0"
{license_line}
authors = [
{{name = "Test Author", email = "test@example.com"}},
]
"""
)
if authors_block:
content += textwrap.dedent(authors_block)
if extra:
content += textwrap.dedent(extra)
return content
Expand Down Expand Up @@ -93,6 +102,61 @@ def test_minimal_project_metadata(self, mock_setup, mock_exit):
platforms=["GNU/Linux"],
)

@patch("sys.exit")
@patch("setuptools.setup")
def test_no_authors(self, mock_setup, mock_exit):
with _project_dir(_minimal_pyproject(authors_block="")):
_run_setup_script()

mock_exit.assert_not_called()
mock_setup.assert_called_once_with(
name="test-pkg",
version="1.0.0",
platforms=["GNU/Linux"],
)

@patch("sys.exit")
@patch("setuptools.setup")
def test_author_name_only(self, mock_setup, mock_exit):
authors_block = textwrap.dedent(
"""\
authors = [
{name = "Test Author"},
]
"""
)
with _project_dir(_minimal_pyproject(authors_block=authors_block)):
_run_setup_script()

mock_exit.assert_not_called()
mock_setup.assert_called_once_with(
name="test-pkg",
version="1.0.0",
author="Test Author",
platforms=["GNU/Linux"],
)

@patch("sys.exit")
@patch("setuptools.setup")
def test_author_email_only(self, mock_setup, mock_exit):
authors_block = textwrap.dedent(
"""\
authors = [
{email = "test@example.com"},
]
"""
)
with _project_dir(_minimal_pyproject(authors_block=authors_block)):
_run_setup_script()

mock_exit.assert_not_called()
mock_setup.assert_called_once_with(
name="test-pkg",
version="1.0.0",
author_email="test@example.com",
platforms=["GNU/Linux"],
)

@patch("sys.exit")
@patch("setuptools.setup")
def test_console_scripts_entry_points(self, mock_setup, mock_exit):
Expand Down
Loading