diff --git a/nb_cli/cli/commands/project.py b/nb_cli/cli/commands/project.py index e3905ae..aea8866 100644 --- a/nb_cli/cli/commands/project.py +++ b/nb_cli/cli/commands/project.py @@ -17,6 +17,7 @@ ) from nb_cli import _ +from nb_cli.config import ConfigManager from nb_cli.exceptions import ModuleLoadFailed from nb_cli.consts import WINDOWS, DEFAULT_DRIVER from nb_cli.cli import CLI_DEFAULT_STYLE, ClickAliasedCommand, run_async @@ -31,6 +32,7 @@ create_virtualenv, terminate_process, generate_run_script, + list_builtin_plugins, remove_signal_handler, list_project_templates, register_signal_handler, @@ -217,7 +219,7 @@ async def create( fg="yellow", ) await create_virtualenv( - venv_dir, prompt=project_dir_name, python_interpreter=python_interpreter + venv_dir, prompt=project_dir_name, python_path=python_interpreter ) path = ( venv_dir @@ -225,9 +227,36 @@ async def create( / ("python.exe" if WINDOWS else "python") ) - proc = await call_pip_install(context.packages, pip_args, python_path=path) + proc = await call_pip_install( + ["nonebot2", *context.packages], pip_args, python_path=path + ) await proc.wait() + builtin_plugins = await list_builtin_plugins(python_path=path) + try: + loaded_builtin_plugins = [ + c.data + for c in await CheckboxPrompt( + _("Which builtin plugin(s) would you like to use?"), + [Choice(p, p) for p in builtin_plugins], + ).prompt_async(style=CLI_DEFAULT_STYLE) + ] + except CancelledError: + ctx.exit() + + try: + m = ConfigManager(python=path, config_file=project_dir / "pyproject.toml") + for plugin in loaded_builtin_plugins: + m.add_builtin_plugin(plugin) + except Exception as e: + click.secho( + _( + "Failed to add builtin plugins {builtin_plugins} to config: {e}" + ).format(builtin_plugin=loaded_builtin_plugins, e=e), + fg="red", + ) + ctx.exit() + click.secho(_("Done!"), fg="green") click.secho( _( diff --git a/nb_cli/cli/commands/self.py b/nb_cli/cli/commands/self.py index c1cdeb1..e7974cf 100644 --- a/nb_cli/cli/commands/self.py +++ b/nb_cli/cli/commands/self.py @@ -67,7 +67,7 @@ async def install( except CancelledError: ctx.exit() - proc = await call_pip_install(name, pip_args, sys.executable) + proc = await call_pip_install(name, pip_args, python_path=sys.executable) await proc.wait() @@ -77,7 +77,7 @@ async def install( @click.argument("pip_args", nargs=-1, default=None) @run_async async def update(pip_args: Optional[List[str]]): - proc = await call_pip_update("nb-cli", pip_args, sys.executable) + proc = await call_pip_update("nb-cli", pip_args, python_path=sys.executable) await proc.wait() @@ -101,7 +101,7 @@ async def uninstall( except CancelledError: ctx.exit() - proc = await call_pip_uninstall(name, pip_args, sys.executable) + proc = await call_pip_uninstall(name, pip_args, python_path=sys.executable) await proc.wait() @@ -112,5 +112,5 @@ async def uninstall( @click.argument("pip_args", nargs=-1, default=None) @run_async async def list(pip_args: Optional[List[str]]): - proc = await call_pip_list(pip_args, sys.executable) + proc = await call_pip_list(pip_args, python_path=sys.executable) await proc.wait() diff --git a/nb_cli/handlers/meta.py b/nb_cli/handlers/meta.py index 98ee741..28c2b67 100644 --- a/nb_cli/handlers/meta.py +++ b/nb_cli/handlers/meta.py @@ -18,6 +18,7 @@ Callable, Optional, Coroutine, + cast, overload, ) @@ -101,7 +102,9 @@ def requires_python( ) -> Callable[P, Coroutine[Any, Any, R]]: @wraps(func) async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: - version = await get_python_version() + version = await get_python_version( + cast(Union[str, None], kwargs.get("python_path")) + ) if (version["major"], version["minor"]) >= REQUIRES_PYTHON: return await func(*args, **kwargs) @@ -143,7 +146,7 @@ def requires_nonebot( @wraps(func) @requires_python async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: - if await get_nonebot_version(): + if await get_nonebot_version(cast(Union[str, None], kwargs.get("python_path"))): return await func(*args, **kwargs) raise NoneBotNotInstalledError("NoneBot is not installed.") @@ -182,7 +185,7 @@ def requires_pip( @wraps(func) @requires_python async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: - if await get_pip_version(): + if await get_pip_version(cast(Union[str, None], kwargs.get("python_path"))): return await func(*args, **kwargs) raise PipNotInstalledError("pip is not installed.") diff --git a/nb_cli/handlers/pip.py b/nb_cli/handlers/pip.py index fbcca5c..c335d4e 100644 --- a/nb_cli/handlers/pip.py +++ b/nb_cli/handlers/pip.py @@ -9,6 +9,7 @@ async def call_pip_install( package: Union[str, List[str]], pip_args: Optional[List[str]] = None, + *, python_path: Optional[str] = None, stdin: Optional[Union[IO[Any], int]] = None, stdout: Optional[Union[IO[Any], int]] = None, @@ -39,6 +40,7 @@ async def call_pip_install( async def call_pip_update( package: Union[str, List[str]], pip_args: Optional[List[str]] = None, + *, python_path: Optional[str] = None, stdin: Optional[Union[IO[Any], int]] = None, stdout: Optional[Union[IO[Any], int]] = None, @@ -70,6 +72,7 @@ async def call_pip_update( async def call_pip_uninstall( package: Union[str, List[str]], pip_args: Optional[List[str]] = None, + *, python_path: Optional[str] = None, stdin: Optional[Union[IO[Any], int]] = None, stdout: Optional[Union[IO[Any], int]] = None, @@ -99,6 +102,7 @@ async def call_pip_uninstall( @requires_pip async def call_pip_list( pip_args: Optional[List[str]] = None, + *, python_path: Optional[str] = None, stdin: Optional[Union[IO[Any], int]] = None, stdout: Optional[Union[IO[Any], int]] = None, diff --git a/nb_cli/handlers/plugin.py b/nb_cli/handlers/plugin.py index db1c066..13ce661 100644 --- a/nb_cli/handlers/plugin.py +++ b/nb_cli/handlers/plugin.py @@ -14,7 +14,7 @@ @requires_nonebot -async def list_builtin_plugins(python_path: Optional[str] = None) -> List[str]: +async def list_builtin_plugins(*, python_path: Optional[str] = None) -> List[str]: if python_path is None: python_path = await get_default_python() diff --git a/nb_cli/handlers/project.py b/nb_cli/handlers/project.py index b3cb588..1053ede 100644 --- a/nb_cli/handlers/project.py +++ b/nb_cli/handlers/project.py @@ -53,6 +53,7 @@ async def run_project( adapters: Optional[List[SimpleInfo]] = None, builtin_plugins: Optional[List[str]] = None, exist_bot: Path = Path("bot.py"), + *, python_path: Optional[str] = None, cwd: Optional[Path] = None, stdin: Optional[Union[IO[Any], int]] = None, diff --git a/nb_cli/handlers/script.py b/nb_cli/handlers/script.py index fbd9a5f..cb0c679 100644 --- a/nb_cli/handlers/script.py +++ b/nb_cli/handlers/script.py @@ -16,7 +16,7 @@ @requires_python -async def list_scripts(python_path: Optional[str] = None) -> List[str]: +async def list_scripts(*, python_path: Optional[str] = None) -> List[str]: if python_path is None: python_path = await get_default_python() @@ -39,6 +39,7 @@ async def run_script( script_args: Optional[List[str]] = None, adapters: Optional[List[SimpleInfo]] = None, builtin_plugins: Optional[List[str]] = None, + *, python_path: Optional[str] = None, cwd: Optional[Path] = None, stdin: Optional[Union[IO[Any], int]] = None, diff --git a/nb_cli/handlers/venv.py b/nb_cli/handlers/venv.py index b67d95b..5939e9e 100644 --- a/nb_cli/handlers/venv.py +++ b/nb_cli/handlers/venv.py @@ -10,12 +10,13 @@ async def create_virtualenv( venv_dir: Path, prompt: Optional[str] = None, - python_interpreter: Optional[str] = None, + *, + python_path: Optional[str] = None, ): - if python_interpreter is None: - python_interpreter = await get_default_python() + if python_path is None: + python_path = await get_default_python() - args = ["--no-download", "--no-periodic-update", "--python", python_interpreter] + args = ["--no-download", "--no-periodic-update", "--python", python_path] if prompt is not None: args.extend(["--prompt", prompt]) diff --git a/nb_cli/locale/zh_CN/LC_MESSAGES/nb-cli.po b/nb_cli/locale/zh_CN/LC_MESSAGES/nb-cli.po index d2e2588..6baee45 100644 --- a/nb_cli/locale/zh_CN/LC_MESSAGES/nb-cli.po +++ b/nb_cli/locale/zh_CN/LC_MESSAGES/nb-cli.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: nb-cli 1.0.0\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-01-18 05:38+0000\n" +"POT-Creation-Date: 2023-01-18 09:46+0000\n" "PO-Revision-Date: 2023-01-11 08:56+0000\n" "Last-Translator: FULL NAME \n" "Language: zh_Hans_CN\n" @@ -46,7 +46,7 @@ msgstr "欢迎使用 NoneBot CLI!" msgid "What do you want to do?" msgstr "你想要进行什么操作?" -#: nb_cli/cli/commands/project.py:267 nb_cli/cli/customize.py:109 +#: nb_cli/cli/commands/project.py:294 nb_cli/cli/customize.py:109 msgid "The working directory." msgstr "工作目录." @@ -236,117 +236,125 @@ msgstr "使用的插件模板." msgid "Plugin name:" msgstr "插件名称:" -#: nb_cli/cli/commands/plugin.py:197 nb_cli/cli/commands/project.py:124 +#: nb_cli/cli/commands/plugin.py:197 nb_cli/cli/commands/project.py:126 msgid "Where to store the plugin?" msgstr "请输入插件存储位置:" -#: nb_cli/cli/commands/project.py:42 +#: nb_cli/cli/commands/project.py:44 msgid "bootstrap (for beginner or user)" msgstr "bootstrap (初学者或用户)" -#: nb_cli/cli/commands/project.py:43 +#: nb_cli/cli/commands/project.py:45 msgid "simple (for developer)" msgstr "simple (开发者)" -#: nb_cli/cli/commands/project.py:64 +#: nb_cli/cli/commands/project.py:66 msgid "Loading adapters..." msgstr "正在加载适配器..." -#: nb_cli/cli/commands/project.py:66 +#: nb_cli/cli/commands/project.py:68 msgid "Loading drivers..." msgstr "正在加载驱动器..." -#: nb_cli/cli/commands/project.py:71 +#: nb_cli/cli/commands/project.py:73 msgid "Project Name:" msgstr "项目名称:" -#: nb_cli/cli/commands/project.py:76 +#: nb_cli/cli/commands/project.py:78 msgid "Which driver(s) would you like to use?" msgstr "要使用哪些驱动器?" -#: nb_cli/cli/commands/project.py:94 +#: nb_cli/cli/commands/project.py:96 msgid "Which adapter(s) would you like to use?" msgstr "要使用哪些适配器?" -#: nb_cli/cli/commands/project.py:104 +#: nb_cli/cli/commands/project.py:106 msgid "You haven't chosen any adapter! Please confirm." msgstr "你没有选择任何适配器! 请确认." -#: nb_cli/cli/commands/project.py:120 +#: nb_cli/cli/commands/project.py:122 msgid "1) In a \"{dir_name}\" folder" msgstr "1) 在 \"{dir_name}\" 文件夹中" -#: nb_cli/cli/commands/project.py:121 +#: nb_cli/cli/commands/project.py:123 msgid "2) In a \"src\" folder" msgstr "2) 在 \"src\" 文件夹中" -#: nb_cli/cli/commands/project.py:141 +#: nb_cli/cli/commands/project.py:143 msgid "Create a NoneBot project." msgstr "创建一个 NoneBot 项目." -#: nb_cli/cli/commands/project.py:149 +#: nb_cli/cli/commands/project.py:151 msgid "The project template to use." msgstr "使用的项目模板." -#: nb_cli/cli/commands/project.py:154 +#: nb_cli/cli/commands/project.py:156 msgid "The python interpreter virtualenv is installed into." msgstr "虚拟环境使用的 Python 解释器." -#: nb_cli/cli/commands/project.py:171 +#: nb_cli/cli/commands/project.py:173 msgid "Select a template to use:" msgstr "选择一个要使用的模板:" -#: nb_cli/cli/commands/project.py:193 +#: nb_cli/cli/commands/project.py:195 msgid "Install dependencies now?" msgstr "立即安装依赖?" -#: nb_cli/cli/commands/project.py:206 +#: nb_cli/cli/commands/project.py:208 msgid "Create virtual environment?" msgstr "创建虚拟环境?" -#: nb_cli/cli/commands/project.py:214 +#: nb_cli/cli/commands/project.py:216 msgid "Creating virtual environment in {venv_dir} ..." msgstr "在 {venv_dir} 中创建虚拟环境..." -#: nb_cli/cli/commands/project.py:231 +#: nb_cli/cli/commands/project.py:238 +msgid "Which builtin plugin(s) would you like to use?" +msgstr "要使用哪些内置插件?" + +#: nb_cli/cli/commands/project.py:251 +msgid "Failed to add builtin plugins {builtin_plugins} to config: {e}" +msgstr "添加内置插件 {builtin_plugins} 到配置文件失败: {e}" + +#: nb_cli/cli/commands/project.py:258 msgid "Done!" msgstr "完成!" -#: nb_cli/cli/commands/project.py:233 +#: nb_cli/cli/commands/project.py:260 msgid "" "Add following packages to your project using dependency manager like " "poetry or pdm:" msgstr "使用 poetry 或 pdm 等依赖管理工具添加以下包:" -#: nb_cli/cli/commands/project.py:239 +#: nb_cli/cli/commands/project.py:266 msgid "Run the following command to start your bot:" msgstr "运行以下命令来启动你的机器人:" -#: nb_cli/cli/commands/project.py:250 +#: nb_cli/cli/commands/project.py:277 msgid "Generate entry file of your bot." msgstr "生成机器人的入口文件." -#: nb_cli/cli/commands/project.py:256 +#: nb_cli/cli/commands/project.py:283 msgid "The file script saved to." msgstr "脚本文件保存路径." -#: nb_cli/cli/commands/project.py:265 +#: nb_cli/cli/commands/project.py:292 msgid "Run the bot in current folder." msgstr "在当前文件夹中运行机器人." -#: nb_cli/cli/commands/project.py:273 +#: nb_cli/cli/commands/project.py:300 msgid "Exist entry file of your bot." msgstr "存在的机器人入口文件." -#: nb_cli/cli/commands/project.py:280 +#: nb_cli/cli/commands/project.py:307 msgid "Reload the bot when file changed." msgstr "当文件发生变化时重新加载机器人." -#: nb_cli/cli/commands/project.py:286 +#: nb_cli/cli/commands/project.py:313 msgid "Files to watch for changes." msgstr "要监视变化的文件." -#: nb_cli/cli/commands/project.py:292 +#: nb_cli/cli/commands/project.py:319 msgid "Files to ignore for changes." msgstr "要忽略变化的文件." diff --git a/nb_cli/template/scripts/plugin/list_builtin_plugin.py.jinja b/nb_cli/template/scripts/plugin/list_builtin_plugin.py.jinja index 85e9f28..02c3944 100644 --- a/nb_cli/template/scripts/plugin/list_builtin_plugin.py.jinja +++ b/nb_cli/template/scripts/plugin/list_builtin_plugin.py.jinja @@ -4,4 +4,4 @@ from pathlib import Path import nonebot d = Path(nonebot.__path__[0]) / "plugins" -print(json.dumps([p.stem for p in d.iterdir()])) +print(json.dumps([p.stem for p in d.iterdir() if not p.stem.startswith("_")]))