summaryrefslogtreecommitdiff
path: root/xmake/modules/private/utils/batchcmds.lua
diff options
context:
space:
mode:
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
commit81ad292ea67f82d88d785a37d23b1f1603996da1 (patch)
tree817b50173948547f7e4b491da271918c67b8a5ff /xmake/modules/private/utils/batchcmds.lua
parent942c32f448d9b8a850438aa2af1de2415b7ae872 (diff)
parent8c1141aba414c07554179cb28687124514f6e770 (diff)
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'xmake/modules/private/utils/batchcmds.lua')
-rw-r--r--xmake/modules/private/utils/batchcmds.lua343
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