-
Notifications
You must be signed in to change notification settings - Fork 329
[fit] 新增build、package 命令 #297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
CodeCasterX
merged 3 commits into
ModelEngine-Group:main
from
Akeyiii:fit-feature-plugin-cli
Sep 24, 2025
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import json | ||
| import shutil | ||
| import uuid | ||
| import tarfile | ||
| from datetime import datetime | ||
| from pathlib import Path | ||
| from fit_cli.utils.build import calculate_checksum, parse_python_file, type_errors | ||
|
|
||
| def generate_tools_json(base_dir: Path, plugin_name: str): | ||
| """生成 tools.json""" | ||
| global type_errors | ||
| type_errors.clear() | ||
|
|
||
| src_dir = base_dir / "src" | ||
| if not src_dir.exists(): | ||
| print(f"❌ 未找到插件目录 {src_dir}") | ||
| return None | ||
|
|
||
| build_dir = base_dir / "build" | ||
| if not build_dir.exists(): | ||
| build_dir.mkdir(exist_ok=True) | ||
|
|
||
| tools_json = { | ||
| "version": "1.0.0", | ||
| "definitionGroups": [], | ||
| "toolGroups": [] | ||
| } | ||
| # 遍历src目录下的所有.py文件 | ||
| for py_file in src_dir.glob("**/*.py"): | ||
| # 跳过__init__.py文件 | ||
| if py_file.name == "__init__.py": | ||
| continue | ||
| # 解析 Python 文件 | ||
| definition_group, tool_groups = parse_python_file(py_file) | ||
| if definition_group is not None: | ||
| tools_json["definitionGroups"].append(definition_group) | ||
| if len(tool_groups) > 0: | ||
| tools_json["toolGroups"].extend(tool_groups) | ||
|
|
||
| if type_errors: | ||
| print("❌ tools.json 类型校验失败:") | ||
| for err in set(type_errors): | ||
| print(f" - {err}") | ||
| print("请修改为支持的类型:int, float, str, bool, dict, list, tuple, set, bytes") | ||
| return None # 终止构建 | ||
|
|
||
| path = build_dir / "tools.json" | ||
| path.write_text(json.dumps(tools_json, indent=2, ensure_ascii=False), encoding="utf-8") | ||
| print(f"✅ 已生成 {path}") | ||
| return tools_json | ||
|
|
||
|
|
||
| def generate_plugin_json(base_dir: Path, plugin_name: str): | ||
| """生成 plugin.json""" | ||
| build_dir = base_dir / "build" | ||
| tar_path = build_dir / f"{plugin_name}.tar" | ||
| if not tar_path.exists(): | ||
| print(f"❌ TAR 文件 {tar_path} 不存在,请先打包源代码") | ||
| return None | ||
|
|
||
| checksum = calculate_checksum(tar_path) | ||
| timestamp = datetime.now().strftime("%Y%m%d%H%M%S") | ||
| short_uuid = str(uuid.uuid4())[:8] | ||
| unique_name = f"{plugin_name}-{timestamp}-{short_uuid}" | ||
|
|
||
| plugin_json = { | ||
| "checksum": checksum, | ||
| "name": plugin_name, | ||
| "description": f"{plugin_name} 插件", | ||
| "type": "python", | ||
| "uniqueness": { | ||
| "name": unique_name | ||
| } | ||
| } | ||
| path = build_dir / "plugin.json" | ||
| path.write_text(json.dumps(plugin_json, indent=2, ensure_ascii=False), encoding="utf-8") | ||
| print(f"✅ 已生成 {path}") | ||
| return plugin_json | ||
|
|
||
|
|
||
| def make_plugin_tar(base_dir: Path, plugin_name: str): | ||
| """打包源代码为 tar 格式""" | ||
| build_dir = base_dir / "build" | ||
| if not build_dir.exists(): | ||
| build_dir.mkdir(exist_ok=True) | ||
|
|
||
| tar_path = build_dir / f"{plugin_name}.tar" | ||
| plugin_dir = base_dir | ||
|
|
||
| with tarfile.open(tar_path, "w") as tar: | ||
| # 遍历插件目录下的所有文件 | ||
| for item in plugin_dir.rglob("*"): | ||
| # 排除build目录及其内容 | ||
| if "build" in item.parts: | ||
| continue | ||
|
|
||
| if item.is_file(): | ||
| arcname = Path(plugin_name) / item.relative_to(plugin_dir) | ||
| tar.add(item, arcname=arcname) | ||
| print(f"✅ 已打包源代码 {tar_path}") | ||
|
|
||
|
|
||
| def run(args): | ||
| """build 命令入口""" | ||
| base_dir = Path("plugin") / args.name | ||
| plugin_name = args.name | ||
|
|
||
| if not base_dir.exists(): | ||
| print(f"❌ 插件目录 {base_dir} 不存在,请先运行 fit_cli init {args.name}") | ||
| return | ||
| # 生成 tools.json | ||
| tools_json = generate_tools_json(base_dir, plugin_name) | ||
| if tools_json is not None: | ||
| make_plugin_tar(base_dir, plugin_name) # 打包源代码 | ||
| generate_plugin_json(base_dir, plugin_name) # 生成 plugin.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import zipfile | ||
| from pathlib import Path | ||
|
|
||
| def package_to_zip(plugin_name: str): | ||
| """将 build 生成的文件打包为 zip""" | ||
| base_dir = Path("plugin") / plugin_name | ||
| build_dir = base_dir / "build" | ||
|
|
||
| # 待打包的文件列表 | ||
| files_to_zip = [ | ||
| build_dir / f"{plugin_name}.tar", | ||
| build_dir / "tools.json", | ||
| build_dir / "plugin.json" | ||
| ] | ||
|
|
||
| # 检查文件是否存在 | ||
| missing_files = [str(f) for f in files_to_zip if not f.exists()] | ||
| if missing_files: | ||
| print(f"❌ 缺少以下文件,请先执行 build 命令:{', '.join(missing_files)}") | ||
| return None | ||
|
|
||
| # 打包文件 | ||
| zip_path = build_dir / f"{plugin_name}_package.zip" | ||
| with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: | ||
| for file in files_to_zip: | ||
| zipf.write(file, arcname=file.name) | ||
|
|
||
| print(f"✅ 已生成打包文件:{zip_path}") | ||
| return zip_path | ||
|
|
||
|
|
||
| def run(args): | ||
| """package 命令入口""" | ||
| plugin_name = args.name | ||
| base_dir = Path("plugin") / plugin_name | ||
| build_dir = base_dir / "build" | ||
|
|
||
| if not base_dir.exists(): | ||
| print(f"❌ 插件目录 {base_dir} 不存在,请先运行 init 和 build 命令") | ||
| return | ||
| if not build_dir.exists(): | ||
| print(f"❌ 构建目录 {build_dir} 不存在,请先运行 build 命令") | ||
| return | ||
|
|
||
| package_to_zip(plugin_name) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,61 @@ | ||
| # FIT CLI 工具 | ||
|
|
||
| FIT CLI 工具是基于 **FIT Framework** 的命令行开发工具,提供插件初始化、打包、发布等功能,帮助用户快速开发和管理 FIT 插件。 | ||
| FIT CLI 工具是基于 **FIT Framework** 的命令行开发工具,提供插件初始化、构建、打包等功能,帮助用户快速开发和管理 FIT 插件。 | ||
|
|
||
| --- | ||
|
|
||
| ## 使用方式 | ||
|
|
||
| FIT CLI 支持 3 个核心子命令:init(初始化)、build(构建)、package(打包),以下是详细说明。 | ||
|
|
||
| ### init | ||
|
|
||
| 以 framework/fit/python 为项目根目录,运行: | ||
|
|
||
| ```bash | ||
| python -m fit_cli init %{your_plugin_name} | ||
| ``` | ||
| 将会在 plugin 目录中创建 %{your_plugin_name} 目录,并生成插件模板。 | ||
| · 参数:``%{your_plugin_name}``: 自定义插件名称 | ||
|
|
||
| 会在 ``plugin`` 目录中创建如下结构: | ||
|
|
||
| └── plugin/ | ||
| └──%{your_plugin_name}/ | ||
| └── src/ | ||
| ├── __init__.py | ||
| └── plugin.py # 插件源码模板 | ||
|
|
||
| ### build | ||
CodeCasterX marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| 在完成插件的开发后,执行 | ||
surpercodehang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ```bash | ||
| python -m fit_cli build %{your_plugin_name} | ||
surpercodehang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
| · 参数:``%{your_plugin_name}``: 插件目录名称 | ||
|
|
||
| 在 ``%{your_plugin_name}`` 目录生成: | ||
|
|
||
| └──%{your_plugin_name}/ | ||
| └── build/ | ||
| ├── %{your_plugin_name}.tar # 插件源码打包文件(工具包)。 | ||
| ├── tools.json # 工具的元数据。 | ||
| └── plugin.json # 插件的完整性校验与唯一性校验以及插件的基本信息。 | ||
|
|
||
| 开发者可根据自己的需要,修改完善``tools.json`` 和 ``plugin.json`` 文件,比如修改 ``description`` 、 ``uniqueness``等条目。 | ||
|
|
||
| ### package | ||
|
|
||
| 在完成插件的构建后,执行 | ||
| ```bash | ||
| python -m fit_cli package %{your_plugin_name} | ||
surpercodehang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
| · 参数:``%{your_plugin_name}``: 插件目录名称 | ||
|
|
||
| 在 ``plugin/%{your_plugin_name}/build/`` 目录生成最终打包文件: ``%{your_plugin_name}_package.zip`` | ||
|
|
||
| --- | ||
|
|
||
| ## 注意事项 | ||
|
|
||
| 1. 运行命令前,请切换至 framework/fit/python 项目根目录。 | ||
| 2. 更多详细信息和使用说明,可参考 https://github.com/ModelEngine-Group/fit-framework 官方仓库。 | ||
Empty file.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.