From 72756255abc3e892c81b36f567eb21705246c36c Mon Sep 17 00:00:00 2001 From: Jason Perkins Date: Thu, 5 Sep 2013 10:24:59 -0400 Subject: [PATCH] Handle virtual path collisions in source trees without losing files --- src/base/project.lua | 31 ------------------------------- src/base/solution.lua | 14 +++++++++++--- src/base/tree.lua | 14 ++++---------- src/project/project.lua | 22 ++++++++++++++-------- 4 files changed, 29 insertions(+), 52 deletions(-) diff --git a/src/base/project.lua b/src/base/project.lua index 67cc81ce..f568ee5a 100644 --- a/src/base/project.lua +++ b/src/base/project.lua @@ -7,37 +7,6 @@ premake.project = { } --- --- Create a tree from a project's list of files, representing the filesystem hierarchy. --- --- @param prj --- The project containing the files to map. --- @returns --- A new tree object containing a corresponding filesystem hierarchy. The root node --- contains a reference back to the original project: prj = tr.project. --- - - function premake.project.buildsourcetree(prj) - local tr = premake.tree.new(prj.name) - tr.project = prj - - local isvpath - - local function onadd(node) - node.isvpath = isvpath - end - - for fcfg in premake.project.eachfile(prj) do - isvpath = (fcfg.name ~= fcfg.vpath) - local node = premake.tree.add(tr, fcfg.vpath, onadd) - node.cfg = fcfg - end - - premake.tree.sort(tr) - return tr - end - - -- -- Returns an iterator for a set of build configuration settings. If a platform is -- specified, settings specific to that platform and build configuration pair are diff --git a/src/base/solution.lua b/src/base/solution.lua index f8822cb1..fa9efdb6 100644 --- a/src/base/solution.lua +++ b/src/base/solution.lua @@ -402,15 +402,23 @@ return sln.grouptree end - local tr = tree.new() - sln.grouptree = tr + -- build the tree of groups + local tr = tree.new() for prj in solution.eachproject_ng(sln) do local prjpath = path.join(prj.group, prj.name) - local node = tree.add(tr, prjpath, function(n) n.uuid = os.uuid(n.path) end) + local node = tree.add(tr, prjpath) node.project = prj end + -- assign UUIDs to each node in the tree + tree.traverse(tr, { + onnode = function(node) + node.uuid = os.uuid(node.path) + end + }) + + sln.grouptree = tr return tr end diff --git a/src/base/tree.lua b/src/base/tree.lua index b3943425..464b6b17 100644 --- a/src/base/tree.lua +++ b/src/base/tree.lua @@ -1,10 +1,10 @@ -- -- tree.lua -- Functions for working with the source code tree. --- Copyright (c) 2009-2012 Jason Perkins and the Premake project +-- Copyright (c) 2009-2013 Jason Perkins and the Premake project -- - premake.tree = { } + premake.tree = {} local tree = premake.tree @@ -18,7 +18,7 @@ function tree.new(n) local t = { name = n, - children = { } + children = {} } return t end @@ -31,14 +31,11 @@ -- The tree to contain the new node. -- @param p -- The path of the new node. --- @param onaddfunc --- A function to call when a new node is added to the tree. Receives the --- new node as an argument. -- @returns -- The new tree node. -- - function tree.add(tr, p, onaddfunc) + function tree.add(tr, p) -- Special case "." refers to the current node if p == "." then return tr @@ -54,9 +51,6 @@ if not childnode or childnode.path ~= p then childnode = tree.insert(parentnode, tree.new(childname)) childnode.path = p - if onaddfunc then - onaddfunc(childnode) - end end return childnode diff --git a/src/project/project.lua b/src/project/project.lua index 9fbe99bf..b3e3c0de 100755 --- a/src/project/project.lua +++ b/src/project/project.lua @@ -6,9 +6,9 @@ premake5.project = {} local project = premake5.project - local context = premake.context - local oven = premake5.oven local configset = premake.configset + local context = premake.context + local tree = premake.tree -- @@ -715,22 +715,28 @@ return prj._.sourcetree end - local tr = premake.tree.new(prj.name) + local tr = tree.new(prj.name) table.foreachi(prj._.files, function(fcfg) - -- 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. - local node = premake.tree.add(tr, fcfg.vpath) + + -- Virtual paths can overlap, potentially putting files with the same + -- name in the same folder, even though they have different paths on + -- the underlying filesystem. The tree.add() call won't overwrite + -- existing nodes, so provide the extra logic here. Start by getting + -- the parent folder node, creating it if necessary. + + local parent = tree.add(tr, path.getdirectory(fcfg.vpath)) + local node = tree.insert(parent, tree.new(path.getname(fcfg.vpath))) -- Pass through value fetches to the file configuration setmetatable(node, { __index = fcfg }) - end) - premake.tree.trimroot(tr) - premake.tree.sort(tr, sorter) + tree.trimroot(tr) + tree.sort(tr, sorter) prj._.sourcetree = tr return tr