summaryrefslogtreecommitdiff
path: root/xmake/modules/private/action/require/impl/utils/plugins.lua
blob: 4656312fcffeba1b4d2b469ece9cd9043b0aac86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author      ruki
-- @file        plugins.lua
--

-- imports
import("core.base.global")

-- get the plugin directory of the given plugin package in the global plugins directory
function plugindir(name)
    return path.join(global.directory(), "plugins", name)
end

-- register the given plugin package to the global plugins directory,
-- then we can run it directly. e.g. `xmake plugin-name`
function register(package)
    local installdir = package:installdir()
    assert(os.isfile(path.join(installdir, "xmake.lua")),
        "plugin(%s): xmake.lua not found in the installed files, it should be installed with `os.cp(\"*\", package:installdir())`!", package:name())
    local dir = plugindir(package:name())
    -- we copy it to the temporary directory first and then swap it,
    -- so the previous plugin will not be lost if copying fails. e.g. disk full
    --
    -- we cannot use the sibling directory, e.g. `plugins/<name>.tmp`,
    -- because the task loader will load all plugins from `plugins/*/xmake.lua`
    local tmpdir = path.join(path.directory(dir), ".tmp", package:name())
    os.tryrm(tmpdir)
    os.cp(installdir, tmpdir)
    -- remove the install logs, they do not belong to the plugin,
    -- but we keep manifest.txt to show the plugin version and description. e.g. `xmake plugin --list`
    os.tryrm(path.join(tmpdir, "logs"))
    -- replace the previous plugin only after the new one is fully ready,
    -- and we backup the previous plugin, it can be restored by `rollback()` if the installation fails later. e.g. test failure
    local bakdir = tmpdir .. ".bak"
    os.tryrm(bakdir)
    if os.isdir(dir) then
        os.mv(dir, bakdir)
    end
    os.mv(tmpdir, dir)
    vprint("register plugin(%s) to %s", package:name(), dir)
end

-- confirm the registered plugin and discard the previous backup
function confirm(name)
    os.tryrm(path.join(path.directory(plugindir(name)), ".tmp", name .. ".bak"))
end

-- rollback the registered plugin and restore the previous backup if the installation fails
function rollback(name)
    local dir = plugindir(name)
    os.tryrm(dir)
    local bakdir = path.join(path.directory(dir), ".tmp", name .. ".bak")
    if os.isdir(bakdir) then
        os.mv(bakdir, dir)
        vprint("restore the previous plugin(%s) to %s", name, dir)
    end
end

-- unregister the given plugin from the global plugins directory
function unregister(name)
    local dir = plugindir(name)
    if os.isdir(dir) then
        os.tryrm(dir)
        vprint("unregister plugin(%s) from %s", name, dir)
    end
end