Skip to content

Commit dfbce99

Browse files
committed
[FEAT] modified startproject cli operation
1 parent 0d4d0bc commit dfbce99

File tree

9 files changed

+81
-43
lines changed

9 files changed

+81
-43
lines changed

.github/workflows/distribute.yml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
name: Distribute source to pypi package
2+
23
on:
3-
pull_request:
4-
branches:
5-
- main
4+
release:
5+
types: [published]
6+
67

78
jobs:
8-
distribute-fastapi-fastkit-package-bundle:
9+
pypi-publish:
10+
name: upload release to PyPI
911
runs-on: ubuntu-latest
12+
permissions:
13+
# This permission is needed for private repositories.
14+
contents: read
15+
# IMPORTANT: this permission is mandatory for trusted publishing
16+
id-token: write
1017
steps:
11-
- name: Checkout code
12-
uses: actions/checkout@v4
18+
- uses: actions/checkout@v4
19+
20+
- uses: pdm-project/setup-pdm@v4
21+
22+
- name: Publish package distributions to PyPI
23+
run: pdm publish

scripts/lint.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ base_dir=$(dirname $(dirname $0))
66

77
isort --sp "${base_dir}/pyproject.toml" --check .
88
isort --sp "${base_dir}/pyproject.toml" .
9-
10-
black --config "${base_dir}/pyproject.toml" --check .
9+
black --config "${base_dir}/pyproject.toml" .
1110

1211
mypy --config-file "${base_dir}/pyproject.toml" src

src/fastapi_fastkit/backend.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ def print_warning(message: str, title: str = "Warning") -> None:
4747
console.print(Panel(warning_text, border_style="yellow", title=title))
4848

4949

50+
def print_info(message: str, title: str = "Info") -> None:
51+
"""Print an info message with specified output style."""
52+
info_text = Text()
53+
info_text.append("ℹ ", style="bold blue")
54+
info_text.append(message)
55+
console.print(Panel(info_text, border_style="blue", title=title))
56+
57+
5058
def create_info_table(
5159
title: str, data: dict[str, str], show_header: bool = False
5260
) -> Table:

src/fastapi_fastkit/cli.py

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
from fastapi_fastkit.core.exceptions import CLIExceptions
1818
from fastapi_fastkit.core.settings import FastkitConfig
19-
from fastapi_fastkit.utils.inspector import delete_project
2019
from fastapi_fastkit.utils.logging import setup_logging
2120
from fastapi_fastkit.utils.transducer import copy_and_convert_template
2221

@@ -25,6 +24,7 @@
2524
create_info_table,
2625
inject_project_metadata,
2726
print_error,
27+
print_info,
2828
print_success,
2929
print_warning,
3030
validate_email,
@@ -234,19 +234,13 @@ def startup(
234234
prompt="Enter project name",
235235
help="Name of the new FastAPI project",
236236
)
237-
@click.option(
238-
"--stack",
239-
type=click.Choice(["minimal", "standard", "full"]),
240-
prompt="Select stack",
241-
help="Project stack configuration",
242-
)
243-
def startproject(project_name: str, stack: str) -> None:
237+
def startproject(project_name: str) -> None:
244238
"""
245239
Start a new FastAPI project.
246-
Dependencies will be automatically installed based on the selected stack.
240+
This command will automatically create a new FastAPI project directory and a python virtual environment.
241+
Dependencies will be automatically installed based on the selected stack at venv.
247242
248243
:param project_name: Project name
249-
:param stack: Project stack configuration
250244
:return: None
251245
"""
252246
settings = FastkitConfig()
@@ -256,28 +250,43 @@ def startproject(project_name: str, stack: str) -> None:
256250
print_error(f"Error: Project '{project_name}' already exists.")
257251
return
258252

253+
dependencies = {
254+
"minimal": ["fastapi", "uvicorn"],
255+
"standard": ["fastapi", "uvicorn", "sqlalchemy", "alembic", "pytest"],
256+
"full": [
257+
"fastapi",
258+
"uvicorn",
259+
"sqlalchemy",
260+
"alembic",
261+
"pytest",
262+
"redis",
263+
"celery",
264+
"docker-compose",
265+
],
266+
}
267+
268+
console.print("\n[bold]Available Stacks and Dependencies:[/bold]")
269+
for stack_name, deps in dependencies.items():
270+
table = create_info_table(
271+
f"{stack_name.upper()} Stack",
272+
{f"Dependency {i+1}": dep for i, dep in enumerate(deps)},
273+
)
274+
console.print(table)
275+
console.print("\n")
276+
277+
stack = click.prompt(
278+
"Select stack",
279+
type=click.Choice(["minimal", "standard", "full"]),
280+
show_choices=True,
281+
)
282+
259283
try:
260284
os.makedirs(project_dir)
261285

262286
table = create_info_table(
263-
f"Creating Project: {project_name}", {"Component": "Status"}
287+
f"Creating Project: {project_name}", {"Component": "Collected"}
264288
)
265289

266-
dependencies = {
267-
"minimal": ["fastapi", "uvicorn"],
268-
"standard": ["fastapi", "uvicorn", "sqlalchemy", "alembic", "pytest"],
269-
"full": [
270-
"fastapi",
271-
"uvicorn",
272-
"sqlalchemy",
273-
"alembic",
274-
"pytest",
275-
"redis",
276-
"celery",
277-
"docker-compose",
278-
],
279-
}
280-
281290
with open(os.path.join(project_dir, "requirements.txt"), "w") as f:
282291
for dep in dependencies[stack]:
283292
f.write(f"{dep}\n")
@@ -287,15 +296,31 @@ def startproject(project_name: str, stack: str) -> None:
287296

288297
with console.status("[bold green]Setting up project environment..."):
289298
console.print("[yellow]Creating virtual environment...[/yellow]")
290-
subprocess.run(["python", "-m", "venv", os.path.join(project_dir, "venv")])
299+
venv_path = os.path.join(project_dir, "venv")
300+
subprocess.run(["python", "-m", "venv", venv_path], check=True)
301+
302+
if os.name == "nt": # Windows
303+
pip_path = os.path.join(venv_path, "Scripts", "pip")
304+
else: # Linux/Mac
305+
pip_path = os.path.join(venv_path, "bin", "pip")
291306

292307
console.print("[yellow]Installing dependencies...[/yellow]")
293308
subprocess.run(
294-
["pip", "install", "-r", "requirements.txt"], cwd=project_dir
309+
[pip_path, "install", "-r", "requirements.txt"],
310+
cwd=project_dir,
311+
check=True,
295312
)
296313

297314
print_success(f"Project '{project_name}' has been created successfully!")
298315

316+
if os.name == "nt":
317+
activate_venv = f" {os.path.join(venv_path, 'Scripts', 'activate.bat')}"
318+
else:
319+
activate_venv = f" source {os.path.join(venv_path, 'bin', 'activate')}"
320+
print_info(
321+
"To activate the virtual environment, run:\n\n" + activate_venv,
322+
)
323+
299324
except Exception as e:
300325
print_error(f"Error during project creation: {e}")
301326
shutil.rmtree(project_dir, ignore_errors=True)
@@ -353,7 +378,7 @@ def deleteproject(ctx: Context, project_name: str) -> None:
353378
return
354379

355380
try:
356-
delete_project(project_dir)
381+
shutil.rmtree(project_dir)
357382
print_success(f"Project '{project_name}' has been deleted successfully!")
358383

359384
except Exception as e:

src/fastapi_fastkit/utils/inspector.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,4 @@
77
#
88
# @author bnbong
99
# --------------------------------------------------------------------------
10-
import shutil
11-
12-
13-
def delete_project(project_dir: str) -> None:
14-
# TODO : add checking step -> preventing 'template' folder deletion.
15-
shutil.rmtree(project_dir)
10+
pass

0 commit comments

Comments
 (0)