Skip to content

Commit b3b39d4

Browse files
authored
add {COPYFILEIFNEWER} token (#2617)
1 parent 874699e commit b3b39d4

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/base/os.lua

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,9 @@
597597
copyfile = function(v)
598598
return "cp -f " .. path.normalize(v)
599599
end,
600+
copyfileifnewer = function(v)
601+
return "cp -u " .. path.normalize(v)
602+
end,
600603
copydir = function(v)
601604
return "cp -rf " .. path.normalize(v)
602605
end,
@@ -675,6 +678,43 @@
675678
-- Just use COPY instead, it actually works.
676679
return "copy /B /Y " .. v
677680
end,
681+
copyfileifnewer = function(v)
682+
-- A trailing * on the destination suppresses xcopy's
683+
-- locale-dependent "File or Directory?" prompt (the old
684+
-- "echo F |" hack only works on English Windows).
685+
--
686+
-- A trailing / on the destination marks it as a
687+
-- directory; the source filename is appended so xcopy
688+
-- sees a file-to-file copy.
689+
690+
-- Check for trailing / before normalize strips it.
691+
local orig_dst = v:match('%S+%s*$') or ''
692+
local orig_dst_bare = orig_dst:gsub('"', '')
693+
local dst_is_dir = orig_dst_bare:sub(-1) == '/'
694+
695+
v = path.translate(path.normalize(v), "\\")
696+
697+
if dst_is_dir then
698+
local src = string.match(v, '^".-"') or string.match(v, '^%S+')
699+
local src_name = path.getname(src:gsub('"', ''))
700+
-- Append source filename inside or outside closing quote.
701+
-- Strip any trailing separator that survived translate.
702+
if v:sub(-1) == '"' then
703+
local base = v:sub(1, -2):gsub('[/\\]$', '')
704+
v = base .. '\\' .. src_name .. '"'
705+
else
706+
v = v:gsub('[/\\]$', '') .. '\\' .. src_name
707+
end
708+
end
709+
710+
-- Put * inside the closing quote when the path is quoted.
711+
if v:sub(-1) == '"' then
712+
v = v:sub(1, -2) .. '*"'
713+
else
714+
v = v .. "*"
715+
end
716+
return "xcopy /D /Y " .. v
717+
end,
678718
copydir = function(v)
679719
v = path.translate(path.normalize(v))
680720
return "xcopy /Q /E /Y /I " .. v

tests/base/test_os.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,37 @@
360360
test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a "b" > nul) ELSE (xcopy /Q /Y /I a "b" > nul)', os.translateCommands('{COPY} a "b" ', "windows"))
361361
end
362362

363+
--
364+
-- os.translateCommand() COPYFILEIFNEWER tests
365+
--
366+
function suite.translateCommand_windowsCopyFileIfNewer()
367+
test.isequal('xcopy /D /Y a b*', os.translateCommands('{COPYFILEIFNEWER} a b', "windows"))
368+
end
369+
370+
function suite.translateCommand_windowsCopyFileIfNewerWithSpaces()
371+
test.isequal('xcopy /D /Y "a a" "b b*"', os.translateCommands('{COPYFILEIFNEWER} "a a" "b b"', "windows"))
372+
end
373+
374+
function suite.translateCommand_windowsCopyFileIfNewerWithPaths()
375+
test.isequal('xcopy /D /Y "src\\dir\\file.txt" "dst\\dir\\file.txt*"', os.translateCommandsAndPaths('{COPYFILEIFNEWER} %[src/dir/file.txt] %[dst/dir/file.txt]', '.', '.', "windows"))
376+
end
377+
378+
function suite.translateCommand_windowsCopyFileIfNewerDirDst()
379+
test.isequal('xcopy /D /Y "src\\Core.dll" "dst\\outdir\\Core.dll*"', os.translateCommandsAndPaths('{COPYFILEIFNEWER} %[src/Core.dll] %[dst/outdir/]', '.', '.', "windows"))
380+
end
381+
382+
function suite.translateCommand_windowsCopyFileIfNewerDirDstQuoted()
383+
test.isequal('xcopy /D /Y "src dir\\Core.dll" "dst dir\\Core.dll*"', os.translateCommandsAndPaths('{COPYFILEIFNEWER} %[src dir/Core.dll] %[dst dir/]', '.', '.', "windows"))
384+
end
385+
386+
function suite.translateCommand_posixCopyFileIfNewer()
387+
test.isequal('cp -u a b', os.translateCommands('{COPYFILEIFNEWER} a b', "posix"))
388+
end
389+
390+
function suite.translateCommand_posixCopyFileIfNewerWithSpaces()
391+
test.isequal('cp -u "a a" "b b"', os.translateCommands('{COPYFILEIFNEWER} "a a" "b b"', "posix"))
392+
end
393+
363394
--
364395
-- os.translateCommand() LINKDIR/LINKFILE tests
365396
--

website/docs/Tokens.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ The available tokens, and their replacements:
103103
|------------|---------------------------------------------|-----------------------|
104104
| {CHDIR} | chdir {args} | cd {args} |
105105
| {COPYFILE} | copy /B /Y {args} | cp -f {args} |
106+
| {COPYFILEIFNEWER} | xcopy /D /Y {args}* | cp -u {args} |
106107
| {COPYDIR} | xcopy /Q /E /Y /I {args} | cp -rf {args} |
107108
| {DELETE} | del {args} | rm -rf {args} |
108109
| {ECHO} | echo {args} | echo {args} |

0 commit comments

Comments
 (0)