summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-09-26 22:37:30 +0800
committerruki <[email protected]>2025-09-26 22:37:30 +0800
commit91b87415d0666c388d5d2f8fada1164c095db098 (patch)
treed763efdaccb426ffdfa89335d7653f6cb0baca33
parent80473173e753bc989f0b6ae216df160eff4e3911 (diff)
improve to change directory
-rw-r--r--xmake/core/base/os.lua45
-rw-r--r--xmake/core/base/scheduler.lua46
2 files changed, 53 insertions, 38 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index f65f47edf..99b702ce8 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -39,6 +39,7 @@ os._mkdir = os._mkdir or os.mkdir
os._rmdir = os._rmdir or os.rmdir
os._touch = os._touch or os.touch
os._tmpdir = os._tmpdir or os.tmpdir
+os._curdir = os._curdir or os.curdir
os._fscase = os._fscase or os.fscase
os._setenv = os._setenv or os.setenv
os._getenvs = os._getenvs or os.getenvs
@@ -197,6 +198,14 @@ function os._sched_chdir_set(chdir)
os._SCHED_CHDIR = chdir
end
+-- notify the current directory have been changed
+function os._notify_curdir_changed()
+ os._CURDIR = nil
+ if os._SCHED_CHDIR then
+ os._SCHED_CHDIR(os.curdir())
+ end
+end
+
-- notify envs have been changed
function os._notify_envs_changed(envs)
os._ENVS = nil
@@ -606,41 +615,33 @@ function os.cd(dir)
-- support path instance
dir = tostring(dir)
- -- the previous directory
- local oldir = os.curdir()
-
-- change to the previous directory?
+ local oldir = os.curdir()
if dir == "-" then
- -- exists the previous directory?
if os._PREDIR then
dir = os._PREDIR
os._PREDIR = nil
else
- -- error
return nil, string.format("not found the previous directory %s", os.strerror())
end
end
- -- is directory?
- if os.isdir(dir) then
+ -- no changed?
+ if dir == oldir then
+ return oldir
+ end
- -- change to directory
+ -- do change directory
+ if os.isdir(dir) then
if not os.chdir(dir) then
return nil, string.format("cannot change directory %s %s", dir, os.strerror())
end
-
- -- save the previous directory
os._PREDIR = oldir
-
- -- not exists?
else
return nil, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror())
end
- -- do chdir callback for scheduler
- if os._SCHED_CHDIR then
- os._SCHED_CHDIR(os.curdir())
- end
+ os._notify_curdir_changed()
return oldir
end
@@ -696,6 +697,16 @@ function os.rmdir(dir)
return true
end
+-- get the current directory
+function os.curdir()
+ local curdir = os._CURDIR
+ if curdir == nil then
+ curdir = os._curdir()
+ os._CURDIR = curdir
+ end
+ return curdir
+end
+
-- get the temporary directory
function os.tmpdir(opt)
@@ -1293,7 +1304,7 @@ end
-- get all current environment variables
-- e.g. envs["PATH"] = "/xxx:/yyy/foo"
function os.getenvs()
- local envs = os._ENVS
+ local envs -- = os._ENVS
if envs == nil then
envs = {}
for _, line in ipairs(os._getenvs()) do
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua
index fc6666c77..c96b32441 100644
--- a/xmake/core/base/scheduler.lua
+++ b/xmake/core/base/scheduler.lua
@@ -273,18 +273,15 @@ function scheduler:_co_curdir_update(curdir)
return
end
- -- save the current directory hash
+ -- save the current directory
curdir = curdir or os.curdir()
- local curdir_hash = hash.uuid4(path.absolute(curdir)):sub(1, 8)
- self._CO_CURDIR_HASH = curdir_hash
-
- -- save the current directory for each coroutine
local co_curdirs = self._CO_CURDIRS
if not co_curdirs then
co_curdirs = {}
self._CO_CURDIRS = co_curdirs
end
- co_curdirs[running] = {curdir_hash, curdir}
+ co_curdirs[running] = curdir
+ self._CO_CURDIR_CURRENT = curdir
end
-- update the current environments hash of current coroutine
@@ -296,15 +293,22 @@ function scheduler:_co_curenvs_update(envs)
return
end
- -- save the current environments
+ -- save the current directory hash
+ local envs_hash = ""
envs = envs or os.getenvs()
+ for _, key in ipairs(table.orderkeys(envs)) do
+ envs_hash = envs_hash .. key:upper() .. envs[key]
+ end
+ envs_hash = hash.uuid4(envs_hash):sub(1, 8)
+ self._CO_CURENVS_HASH = envs_hash
+
+ -- save the current directory for each coroutine
local co_curenvs = self._CO_CURENVS
if not co_curenvs then
co_curenvs = {}
self._CO_CURENVS = co_curenvs
end
- co_curenvs[running] = envs
- self._CO_CURENVS_CURRENT = envs
+ co_curenvs[running] = {envs_hash, envs}
end
-- resume it's waiting coroutine if all coroutines are dead in group
@@ -437,17 +441,17 @@ function scheduler:co_resume(co, ...)
if running then
-- has the current directory been changed? restore it
- local curdir = self._CO_CURDIR_HASH
+ local curdir = self._CO_CURDIR_CURRENT
local olddir = self._CO_CURDIRS and self._CO_CURDIRS[running] or nil
- if olddir and curdir ~= olddir[1] then -- hash changed?
- os.cd(olddir[2])
+ if olddir and curdir ~= olddir then -- hash changed?
+ os.cd(olddir)
end
-- has the current environments been changed? restore it
- local curenvs = self._CO_CURENVS_CURRENT
+ local curenvs = self._CO_CURENVS_HASH
local oldenvs = self._CO_CURENVS and self._CO_CURENVS[running] or nil
- if oldenvs and curenvs ~= oldenvs and running:is_isolated() then -- hash changed?
- os.setenvs(oldenvs)
+ if oldenvs and curenvs ~= oldenvs[1] and running:is_isolated() then -- hash changed?
+ os.setenvs(oldenvs[2])
end
end
@@ -462,17 +466,17 @@ function scheduler:co_suspend(...)
-- has the current directory been changed? restore it
local running = assert(self:co_running())
- local curdir = self._CO_CURDIR_HASH
+ local curdir = self._CO_CURDIR_CURRENT
local olddir = self._CO_CURDIRS and self._CO_CURDIRS[running] or nil
- if olddir and curdir ~= olddir[1] then -- hash changed?
- os.cd(olddir[2])
+ if olddir and curdir ~= olddir then -- hash changed?
+ os.cd(olddir)
end
-- has the current environments been changed? restore it
- local curenvs = self._CO_CURENVS_CURRENT
+ local curenvs = self._CO_CURENVS_HASH
local oldenvs = self._CO_CURENVS and self._CO_CURENVS[running] or nil
- if oldenvs and curenvs ~= oldenvs and running:is_isolated() then -- hash changed?
- os.setenvs(oldenvs)
+ if oldenvs and curenvs ~= oldenvs[1] and running:is_isolated() then -- hash changed?
+ os.setenvs(oldenvs[2])
end
-- return results