Prevent single-child ".." folders from appearing at the top of the source tree; merge project.eachfile() into project.getsourcetree()
This commit is contained in:
parent
0b241993c2
commit
a1a0afd327
@ -228,6 +228,7 @@
|
||||
function tree.trimroot(tr)
|
||||
local trimmed
|
||||
|
||||
-- start by removing single-children folders from the top of the tree
|
||||
while #tr.children == 1 do
|
||||
local node = tr.children[1]
|
||||
|
||||
@ -237,8 +238,7 @@
|
||||
end
|
||||
|
||||
-- remove this node from the tree, and move its children up a level
|
||||
trimmed = node.path
|
||||
|
||||
trimmed = true
|
||||
local numChildren = #node.children
|
||||
for i = 1, numChildren do
|
||||
local child = node.children[i]
|
||||
@ -247,13 +247,33 @@
|
||||
end
|
||||
end
|
||||
|
||||
-- found the top, now remove any single-children ".." folders from here
|
||||
local dotdot
|
||||
local count = #tr.children
|
||||
repeat
|
||||
dotdot = false
|
||||
for i = 1, count do
|
||||
local node = tr.children[i]
|
||||
if node.name == ".." and #node.children == 1 then
|
||||
local child = node.children[1]
|
||||
child.parent = node.parent
|
||||
tr.children[i] = child
|
||||
trimmed = true
|
||||
dotdot = true
|
||||
end
|
||||
end
|
||||
until not dotdot
|
||||
|
||||
-- if nodes were removed, adjust the paths on all remaining nodes
|
||||
if trimmed then
|
||||
local trimlen = #trimmed + 2
|
||||
tree.traverse(tr, {
|
||||
onnode = function(node)
|
||||
node.path = node.path:sub(trimlen)
|
||||
if node.parent.path then
|
||||
node.path = path.join(node.parent.path, node.name)
|
||||
else
|
||||
node.path = node.name
|
||||
end
|
||||
end
|
||||
})
|
||||
}, false)
|
||||
end
|
||||
end
|
||||
|
@ -65,54 +65,6 @@
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Return an iterator for the list of source code files contained by a project.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project to query.
|
||||
-- @return
|
||||
-- A source code file iterator, which returns file configuration objects.
|
||||
-- These file configurations contain:
|
||||
--
|
||||
-- fullpath - the relative path from the project to the file
|
||||
-- vpath - the file's virtual path, if specified, or fullpath if not
|
||||
--
|
||||
|
||||
function project.eachfile(prj)
|
||||
-- make sure I have the project, and not it's root configuration
|
||||
prj = prj.project or prj
|
||||
|
||||
-- find *all* files referenced by the project, regardless of configuration,
|
||||
-- and cache the list for future calls
|
||||
if not prj.files then
|
||||
local files = {}
|
||||
for _, block in ipairs(prj.blocks) do
|
||||
for _, file in ipairs(block.files) do
|
||||
if not files[file] then
|
||||
local fcfg = project.getfileconfig(prj, file)
|
||||
|
||||
-- add it both indexed for iteration and keyed for quick tests
|
||||
table.insert(files, file)
|
||||
files[file] = fcfg
|
||||
end
|
||||
end
|
||||
end
|
||||
prj.files = files
|
||||
end
|
||||
|
||||
local files = prj.files
|
||||
local i = 0
|
||||
|
||||
return function()
|
||||
i = i + 1
|
||||
if i <= #files then
|
||||
local filename = files[i]
|
||||
return files[filename]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Locate a project by name; case insensitive.
|
||||
--
|
||||
@ -305,14 +257,28 @@
|
||||
--
|
||||
|
||||
function project.getsourcetree(prj)
|
||||
-- make sure I have the project, and not it's root configuration
|
||||
prj = prj.project or prj
|
||||
|
||||
-- check for a previously cached tree
|
||||
if prj.sourcetree then
|
||||
return prj.sourcetree
|
||||
end
|
||||
|
||||
local tr = premake.tree.new(prj.name)
|
||||
|
||||
for fcfg in project.eachfile(prj) do
|
||||
-- find *all* files referenced by the project, regardless of configuration
|
||||
local files = {}
|
||||
for _, block in ipairs(prj.blocks) do
|
||||
for _, file in ipairs(block.files) do
|
||||
files[file] = file
|
||||
end
|
||||
end
|
||||
|
||||
-- create a tree from the file list
|
||||
local tr = premake.tree.new(prj.name)
|
||||
|
||||
for file in pairs(files) do
|
||||
local fcfg = project.getfileconfig(prj, file)
|
||||
|
||||
-- The tree represents the logical source code tree to be displayed
|
||||
-- in the IDE, not the physical organization of the file system. So
|
||||
-- virtual paths are used when adding nodes.
|
||||
@ -324,10 +290,10 @@
|
||||
end
|
||||
end)
|
||||
|
||||
-- Store additional path information for file (leaf) nodes
|
||||
node.abspath = fcfg.abspath
|
||||
node.relpath = fcfg.relpath
|
||||
node.vpath = fcfg.vpath
|
||||
-- Store full file configuration in file (leaf) nodes
|
||||
for key, value in pairs(fcfg) do
|
||||
node[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
premake.tree.trimroot(tr)
|
||||
|
@ -202,6 +202,51 @@
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- A ".." folder containing a single subfolder should never appear
|
||||
-- at the top of the source tree.
|
||||
--
|
||||
|
||||
function suite.trimroot_removesDotDot_onTopLevelSiblings()
|
||||
tree.add(tr, "../../tests/test_hello.c")
|
||||
tree.add(tr, "../src/test.c")
|
||||
tree.trimroot(tr)
|
||||
prepare()
|
||||
test.capture [[
|
||||
tests
|
||||
test_hello.c
|
||||
src
|
||||
test.c
|
||||
]]
|
||||
end
|
||||
|
||||
function suite.trimroot_removesDotDot_onTopLevel()
|
||||
tree.add(tr, "../tests/test_hello.c")
|
||||
tree.add(tr, "src/test.c")
|
||||
tree.trimroot(tr)
|
||||
prepare()
|
||||
test.capture [[
|
||||
tests
|
||||
test_hello.c
|
||||
src
|
||||
test.c
|
||||
]]
|
||||
end
|
||||
|
||||
function suite.trimroot_removesDotDot_onMultipleNestings()
|
||||
tree.add(tr, "../../../tests/test_hello.c")
|
||||
tree.add(tr, "../src/test.c")
|
||||
tree.trimroot(tr)
|
||||
prepare()
|
||||
test.capture [[
|
||||
tests
|
||||
test_hello.c
|
||||
src
|
||||
test.c
|
||||
]]
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- When nodes are trimmed, the paths on the remaining nodes should
|
||||
-- be updated to reflect the new hierarchy.
|
||||
@ -211,6 +256,13 @@
|
||||
tree.add(tr, "A/1")
|
||||
tree.add(tr, "A/2")
|
||||
tree.trimroot(tr)
|
||||
prepare()
|
||||
test.isequal("1", tr.children[1].path)
|
||||
end
|
||||
|
||||
|
||||
function suite.trimroot_updatesPaths_onDotDotRemoved()
|
||||
tree.add(tr, "../../../tests/test_hello.c")
|
||||
tree.add(tr, "../src/test.c")
|
||||
tree.trimroot(tr)
|
||||
test.isequal("tests", tr.children[1].path)
|
||||
end
|
||||
|
@ -63,7 +63,6 @@
|
||||
dofile("test_project.lua")
|
||||
dofile("project/test_baking.lua")
|
||||
dofile("project/test_eachconfig.lua")
|
||||
dofile("project/test_eachfile.lua")
|
||||
dofile("project/test_filtering.lua")
|
||||
dofile("project/test_getconfig.lua")
|
||||
dofile("project/test_hasconfig.lua")
|
||||
|
@ -1,84 +0,0 @@
|
||||
--
|
||||
-- tests/project/test_eachfile.lua
|
||||
-- Automated test suite for the file iteration function.
|
||||
-- Copyright (c) 2011-2012 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
T.project_eachfile = { }
|
||||
local suite = T.project_eachfile
|
||||
local project = premake5.project
|
||||
|
||||
|
||||
--
|
||||
-- Setup and teardown
|
||||
--
|
||||
|
||||
local sln, prj
|
||||
function suite.setup()
|
||||
sln, prj = test.createsolution()
|
||||
end
|
||||
|
||||
local function prepare(field)
|
||||
if not field then
|
||||
field = "relpath"
|
||||
end
|
||||
for file in project.eachfile(prj) do
|
||||
_p(2, file[field])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Sanity check that all files are returned, with project relative paths.
|
||||
--
|
||||
|
||||
function suite.listsAllFiles()
|
||||
files { "hello.h", "hello.c" }
|
||||
prepare()
|
||||
test.capture [[
|
||||
hello.h
|
||||
hello.c
|
||||
]]
|
||||
end
|
||||
|
||||
--
|
||||
-- Ensure that the virtual path field defaults to the real file path.
|
||||
--
|
||||
|
||||
function suite.vpathsAreNil_onNoVpaths()
|
||||
files { "hello.h", "hello.c" }
|
||||
prepare("vpath")
|
||||
test.capture [[
|
||||
hello.h
|
||||
hello.c
|
||||
]]
|
||||
end
|
||||
|
||||
--
|
||||
-- If a virtual path is specified, the vpath field should be set.
|
||||
--
|
||||
|
||||
function suite.vpathSet_onVpath()
|
||||
files { "hello.h", "hello.c" }
|
||||
vpaths { Headers = "**.h" }
|
||||
prepare("vpath")
|
||||
test.capture [[
|
||||
Headers/hello.h
|
||||
hello.c
|
||||
]]
|
||||
end
|
||||
|
||||
--
|
||||
-- A file listed in a configuration should be included in the list.
|
||||
--
|
||||
|
||||
function suite.includesFile_setInConfiguration()
|
||||
files { "hello.h" }
|
||||
configuration { "Debug" }
|
||||
files { "hello.c" }
|
||||
prepare()
|
||||
test.capture [[
|
||||
hello.h
|
||||
hello.c
|
||||
]]
|
||||
end
|
Reference in New Issue
Block a user