fix(management):

- Add `path` argument for custom component path
- Add `js`, `css`, `template` arguments for custom component script, style and template files
- Add `force` argument to force rewrite the existing component
- Add `verbose` option to make the command more informative
- Add `dry-run` option to simulate the command without writing to disk
- related #249
This commit is contained in:
Hanif Birgani 2023-09-05 14:51:32 +03:30 committed by Emil Stenström
parent af107910a6
commit 58c7d55256

View file

@ -10,78 +10,150 @@ class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
"name", type=str, help="The name of the component to create"
"name",
type=str,
help="The name of the component to create"
)
parser.add_argument(
"--path",
type=str,
help="The path to the components directory",
default=None,
)
parser.add_argument(
"--js",
type=str,
help="The name of the javascript file",
default="script.js",
)
parser.add_argument(
"--css",
type=str,
help="The name of the style file",
default="style.css",
)
parser.add_argument(
"--template",
type=str,
help="The name of the template file",
default="template.html",
)
parser.add_argument(
"--force",
action="store_true",
help="Overwrite existing files if they exist",
)
parser.add_argument(
"--verbose",
action="store_true",
help="Print additional information during component creation",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Simulate component creation without actually creating any files",
default=False,
)
def handle(self, *args, **kwargs):
name = kwargs["name"]
base_dir = settings.BASE_DIR
components_path = os.path.join(base_dir, f"components/{name}")
if name:
path = kwargs["path"]
js_filename = kwargs["js"]
css_filename = kwargs["css"]
template_filename = kwargs["template"]
base_dir = settings.BASE_DIR
force = kwargs["force"]
verbose = kwargs["verbose"]
dry_run = kwargs["dry_run"]
if os.path.exists(
components_path
): # If component directory already exists
raise CommandError(
f'The component "{name}" already exists at {components_path}.'
)
component_path = os.path.join(path or f"{base_dir}/components", name)
os.makedirs(components_path)
if os.path.exists(component_path):
if force:
if verbose:
self.stdout.write(
self.style.WARNING(
f'The component "{name}" already exists at {component_path}. Overwriting...'
)
)
else:
self.stdout.write(
self.style.WARNING(
f'The component "{name}" already exists. Overwriting...'
)
)
else:
raise CommandError(
f'The component "{name}" already exists at {component_path}. Use --force to overwrite.'
)
with open(components_path + "/index.js", "w") as f:
script_content = dedent(
f"""
window.addEventListener('load', (event) => {{
console.log("{name} component is fully loaded");
}});
"""
)
f.write(script_content.strip())
if not dry_run:
os.makedirs(component_path, exist_ok=force)
with open(components_path + "/style.css", "w") as f:
style_content = dedent(
f"""
.component-{name} {{
background: red;
}}
"""
)
f.write(style_content.strip())
with open(os.path.join(component_path, js_filename), "w") as f:
script_content = dedent(
f"""
window.addEventListener('load', (event) => {{
console.log("{name} component is fully loaded");
}});
"""
)
f.write(script_content.strip())
with open(components_path + "/template.html", "w") as f:
template_content = dedent(
f"""
<div class="component-{name}">
Hello from {name} component!
</div>
"""
)
f.write(template_content.strip())
with open(components_path + f"/{name}.py", "w") as f:
py_content = dedent(
f"""
from django_components import component
@component.register("{name}")
class {name.capitalize()}(component.Component):
template_name = "{name}/template.html"
# This component takes one parameter, a date string to show in the template
def get_context_data(self, date):
return {{
"date": date,
with open(os.path.join(component_path, css_filename), "w") as f:
style_content = dedent(
f"""
.component-{name} {{
background: red;
}}
"""
)
f.write(style_content.strip())
class Media:
css = "{name}/style.css"
js = "{name}/script.js"
"""
)
f.write(py_content.strip())
with open(os.path.join(component_path, template_filename), "w") as f:
template_content = dedent(
f"""
<div class="component-{name}">
Hello from {name} component!
</div>
"""
)
f.write(template_content.strip())
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {name} component at {components_path}"
)
)
with open(os.path.join(component_path, f"{name}.py"), "w") as f:
py_content = dedent(
f"""
from django_components import component
@component.register("{name}")
class {name.capitalize()}(component.Component):
template_name = "{name}/{template_filename}"
def get_context_data(self, date):
return {{
"date": date,
}}
class Media:
css = "{name}/{css_filename}"
js = "{name}/{js_filename}"
"""
)
f.write(py_content.strip())
if verbose:
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {name} component at {component_path}"
)
)
else:
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {name} component"
)
)
else:
raise CommandError("You must specify a component name")