summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-03-24 00:48:50 +0800
committerruki <[email protected]>2020-03-23 22:53:01 +0800
commit9243d46338684ca5bceafe91ab5e45db3dc4fabf (patch)
tree5454e8546da33d2d6804b297e412350fdddfd6df
parent44f3296096c3c18fa2825207445341410bddb428 (diff)
improve os.cp
-rw-r--r--xmake/core/base/os.lua34
-rw-r--r--xmake/core/sandbox/modules/os.lua8
2 files changed, 32 insertions, 10 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 940f99696..4c10c4fac 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -48,17 +48,35 @@ os.SYSERR_NOT_PERM = 1
os.SYSERR_NOT_FILEDIR = 2
-- copy single file or directory
-function os._cp(src, dst)
+function os._cp(src, dst, opt)
-- check
assert(src and dst)
+ -- preserve the source directory structure if opt.rootdir is given
+ local rootdir = opt and opt.rootdir
+ if rootdir then
+ if not path.is_absolute(rootdir) then
+ rootdir = path.absolute(rootdir)
+ end
+ if not path.is_absolute(src) then
+ src = path.absolute(src)
+ end
+ if not src:startswith(rootdir) then
+ return false, string.format("cannot copy file %s to %s, error: invalid rootdir(%s)", src, dst, rootdir)
+ end
+ end
+
-- is file?
if os.isfile(src) then
-- the destination is directory? append the filename
if os.isdir(dst) or path.islastsep(dst) then
- dst = path.join(dst, path.filename(src))
+ if rootdir then
+ dst = path.join(dst, path.relative(src, rootdir))
+ else
+ dst = path.join(dst, path.filename(src))
+ end
end
-- copy file
@@ -70,7 +88,11 @@ function os._cp(src, dst)
-- the destination directory exists? append the filename
if os.isdir(dst) or path.islastsep(dst) then
- dst = path.join(dst, path.filename(path.translate(src)))
+ if rootdir then
+ dst = path.join(dst, path.relative(src, rootdir))
+ else
+ dst = path.join(dst, path.filename(path.translate(src)))
+ end
end
-- copy directory
@@ -366,7 +388,7 @@ function os.filedirs(pattern, callback)
end
-- copy files or directories
-function os.cp(srcpath, dstpath)
+function os.cp(srcpath, dstpath, opt)
-- check arguments
if not srcpath or not dstpath then
@@ -376,10 +398,10 @@ function os.cp(srcpath, dstpath)
-- copy files or directories
local srcpathes = os._match_wildcard_pathes(srcpath)
if type(srcpathes) == "string" then
- return os._cp(srcpathes, dstpath)
+ return os._cp(srcpathes, dstpath, opt)
else
for _, _srcpath in ipairs(srcpathes) do
- local ok, errors = os._cp(_srcpath, dstpath)
+ local ok, errors = os._cp(_srcpath, dstpath, opt)
if not ok then
return false, errors
end
diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua
index 0436eced3..e0acaaeba 100644
--- a/xmake/core/sandbox/modules/os.lua
+++ b/xmake/core/sandbox/modules/os.lua
@@ -76,9 +76,9 @@ sandbox_os.SYSERR_NOT_PERM = os.SYSERR_NOT_PERM
sandbox_os.SYSERR_NOT_FILEDIR = os.SYSERR_NOT_FILEDIR
-- copy file or directory
-function sandbox_os.cp(srcpath, dstpath)
+function sandbox_os.cp(srcpath, dstpath, opt)
assert(srcpath and dstpath)
- local ok, errors = os.cp(vformat(srcpath), vformat(dstpath))
+ local ok, errors = os.cp(vformat(srcpath), vformat(dstpath), opt)
if not ok then
os.raise(errors)
end
@@ -112,12 +112,12 @@ function sandbox_os.ln(srcpath, dstpath)
end
-- copy file or directory with the verbose info
-function sandbox_os.vcp(srcpath, dstpath)
+function sandbox_os.vcp(srcpath, dstpath, opt)
assert(srcpath and dstpath)
if option.get("verbose") then
utils.cprint("${dim}> copy %s to %s ..", srcpath, dstpath)
end
- return sandbox_os.cp(srcpath, dstpath)
+ return sandbox_os.cp(srcpath, dstpath, opt)
end
-- move file or directory with the verbose info