From bce3f2c4ed1f54aa2b46ea395d12e554d98e6221 Mon Sep 17 00:00:00 2001 From: "R. Blaine Whittle" Date: Tue, 18 Apr 2017 09:37:29 -0700 Subject: [PATCH 1/2] [core] new cmd path decorations with %[] syntax this is for marking cmd options as paths relative to the projects base dir. decorated paths can use tokens / macros decorated paths are wrapped with "". Final slashes are honored. Slashes are platform specific. Note that the working dir for custom cmd is undefined as the current working dir will be different between xcode (wks.location) and visual studio / make (prj.location.) Changing the CWD isn't a good default behavior (for reasons.) This leads to prior use of premake requiring alot of string concating / function calls for path translations which make the cmd line difficult to read and maintain. With path decorations, one can just make those relative paths with %[] and everything should work. --- src/actions/make/_make.lua | 2 +- src/actions/make/make_cpp.lua | 2 +- src/actions/make/make_makefile.lua | 4 +-- src/actions/vstudio/vs2005_csproj.lua | 2 +- src/actions/vstudio/vs200x_vcproj.lua | 8 ++--- src/actions/vstudio/vs2010_vcxproj.lua | 6 ++-- src/base/os.lua | 41 ++++++++++++++++++++++++++ tests/base/test_os.lua | 15 ++++++++++ 8 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/actions/make/_make.lua b/src/actions/make/_make.lua index d9c5d85b..585fa913 100644 --- a/src/actions/make/_make.lua +++ b/src/actions/make/_make.lua @@ -256,7 +256,7 @@ local steps = cfg[event .. "commands"] local msg = cfg[event .. "message"] if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) msg = msg or string.format("Running %s commands", event) _p('\t@echo %s', msg) _p('\t%s', table.implode(steps, "", "", "\n\t")) diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua index fb3a227f..aa3cb432 100644 --- a/src/actions/make/make_cpp.lua +++ b/src/actions/make/make_cpp.lua @@ -178,7 +178,7 @@ _p('%s: %s', output, dependencies) _p('\t@echo "%s"', filecfg.buildmessage or ("Building " .. filecfg.relpath)) - local cmds = os.translateCommands(filecfg.buildcommands) + local cmds = os.translateCommandsAndPaths(filecfg.buildcommands, cfg.project.basedir, cfg.project.location) for _, cmd in ipairs(cmds) do if cfg.bindirs and #cfg.bindirs > 0 then _p('\t$(SILENT) $(EXE_PATHS) %s', cmd) diff --git a/src/actions/make/make_makefile.lua b/src/actions/make/make_makefile.lua index 739995b0..e5c67bcd 100644 --- a/src/actions/make/make_makefile.lua +++ b/src/actions/make/make_makefile.lua @@ -72,7 +72,7 @@ _p(' define BUILDCMDS') local steps = cfg.buildcommands if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) _p('\t@echo Running build commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end @@ -84,7 +84,7 @@ _p(' define CLEANCMDS') local steps = cfg.cleancommands if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) _p('\t@echo Running clean commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua index b6d5ab01..0ce1c3f4 100644 --- a/src/actions/vstudio/vs2005_csproj.lua +++ b/src/actions/vstudio/vs2005_csproj.lua @@ -226,7 +226,7 @@ function cs2005.buildEvents(prj) local function output(name, steps) if #steps > 0 then - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, prj.basedir, prj.location) steps = table.implode(steps, "", "", "\r\n") _x(2,'<%sBuildEvent>%s', name, steps, name) end diff --git a/src/actions/vstudio/vs200x_vcproj.lua b/src/actions/vstudio/vs200x_vcproj.lua index e42e8cc4..43895923 100644 --- a/src/actions/vstudio/vs200x_vcproj.lua +++ b/src/actions/vstudio/vs200x_vcproj.lua @@ -945,7 +945,7 @@ function m.buildCommandLine(cfg) - local cmds = os.translateCommands(cfg.buildcommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(cfg.buildcommands, cfg.project.basedir, cfg.project.location) p.x('BuildCommandLine="%s"', table.concat(cmds, "\r\n")) end @@ -960,7 +960,7 @@ function m.cleanCommandLine(cfg) - local cmds = os.translateCommands(cfg.cleancommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(cfg.cleancommands, cfg.project.basedir, cfg.project.location) cmds = table.concat(cmds, "\r\n") p.x('CleanCommandLine="%s"', cmds) end @@ -975,7 +975,7 @@ if msg then p.x('Description="%s"', msg) end - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) p.x('CommandLine="%s"', table.implode(steps, "", "", "\r\n")) end end @@ -1045,7 +1045,7 @@ function m.customBuildTool(cfg) local cfg, filecfg = config.normalize(cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then - local cmds = os.translateCommands(filecfg.buildcommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(filecfg.buildcommands, filecfg.project.basedir, filecfg.project.location) p.x('CommandLine="%s"', table.concat(cmds,'\r\n')) local outputs = project.getrelative(filecfg.project, filecfg.buildoutputs) diff --git a/src/actions/vstudio/vs2010_vcxproj.lua b/src/actions/vstudio/vs2010_vcxproj.lua index 9d08315f..1c6afd5d 100644 --- a/src/actions/vstudio/vs2010_vcxproj.lua +++ b/src/actions/vstudio/vs2010_vcxproj.lua @@ -511,7 +511,7 @@ local msg = cfg[field .. "message"] if #steps > 0 then - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) p.push('<%s>', name) p.x('%s', table.implode(steps, "", "", "\r\n")) if msg then @@ -1131,7 +1131,7 @@ function m.buildCommands(fcfg, condition) - local commands = os.translateCommands(fcfg.buildcommands, p.WINDOWS) + local commands = os.translateCommandsAndPaths(fcfg.buildcommands, fcfg.project.basedir, fcfg.project.location) commands = table.concat(commands,'\r\n') m.element("Command", condition, '%s', commands) end @@ -1768,7 +1768,7 @@ function m.nmakeCommandLine(cfg, commands, phase) if #commands > 0 then - commands = os.translateCommands(commands, p.WINDOWS) + commands = os.translateCommandsAndPaths(commands, cfg.project.basedir, cfg.project.location) commands = table.concat(p.esc(commands), p.eol()) p.w('%s', phase, commands, phase) end diff --git a/src/base/os.lua b/src/base/os.lua index 43ed5f6d..2ac7c323 100644 --- a/src/base/os.lua +++ b/src/base/os.lua @@ -610,6 +610,47 @@ +--- +-- Translate decorated command paths into their OS equivalents. +--- + + function os.translateCommandsAndPaths(cmds, basedir, location, map) + local translatedBaseDir = path.getrelative(location, basedir) + + map = map or os.target() + + local translateFunction = function(value) + local result = path.join(translatedBaseDir, value) + if value:endswith('/') or value:endswith('\\') or + value:endswith('/"') or value:endswith('\\"') then + result = result .. '/' + end + if map == 'windows' then + result = path.translate(result) + end + return result + end + + local processOne = function(cmd) + local replaceFunction = function(value) + value = value:sub(3, #value - 1) + return '"' .. translateFunction(value) .. '"' + end + return string.gsub(cmd, "%%%[[^%]\r\n]*%]", replaceFunction) + end + + if type(cmds) == "table" then + local result = {} + for i = 1, #cmds do + result[i] = processOne(cmds[i]) + end + return os.translateCommands(result, map) + else + return os.translateCommands(processOne(cmds), map) + end + end + + -- -- Generate a UUID. -- diff --git a/tests/base/test_os.lua b/tests/base/test_os.lua index f2414b95..37463734 100644 --- a/tests/base/test_os.lua +++ b/tests/base/test_os.lua @@ -281,3 +281,18 @@ local version = os.getversion(); test.istrue(version ~= nil) end + + + +-- +-- os.translateCommandsAndPaths. +-- + + function suite.translateCommandsAndPaths() + test.isequal('cmdtool "../foo/path1"', os.translateCommandsAndPaths("cmdtool %[path1]", '../foo', '.', 'osx')) + end + + function suite.translateCommandsAndPaths_PreserveSlash() + test.isequal('cmdtool "../foo/path1/"', os.translateCommandsAndPaths("cmdtool %[path1/]", '../foo', '.', 'osx')) + end + From f1d461f3a59e0d4e8f916fde3538cc2501ff0296 Mon Sep 17 00:00:00 2001 From: Tom van Dijck Date: Tue, 2 May 2017 09:09:38 -0700 Subject: [PATCH 2/2] Add test for multiple tokens. --- tests/base/test_os.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/base/test_os.lua b/tests/base/test_os.lua index 37463734..ce5222db 100644 --- a/tests/base/test_os.lua +++ b/tests/base/test_os.lua @@ -296,3 +296,7 @@ test.isequal('cmdtool "../foo/path1/"', os.translateCommandsAndPaths("cmdtool %[path1/]", '../foo', '.', 'osx')) end + function suite.translateCommandsAndPaths_MultipleTokens() + test.isequal('cmdtool "../foo/path1" "../foo/path2/"', os.translateCommandsAndPaths("cmdtool %[path1] %[path2/]", '../foo', '.', 'osx')) + end +