Make virtual path processing order deterministic

This commit is contained in:
Jason Perkins 2014-03-09 13:17:10 -04:00
parent 4f40197ab0
commit 6355a3215d
4 changed files with 59 additions and 73 deletions

View File

@ -688,7 +688,7 @@
api.register {
name = "vpaths",
scope = "project",
kind = "keyed:list:path",
kind = "list:keyed:list:path",
}
api.register {

View File

@ -576,15 +576,10 @@
current = current or {}
for k, v in pairs(value) do
-- if type(k) == "number" then
-- error ()
-- current = storeKeyed(field, current, v, processor)
-- else
if processor then
v = processor(field, current[k], v)
end
current[k] = v
-- end
if processor then
v = processor(field, current[k], v)
end
current[k] = v
end
return current
@ -604,10 +599,18 @@
local function storeList(field, current, value, processor)
if type(value) == "table" then
table.foreachi(value, function(item)
current = storeList(field, current, item, processor)
end)
return current
-- Flatten out incoming arrays of values
if #value > 0 then
table.foreachi(value, function(item)
current = storeList(field, current, item, processor)
end)
return current
end
-- Ignore empty lists
if table.isempty(value) then
return current
end
end
local function store(item)
@ -624,7 +627,7 @@
value = processor(field, nil, value)
end
if type(value) == "table" then
if type(value) == "table" and #value > 0 then
table.foreachi(value, store)
else
store(value)

View File

@ -345,53 +345,58 @@
local fname = path.getname(abspath)
local max = abspath:len() - fname:len()
-- Look for matching patterns
for replacement, patterns in pairs(prj.vpaths or {}) do
for _, pattern in ipairs(patterns) do
local i = abspath:find(path.wildcards(pattern))
if i == 1 then
-- Look for matching patterns. Virtual paths are stored as an array
-- for tables, each table continuing the path key, which looks up the
-- array of paths with should match against that path.
-- Trim out the part of the name that matched the pattern; what's
-- left is the part that gets appended to the replacement to make
-- the virtual path. So a pattern like "src/**.h" matching the
-- file src/include/hello.h, I want to trim out the src/ part,
-- leaving include/hello.h.
for _, vpaths in ipairs(prj.vpaths) do
for replacement, patterns in pairs(vpaths) do
for _, pattern in ipairs(patterns) do
local i = abspath:find(path.wildcards(pattern))
if i == 1 then
-- Find out where the wildcard appears in the match. If there is
-- no wildcard, the match includes the entire pattern
-- Trim out the part of the name that matched the pattern; what's
-- left is the part that gets appended to the replacement to make
-- the virtual path. So a pattern like "src/**.h" matching the
-- file src/include/hello.h, I want to trim out the src/ part,
-- leaving include/hello.h.
i = pattern:find("*", 1, true) or (pattern:len() + 1)
-- Find out where the wildcard appears in the match. If there is
-- no wildcard, the match includes the entire pattern
-- Trim, taking care to keep the actual file name intact.
i = pattern:find("*", 1, true) or (pattern:len() + 1)
local leaf
if i < max then
leaf = abspath:sub(i)
else
leaf = fname
end
-- Trim, taking care to keep the actual file name intact.
if leaf:startswith("/") then
leaf = leaf:sub(2)
end
local leaf
if i < max then
leaf = abspath:sub(i)
else
leaf = fname
end
-- check for (and remove) stars in the replacement pattern.
-- If there are none, then trim all path info from the leaf
-- and use just the filename in the replacement (stars should
-- really only appear at the end; I'm cheating here)
if leaf:startswith("/") then
leaf = leaf:sub(2)
end
local stem = ""
if replacement:len() > 0 then
stem, stars = replacement:gsub("%*", "")
if stars == 0 then
-- check for (and remove) stars in the replacement pattern.
-- If there are none, then trim all path info from the leaf
-- and use just the filename in the replacement (stars should
-- really only appear at the end; I'm cheating here)
local stem = ""
if replacement:len() > 0 then
stem, stars = replacement:gsub("%*", "")
if stars == 0 then
leaf = path.getname(leaf)
end
else
leaf = path.getname(leaf)
end
else
leaf = path.getname(leaf)
vpath = path.join(stem, leaf)
return vpath
end
vpath = path.join(stem, leaf)
end
end
end

View File

@ -240,25 +240,3 @@
local x = configset.fetch(cset, f, {"windows"})
test.isequal({"Development"}, x.Debug)
end
--
-- Keyed values should merge when merged fields are fetched.
--
function suite.keyed_mergesValues_onMergeFetch()
local f = field.get("vpaths")
configset.store(cset, f, { includes="*.h" })
configset.addblock(cset, { "windows" })
configset.store(cset, f, { includes="*.hpp" })
local x = configset.fetch(cset, f, {"windows"})
test.isequal({ os.getcwd().."/*.h", os.getcwd().."/*.hpp" }, x.includes)
end
function suite.keyed_mergesValues_onMergeAdd()
local f = field.get("vpaths")
configset.store(cset, f, { includes="*.h" })
configset.store(cset, f, { includes="*.hpp" })
local x = configset.fetch(cset, f, {"windows"})
test.isequal({ os.getcwd().."/*.h", os.getcwd().."/*.hpp" }, x.includes)
end