Skip to content

Commit

Permalink
Add minimal CLI
Browse files Browse the repository at this point in the history
This can be useful for testing purposes.

Signed-off-by: Stephen Finucane <stephen@that.guru>
  • Loading branch information
stephenfin committed Jan 4, 2023
1 parent b406d8b commit e2ee7fe
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 0 deletions.
99 changes: 99 additions & 0 deletions src/pyproject_api/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from __future__ import annotations

import argparse
import os
import pathlib
import sys
import textwrap

from ._frontend import EditableResult, SdistResult, WheelResult
from ._via_fresh_subprocess import SubprocessFrontend


def main_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description=textwrap.indent(
textwrap.dedent(
"""A pyproject.toml-based build frontend.
This is mainly useful for debugging PEP-517 backends. This frontend will not
do things like install required build dependencies.
"""
).strip(),
" ",
),
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
"srcdir",
type=pathlib.Path,
nargs="?",
default=pathlib.Path.cwd(),
help="source directory (defaults to current directory)",
)
parser.add_argument(
"--sdist",
"-s",
dest="distributions",
action="append_const",
const="sdist",
default=[],
help="build a source distribution",
)
parser.add_argument(
"--wheel",
"-w",
dest="distributions",
action="append_const",
const="wheel",
help="build a wheel distribution",
)
parser.add_argument(
"--editable",
"-e",
dest="distributions",
action="append_const",
const="editable",
help="build an editable wheel distribution",
)
parser.add_argument(
"--outdir",
"-o",
type=pathlib.Path,
help=f"output directory (defaults to {{srcdir}}{os.sep}dist)",
)
return parser


def main(argv: list[str]) -> None:
parser = main_parser()
args = parser.parse_args(argv)

outdir = args.outdir or args.srcdir / "dist"
# we intentionally do not build editable distributions by default
distributions = args.distributions or ["sdist", "wheel"]

frontend = SubprocessFrontend(*SubprocessFrontend.create_args_from_folder(args.srcdir)[:-1])
res: SdistResult | WheelResult | EditableResult

if "sdist" in distributions:
print("Building sdist...")
res = frontend.build_sdist(outdir)
print(res.out)
print(res.err, file=sys.stderr)

if "wheel" in distributions:
print("Building wheel...")
res = frontend.build_wheel(outdir)
print(res.out)
print(res.err, file=sys.stderr)

if "editable" in distributions:
print("Building editable wheel...")
res = frontend.build_editable(outdir)
print(res.out)
print(res.err, file=sys.stderr)


if __name__ == "__main__":
main(sys.argv[1:])
104 changes: 104 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from __future__ import annotations

from pathlib import Path

import pytest
import pytest_mock

import pyproject_api.__main__
from pyproject_api._frontend import EditableResult, SdistResult, WheelResult


@pytest.mark.parametrize(
("cli_args", "srcdir", "outdir", "hooks"),
[
(
[],
Path.cwd(),
Path.cwd() / "dist",
["build_sdist", "build_wheel"],
),
(
["src"],
Path("src"),
Path("src") / "dist",
["build_sdist", "build_wheel"],
),
(
["-o", "out"],
Path.cwd(),
Path("out"),
["build_sdist", "build_wheel"],
),
(
["-s"],
Path.cwd(),
Path.cwd() / "dist",
["build_sdist"],
),
(
["-w"],
Path.cwd(),
Path.cwd() / "dist",
["build_wheel"],
),
(
["-e"],
Path.cwd(),
Path.cwd() / "dist",
["build_editable"],
),
(
["-s", "-w"],
Path.cwd(),
Path.cwd() / "dist",
["build_sdist", "build_wheel"],
),
],
)
def test_parse_args(
mocker: pytest_mock.MockerFixture,
capsys: pytest.CaptureFixture[str],
cli_args: list[str],
srcdir: Path,
outdir: Path,
hooks: list[str],
) -> None:
subprocess_frontend = mocker.patch("pyproject_api.__main__.SubprocessFrontend", autospec=True)
subprocess_frontend.create_args_from_folder.return_value = (srcdir, (), "foo.bar", "baz", (), True)
subprocess_frontend.return_value.build_sdist.return_value = SdistResult(
sdist=outdir / "foo.whl",
out="sdist out",
err="sdist err",
)
subprocess_frontend.return_value.build_wheel.return_value = WheelResult(
wheel=outdir / "foo.whl", out="wheel out", err="wheel err"
)
subprocess_frontend.return_value.build_editable.return_value = EditableResult(
wheel=outdir / "foo.whl",
out="editable wheel out",
err="editable wheel err",
)

pyproject_api.__main__.main(cli_args)

subprocess_frontend.create_args_from_folder.assert_called_once_with(srcdir)
captured = capsys.readouterr()

if "build_sdist" in hooks:
assert "Building sdist..." in captured.out
subprocess_frontend.return_value.build_sdist.assert_called_once_with(outdir)
assert "sdist out" in captured.out
assert "sdist err" in captured.err

if "build_wheel" in hooks:
assert "Building wheel..." in captured.out
subprocess_frontend.return_value.build_wheel.assert_called_once_with(outdir)
assert "wheel out" in captured.out
assert "wheel err" in captured.err

if "build_editable" in hooks:
assert "Building editable wheel..." in captured.out
subprocess_frontend.return_value.build_editable.assert_called_once_with(outdir)
assert "editable wheel out" in captured.out
assert "editable wheel err" in captured.err
2 changes: 2 additions & 0 deletions whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ iwusr
mktemp
namelist
nitpicky
outdir
prj
py311
py38
Expand All @@ -21,6 +22,7 @@ pyproject
readouterr
sdist
setenv
srcdir
tmpdir
toml
tomli
Expand Down

0 comments on commit e2ee7fe

Please sign in to comment.