Skip to content

创建插件

插件里有什么

目录结构如下:

shell
    .
    ├── README.md
    ├── LICENSE
    └── hooks
        └── available.lua
        └── env_keys.lua
        └── post_install.lua
        └── pre_install.lua
        ....
    └── lib
        └── xxx.lua
        └── xxx.lua
        └── xxx.lua
    └── metadata.lua
  • hooks 目录用于存放插件的钩子函数。一个钩子函数对应一个.lua文件。
  • lib 目录用于存放插件的依赖库。vfox会自动加载这个目录下的所有.lua文件。放在其他目录下,则无法加载。
  • metadata.lua 插件的元数据信息。用于描述插件的基本信息,如插件名称、版本等。
  • README.md 插件的说明文档。
  • LICENSE 插件的许可证。

插件模板

为了方便插件的开发,我们提供了一个插件模板,你可以直接使用vfox-plugin-template创建一个插件。

钩子概览

vfox支持的所有钩子函数列表。

钩子必须描述
hooks/available.lua列举所有可用版本
hooks/pre_install.lua解析版本号并返回预安装信息,如下载地址等
hooks/env_keys.lua配置环境变量
hooks/post_install.lua执行额外的操作, 如编译源码等
hooks/pre_use.lua在切换版本之前, 提供修改版本的机会
hooks/parse_legacy_file.lua自定义解析遗留文件
hooks/pre_uninstall.lua删除之前进行额外操作

必须实现的钩子函数

PreInstall

返回预安装信息, 例如具体版本号、下载源等信息。 vfox会帮你提前将这些文件下载到特定目录下。如果是压缩包如tartar.gztar.xzzip这四种压缩包, vfox会直接帮你解压处理。

vfox默认从下载链接中获取文件名,如果下载链接最后一项不是有效的文件名,可以通过在链接末尾附加Fragment来指定文件名,以便于vfox识别文件格式并解压。 如:https://example.com/1234567890#/filename.zip

如果版本的返回值为空,表示未找到版本,vfox会询问用户是否进行搜索操作。

位置: hooks/pre_install.lua

lua
function PLUGIN:PreInstall(ctx)
    --- 用户输入
    local version = ctx.version
    return {
        --- 版本号
        version = "xxx",
        --- 文件地址, 可以是远程地址或者本地文件路径 [可选]
        url = "xxx",
        --- 下载链接的请求头 [可选]
        headers = {
            ["xxx"] = "xxx",
        },
        --- 备注信息 [可选]
        note = "xxx",
        --- SHA256 checksum [optional]
        sha256 = "xxx",
        --- md5 checksum [optional]
        md5= "xxx",
        --- sha1 checksum [optional]
        sha1 = "xxx",
        --- sha512 checksum [optional]
        sha512 = "xxx",
        --- 额外需要的文件 [optional]
        addition = {
            {
                --- additional file name !
                name = "xxx",
                --- 其余同上
            }
        }
    }
end

Available

返回当前可用版本列表。如没有则返回空数组。

位置: hooks/available.lua

lua
function PLUGIN:Available(ctx)
    --- 用户输入附带的参数, 数组
    local args = ctx.args
    return {
        {
            version = "xxxx",
            note = "LTS",
            addition = {
                {
                    name = "npm",
                    version = "8.8.8",
                }
            }
        }
    }
end

缓存

vfox会缓存Available返回的结果, 默认缓存时间为12h。请查看配置#缓存

EnvKeys

告诉vfox当前SDK需要配置的环境变量有哪些。

位置: hooks/env_keys.lua

lua
function PLUGIN:EnvKeys(ctx)
    local mainSdkInfo = ctx.main
    local mainPath = mainSdkInfo.path
    local mversion = mainSdkInfo.version
    local mname = mainSdkInfo.name
    local sdkInfo = ctx.sdkInfo['sdk-name']
    local path = sdkInfo.path
    local version = sdkInfo.version
    local name = sdkInfo.name
    return {
        {
            key = "JAVA_HOME",
            value = mainPath
        },
        --- 注意, 如果需要设置多个PATH路径, 只需要传递多个PATH即可,vfox将会自动去重并按配置顺序设置
        {
            key = "PATH",
            value = mainPath .. "/bin"
        },
        {
            key = "PATH",
            value = mainPath .. "/bin2"
        }
    }
end

可选钩子函数

WARNING

如果不需要这些钩子函数,请删除对应的.lua文件!

PostInstall

拓展点,在PreInstall执行之后调用,用于执行额外的操作, 如编译源码等。根据需要实现。

位置: hooks/post_install.lua

lua
function PLUGIN:PostInstall(ctx)
    --- ctx.rootPath SDK 安装目录
    local rootPath = ctx.rootPath
    --- 根据PreInstall返回的name获取
    local sdkInfo = ctx.sdkInfo['sdk-name']
    --- 文件存放路径
    local path = sdkInfo.path
    local version = sdkInfo.version
    local name = sdkInfo.name
end

PreUse

当用户使用 vfox use 的时候,会调用插件的 PreUse 函数。这个函数的作用是返回用户输入的版本信息。 如果 PreUse 函数返回了版本信息, vfox 将会使用这个新的版本信息。

位置: hooks/pre_use.lua

lua
function PLUGIN:PreUse(ctx)
    --- 用户输入的版本
    local version = ctx.version
    --- 用户之前环境中设置的版本
    local previousVersion = ctx.previousVersion

    --- 已安装的 SDK 信息
    local sdkInfo = ctx.installedSdks['version']
    local path = sdkInfo.path
    local name = sdkInfo.name
    local version = sdkInfo.version

    --- 当前工作目录
    local cwd = ctx.cwd

    --- 用户输入的 scope 信息,值为 global/project/session 其中之一
    local scope = ctx.scope

    --- 返回版本信息
    return {
        version = version,
    }
end

ParseLegacyFile >= 0.4.0

解析其他配置文件,以确定工具的版本。例如,nvm.nvmrc 文件、SDKMAN.sdkmanrc 文件等。

DANGER

该钩子函数必须配合 legacyFilenames 配置项使用, 告诉vfox 你的插件支持解析哪些文件。

位置: metadata.lua

lua
--- 当前插件支持解析的遗留文件名列表, 例如: .nvmrc, .node-version, .sdkmanrc
PLUGIN.legacyFilenames = {
    '.nvmrc',
    '.node-version',
}

位置: hooks/parse_legacy_file.lua

lua
function PLUGIN:ParseLegacyFile(ctx)
    --- 文件名
    local filename = ctx.filename
    --- 文件路径
    local filepath = ctx.filepath
    --- 获取当前插件已安装的版本列表
    local versions = ctx:getInstalledVersions()

    return {
        --- 返回具体版本号
        version = "x.y.z"
    }
end

PreUninstall >= 0.4.0

在卸载 SDK 之前执行的钩子函数。如果插件需要在卸载之前执行一些操作,可以实现这个钩子函数。例如清理缓存、删除配置文件等。

位置: hooks/pre_uninstall.lua

lua
function PLUGIN:PreUninstall(ctx)
    local mainSdkInfo = ctx.main
    local mainPath = mainSdkInfo.path
    local mversion = mainSdkInfo.version
    local mname = mainSdkInfo.name
    --- 其他 SDK 信息, PreInstall中返回的`addition`字段, 通过name获取
    local sdkInfo = ctx.sdkInfo['sdk-name']
    local path = sdkInfo.path
    local version = sdkInfo.version
    local name = sdkInfo.name
end

测试插件

目前,vfox 插件测试方法很简陋。您需要将插件放在 ${HOME}/.version-fox/plugins 目录中,并使用不同的命令验证您的功能是否正常工作。 您可以在插件中使用 print/printTable 函数来打印日志进行调试。

  • PLUGIN:PreInstall -> vfox install <sdk-name>@<version>
  • PLUGIN:PostInstall -> vfox install <sdk-name>@<version>
  • PLUGIN:Available -> vfox search <sdk-name>
  • PLUGIN:EnvKeys -> vfox use <sdk-name>@<version>

另外, 你可以通过添加 --debug 参数来查看更多的日志信息, 例如:

shell
vfox --debug install <sdk-name>@<version>
vfox --debug use <sdk-name>@<version>

...

插件示例

https://github.com/version-fox/vfox-nodejs

你可以参考这个插件来开发自己的插件。

向官方插件存储库提交插件

vfox可以允许自定义安装插件,比如:

shell
vfox add --source https://github.com/version-fox/vfox-nodejs/releases/download/v0.0.5/vfox-nodejs_0.0.5.zip

为了使你的用户更轻松,你可以将插件添加到官方插件存储库中,以列出你的插件并使用较短的命令轻松安装,比如 vfox add nodejs

具体步骤请查看如何将插件提交到索引仓库

基于 Apache 2.0 许可发布