將現有的外掛程式遷移至子工具

為何要遷移

新的 FHO 子工具程式庫提供了一些實用的巨集,方便您將現有外掛程式遷移至新的子工具介面。將外掛程式遷移至子工具能享有以下好處:

  • 針對錯誤提供更明確的介面邊界。
  • 型別安全機器 writer 輸出,最終結構定義驗證。
  • 子工具從沙發和 ffx 環境取得更彈性的輸入資料 (請參閱上方連結的 FHO 文件)。
  • 魔術效果更少,
  • ffx 本身分開建構時的建構時間加快。

請注意,當您要啟動新的子工具時,可以略過舊版外掛程式系統涉及的許多步驟,因此請改為按照入門操作說明進行。

非遞迴外掛程式

沒有子外掛程式且 ffx_plugin() 動作中沒有 plugin_deps 區段的外掛程式相對容易遷移。遷移具有子外掛程式的外掛程式會視為單獨的工作。

下列操作說明主要取決於最初編寫的 ffx daemon echo 外掛程式與 ffx echo 子工具 (用於開發新子工具介面的概念驗證) 之間的差異。

遷移 Rust lib.rs

假設有一個外掛程式 lib.rs 檔案,看起來如下:

use anyhow::Result;
use ffx_core::ffx_plugin;
use ffx_echo_args::EchoCommand;
use ffx_writer::Writer;
use fidl_fuchsia_developer_ffx::EchoProxy;

#[ffx_plugin(EchoProxy = "daemon::protocol")]
pub async fn echo(echo_proxy: EchoProxy, cmd: EchoCommand, #[ffx(machine = String)] mut writer: Writer) -> Result<()> {
    // implementation here
    Ok(())
}

如要遷移至新外掛程式系統,最簡單的方法是移除 #[ffx_plugin] 巨集,並新增以下衍生巨集程式碼:

use fho::{FfxTool, FfxMain, MachineWriter, Result};
use ffx_echo_args::EchoCommand;
use fidl_fuchsia_developer_ffx::EchoProxy;

#[derive(FfxTool)]
pub struct EchoTool {
    #[command]
    cmd: EchoCommand,
    #[with(fho::daemon_protocol())]
    echo_proxy: ffx::EchoProxy,
}

#[async_trait(?Send)]
impl FfxMain for EchoTool {
    type Writer = MachineWriter<String>;
    async fn main(self, writer: MachineWriter<String>) -> Result<()> {
        // implementation here
        Ok(())
    }
}

與先前的巨集不同的是,為 EchoTool 結構體的成員命名沒有任何限制。如果您想執行更複雜的操作,甚至可以從 FHO 衍生特徵來實作自己的載入器。

將這個結構與寫入者視為移動的物件,為 main() 函式提供移動的物件,因此您可以視需要自行解構。

另請注意,Result 類型來自 FHO,而非 anyhow。在這個邊界內,現在有特定的錯誤類型,其中保留錯誤是否可向使用者顯示及呈現方式。如要進一步瞭解如何處理此錯誤類型,以及這類錯誤與 ffx_errorffx_bail 巨集的互動方式,請參閱錯誤

目前遷移的外掛程式大多仍須納入主要 ffx 二進位檔中,也就是說,你還需要新增下列巨集叫用,才能產生舊版外掛程式進入點:

fho::embedded_plugin!(EchoTool);

新增 main.rs

由於現在子工具可以獨立執行,因此您需要新增簡單的 main.rs 來呼叫 FHO,讓外掛程式程式庫在 ffx 叫用時正確執行:

use ffx_tool_echo::EchoTool;
use fho::FfxTool;

#[fuchsia_async::run_singlethreaded]
async fn main() {
    EchoTool::execute_tool().await
}

一般來說,您不會遇到 main.rs 較為複雜。

適用於頂層外掛程式的 BUILD.gn

針對仍需與現有 ffx 外掛程式系統整合的現有外掛程式,這些外掛程式將繼續使用 ffx_plugin GN 動作,因為會正確設定所有依附元件,並新增至 ffx 二進位檔。

如果外掛程式是 ffx 的頂層子指令,我們也會新增 ffx_tool() 動作來建構單獨編譯的外掛程式:

# Existing import for the plugin action
import("//src/developer/ffx/build/ffx_plugin.gni")
# New import for the ffx_tool action.
import("//src/developer/ffx/build/ffx_tool.gni")

ffx_plugin("ffx_echo") {
  version = "0.1.0"
  edition = "2021"
  with_unit_tests = true

  args_sources = [ "src/args.rs" ]

  sources = [ "src/lib.rs" ]

  deps = [ "//src/developer/ffx/fidl:fuchsia.developer.ffx_rust" ]

  test_deps = [ "//src/lib/fuchsia-async" ]
}

# This will generate the executable file for your plugin.
ffx_tool("ffx_echo_tool") {
  edition = "2021"
  output_name = "ffx-echo"
  deps = [
    ":ffx_echo",
    "//src/developer/ffx/lib/fho:lib",
    "//src/lib/fuchsia-async",
  ]
  sources = [ "src/main.rs" ]

  # To be included in the sdk in the future, add this:
  sdk_category = "partner"
  sdk_target_name = "ffx_echo_tool_sdk"
}

在 SDK 中新增個別的子工具建構

此時,您可以建構子工具,但不會主動建構。為此,您需要將其新增至 ffx config.gni 的「雙模式外掛程式」清單:

# ...snip...
dual_mode_plugins = [
  # ...
  "//path/to/your/plugin:ffx_echo_tool",
  # ...
]
# ...snip...

現在,執行 fx build ffx 應會重新建構 ffx 和外掛程式,如果您執行 ffx commands,應該就能在「Workspace Commands」清單中看見您的指令。