diff --git a/src/cli/cpl.project.json b/src/cli/cpl.project.json index 886fbd05..91a1ef44 100644 --- a/src/cli/cpl.project.json +++ b/src/cli/cpl.project.json @@ -17,8 +17,9 @@ "../core/cpl.project.json" ], "main": "cpl/cli/main.py", - "directory": "cpl/cli", + "directory": "cpl", "build": { + "build": "python -m build", "include": [ "_templates/" ], diff --git a/src/cli/cpl/cli/command/project/build.py b/src/cli/cpl/cli/command/project/build.py index 16d7718c..f8c51fa1 100644 --- a/src/cli/cpl/cli/command/project/build.py +++ b/src/cli/cpl/cli/command/project/build.py @@ -1,10 +1,12 @@ import os.path +import subprocess from pathlib import Path import click from cpl.cli.cli import cli from cpl.cli.utils.structure import get_project_by_name_or_path +from cpl.cli.utils.venv import ensure_venv, get_venv_python from cpl.core.configuration import Configuration from cpl.core.console import Console @@ -12,9 +14,11 @@ from cpl.core.console import Console @cli.command("build", aliases=["b"]) @click.argument("project", type=click.STRING, required=False) @click.option("--dist", "-d", type=str) +@click.option("--skip-py-build", "-spb", is_flag=True, help="Skip toml generation and python build") @click.option("--verbose", "-v", is_flag=True, help="Enable verbose output") -def build(project: str, dist: str | None, verbose: bool): +def build(project: str, dist: str = None, skip_py_build: bool = None, verbose: bool = None): project = get_project_by_name_or_path(project or "./") + venv = ensure_venv().absolute() dist_path = dist or Path(project.path).parent / "dist" if dist is None and Configuration.get("workspace") is not None: @@ -28,4 +32,28 @@ def build(project: str, dist: str | None, verbose: bool): os.makedirs(dist_path, exist_ok=True) project.do_build(dist_path, verbose) + + if skip_py_build: + Console.write_line("\nDone!") + return + + from cpl.cli.utils.structure import create_pyproject_toml + + create_pyproject_toml(project, dist_path / project.name) + python = str(get_venv_python(venv)) + + subprocess.run( + [ + python, + "-m", + "build", + "--outdir", + str(dist_path / project.name), + str(dist_path / project.name), + ], + check=True, + stdin=subprocess.DEVNULL if not verbose else None, + stdout=subprocess.DEVNULL if not verbose else None, + stderr=subprocess.DEVNULL if not verbose else None, + ) Console.write_line("\nDone!") diff --git a/src/cli/cpl/cli/utils/structure.py b/src/cli/cpl/cli/utils/structure.py index 0044bd24..a2c50dbe 100644 --- a/src/cli/cpl/cli/utils/structure.py +++ b/src/cli/cpl/cli/utils/structure.py @@ -1,3 +1,4 @@ +import textwrap from pathlib import Path from cpl.cli.model.project import Project @@ -34,4 +35,24 @@ def get_project_by_name_or_path(project: str) -> Project: if p.name == workspace.default_project: return Project.from_file(Path(p.path)) - raise ValueError(f"Project '{project}' not found.") \ No newline at end of file + raise ValueError(f"Project '{project}' not found.") + +def create_pyproject_toml(project: Project, path: Path): + pyproject_path = path / "pyproject.toml" + if pyproject_path.exists(): + return + + content = textwrap.dedent(f""" + [build-system] + requires = ["setuptools>=70.1.0", "wheel", "build"] + build-backend = "setuptools.build_meta" + [project] + name = "{project.name}" + version = "{project.version or '0.1.0'}" + description = "{project.description or ''}" + authors = [{{name="{project.author or ''}"}}] + license = "{project.license or ''}" + dependencies = [{', '.join([f'"{dep}"' for dep in project.dependencies])}] + """).lstrip() + + pyproject_path.write_text(content)