Added first tests #191
Some checks failed
Test before pr merge / test-lint (pull_request) Failing after 7s
Some checks failed
Test before pr merge / test-lint (pull_request) Failing after 7s
This commit is contained in:
9
src/cli/cpl/cli/.cpl/new/unittest/main.py
Normal file
9
src/cli/cpl/cli/.cpl/new/unittest/main.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from cpl.core.console import Console
|
||||
|
||||
|
||||
def main():
|
||||
Console.write_line("Hello, World!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
import click
|
||||
|
||||
from cpl.cli.cli import cli
|
||||
from cpl.cli.model.project import Project
|
||||
from cpl.cli.utils.structure import Structure
|
||||
from cpl.cli.utils.venv import get_venv_python, ensure_venv
|
||||
from cpl.core.configuration import Configuration
|
||||
@@ -21,35 +22,42 @@ def run(project: str, args: list[str], dev: bool, verbose: bool):
|
||||
if project is not None:
|
||||
project_path = (Path("./") / project).resolve().absolute()
|
||||
|
||||
project = Structure.get_project_by_name_or_path(str(project_path))
|
||||
if project.main is None:
|
||||
project = Structure.get_project_by_name_or_path(project_path)
|
||||
is_unittest = project.type == "unittest"
|
||||
if not is_unittest and project.main is None:
|
||||
Console.error(f"Project {project.name} has no executable")
|
||||
return
|
||||
|
||||
path = str(Path(project.path).parent.resolve().absolute())
|
||||
executable = project.main
|
||||
if not dev:
|
||||
dist_path = Path(project.path).parent / "dist"
|
||||
|
||||
if Configuration.get("workspace") is not None:
|
||||
dist_path = Path(Configuration.get("workspace").path).parent / "dist"
|
||||
|
||||
dist_path = Path(dist_path).resolve().absolute()
|
||||
if verbose:
|
||||
Console.write_line(f"Creating dist folder at {dist_path}...")
|
||||
|
||||
os.makedirs(dist_path, exist_ok=True)
|
||||
project.do_build(dist_path, verbose)
|
||||
path = dist_path / project.name
|
||||
main = project.main.replace(project.directory, "").lstrip("/\\")
|
||||
|
||||
executable = path / main
|
||||
|
||||
python = str(get_venv_python(ensure_venv()).absolute())
|
||||
Console.write_line(f"\nStarting project {project.name}...")
|
||||
if verbose:
|
||||
Console.write_line(f" with args {args}...")
|
||||
|
||||
Console.write_line("\n\n")
|
||||
|
||||
subprocess.run([python, executable, *args], cwd=path)
|
||||
path = str(Path(project.path).parent.resolve().absolute())
|
||||
python = str(get_venv_python(ensure_venv()).absolute())
|
||||
if is_unittest:
|
||||
subprocess.run([python, "-m", "pytest", path], cwd=path)
|
||||
return
|
||||
subprocess.run([python, _get_executable(project, dev, verbose), *args], cwd=path)
|
||||
|
||||
|
||||
def _get_executable(project: Project, dev: bool, verbose: bool) -> str:
|
||||
if dev:
|
||||
return project.main
|
||||
|
||||
dist_path = Path(project.path).parent / "dist"
|
||||
|
||||
if Configuration.get("workspace") is not None:
|
||||
dist_path = Path(Configuration.get("workspace").path).parent / "dist"
|
||||
|
||||
dist_path = Path(dist_path).resolve().absolute()
|
||||
if verbose:
|
||||
Console.write_line(f"Creating dist folder at {dist_path}...")
|
||||
|
||||
os.makedirs(dist_path, exist_ok=True)
|
||||
project.do_build(dist_path, verbose)
|
||||
path = dist_path / project.name
|
||||
main = project.main.replace(project.directory, "").lstrip("/\\")
|
||||
|
||||
return str(path / main)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PROJECT_TYPES = ["console", "web", "graphql", "library", "service"]
|
||||
PROJECT_TYPES = ["console", "web", "graphql", "library", "service", "unittest"]
|
||||
PROJECT_TYPES_SHORT = [x[0] for x in PROJECT_TYPES]
|
||||
|
||||
PIP_URL = "https://git.sh-edraft.de/api/packages/sh-edraft.de/pypi/simple/"
|
||||
|
||||
@@ -33,10 +33,11 @@ class Workspace(CPLStructureModel):
|
||||
self._actual_projects = []
|
||||
self._project_names = []
|
||||
for project in projects:
|
||||
if Path(project).is_dir() or not Path(project).exists():
|
||||
p_path = (Path(path).parent / Path(project)).resolve().absolute()
|
||||
if p_path.is_dir() or not p_path.exists():
|
||||
raise ValueError(f"Project path '{project}' does not exist or is a directory.")
|
||||
|
||||
p = Project.from_file(project)
|
||||
p = Project.from_file(p_path)
|
||||
self._actual_projects.append(p)
|
||||
self._project_names.append(p.name)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class Structure:
|
||||
pyproject_path.write_text(content)
|
||||
|
||||
@staticmethod
|
||||
def get_project_by_name_or_path(project: str) -> Project:
|
||||
def get_project_by_name_or_path(project: str | Path) -> Project:
|
||||
if project is None:
|
||||
raise ValueError("Project name or path must be provided.")
|
||||
|
||||
@@ -86,9 +86,10 @@ class Structure:
|
||||
if workspace is None:
|
||||
raise RuntimeError("No workspace found. Please run 'cpl init workspace' first.")
|
||||
|
||||
project_name = project.name if isinstance(project, Path) else project
|
||||
for p in workspace.actual_projects:
|
||||
if p.name == project:
|
||||
return Project.from_file(Path(p.path))
|
||||
if p.name == project_name:
|
||||
return Project.from_file((Path(workspace.path).parent / Path(p.path)).resolve())
|
||||
|
||||
if not path.is_dir() and not path.is_file():
|
||||
raise ValueError(f"Unknown project {project}")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from types import NoneType
|
||||
from typing import Any
|
||||
|
||||
|
||||
@@ -6,7 +7,17 @@ class Number:
|
||||
@staticmethod
|
||||
def is_number(value: Any) -> bool:
|
||||
"""Check if the value is a number (int or float)."""
|
||||
return isinstance(value, (int, float, complex))
|
||||
if isinstance(value, (bool, NoneType)):
|
||||
return False
|
||||
|
||||
if isinstance(value, (int, float, complex)):
|
||||
return True
|
||||
|
||||
try:
|
||||
Number.to_number(value)
|
||||
return True
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def to_number(value: Any) -> int | float | complex:
|
||||
|
||||
@@ -18,14 +18,15 @@ class String:
|
||||
String converted to CamelCase
|
||||
"""
|
||||
|
||||
parts = re.split(r"[^a-zA-Z0-9]+", s.strip())
|
||||
if re.search(r'[_\-\s]', s):
|
||||
words = re.split(r'[_\-\s]+', s)
|
||||
else:
|
||||
words = re.findall(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z]|$)', s)
|
||||
|
||||
parts = [p for p in parts if p]
|
||||
|
||||
if not parts:
|
||||
return ""
|
||||
|
||||
return parts[0].lower() + "".join(word.capitalize() for word in parts[1:])
|
||||
words = [w.lower() for w in words if w]
|
||||
if not words:
|
||||
return ''
|
||||
return words[0] + ''.join(w.capitalize() for w in words[1:])
|
||||
|
||||
@staticmethod
|
||||
def to_pascal_case(s: str) -> str:
|
||||
@@ -39,14 +40,12 @@ class String:
|
||||
String converted to PascalCase
|
||||
"""
|
||||
|
||||
parts = re.split(r"[^a-zA-Z0-9]+", s.strip())
|
||||
if re.search(r'[_\-\s]', s):
|
||||
words = re.split(r'[_\-\s]+', s)
|
||||
else:
|
||||
words = re.findall(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z]|$)', s)
|
||||
|
||||
parts = [p for p in parts if p]
|
||||
|
||||
if not parts:
|
||||
return ""
|
||||
|
||||
return "".join(word.capitalize() for word in parts)
|
||||
return ''.join(word.capitalize() for word in words if word)
|
||||
|
||||
@staticmethod
|
||||
def to_snake_case(chars: str) -> str:
|
||||
|
||||
Reference in New Issue
Block a user