mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-04-24 01:00:45 +02:00
87 lines
3.5 KiB
Python
87 lines
3.5 KiB
Python
import traceback
|
|
from pathlib import Path
|
|
from typing import Annotated
|
|
|
|
import copier
|
|
import typer
|
|
from bec_lib.logger import bec_logger
|
|
from bec_lib.plugin_helper import plugin_repo_path
|
|
from bec_lib.utils.plugin_manager._constants import ANSWER_KEYS
|
|
from bec_lib.utils.plugin_manager._util import existing_data, git_stage_files, make_commit
|
|
|
|
from bec_widgets.utils.bec_plugin_manager.edit_ui import open_and_watch_ui_editor
|
|
|
|
logger = bec_logger.logger
|
|
_app = typer.Typer(rich_markup_mode="rich")
|
|
|
|
|
|
def _commit_added_widget(repo: Path, name: str):
|
|
git_stage_files(repo, [".copier-answers.yml"])
|
|
git_stage_files(repo / repo.name / "bec_widgets" / "widgets" / name, [])
|
|
make_commit(repo, f"plugin-manager added new widget: {name}")
|
|
logger.info(f"Committing new widget {name}")
|
|
|
|
|
|
def _widget_exists(widget_list: list[dict[str, str | bool]], name: str):
|
|
return name in [w["name"] for w in widget_list]
|
|
|
|
|
|
def _editor_cb(ctx: typer.Context, value: bool):
|
|
if value and not ctx.params["use_ui"]:
|
|
raise typer.BadParameter("Can only open the editor if creating a .ui file!")
|
|
return value
|
|
|
|
|
|
_bold_blue = "\033[34m\033[1m"
|
|
_off = "\033[0m"
|
|
_USE_UI_MSG = "Generate a .ui file for use in bec-designer."
|
|
_OPEN_DESIGNER_MSG = f"""This app can watch for changes and recompile them to a python file imported to the widget whenever it is saved.
|
|
To open this editor independently, you can use {_bold_blue}bec-plugin-manager edit-ui [widget_name]{_off}.
|
|
Open the created widget .ui file in bec-designer now?"""
|
|
|
|
|
|
@_app.command()
|
|
def widget(
|
|
name: Annotated[str, typer.Argument(help="Enter a name for your widget in snake_case")],
|
|
use_ui: Annotated[bool, typer.Option(prompt=_USE_UI_MSG, help=_USE_UI_MSG)] = True,
|
|
open_editor: Annotated[
|
|
bool, typer.Option(prompt=_OPEN_DESIGNER_MSG, help=_OPEN_DESIGNER_MSG, callback=_editor_cb)
|
|
] = True,
|
|
):
|
|
"""Create a new widget plugin with the given name.
|
|
|
|
If [bold white]use_ui[/bold white] is set, a bec-designer .ui file will also be created. If \
|
|
[bold white]open_editor[/bold white] is additionally set, the .ui file will be opened in \
|
|
bec-designer and the compiled python version will be updated when changes are made and saved."""
|
|
if (formatted_name := name.lower().replace("-", "_")) != name:
|
|
logger.warning(f"Adjusting widget name from {name} to {formatted_name}")
|
|
if not formatted_name.isidentifier():
|
|
logger.error(
|
|
f"{name} is not a valid name for a widget (even after converting to {formatted_name}) - please enter something in snake_case"
|
|
)
|
|
exit(-1)
|
|
logger.info(f"Adding new widget {formatted_name} to the template...")
|
|
try:
|
|
repo = Path(plugin_repo_path())
|
|
plugin_data = existing_data(repo, [ANSWER_KEYS.VERSION, ANSWER_KEYS.WIDGETS])
|
|
if _widget_exists(plugin_data[ANSWER_KEYS.WIDGETS], formatted_name):
|
|
logger.error(f"Widget {formatted_name} already exists!")
|
|
exit(-1)
|
|
plugin_data[ANSWER_KEYS.WIDGETS].append({"name": formatted_name, "use_ui": use_ui})
|
|
copier.run_update(
|
|
repo,
|
|
data=plugin_data,
|
|
defaults=True,
|
|
unsafe=True,
|
|
overwrite=True,
|
|
vcs_ref=plugin_data[ANSWER_KEYS.VERSION],
|
|
)
|
|
_commit_added_widget(repo, formatted_name)
|
|
except Exception:
|
|
logger.error(traceback.format_exc())
|
|
logger.error("exiting...")
|
|
exit(-1)
|
|
logger.success(f"Added widget {formatted_name}!")
|
|
if open_editor:
|
|
open_and_watch_ui_editor(formatted_name)
|