Skip to content

Commit 931a10f

Browse files
committed
Fixed directory argument for new command and added directory argument for create-project command
1 parent 10f5b64 commit 931a10f

File tree

6 files changed

+92
-15
lines changed

6 files changed

+92
-15
lines changed

ellar_cli/file_scaffolding.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ def __init__(
2828
specified_directory: t.Optional[str] = None,
2929
) -> None:
3030
self._specified_directory = specified_directory
31+
if specified_directory and specified_directory.startswith("/"):
32+
self._specified_directory = specified_directory[1:]
33+
3134
self._schema = schema
3235
self._ctx = ProjectScaffoldContext(Environment())
3336
self._scaffold_ellar_template_root_path = scaffold_ellar_template_root_path
@@ -79,7 +82,9 @@ def on_scaffold_completed(self) -> None:
7982

8083
def on_scaffold_started(self) -> None:
8184
for context in self._schema.context:
82-
assert self._ctx[context], f"{context} template context is missing."
85+
assert (
86+
self._ctx.get(context) is not None
87+
), f"{context} template context is missing."
8388

8489
def create_directory(
8590
self,
@@ -125,7 +130,7 @@ def _handle_directory_change(self, working_directory: str) -> str:
125130
_specified_directory = (
126131
self._specified_directory.lower() # type:ignore[union-attr]
127132
)
128-
return os.path.join(working_directory, _specified_directory)
133+
return os.path.join(str(working_directory), _specified_directory)
129134

130135
def get_templating_context(self) -> ProjectScaffoldContext:
131136
return ProjectScaffoldContext(

ellar_cli/manage_commands/create_project.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import os
2+
import secrets
23
import typing as t
3-
import uuid
44
from importlib import import_module
5+
from pathlib import Path
56

67
import typer
78
from ellar.common.helper.module_loading import module_dir
@@ -22,14 +23,42 @@
2223

2324

2425
class ProjectTemplateScaffold(FileTemplateScaffold):
25-
def __init__(self, ellar_cli_service: EllarCLIService, **kwargs: t.Any) -> None:
26-
super().__init__(**kwargs)
26+
def __init__(
27+
self,
28+
ellar_cli_service: EllarCLIService,
29+
working_project_name: str,
30+
working_directory: str,
31+
**kwargs: t.Any,
32+
) -> None:
33+
super().__init__(
34+
**kwargs,
35+
working_project_name=working_project_name,
36+
working_directory=working_directory,
37+
)
2738
self.ellar_cli_service = ellar_cli_service
39+
self._working_project_name = working_project_name
40+
if self._specified_directory:
41+
_cwd_path = Path(self._get_working_cwd(working_directory))
42+
self._working_directory = str(_cwd_path)
43+
else:
44+
self._working_directory = working_directory
45+
46+
self.prefix: t.Optional[str] = None
47+
if self._specified_directory and "." not in self._specified_directory:
48+
self.prefix = self._specified_directory.replace("/", ".").lower()
49+
50+
if self.prefix.startswith("."):
51+
self.prefix = self.prefix[1:]
52+
53+
if self.prefix.endswith("."):
54+
self.prefix = self.prefix[:-1]
2855

2956
def get_scaffolding_context(self, working_project_name: str) -> t.Dict:
57+
_prefix = f"{self.prefix}." if self.prefix else ""
3058
template_context = {
3159
"project_name": working_project_name,
32-
"secret_key": f"ellar_{uuid.uuid4()}",
60+
"secret_key": f"ellar_{secrets.token_hex(32)}",
61+
"config_prefix": _prefix,
3362
}
3463
return template_context
3564

@@ -60,8 +89,10 @@ def validate_project_name(self) -> None:
6089
raise EllarCLIException(message)
6190

6291
def on_scaffold_completed(self) -> None:
92+
_working_project_name = self._working_project_name
93+
6394
self.ellar_cli_service.create_ellar_project_meta(
64-
project_name=self._working_project_name
95+
project_name=_working_project_name, prefix=self.prefix
6596
)
6697
print(
6798
f"`{self._working_project_name}` project scaffold completed. To start your server, run the command below"
@@ -70,7 +101,15 @@ def on_scaffold_completed(self) -> None:
70101
print("Happy coding!")
71102

72103

73-
def create_project(ctx: typer.Context, project_name: str):
104+
def create_project(
105+
ctx: typer.Context,
106+
project_name: str,
107+
directory: t.Optional[str] = typer.Argument(
108+
None,
109+
help="The name of a new directory to scaffold the project into.",
110+
show_default=False,
111+
),
112+
):
74113
"""- Scaffolds Ellar Application -"""
75114

76115
ellar_project_meta = t.cast(t.Optional[EllarCLIService], ctx.meta.get(ELLAR_META))
@@ -86,6 +125,7 @@ def create_project(ctx: typer.Context, project_name: str):
86125
working_directory=os.getcwd(),
87126
scaffold_ellar_template_root_path=root_scaffold_template_path,
88127
ellar_cli_service=ellar_project_meta,
128+
specified_directory=directory,
89129
working_project_name=project_name.lower(),
90130
)
91131
project_template_scaffold.scaffold()

ellar_cli/scaffolding/project_template/project_name/server.ellar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ from .root_module import ApplicationModule
88
application = AppFactory.create_from_app_module(
99
ApplicationModule,
1010
config_module=os.environ.get(
11-
ELLAR_CONFIG_MODULE, "{{project_name}}.config:DevelopmentConfig"
11+
ELLAR_CONFIG_MODULE, "{{config_prefix}}{{project_name}}.config:DevelopmentConfig"
1212
),
1313
global_guards=[]
1414
)

ellar_cli/scaffolding/project_template/setup.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"context": ["project_name", "secret_key"],
2+
"context": ["project_name", "secret_key", "config_prefix"],
33
"files": [
44
{
55
"name": "project_name",

ellar_cli/service.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ def import_project_meta(
139139
)
140140
return None
141141

142-
def create_ellar_project_meta(self, project_name: str) -> None:
142+
def create_ellar_project_meta(
143+
self, project_name: str, prefix: t.Optional[str] = None
144+
) -> None:
143145
pyproject_table = EllarCLIService.read_py_project(self.py_project_path)
144146
if pyproject_table is None:
145147
raise EllarCLIException("Could not locate `pyproject.toml`")
@@ -156,12 +158,18 @@ def create_ellar_project_meta(self, project_name: str) -> None:
156158
if not ellar_py_project.has_default_project:
157159
ellar_py_project.default_project = project_name.lower()
158160

161+
_prefix = f"{prefix}." if prefix else ""
162+
159163
ellar_new_project = ellar_py_project.get_or_create_project(project_name.lower())
160164
ellar_new_project.add("project-name", project_name.lower())
161-
ellar_new_project.add("application", f"{project_name}.server:application")
162-
ellar_new_project.add("config", f"{project_name}.config:DevelopmentConfig")
163165
ellar_new_project.add(
164-
"root-module", f"{project_name}.root_module:ApplicationModule"
166+
"application", f"{_prefix}{project_name}.server:application"
167+
)
168+
ellar_new_project.add(
169+
"config", f"{_prefix}{project_name}.config:DevelopmentConfig"
170+
)
171+
ellar_new_project.add(
172+
"root-module", f"{_prefix}{project_name}.root_module:ApplicationModule"
165173
)
166174

167175
# TODO: lock pyproject.toml file

tests/test_ellar_commands/test_create_project_command.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22

3-
from ellar.core import App
3+
from ellar.core import App, Config
44

55
from ellar_cli.service import EllarCLIService
66

@@ -79,3 +79,27 @@ def test_create_project_command_works(tmpdir, process_runner, write_empty_py_pro
7979

8080
application = ellar_cli_service.import_application()
8181
assert isinstance(application, App)
82+
83+
84+
def test_create_project_command_works_with_specific_directory(
85+
tmpdir, process_runner, write_empty_py_project
86+
):
87+
result = process_runner(["ellar", "create-project", "ellar_project", "Another/me"])
88+
assert result.returncode == 0
89+
assert result.stdout.decode("utf8") == (
90+
"`ellar_project` project scaffold completed. To start your server, run the command below\n"
91+
"ellar --project ellar_project runserver --reload\n"
92+
"Happy coding!\n"
93+
)
94+
ellar_cli_service = EllarCLIService.import_project_meta()
95+
assert ellar_cli_service._meta.dict() == {
96+
"project_name": "ellar_project",
97+
"application": "another.me.ellar_project.server:application",
98+
"config": "another.me.ellar_project.config:DevelopmentConfig",
99+
"root_module": "another.me.ellar_project.root_module:ApplicationModule",
100+
}
101+
application = ellar_cli_service.import_application()
102+
assert isinstance(application, App)
103+
config = ellar_cli_service.get_application_config()
104+
assert isinstance(config, Config)
105+
assert ellar_cli_service.import_root_module()

0 commit comments

Comments
 (0)