Skip to content

Plugins Guide

Shih Yu Ho edited this page Jan 4, 2019 · 72 revisions

Slctl 有完整的 plugin 系統以延伸開發更多的功能, 包含許多優點:

  1. 支援多種安裝來源
  2. 不限制撰寫的語言
  3. 取得 slctl 本身的使用者設定, 如 GitHub Access Token

Stateless Plugins

Slctl 建議將 Plugin 設計為 Stateless, 也就本身無狀態的. 若需要儲存資料或狀態, 儲存的位置請參考 Mount Volume 章節, 但必須考慮到日後升級 Plugin 時的資料轉移.

Installing a Plugin

Plugin 可以透過指令 $ slctl plugin install SOURCE 來安裝, SOURCE 支援以下幾種:

Local Reference

Plugin 可以是本機上的任何目錄, 透過給予絕對或相對路徑來安裝

$ slctl plugin install /path/to/plugin-dir/

Archive

Plugin 也可以是來自於網路上或在本機中壓縮檔, 透過給予網址或路徑來安裝, 格式支援: .zip, .tar, .tar.gz, .tgz, .tar.bz2, .tbz2, .tar.xz, .txz, .tar.lz4, .tlz4, .tar.sz, .tsz, .rar, .bz2, .gz, .lz4, .sz, .xz

$ slctl plugin install /path/to/plugin-archive.zip
$ slctl plugin install http://host/plugin-archive.zip

GitHub Repo

Plugin 也可以是一個 GitHub repo, 傳入 github.com/OWNER/REPO, slctl 會自動收尋最新一版的 release, 並從該 release 的所有下載檔中, 嘗試找出含有當前 OS 名稱的壓縮檔來安裝, 當找不到時會改下載第一個壓縮檔來安裝

$ slctl plugin install github.com/softleader/slctl-whereis

傳入 --tag 可以指定 release 版本

$ slctl plugin install github.com/softleader/slctl-whereis --tag 1.0.0

傳入 --tag--asset 可以指定 release 版本以及要下載第幾個 asset 檔案 (從 0 開始) 來安裝

$ slctl plugin install github.com/softleader/slctl-whereis --tag 1.0.0 --asset 2

傳入 --force 在 install 時自動刪除已存在的 plugin

$ slctl plugin install github.com/softleader/slctl-whereis -f

傳入 --dry-run 可以模擬真實的 install, 但不會真的影響當前的配置

$ slctl plugin install github.com/softleader/slctl-whereis -f --dry-run

Upgrading Plugins

Upgrade plugin which installed from GitHub Repo

$ slctl plugin upgrade NAME...

NAME 可傳入指定要更新的 Plugin 完整名稱 (一或多個, 以空白區隔); 反之更新全部

$ slctl plugin upgrade
$ slctl plugin upgrade whereis

傳入 --tag 可以指定要更新的 release 版本

$ slctl plugin upgrade whereis --tag 1.0.0

傳入 --tag--asset 可以指定要更新的 release 版本以及要下載第幾個 asset 檔案 (從 0 開始)

$ slctl plugin upgrade whereis --tag 1.0.0 --asset 2

傳入 --dry-run 可以模擬真實的 upgrade, 但不會真的影響當前的配置, 通常可以用來檢查 plugin 是否有新版的再決定是否安裝

$ slctl plugin upgrade whereis --dry-run

Building Plugins

Plugin 的根目錄下必須有一份 metadata.yaml 檔案來描述該 Plugin 的相關資訊, 包含:

name: foo
version: 0.1.0
usage: foo
description: The foo plugin
exec:
  command: $SL_BIN
  platform:
  - os: darwin
    arch: ""
    command: $SL_BIN
  - os: windows
    arch: ""
    command: $SL_BIN
hook:
  command: echo hello foo
  platform: []
ignoreGlobalFlags: false
github:
  scopes: []
  • name - 從 slctl 執行的 subcommand, 如 foo 即代表將使用 slctl foo 來執行, name 不可跟 slctl 第一層 command 或任何其他 plugin name 重複, name 也必須符正規式驗證: ^[\w\d_-]+$
  • version - 必須是符合 Semantic Versioning 2 規格的版本號
  • usage - 顯示在 slctl --help 的說明, 應以一句話簡短說明
  • description - 顯示在 slctl plugin list 的說明
  • exec - 執行 plugin 時的指令, 如果有定義 platform 且符合 runtime 環境, 會優先選擇 platform 的 command 執行
  • hook - 安裝好 plugin 後要執行的指令, 通常用來配置環境使用, 如果有定義 platform 且符合 runtime 環境, 會優先選擇 platform 的 command 執行
  • ignoreGlobalFlags - 執行 plugin 時忽略 Global Flags
  • github.scopes - plugin 需要的 token 權限, slctl 會自動的補齊不足的權限, 執行 slctl init scopes 可查詢 slctl 預設要求的權限清單

Os 及 Arch 可參考: Golang environment variables

Plugin Templates

Plugin 本身沒有撰寫的語言限制, slctl 推薦並預設產生 golang 的範本, 選擇不同撰寫語言時, 需注意該語言本身的限制: 如執行 java plugin 的 runtime 必須有 JRE

slctl 已內含了幾種語言的範本, 使用 --lang 來指定產生語言範本

$ slctl plugin create foo --lang java

使用 plugin create langs 列出所有內含的範本語言

$ slctl plugin create langs
golang
java
nodejs
...

Slctl 預設會在當前目錄下, 建立一個名為 Plugin 名稱的目錄, 並將範本產生在該目錄中, 可以傳入 --output 來指定 Plugin 的產生目錄

$ slctl plugin create foo -o /path/to/plugin-dir

Environment Variables

Slctl 在執行 plugin 時, 會將以下環境變數設置到系統變數中, 讓不同語言的 plugin 都可以從中取出:

  • golang - os.LookupEnv("SL_TOKEN")
  • java - System.getenv("SL_TOKEN")
  • nodejs - process.env.SL_TOKEN

這些變數有個共同點都是 SL_ 開頭, 可以透過 plugin evns 查看變數清單:

$ slctl plugin envs
SL_PLUGIN_DIR=~/.sl/plugins/foo
SL_PLUGIN_MOUNT=~/.sl/mounts/foo
SL_PLUGIN=~/.sl/plugins
SL_VERBOSE=false
SL_CLI=slctl
SL_VERSION=<version.of.slctl>
SL_HOME=~/.sl/
SL_OFFLINE=false
SL_TOKEN=<github.token>
SL_PLUGIN_NAME=foo
SL_BIN=slctl
...

Mount Volume

Slctl 會依照當前 Home Path 的設定, 分派一個 Mount Volume 給該 Plugin 使用, Slctl 會保證:

  • Mount Volume 資料夾一定會存在
  • Mount Volume 會一直保留, 不會因為移除 Plugin 而遭到刪除

Slctl 會將 Mount Volume 的路徑以 $SL_PLUGIN_MOUNT 變數存放, 以 golang 語言為例:

mount, found := os.LookupEnv("SL_PLUGIN_MOUNT")
if !found {
	return errors.New("$SL_PLUGIN_MOUNT not found")
}

Mount Volume 的路徑會 Plugin Name 作區分, 也就是不同版本之間將使用相同的 Mount Volume, 因此 Plugin 版本更新時一定要考慮到資料的更新

Global Flags

執行 plugin 時, global flags 會被 slctl 擷取掉而 不會 傳給 plugin, 可以透過 plugin flags 查看 flags 清單:

$ slctl plugin flags
--home
--offline
--verbose
-v
...

若將 metadata.yaml 中的 ignoreGlobalFlags 設為 true, 則 slctl 不會做任何的截取而是將 flags 完整的傳入 plugin 中-

Clone this wiki locally