diff options
| author | Ângelo Andrade Cirino <[email protected]> | 2021-07-15 23:23:48 -0300 |
|---|---|---|
| committer | Ângelo Andrade Cirino <[email protected]> | 2021-07-15 23:23:48 -0300 |
| commit | 81ad292ea67f82d88d785a37d23b1f1603996da1 (patch) | |
| tree | 817b50173948547f7e4b491da271918c67b8a5ff /xmake/modules/private/utils/batchcmds.lua | |
| parent | 942c32f448d9b8a850438aa2af1de2415b7ae872 (diff) | |
| parent | 8c1141aba414c07554179cb28687124514f6e770 (diff) | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'xmake/modules/private/utils/batchcmds.lua')
| -rw-r--r-- | xmake/modules/private/utils/batchcmds.lua | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/xmake/modules/private/utils/batchcmds.lua b/xmake/modules/private/utils/batchcmds.lua new file mode 100644 index 000000000..371735321 --- /dev/null +++ b/xmake/modules/private/utils/batchcmds.lua @@ -0,0 +1,343 @@ +--!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, TBOOX Open Source Group. +-- +-- @author ruki +-- @file batchcmds.lua +-- + +-- imports +import("core.base.option") +import("core.base.object") +import("core.base.tty") +import("core.base.colors") +import("core.project.depend") +import("core.theme.theme") +import("core.tool.linker") +import("core.tool.compiler") +import("core.language.language") +import("private.utils.progress", {alias = "progress_utils"}) + +-- define module +local batchcmds = batchcmds or object { _init = {"_TARGET", "_CMDS", "_DEPS", "_tip"}} + +-- show text +function _show(showtext, progress) + if option.get("verbose") then + cprint(showtext) + else + local is_scroll = _g.is_scroll + if is_scroll == nil then + is_scroll = theme.get("text.build.progress_style") == "scroll" + _g.is_scroll = is_scroll + end + if is_scroll then + cprint(showtext) + else + tty.erase_line_to_start().cr() + local msg = showtext + local msg_plain = colors.translate(msg, {plain = true}) + local maxwidth = os.getwinsize().width + if #msg_plain <= maxwidth then + cprintf(msg) + else + -- windows width is too small? strip the partial message in middle + local partlen = math.floor(maxwidth / 2) - 3 + local sep = msg_plain:sub(partlen + 1, #msg_plain - partlen - 1) + local split = msg:split(sep, {plain = true, strict = true}) + cprintf(table.concat(split, "...")) + end + if math.floor(progress) == 100 then + print("") + _g.showing_without_scroll = false + else + _g.showing_without_scroll = true + end + io.flush() + end + end +end + +-- run command: show +function _runcmd_show(cmd, opt) + local showtext = cmd.showtext + if showtext then + _show(showtext, cmd.progress) + end +end + +-- run command: os.runv +function _runcmd_runv(cmd, opt) + if cmd.program then + if not opt.dryrun then + os.runv(cmd.program, cmd.argv, cmd.opt) + end + end +end + +-- run command: os.vrunv +function _runcmd_vrunv(cmd, opt) + if cmd.program then + if opt.dryrun then + vprint(os.args(table.join(cmd.program, cmd.argv))) + else + os.vrunv(cmd.program, cmd.argv, cmd.opt) + end + end +end + +-- run command: os.execv +function _runcmd_execv(cmd, opt) + if cmd.program then + if opt.dryrun then + print(os.args(table.join(cmd.program, cmd.argv))) + else + os.execv(cmd.program, cmd.argv, cmd.opt) + end + end +end + +-- run command: os.mkdir +function _runcmd_mkdir(cmd, opt) + local dir = cmd.dir + if not opt.dryrun and not os.isdir(dir) then + os.mkdir(dir) + end +end + +-- run command: os.rm +function _runcmd_rm(cmd, opt) + local filepath = cmd.filepath + if not opt.dryrun then + os.tryrm(filepath) + end +end + +-- run command: os.cp +function _runcmd_cp(cmd, opt) + if not opt.dryrun then + os.cp(opt.srcpath, opt.dstpath, opt.opt) + end +end + +-- run command: os.mv +function _runcmd_mv(cmd, opt) + if not opt.dryrun then + os.mv(opt.srcpath, opt.dstpath, opt.opt) + end +end + +-- run command: os.ln +function _runcmd_ln(cmd, opt) + if not opt.dryrun then + os.ln(opt.srcpath, opt.dstpath, opt.opt) + end +end + +-- run command +function _runcmd(cmd, opt) + local kind = cmd.kind + local maps = _g.maps + if not maps then + maps = + { + show = _runcmd_show, + runv = _runcmd_runv, + vrunv = _runcmd_vrunv, + execv = _runcmd_execv, + mkdir = _runcmd_mkdir, + rm = _runcmd_rm, + cp = _runcmd_cp, + mv = _runcmd_mv, + ln = _runcmd_ln + } + _g.maps = maps + end + local script = maps[kind] + if script then + script(cmd, opt) + end +end + +-- run commands +function _runcmds(cmds, opt) + for _, cmd in ipairs(cmds) do + _runcmd(cmd, opt) + end +end + +-- is empty? no commands +function batchcmds:empty() + return #self:cmds() == 0 +end + +-- get commands +function batchcmds:cmds() + return self._CMDS +end + +-- add command: os.runv +function batchcmds:runv(program, argv, opt) + table.insert(self:cmds(), {kind = "runv", program = program, argv = argv, opt = opt}) + self:add_depvalues(program, argv) +end + +-- add command: os.vrunv +function batchcmds:vrunv(program, argv, opt) + table.insert(self:cmds(), {kind = "vrunv", program = program, argv = argv, opt = opt}) + self:add_depvalues(program, argv) +end + +-- add command: os.execv +function batchcmds:execv(program, argv, opt) + table.insert(self:cmds(), {kind = "execv", program = program, argv = argv, opt = opt}) + self:add_depvalues(program, argv) +end + +-- add command: compiler.compile +function batchcmds:compile(sourcefiles, objectfile, opt) + + -- bind target if exists + opt = opt or {} + opt.target = self._TARGET + + -- load compiler and get compilation command + local sourcekind = opt.sourcekind + if not sourcekind and type(sourcefiles) == "string" then + sourcekind = language.sourcekind_of(sourcefiles) + end + local compiler_inst = compiler.load(sourcekind, opt) + local program, argv = compiler_inst:compargv(sourcefiles, objectfile, opt) + + -- add compilation command and bind run environments of compiler + self:mkdir(path.directory(objectfile)) + self:vrunv(program, argv, {envs = table.join(compiler_inst:runenvs(), opt.envs)}) +end + +-- add command: linker.link +function batchcmds:link(objectfiles, targetfile, opt) + + -- bind target if exists + local target = self._TARGET + opt = opt or {} + opt.target = target + + -- load linker and get link command + local linker_inst = target and target:linker() or linker.load(opt.targetkind, opt.sourcekinds, opt) + local program, argv = linker_inst:linkargv(objectfiles, targetfile, opt) + + -- add link command and bind run environments of linker + self:mkdir(path.directory(targetfile)) + self:vrunv(program, argv, {envs = table.join(linker_inst:runenvs(), opt.envs)}) +end + +-- add command: os.mkdir +function batchcmds:mkdir(dir) + table.insert(self:cmds(), {kind = "mkdir", dir = dir}) +end + +-- add command: os.rm +function batchcmds:rm(filepath) + table.insert(self:cmds(), {kind = "rm", filepath = filepath}) +end + +-- add command: os.cp +function batchcmds:cp(srcpath, dstpath, opt) + table.insert(self:cmds(), {kind = "cp", srcpath = srcpath, dstpath = dstpath, opt = opt}) +end + +-- add command: os.mv +function batchcmds:mv(srcpath, dstpath, opt) + table.insert(self:cmds(), {kind = "mv", srcpath = srcpath, dstpath = dstpath, opt = opt}) +end + +-- add command: os.ln +function batchcmds:ln(srcpath, dstpath, opt) + table.insert(self:cmds(), {kind = "ln", srcpath = srcpath, dstpath = dstpath, opt = opt}) +end + +-- add command: show +function batchcmds:show(format, ...) + local showtext = string.format(format, ...) + table.insert(self:cmds(), {kind = "show", showtext = showtext}) +end + +-- add command: show progress +function batchcmds:show_progress(progress, format, ...) + if progress then + local showtext = progress_utils.text(progress, format, ...) + table.insert(self:cmds(), {kind = "show", showtext = showtext, progress = progress}) + end +end + +-- get deps +function batchcmds:deps() + return self._DEPS +end + +-- add dependent files +function batchcmds:add_depfiles(...) + local deps = self._DEPS or {} + deps.files = deps.files or {} + table.join2(deps.files, ...) + self._DEPS = deps +end + +-- add dependent values +function batchcmds:add_depvalues(...) + local deps = self._DEPS or {} + deps.values = deps.values or {} + table.join2(deps.values, ...) + self._DEPS = deps +end + +-- set the last mtime of dependent files and values +function batchcmds:set_depmtime(lastmtime) + local deps = self._DEPS or {} + deps.lastmtime = lastmtime + self._DEPS = deps +end + +-- set cache file of depend info +function batchcmds:set_depcache(cachefile) + local deps = self._DEPS or {} + deps.dependfile = cachefile + self._DEPS = deps +end + +-- run cmds +function batchcmds:runcmds(opt) + opt = opt or {} + if self:empty() then + return + end + local deps = self:deps() + if deps and deps.files then + depend.on_changed(function () + _runcmds(self:cmds(), opt) + end, self:deps()) + else + _runcmds(self:cmds(), opt) + end +end + +-- new a batch commands for rule/xx_xxcmd_xxx() +-- +-- @params opt options, e.g. {target = ..} +-- +function new(opt) + opt = opt or {} + return batchcmds {_TARGET = opt.target, _CMDS = {}} +end |
