mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-09-20 08:58:03 +00:00
refactor(toolchain)!: 工具链 plugindev 更名为 hmapdev,module path 改回 gitcode
- 目录 tools/plugindev → tools/hmapdev,可执行文件名/平台产物名同步
(hmapdev_linux_amd64 等;包格式仍叫 .hmap)
- module path github.com/JianFeeeee/homeagent-sdk/tools/... → gitcode.com/...
(与仓库实际托管一致;核心仓不依赖该 path,改动无外部影响)
- SDK 存储目录 ~/.homeagent/plugindev/sdk → ~/.homeagent/hmapdev/sdk
新目录不存在而旧目录存在时沿用旧目录 → 已装 SDK 版本不会丢失
- 命令表/usage/--help/生成项目 README/示例 README/NSIS 安装器/
package/build.sh/build-examples.sh 全部同步;PLUGINDEV 环境变量保留兼容
- sdk/ 目录零改动(公开接口不变)
验证:
- go build ./... ok;go test ./tools/hmapdev/ ok(含模板接线守卫 TestProcTemplate_CoversAllCoreMethods)
- bash -n package/{build,build-examples}.sh ok
- 端到端:hmapdev init demo && hmapdev build → dist/demo_bundle.hmap(linux+darwin)
- 本机安装 /usr/local/bin/hmapdev,旧名以软链保留;sdk list/current 正常
This commit is contained in:
45
README.md
45
README.md
@ -25,8 +25,8 @@ HomeAgent 插件开发 SDK,用于构建与 HomeAgent 平台交互的智能插
|
||||
**1.1.x 插件升到 1.2.x:接口纯追加,但必须重编。** 公开接口没有签名变更(新增
|
||||
`InjectOptions` 与六个 `*Opts` 变体、`ChannelDef.ContextPolicy`),不调新能力就不受影响;
|
||||
但内核的**插件运行协议升到了 2**(统一共享内存区的 fd3 布局改变,**不支持滚动升级**),
|
||||
所以 `plugin.bin` 必须用配套的 `plugindev` 重编后与内核**同批**安装——否则握手时协议版本
|
||||
不匹配会被拒绝(错误信息会明确提示用配套 plugindev 重编,不会静默降级)。
|
||||
所以 `plugin.bin` 必须用配套的 `hmapdev` 重编后与内核**同批**安装——否则握手时协议版本
|
||||
不匹配会被拒绝(错误信息会明确提示用配套 hmapdev 重编,不会静默降级)。
|
||||
|
||||
## 注入行为与上下文裁剪(1.2.0)
|
||||
|
||||
@ -284,18 +284,23 @@ func New(name string, sett SettingsAPI, regTool ToolRegistrar, regStage StageReg
|
||||
|
||||
插件开发者只需实现 `Plugin` 接口并导出 `NewPluginFactory()` 入口函数。
|
||||
|
||||
## plugindev 工具链
|
||||
## hmapdev 工具链
|
||||
|
||||
`plugindev` 提供插件开发全流程支持。预编译二进制作为 **release 附件**分发(linux/darwin/windows × amd64/arm64),从
|
||||
`hmapdev` 提供插件开发全流程支持,最终产出 `.hmap` 插件包(工具名即来自该包格式)。
|
||||
预编译二进制作为 **release 附件**分发(linux/darwin/windows × amd64/arm64),从
|
||||
[Releases](https://gitcode.com/JianFeeeee/homeagent-sdk/releases) 下载后加入 PATH 即可:
|
||||
|
||||
> 改名说明:工具链原名 `plugindev`,自 1.2.0 起更名 `hmapdev`。
|
||||
> SDK 存储目录同时由 `~/.homeagent/plugindev/sdk` 迁到 `~/.homeagent/hmapdev/sdk`
|
||||
> (旧目录会被自动沿用,不会丢已装版本)。
|
||||
|
||||
```bash
|
||||
# 从 release 附件下载(以 v1.1.0 / linux amd64 为例)
|
||||
curl -Lo plugindev https://gitcode.com/JianFeeeee/homeagent-sdk/releases/download/v1.1.0/plugindev_linux_amd64
|
||||
chmod +x plugindev
|
||||
# 从 release 附件下载(以最新 SDK 发布 / linux amd64 为例)
|
||||
curl -Lo hmapdev https://gitcode.com/JianFeeeee/homeagent-sdk/releases/download/<版本>/hmapdev_linux_amd64
|
||||
chmod +x hmapdev
|
||||
|
||||
# 或从源码自己编
|
||||
cd tools/plugindev && go build -o plugindev .
|
||||
cd tools/hmapdev && go build -o hmapdev .
|
||||
```
|
||||
|
||||
> 二进制不再随仓库分发(旧的 `bin/` 目录已停用):5 个平台各 26-28MB,
|
||||
@ -303,11 +308,11 @@ cd tools/plugindev && go build -o plugindev .
|
||||
|
||||
| 命令 | 说明 |
|
||||
|------|------|
|
||||
| `plugindev init <name> [--lua]` | 初始化插件项目(生成 plg.json、plugin.go 或 main.lua、go.mod、README.md) |
|
||||
| `plugindev build [flags]` | 编译并打包为 `.hmap` 包(支持跨平台编译和 bundle 模式) |
|
||||
| `plugindev clean` | 清理 `build/`、`dist/` 目录及生成文件(plugin.json、z_bridge_gen.go) |
|
||||
| `plugindev debug [dir]` | 通过 Yaegi Go 解释器加载插件源码,启动交互式 REPL 调试 |
|
||||
| `plugindev sdk <command>` | SDK 版本管理(子命令:list/install/use/path/current/latest) |
|
||||
| `hmapdev init <name> [--lua]` | 初始化插件项目(生成 plg.json、plugin.go 或 main.lua、go.mod、README.md) |
|
||||
| `hmapdev build [flags]` | 编译并打包为 `.hmap` 包(支持跨平台编译和 bundle 模式) |
|
||||
| `hmapdev clean` | 清理 `build/`、`dist/` 目录及生成文件(plugin.json、z_bridge_gen.go) |
|
||||
| `hmapdev debug [dir]` | 通过 Yaegi Go 解释器加载插件源码,启动交互式 REPL 调试 |
|
||||
| `hmapdev sdk <command>` | SDK 版本管理(子命令:list/install/use/path/current/latest) |
|
||||
|
||||
支持 **Go** 和 **Lua** 两种插件语言。
|
||||
|
||||
@ -414,7 +419,7 @@ return plugin
|
||||
|
||||
- `sdk.RegisterOnRemoveHandler(fn func())` — 注册删除清理回调。内核在 `RemovePlugin` 流程中、插件 `Stop()` **之后**执行(后注册先执行,执行后清空、幂等)。用于删除插件自身创建的持久化文件(数据/缓存/状态文件)。
|
||||
- 内核卸载时一并清理:工具注册、`disabled_plugins` 记录、插件配置项定义(`plugin.<name>.*`)与插件配置表(`config_<name>`),卸载后插件配置区完全消失。
|
||||
- 示例:`example/calendar`(删 events.json)、`example/memo`(删 memos.json)、`example/rss`(删订阅数据目录)、`example/weather`(删缓存目录);`plugindev` 模板含 onRemove 演示。
|
||||
- 示例:`example/calendar`(删 events.json)、`example/memo`(删 memos.json)、`example/rss`(删订阅数据目录)、`example/weather`(删缓存目录);`hmapdev` 模板含 onRemove 演示。
|
||||
|
||||
```go
|
||||
sdk.RegisterOnRemoveHandler(func() {
|
||||
@ -488,7 +493,7 @@ ctx.Unlock()
|
||||
| [rss](example/rss) | Go | RSS 订阅 |
|
||||
| [sanitizer](example/sanitizer) | Go | 内容清洗/安全过滤 |
|
||||
|
||||
**发版时附带预编译示例产物**:SDK 的 release 除 5 平台 `plugindev` 外,还包含各示例插件的
|
||||
**发版时附带预编译示例产物**:SDK 的 release 除 5 平台 `hmapdev` 外,还包含各示例插件的
|
||||
`.hmap` 与 `SHA256SUMS`/`MANIFEST.txt`。原因是插件二进制与内核**协议绑定**(`ProtocolVersion`
|
||||
+ 共享内存区魔数),只发工具链不发示例产物,很容易拿旧产物去装而握手失败——那看起来像
|
||||
「插件坏了」而不是「版本不配套」。
|
||||
@ -594,10 +599,10 @@ ha_transport_t my_transport = {
|
||||
|
||||
### 使用方式
|
||||
|
||||
通过 `plugindev` 工具链初始化项目:
|
||||
通过 `hmapdev` 工具链初始化项目:
|
||||
|
||||
```bash
|
||||
plugindev init my-adapter --type remotedevice
|
||||
hmapdev init my-adapter --type remotedevice
|
||||
```
|
||||
|
||||
生成 `main.c` + `CMakeLists.txt`,可直接编译或作为三方库引入:
|
||||
@ -809,17 +814,17 @@ curl -X POST http://<homeagent-server>:8080/api/v1/device/esp32-cam-1/cmd \
|
||||
### 位置
|
||||
|
||||
- **SDK 源码**: `remotedevice/`
|
||||
- **plugindev 模板**: `plugindev init --type remotedevice`
|
||||
- **hmapdev 模板**: `hmapdev init --type remotedevice`
|
||||
|
||||
## 构建与安装
|
||||
|
||||
### 构建
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
输出 `.hmap` 包到 `dist/` 目录(默认 bundle 多平台合集;单平台构建使用 `plugindev build --no-bundle`)。
|
||||
输出 `.hmap` 包到 `dist/` 目录(默认 bundle 多平台合集;单平台构建使用 `hmapdev build --no-bundle`)。
|
||||
|
||||
### 安装
|
||||
|
||||
|
||||
45
README_EN.md
45
README_EN.md
@ -30,8 +30,8 @@ No public signature changed (the SDK adds `InjectOptions`, six `*Opts` variants
|
||||
`ChannelDef.ContextPolicy`), so not calling the new capabilities means not being affected — but the
|
||||
kernel's **plugin protocol went to 2** (the fd3 layout of the unified shared-memory region changed,
|
||||
and **rolling upgrades are not supported**). `plugin.bin` must therefore be rebuilt with the matching
|
||||
`plugindev` and installed **together with** the kernel; otherwise the handshake fails on protocol
|
||||
version mismatch (the error says explicitly to rebuild with the matching plugindev — it never
|
||||
`hmapdev` and installed **together with** the kernel; otherwise the handshake fails on protocol
|
||||
version mismatch (the error says explicitly to rebuild with the matching hmapdev — it never
|
||||
degrades silently).
|
||||
|
||||
## Injection Behaviour and Context Pruning (1.2.0)
|
||||
@ -303,19 +303,24 @@ func New(name string, sett SettingsAPI, regTool ToolRegistrar, regStage StageReg
|
||||
|
||||
Plugin developers only need to implement the `Plugin` interface and export a `NewPlugin()` entry function.
|
||||
|
||||
## plugindev Toolchain
|
||||
## hmapdev Toolchain
|
||||
|
||||
`plugindev` provides full development workflow support. Prebuilt binaries ship as **release assets**
|
||||
`hmapdev` provides full development workflow support and produces `.hmap` plugin bundles (the tool is
|
||||
named after that package format). Prebuilt binaries ship as **release assets**
|
||||
(linux/darwin/windows × amd64/arm64); download from
|
||||
[Releases](https://gitcode.com/JianFeeeee/homeagent-sdk/releases) and put it on your PATH:
|
||||
|
||||
> Rename note: the toolchain was called `plugindev` and is `hmapdev` since 1.2.0.
|
||||
> The SDK store moved from `~/.homeagent/plugindev/sdk` to `~/.homeagent/hmapdev/sdk`
|
||||
> (the old directory is still honored, so installed versions are not lost).
|
||||
|
||||
```bash
|
||||
# From release assets (v1.1.0 / linux amd64 shown)
|
||||
curl -Lo plugindev https://gitcode.com/JianFeeeee/homeagent-sdk/releases/download/v1.1.0/plugindev_linux_amd64
|
||||
chmod +x plugindev
|
||||
# From release assets (latest SDK release / linux amd64 shown)
|
||||
curl -Lo hmapdev https://gitcode.com/JianFeeeee/homeagent-sdk/releases/download/<version>/hmapdev_linux_amd64
|
||||
chmod +x hmapdev
|
||||
|
||||
# Or build from source
|
||||
cd tools/plugindev && go build -o plugindev .
|
||||
cd tools/hmapdev && go build -o hmapdev .
|
||||
```
|
||||
|
||||
> Binaries no longer ship inside the repository (the old `bin/` directory is retired): five
|
||||
@ -324,11 +329,11 @@ cd tools/plugindev && go build -o plugindev .
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `plugindev init <name> [--lua]` | Initialize plugin project (generates plg.json, plugin.go or main.lua, go.mod, README.md) |
|
||||
| `plugindev build [flags]` | Build and package into a `.hmap` (supports cross-compilation and bundle mode) |
|
||||
| `plugindev clean` | Clean `build/` and `dist/` plus generated files |
|
||||
| `plugindev debug [dir]` | Load plugin source through the Yaegi Go interpreter and start an interactive REPL |
|
||||
| `plugindev sdk <command>` | SDK version management (list/install/use/path/current/latest) |
|
||||
| `hmapdev init <name> [--lua]` | Initialize plugin project (generates plg.json, plugin.go or main.lua, go.mod, README.md) |
|
||||
| `hmapdev build [flags]` | Build and package into a `.hmap` (supports cross-compilation and bundle mode) |
|
||||
| `hmapdev clean` | Clean `build/` and `dist/` plus generated files |
|
||||
| `hmapdev debug [dir]` | Load plugin source through the Yaegi Go interpreter and start an interactive REPL |
|
||||
| `hmapdev sdk <command>` | SDK version management (list/install/use/path/current/latest) |
|
||||
|
||||
Supports both **Go** and **Lua** plugin languages.
|
||||
|
||||
@ -400,7 +405,7 @@ Supports both **Go** and **Lua** plugin languages.
|
||||
|
||||
- `sdk.RegisterOnRemoveHandler(fn func())` — Register a remove cleanup callback. The kernel runs it **after** the plugin's `Stop()` in the `RemovePlugin` flow (LIFO order, cleared after running — idempotent). Use it to delete persistent files the plugin created itself (data/cache/state files).
|
||||
- The kernel also cleans up on uninstall: tool registrations, the `disabled_plugins` record, the plugin's config definitions (`plugin.<name>.*`) and its config table (`config_<name>`) — the plugin's config section disappears completely after removal.
|
||||
- Examples: `example/calendar` (removes events.json), `example/memo` (removes memos.json), `example/rss` (removes the subscription data dir), `example/weather` (removes the cache dir); the `plugindev` template includes an onRemove demo.
|
||||
- Examples: `example/calendar` (removes events.json), `example/memo` (removes memos.json), `example/rss` (removes the subscription data dir), `example/weather` (removes the cache dir); the `hmapdev` template includes an onRemove demo.
|
||||
|
||||
```go
|
||||
sdk.RegisterOnRemoveHandler(func() {
|
||||
@ -476,7 +481,7 @@ Internal plugins (platform built-in) have full SDK access including SocialAPI wr
|
||||
| [rss](example/rss) | Go | RSS subscriptions |
|
||||
| [sanitizer](example/sanitizer) | Go | Content sanitization / safety filtering |
|
||||
|
||||
**Prebuilt example artifacts ship with every release**: besides the 5-platform `plugindev`, an SDK
|
||||
**Prebuilt example artifacts ship with every release**: besides the 5-platform `hmapdev`, an SDK
|
||||
release contains the example plugins' `.hmap` files plus `SHA256SUMS`/`MANIFEST.txt`. The reason is
|
||||
that plugin binaries are **protocol-bound** to the kernel (`ProtocolVersion` + the shared-memory
|
||||
magic), so shipping the toolchain without matching artifacts invites installing an old artifact —
|
||||
@ -567,10 +572,10 @@ ha_transport_t my_transport = {
|
||||
|
||||
### Usage
|
||||
|
||||
Initialize a project via the `plugindev` toolchain:
|
||||
Initialize a project via the `hmapdev` toolchain:
|
||||
|
||||
```bash
|
||||
plugindev init my-adapter --type remotedevice
|
||||
hmapdev init my-adapter --type remotedevice
|
||||
```
|
||||
|
||||
Generates `main.c` + `CMakeLists.txt`, can be built directly or used as a third-party library:
|
||||
@ -780,17 +785,17 @@ curl -X POST http://<homeagent-server>:8080/api/v1/device/esp32-cam-1/cmd \
|
||||
### Location
|
||||
|
||||
- **SDK Source**: `remotedevice/`
|
||||
- **plugindev template**: `plugindev init --type remotedevice`
|
||||
- **hmapdev template**: `hmapdev init --type remotedevice`
|
||||
|
||||
## Building & Installing
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
Outputs a `.hmap` package to the `dist/` directory (default is the multi-platform bundle; use `plugindev build --no-bundle` for a single-target build).
|
||||
Outputs a `.hmap` package to the `dist/` directory (default is the multi-platform bundle; use `hmapdev build --no-bundle` for a single-target build).
|
||||
|
||||
### Install
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ ai_image plugin
|
||||
## Build
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
@ -5,7 +5,7 @@ calendar plugin
|
||||
## Build
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
@ -17,7 +17,7 @@ lua main.lua # 使用 sdk.lua mock,不依赖内核
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## 安装
|
||||
|
||||
@ -5,7 +5,7 @@ rss plugin
|
||||
## Build
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
@ -5,7 +5,7 @@ weather plugin
|
||||
## Build
|
||||
|
||||
```bash
|
||||
plugindev build
|
||||
hmapdev build
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
@ -61,7 +61,7 @@ var (
|
||||
// SDKName 是 SDK 名称。
|
||||
SDKName = "HomeAgent SDK"
|
||||
|
||||
// CoreModule 是核心仓的 Go module path,供 plugindev 生成 go.mod 时使用。
|
||||
// CoreModule 是核心仓的 Go module path,供 hmapdev 生成 go.mod 时使用。
|
||||
CoreModule = "gitcode.com/JianFeeeee/HomeAgent"
|
||||
|
||||
// CoreVersion 是此 SDK 所兼容的最低核心版本。
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
# <OUT_DIR>/MANIFEST.txt 版本、协议版本、产自哪个 commit
|
||||
#
|
||||
# 纪律(与本项目其它构建脚本一致):
|
||||
# 1. 判成功看**产物是否存在**,不看退出码——plugindev 对部分错误只打印不退出。
|
||||
# 1. 判成功看**产物是否存在**,不看退出码——hmapdev 对部分错误只打印不退出。
|
||||
# 2. SHA256SUMS 必须在全部产物生成完毕后一次算完,边打边算会漏掉后生成的包。
|
||||
set -uo pipefail
|
||||
|
||||
@ -67,14 +67,15 @@ fi
|
||||
|
||||
# 1) 先保证工具链可用:示例必须用**本仓当前源码**构建,否则产物协议与这一版 SDK 不符。
|
||||
# 允许外部指定(发版脚本会在跨平台构建后把刚产出的工具链路径传进来)。
|
||||
PLUGINDEV="${PLUGINDEV:-$SDK_ROOT/build/plugindev}"
|
||||
# 工具链二进制名由 plugindev 改为 hmapdev;旧变量名 PLUGINDEV 仍兼容。
|
||||
HMAPDEV="${HMAPDEV:-${PLUGINDEV:-$SDK_ROOT/build/hmapdev}}"
|
||||
if [ ! -x "$PLUGINDEV" ]; then
|
||||
echo "[examples] 先构建 plugindev ..."
|
||||
( cd "$SDK_ROOT/tools/plugindev" && "$GO" build -o "$PLUGINDEV" . ) || {
|
||||
echo "[examples] plugindev 构建失败,无法继续" >&2; exit 1; }
|
||||
echo "[examples] 先构建 hmapdev ..."
|
||||
( cd "$SDK_ROOT/tools/hmapdev" && "$GO" build -o "$HMAPDEV" . ) || {
|
||||
echo "[examples] hmapdev 构建失败,无法继续" >&2; exit 1; }
|
||||
fi
|
||||
if [ ! -x "$PLUGINDEV" ]; then
|
||||
echo "[examples] plugindev 不存在或不可执行:$PLUGINDEV" >&2
|
||||
echo "[examples] hmapdev 不存在或不可执行:$HMAPDEV" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -100,7 +101,7 @@ for dir in "$SDK_ROOT"/example/*/; do
|
||||
rc=$?
|
||||
|
||||
# 判据是**退出码 + 产物存在**,两者都要。
|
||||
# 只看退出码:plugindev 曾经出错也退 0(已修,但脚本不该依赖它「现在」是对的)。
|
||||
# 只看退出码:hmapdev 曾经出错也退 0(已修,但脚本不该依赖它「现在」是对的)。
|
||||
# 只看产物:部分平台失败时会留下上一次的产物,看起来像成功。
|
||||
hmap="$(ls "$dir"/dist/*.hmap 2>/dev/null | head -1)"
|
||||
if [ $rc -eq 0 ] && [ -n "$hmap" ]; then
|
||||
|
||||
@ -28,7 +28,7 @@ case "$TARGET" in
|
||||
;;
|
||||
*)
|
||||
echo "Unknown target: $TARGET"
|
||||
echo "Usage: $0 [native|linux/amd64|linux/arm64|darwin/amd64|darwin/arm64|windows/amd64|all] [all|plugindev|examples]"
|
||||
echo "Usage: $0 [native|linux/amd64|linux/arm64|darwin/amd64|darwin/arm64|windows/amd64|all] [all|hmapdev|examples]"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
@ -42,12 +42,12 @@ export CGO_ENABLED=0
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
build_plugindev() {
|
||||
local src="tools/plugindev"
|
||||
local out="$BUILD_DIR/plugindev${SUFFIX:+_$SUFFIX}"
|
||||
build_hmapdev() {
|
||||
local src="tools/hmapdev"
|
||||
local out="$BUILD_DIR/hmapdev${SUFFIX:+_$SUFFIX}"
|
||||
if [ "$GOOS" = "windows" ]; then out="${out}.exe"; fi
|
||||
|
||||
echo "[BUILD] plugindev ${GOOS:-linux}/${GOARCH:-amd64} → $out"
|
||||
echo "[BUILD] hmapdev ${GOOS:-linux}/${GOARCH:-amd64} → $out"
|
||||
cd "$PROJECT_ROOT/$src"
|
||||
"$GO" build -trimpath -ldflags "-X gitcode.com/JianFeeeee/homeagent-sdk/meta.Version=${VERSION}" \
|
||||
-o "$out" .
|
||||
@ -64,7 +64,7 @@ build_plugindev() {
|
||||
#
|
||||
# 用刚构建出来的那把工具链(而非 PATH 里的),保证产物与本次发版同源。
|
||||
build_examples() {
|
||||
local dev="$BUILD_DIR/plugindev${SUFFIX:+_$SUFFIX}"
|
||||
local dev="$BUILD_DIR/hmapdev${SUFFIX:+_$SUFFIX}"
|
||||
[ "$GOOS" = "windows" ] && dev="${dev}.exe"
|
||||
echo "[BUILD] example plugins ${GOOS:-linux}/${GOARCH:-amd64} → $BUILD_DIR/examples"
|
||||
PLUGINDEV="$dev" VERSION="$VERSION" bash "$PROJECT_ROOT/package/build-examples.sh" "$TARGET" "$BUILD_DIR/examples"
|
||||
@ -74,10 +74,10 @@ build_examples() {
|
||||
case "$COMPONENT" in
|
||||
all)
|
||||
# 工具链必须先建完:示例用它来构建(同源保证协议一致)。
|
||||
build_plugindev
|
||||
build_hmapdev
|
||||
build_examples
|
||||
;;
|
||||
plugindev) build_plugindev ;;
|
||||
hmapdev) build_hmapdev ;;
|
||||
examples) build_examples ;;
|
||||
*)
|
||||
echo "Unknown component: $COMPONENT"
|
||||
|
||||
@ -48,7 +48,7 @@ Function pageConfirm
|
||||
${EndIf}
|
||||
${NSD_CreateLabel} 0 5u 100% 12u "将安装以下组件:"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 15u 20u 100% 12u "• plugindev.exe — 插件开发工具"
|
||||
${NSD_CreateLabel} 15u 20u 100% 12u "• hmapdev.exe — 插件开发工具"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 15u 35u 100% 12u "• SDK ${SDK_VERSION} — 将从远程仓库自动下载"
|
||||
Pop $0
|
||||
@ -64,11 +64,11 @@ Section "Install" SEC_INSTALL
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
DetailPrint "复制工具链文件..."
|
||||
File "plugindev.exe"
|
||||
File "hmapdev.exe"
|
||||
|
||||
DetailPrint "创建快捷方式..."
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\plugindev.lnk" "$INSTDIR\plugindev.exe" "" "$INSTDIR\plugindev.exe" 0
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\hmapdev.lnk" "$INSTDIR\hmapdev.exe" "" "$INSTDIR\hmapdev.exe" 0
|
||||
|
||||
DetailPrint "配置环境变量..."
|
||||
; Add to system PATH
|
||||
@ -93,23 +93,23 @@ Section "Install" SEC_INSTALL
|
||||
DetailPrint "Git 已安装: $1"
|
||||
${Else}
|
||||
DetailPrint "未检测到 Git,将跳过 SDK 自动下载"
|
||||
DetailPrint "安装完成后请手动运行: plugindev sdk install ${SDK_VERSION}"
|
||||
DetailPrint "安装完成后请手动运行: hmapdev sdk install ${SDK_VERSION}"
|
||||
${EndIf}
|
||||
|
||||
${If} $hasGit == "1"
|
||||
DetailPrint "正在下载 SDK ${SDK_VERSION}..."
|
||||
nsExec::ExecToStack '"$INSTDIR\plugindev.exe" sdk install ${SDK_VERSION}'
|
||||
nsExec::ExecToStack '"$INSTDIR\hmapdev.exe" sdk install ${SDK_VERSION}'
|
||||
Pop $0
|
||||
Pop $1
|
||||
${If} $0 == 0
|
||||
StrCpy $sdkInstallOk "1"
|
||||
DetailPrint "SDK ${SDK_VERSION} 下载完成"
|
||||
DetailPrint "正在激活 SDK ${SDK_VERSION}..."
|
||||
nsExec::Exec '"$INSTDIR\plugindev.exe" sdk use ${SDK_VERSION}'
|
||||
nsExec::Exec '"$INSTDIR\hmapdev.exe" sdk use ${SDK_VERSION}'
|
||||
Pop $0
|
||||
${Else}
|
||||
DetailPrint "SDK 下载失败 (错误码: $0)"
|
||||
DetailPrint "请手动运行: plugindev sdk install ${SDK_VERSION}"
|
||||
DetailPrint "请手动运行: hmapdev sdk install ${SDK_VERSION}"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
@ -126,10 +126,10 @@ SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
Delete "$INSTDIR\plugindev.exe"
|
||||
Delete "$INSTDIR\hmapdev.exe"
|
||||
RMDir /r "$INSTDIR\sdk"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\plugindev.lnk"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\hmapdev.lnk"
|
||||
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SDK_DIR"
|
||||
DeleteRegKey HKLM "Software\Microsoft\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
|
||||
@ -441,8 +441,8 @@ func ensureSDKResolvable(plg *PlgConfig, sdkModule, sdkPath string) {
|
||||
fmt.Printf(" %s\n", strings.TrimSpace(string(out)))
|
||||
}
|
||||
fmt.Printf(" 提示:%s 不在公共 proxy 上。用以下任一方式指向本机 SDK:\n", sdkModule)
|
||||
fmt.Printf(" plugindev sdk install latest # 装一份到 ~/.homeagent/plugindev/sdk\n")
|
||||
fmt.Printf(" plugindev build --sdk-path <路径> # 或直接指定源码目录\n")
|
||||
fmt.Printf(" hmapdev sdk install latest # 装一份到 ~/.homeagent/hmapdev/sdk\n")
|
||||
fmt.Printf(" hmapdev build --sdk-path <路径> # 或直接指定源码目录\n")
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,17 +457,12 @@ func findLocalSDK(sdkPath string) string {
|
||||
candidates = append(candidates, abs)
|
||||
}
|
||||
}
|
||||
// plugindev 自身所在位置往上三级(tools/plugindev/plugindev → SDK 根)
|
||||
// hmapdev 自身所在位置往上三级(tools/hmapdev/hmapdev → SDK 根)
|
||||
if self, err := os.Executable(); err == nil {
|
||||
candidates = append(candidates, filepath.Dir(filepath.Dir(filepath.Dir(self))))
|
||||
}
|
||||
// plugindev sdk use 选定的版本
|
||||
store := os.Getenv("HOMEAGENT_SDK_DIR")
|
||||
if store == "" {
|
||||
if home, err := os.UserHomeDir(); err == nil {
|
||||
store = filepath.Join(home, ".homeagent", "plugindev", "sdk")
|
||||
}
|
||||
}
|
||||
// hmapdev sdk use 选定的版本(复用 sdkStore(),含改名前的旧目录回退)
|
||||
store := sdkStore()
|
||||
if store != "" {
|
||||
if d, err := os.ReadFile(filepath.Join(store, "current")); err == nil {
|
||||
if ver := strings.TrimSpace(string(d)); ver != "" {
|
||||
@ -511,7 +506,7 @@ func resolveSDKPath(sdkPath string) string {
|
||||
fmt.Printf("error: --sdk-path %q not a valid SDK\n", sdkPath)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Detect from plugindev's own location (internal dev)
|
||||
// Detect from hmapdev's own location (internal dev)
|
||||
self, err := os.Executable()
|
||||
if err == nil {
|
||||
cand := filepath.Dir(filepath.Dir(filepath.Dir(self)))
|
||||
@ -519,14 +514,8 @@ func resolveSDKPath(sdkPath string) string {
|
||||
return cand
|
||||
}
|
||||
}
|
||||
// Active SDK via plugindev sdk use
|
||||
store := os.Getenv("HOMEAGENT_SDK_DIR")
|
||||
if store == "" {
|
||||
home, _ := os.UserHomeDir()
|
||||
if home != "" {
|
||||
store = filepath.Join(home, ".homeagent", "plugindev", "sdk")
|
||||
}
|
||||
}
|
||||
// Active SDK via hmapdev sdk use
|
||||
store := sdkStore()
|
||||
if store != "" {
|
||||
if d, err := os.ReadFile(filepath.Join(store, "current")); err == nil {
|
||||
ver := strings.TrimSpace(string(d))
|
||||
@ -538,7 +527,7 @@ func resolveSDKPath(sdkPath string) string {
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("error: cannot locate SDK. Use --sdk-path or 'plugindev sdk use'\n")
|
||||
fmt.Printf("error: cannot locate SDK. Use --sdk-path or 'hmapdev sdk use'\n")
|
||||
os.Exit(1)
|
||||
return ""
|
||||
}
|
||||
@ -7,12 +7,12 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/JianFeeeee/homeagent-sdk/tools/plugindev/yaegi"
|
||||
"gitcode.com/JianFeeeee/homeagent-sdk/tools/hmapdev/yaegi"
|
||||
)
|
||||
|
||||
// tmplLuaDebug is the temporary Lua debug script template
|
||||
const tmplLuaDebug = `-- HomeAgent Lua Plugin Debug
|
||||
-- Generated by plugindev debug --lua
|
||||
-- Generated by hmapdev debug --lua
|
||||
sdk = require("sdk")
|
||||
local ok, plugin = pcall(dofile, "main.lua")
|
||||
if not ok then
|
||||
@ -115,7 +115,7 @@ func debugLua(dir, sdkPath, luaPath string) {
|
||||
luaBin, err := exec.LookPath("lua")
|
||||
if err != nil {
|
||||
fmt.Println("error: lua interpreter not found in PATH")
|
||||
fmt.Println(" install Lua 5.1+ or use plugindev build to compile your plugin")
|
||||
fmt.Println(" install Lua 5.1+ or use hmapdev build to compile your plugin")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ type TemplateData struct {
|
||||
// SDKLocalPath 是本机 SDK 源码绝对路径,写入生成的 go.mod 作为 replace 目标。
|
||||
//
|
||||
// 为何必须写:gitcode 的模块不在 proxy.golang.org 上,只 require 一个
|
||||
// 版本号的 go.mod 配上缺失的 go.sum,新用户第一次 `plugindev build`
|
||||
// 版本号的 go.mod 配上缺失的 go.sum,新用户第一次 `hmapdev build`
|
||||
// 必定死在 "missing go.sum entry",而 `go mod tidy` 又会去公共 proxy 拉
|
||||
// 一个不存在的条目。有了本地 replace,go 完全不需要 go.sum 条目。
|
||||
SDKLocalPath string
|
||||
@ -71,7 +71,7 @@ type TemplateData struct {
|
||||
|
||||
func cmdInit(args []string) {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Usage: plugindev init <name> [--lua] [--type remotedevice]")
|
||||
fmt.Println("Usage: hmapdev init <name> [--lua] [--type remotedevice]")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ func cmdInit(args []string) {
|
||||
if isLua {
|
||||
fmt.Printf(" cd %s && lua main.lua (standalone test)\n", dir)
|
||||
}
|
||||
fmt.Printf(" cd %s && plugindev build\n", dir)
|
||||
fmt.Printf(" cd %s && hmapdev build\n", dir)
|
||||
}
|
||||
|
||||
// detectSDKInfo reads the HomeAgent SDK's go.mod and meta to get module path, go version, and SDK version.
|
||||
@ -14,7 +14,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const sdkDirName = "plugindev/sdk"
|
||||
const sdkDirName = "hmapdev/sdk"
|
||||
|
||||
// legacySDKDirName 是改名前的存储目录。工具链在 1.2.0 从 plugindev 改名 hmapdev;
|
||||
// 已装过旧版的机器上 SDK 仍在旧路径,直接换名会让它找不到已装 SDK
|
||||
// (表现为「没有活动版本」)。新目录不存在而旧目录存在时沿用旧目录。
|
||||
const legacySDKDirName = "plugindev/sdk"
|
||||
|
||||
// sdkStore returns the root directory for stored SDK versions.
|
||||
func sdkStore() string {
|
||||
@ -26,7 +31,15 @@ func sdkStore() string {
|
||||
fmt.Printf("error: cannot determine home directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return filepath.Join(home, ".homeagent", sdkDirName)
|
||||
dir := filepath.Join(home, ".homeagent", sdkDirName)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
if legacy := filepath.Join(home, ".homeagent", legacySDKDirName); legacy != "" {
|
||||
if _, err := os.Stat(legacy); err == nil {
|
||||
return legacy
|
||||
}
|
||||
}
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
func sdkCurrentDir() string {
|
||||
@ -50,13 +63,13 @@ func cmdSDK(args []string) {
|
||||
cmdSDKList()
|
||||
case "install":
|
||||
if len(args) < 2 {
|
||||
fmt.Println("Usage: plugindev sdk install <version>")
|
||||
fmt.Println("Usage: hmapdev sdk install <version>")
|
||||
os.Exit(1)
|
||||
}
|
||||
cmdSDKInstall(args[1])
|
||||
case "use":
|
||||
if len(args) < 2 {
|
||||
fmt.Println("Usage: plugindev sdk use <version>")
|
||||
fmt.Println("Usage: hmapdev sdk use <version>")
|
||||
os.Exit(1)
|
||||
}
|
||||
cmdSDKUse(args[1])
|
||||
@ -72,7 +85,7 @@ func cmdSDK(args []string) {
|
||||
}
|
||||
|
||||
func sdkHelp() {
|
||||
fmt.Print(`Usage: plugindev sdk <command>
|
||||
fmt.Print(`Usage: hmapdev sdk <command>
|
||||
|
||||
Manage installed HomeAgent SDK versions.
|
||||
|
||||
@ -85,9 +98,9 @@ Commands:
|
||||
latest Show the latest available version from remote
|
||||
|
||||
Examples:
|
||||
plugindev sdk install v0.7.1
|
||||
plugindev sdk install latest
|
||||
plugindev sdk use v0.7.1
|
||||
hmapdev sdk install v0.7.1
|
||||
hmapdev sdk install latest
|
||||
hmapdev sdk use v0.7.1
|
||||
`)
|
||||
}
|
||||
|
||||
@ -127,7 +140,7 @@ func cmdSDKList() {
|
||||
fmt.Printf(" %s %s\n", mark, v)
|
||||
}
|
||||
if current == "" {
|
||||
fmt.Println("\nNo version active. Use 'plugindev sdk use <version>' to set one.")
|
||||
fmt.Println("\nNo version active. Use 'hmapdev sdk use <version>' to set one.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +305,7 @@ func cmdSDKUse(version string) {
|
||||
verDir := sdkVersionDir(version)
|
||||
if _, err := os.Stat(verDir); os.IsNotExist(err) {
|
||||
fmt.Printf("SDK version %s is not installed.\n", version)
|
||||
fmt.Printf("Install it first: plugindev sdk install %s\n", version)
|
||||
fmt.Printf("Install it first: hmapdev sdk install %s\n", version)
|
||||
os.Exit(1)
|
||||
}
|
||||
setCurrentVersion(store, version)
|
||||
@ -305,7 +318,7 @@ func cmdSDKPath() {
|
||||
current := resolveCurrentVersion(store)
|
||||
if current == "" {
|
||||
fmt.Println("No active SDK version set.")
|
||||
fmt.Println("Use 'plugindev sdk use <version>' to set one.")
|
||||
fmt.Println("Use 'hmapdev sdk use <version>' to set one.")
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(sdkVersionDir(current))
|
||||
@ -440,21 +453,21 @@ func parseSemver(tag string) [3]int {
|
||||
}
|
||||
|
||||
// activeSDKRoot returns the path to the active SDK root.
|
||||
// It replaces the old runtime.Caller(0) approach so plugindev can work
|
||||
// It replaces the old runtime.Caller(0) approach so hmapdev can work
|
||||
// independently of its own build location.
|
||||
func activeSDKRoot() string {
|
||||
store := sdkStore()
|
||||
current := resolveCurrentVersion(store)
|
||||
if current == "" {
|
||||
fmt.Printf("error: no active SDK version set\n")
|
||||
fmt.Printf(" Install one: plugindev sdk install latest\n")
|
||||
fmt.Printf(" Or set one: plugindev sdk use <version>\n")
|
||||
fmt.Printf(" Install one: hmapdev sdk install latest\n")
|
||||
fmt.Printf(" Or set one: hmapdev sdk use <version>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
root := sdkVersionDir(current)
|
||||
if _, err := os.Stat(root); os.IsNotExist(err) {
|
||||
fmt.Printf("error: active SDK version %s not found at %s\n", current, root)
|
||||
fmt.Printf(" Reinstall: plugindev sdk install %s\n", current)
|
||||
fmt.Printf(" Reinstall: hmapdev sdk install %s\n", current)
|
||||
os.Exit(1)
|
||||
}
|
||||
return root
|
||||
@ -1,4 +1,4 @@
|
||||
module github.com/JianFeeeee/homeagent-sdk/tools/plugindev
|
||||
module gitcode.com/JianFeeeee/homeagent-sdk/tools/hmapdev
|
||||
|
||||
go 1.21.0
|
||||
|
||||
@ -30,14 +30,14 @@ func help() {
|
||||
fmt.Print(`HomeAgent Plugin Dev Tool
|
||||
|
||||
Usage:
|
||||
plugindev init <name> Scaffold a new plugin project
|
||||
plugindev init <name> --lua Create Lua plugin
|
||||
plugindev init <name> --type remotedevice
|
||||
hmapdev init <name> Scaffold a new plugin project
|
||||
hmapdev init <name> --lua Create Lua plugin
|
||||
hmapdev init <name> --type remotedevice
|
||||
Create C remote device adapter
|
||||
plugindev build [flags] Compile and package plugin
|
||||
plugindev clean Clean build/dist artifacts
|
||||
plugindev debug [dir] Interpret and debug plugin source
|
||||
plugindev sdk <command> Manage SDK versions
|
||||
hmapdev build [flags] Compile and package plugin
|
||||
hmapdev clean Clean build/dist artifacts
|
||||
hmapdev debug [dir] Interpret and debug plugin source
|
||||
hmapdev sdk <command> Manage SDK versions
|
||||
|
||||
Flags:
|
||||
--outdir Output directory (default: dist)
|
||||
@ -56,7 +56,7 @@ const procGenFile = "z_proc_gen.go"
|
||||
// generateProcRuntime 把子进程运行时(平台无关主体 + 两个平台挂载实现)
|
||||
// 写入插件目录,返回清理函数。
|
||||
func generateProcRuntime() (func(), error) {
|
||||
// 清理历史 C ABI 产物:旧版 plugindev 生成过这两个文件,残留下来会与
|
||||
// 清理历史 C ABI 产物:旧版 hmapdev(原名 plugindev)生成过这两个文件,残留下来会与
|
||||
// 本模板的 main 冲突。无需人工清理就能从旧版升级。
|
||||
for _, stale := range []string{"z_bridge_gen.go", "z_entry.c"} {
|
||||
os.Remove(stale)
|
||||
@ -511,7 +511,7 @@ const tmplReadme = `# {{.Plg.Name}}
|
||||
## Build
|
||||
|
||||
` + "```bash" + `
|
||||
plugindev build
|
||||
hmapdev build
|
||||
` + "```" + `
|
||||
|
||||
## Install
|
||||
@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/traefik/yaegi/interp"
|
||||
"github.com/traefik/yaegi/stdlib"
|
||||
"github.com/JianFeeeee/homeagent-sdk/tools/plugindev/yaegi/mocksdk"
|
||||
"gitcode.com/JianFeeeee/homeagent-sdk/tools/hmapdev/yaegi/mocksdk"
|
||||
)
|
||||
|
||||
type YaegiDebugger struct {
|
||||
Reference in New Issue
Block a user