diff options
| author | ruki <[email protected]> | 2017-03-27 15:43:19 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-03-27 15:43:19 +0800 |
| commit | 235bb967883ab0686bab731c8e94a4a0bb7677ab (patch) | |
| tree | 08b79c48dd0da33d9dfc59d2955e8bfe0f5d08db | |
| parent | f9ff6e5e50c26501964a3b35279aa4881d3865a3 (diff) | |
fix uninstall with perm tips
| -rw-r--r-- | xmake/actions/uninstall/main.lua | 109 | ||||
| -rw-r--r-- | xmake/actions/uninstall/uninstall.lua | 90 | ||||
| -rw-r--r-- | xmake/actions/uninstall/uninstall_admin.lua | 60 |
3 files changed, 199 insertions, 60 deletions
diff --git a/xmake/actions/uninstall/main.lua b/xmake/actions/uninstall/main.lua index b4217f3d3..297c56bc6 100644 --- a/xmake/actions/uninstall/main.lua +++ b/xmake/actions/uninstall/main.lua @@ -25,75 +25,64 @@ -- imports import("core.base.option") import("core.project.task") -import("core.project.config") -import("core.project.global") -import("core.project.project") -import("core.platform.platform") +import("uninstall") --- uninstall the given target -function _uninstall_target(target) - - -- enter project directory - local olddir = os.cd(project.directory()) - - -- the target scripts - local scripts = - { - target:get("uninstall_before") - , target:get("uninstall") or platform.get("uninstall") - , target:get("uninstall_after") - } - - -- uninstall the target scripts - for i = 1, 3 do - local script = scripts[i] - if script ~= nil then - script(target) - end - end - - -- leave project directory - os.cd(olddir) -end +-- main +function main() --- uninstall the given target and deps -function _uninstall_target_and_deps(target) + -- get the target name + local targetname = option.get("target") - -- this target have been finished? - if _g.finished[target:name()] then - return - end + -- config it first + task.run("config", {target = targetname}) - -- uninstall for all dependent targets - for _, depname in ipairs(target:get("deps")) do - _uninstall_target_and_deps(project.target(depname)) - end + -- attempt to uninstall directly + try + { + function () + -- uninstall target + install.uninstall(targetname) + end, - -- uninstall target - _uninstall_target(target) + catch + { + -- failed or not permission? request administrator permission and uninstall it again + function (errors) - -- finished - _g.finished[target:name()] = true -end + -- init argv + local argv = {"xmake", "lua"} + for _, name in ipairs({"file", "project", "backtrace", "verbose", "quiet"}) do + local value = option.get(name) + if type(value) == "string" then + table.insert(argv, "--" .. name .. "=" .. value) + elseif value then + table.insert(argv, "--" .. name) + end + end + table.insert(argv, path.join(os.scriptdir(), "uninstall_admin.lua")) + table.insert(argv, targetname) + table.insert(argv, option.get("installdir")) --- main -function main() + -- show tips + cprint("${bright red}error: ${default red}failed to uninstall, may permission denied!") - -- get the target name - local targetname = option.get("target") + -- continue to install with administrator permission? + if os.sudo() then - -- init finished states - _g.finished = {} + -- show tips + cprint("${bright yellow}note: ${default yellow}try continue to uninstall with administrator permission again?") + cprint("please input: y (y/n)") - -- config it first - task.run("config", {target = targetname}) + -- TODO fix read api + -- get answer + io.flush() + if io._read() == 'y' then - -- uninstall all? - if targetname == "all" then - for _, target in pairs(project.targets()) do - _uninstall_target_and_deps(target) - end - else - _uninstall_target_and_deps(project.target(targetname)) - end + -- install target with administrator permission + os.runv(os.sudo(), argv) + end + end + end + } + } end diff --git a/xmake/actions/uninstall/uninstall.lua b/xmake/actions/uninstall/uninstall.lua new file mode 100644 index 000000000..b89aa2440 --- /dev/null +++ b/xmake/actions/uninstall/uninstall.lua @@ -0,0 +1,90 @@ +--!The Make-like Build Utility based on Lua +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you 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 - 2017, TBOOX Open Source Group. +-- +-- @author ruki +-- @file uninstall.lua +-- + +-- imports +import("core.project.task") +import("core.project.project") +import("core.platform.platform") + +-- uninstall the given target +function _uninstall_target(target) + + -- enter project directory + local olddir = os.cd(project.directory()) + + -- the target scripts + local scripts = + { + target:get("uninstall_before") + , target:get("uninstall") or platform.get("uninstall") + , target:get("uninstall_after") + } + + -- uninstall the target scripts + for i = 1, 3 do + local script = scripts[i] + if script ~= nil then + script(target) + end + end + + -- leave project directory + os.cd(olddir) +end + +-- uninstall the given target and deps +function _uninstall_target_and_deps(target) + + -- this target have been finished? + if _g.finished[target:name()] then + return + end + + -- uninstall for all dependent targets + for _, depname in ipairs(target:get("deps")) do + _uninstall_target_and_deps(project.target(depname)) + end + + -- uninstall target + _uninstall_target(target) + + -- finished + _g.finished[target:name()] = true +end + +-- uninstall +function uninstall(targetname) + + -- init finished states + _g.finished = {} + + -- uninstall all? + if targetname == "all" then + for _, target in pairs(project.targets()) do + _uninstall_target_and_deps(target) + end + else + _uninstall_target_and_deps(project.target(targetname)) + end +end diff --git a/xmake/actions/uninstall/uninstall_admin.lua b/xmake/actions/uninstall/uninstall_admin.lua new file mode 100644 index 000000000..a0408d38b --- /dev/null +++ b/xmake/actions/uninstall/uninstall_admin.lua @@ -0,0 +1,60 @@ +--!The Make-like Build Utility based on Lua +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you 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 - 2017, TBOOX Open Source Group. +-- +-- @author ruki +-- @file uninstall_admin.lua +-- + +-- imports +import("core.base.option") +import("core.project.config") +import("core.project.project") +import("core.platform.platform") +import("uninstall") + +-- uninstall +function main(targetname, installdir) + + -- enter project directory + os.cd(project.directory()) + + -- load config + config.load() + + -- load platform + platform.load(config.plat()) + + -- laod project + project.load() + + -- save the current option and push a new option context + option.save() + + -- pass installdir to option + if installdir then + option.set("installdir", installdir) + end + + -- uninstall target + uninstall.uninstall(targetname) + + -- restore the previous option context + option.restore() +end |
