diff --git a/src/base/project.lua b/src/base/project.lua index 1e706332..261f0fad 100644 --- a/src/base/project.lua +++ b/src/base/project.lua @@ -524,7 +524,48 @@ end - + +-- +-- Given a source file path, return a corresponding virtual path based on +-- the vpath entries in the project. If no matching vpath entry is found, +-- the original path is returned. +-- + + function premake.project.getvpath(prj, filename) + -- if there is no match, return the input filename + local vpath = filename + + for pattern, replacement in pairs(prj.vpaths) do + -- does the filename match this vpath pattern? + local i = vpath:find(path.wildcards(pattern)) + if i == 1 then + -- yes; trim the leading portion of the path + i = pattern:find("*", 1, true) or (pattern:len() + 1) + local leaf = vpath:sub(i) + if leaf:startswith("/") then + leaf = leaf:sub(2) + 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) + local stem = "" + if replacement:len() > 0 then + stem, stars = replacement:gsub("%*", "") + if stars == 0 then + leaf = path.getname(leaf) + end + end + + vpath = path.join(stem, leaf) + end + end + + return vpath + end + + -- -- Returns true if the solution contains at least one C/C++ project. -- diff --git a/tests/premake4.lua b/tests/premake4.lua index 992dd403..071ebddd 100644 --- a/tests/premake4.lua +++ b/tests/premake4.lua @@ -40,7 +40,6 @@ dofile("test_dofile.lua") dofile("test_string.lua") dofile("test_premake.lua") - dofile("test_project.lua") dofile("test_platforms.lua") dofile("test_targets.lua") dofile("test_keywords.lua") @@ -57,6 +56,10 @@ dofile("tools/test_gcc.lua") dofile("base/test_config_bug.lua") + -- Project API tests + dofile("test_project.lua") + dofile("project/test_vpaths.lua") + -- Baking tests dofile("base/test_baking.lua") dofile("baking/test_merging.lua") diff --git a/tests/project/test_vpaths.lua b/tests/project/test_vpaths.lua new file mode 100644 index 00000000..c7b2e1d6 --- /dev/null +++ b/tests/project/test_vpaths.lua @@ -0,0 +1,112 @@ +-- +-- tests/project/test_vpaths.lua +-- Automated test suite for the project support functions. +-- Copyright (c) 2011 Jason Perkins and the Premake project +-- + + T.project_vpaths = { } + local suite = T.project_vpaths + local project = premake.project + + +-- +-- Setup and teardown +-- + + local sln, prj + function suite.setup() + sln = test.createsolution() + end + + local function prepare() + premake.bake.buildconfigs() + prj = premake.solution.getproject(sln, 1) + end + +-- +-- Test simple replacements +-- + + function suite.ReturnsOriginalPath_OnNoVpaths() + prepare() + test.isequal("hello.c", project.getvpath(prj, "hello.c")) + end + + function suite.ReturnsOriginalPath_OnNoMatches() + vpaths { ["**.h"] = "Headers" } + prepare() + test.isequal("hello.c", project.getvpath(prj, "hello.c")) + end + + + function suite.CanTrimLeadingPaths() + vpaths { ["src"] = "" } + prepare() + test.isequal("myproject/hello.c", project.getvpath(prj, "src/myproject/hello.c")) + end + + + function suite.PatternMayIncludeTrailingSlash() + vpaths { ["src/myproject/"] = "" } + prepare() + test.isequal("hello.c", project.getvpath(prj, "src/myproject/hello.c")) + end + + + function suite.SimpleReplacementPatterns() + vpaths { ["src/myproject"] = "sources" } + prepare() + test.isequal("sources/hello.c", project.getvpath(prj, "src/myproject/hello.c")) + end + +-- +-- Test wildcard patterns +-- + + function suite.MatchFilePattern_ToGroup_Flat() + vpaths { ["**.h"] = "Headers" } + prepare() + test.isequal("Headers/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePattern_ToNestedGroup_Flat() + vpaths { ["**.h"] = "Source/Headers" } + prepare() + test.isequal("Source/Headers/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePattern_ToGroup_WithTrailingSlash() + vpaths { ["**.h"] = "Headers/" } + prepare() + test.isequal("Headers/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePattern_ToNestedGroup_Flat() + vpaths { ["**.h"] = "Group/Headers" } + prepare() + test.isequal("Group/Headers/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePattern_ToGroup_Nested() + vpaths { ["**.h"] = "Headers/**" } + prepare() + test.isequal("Headers/src/myproject/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePattern_ToGroup_Nested_OneStar() + vpaths { ["**.h"] = "Headers/*" } + prepare() + test.isequal("Headers/src/myproject/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end + + + function suite.MatchFilePatternWithPath_ToGroup_Nested() + vpaths { ["src/**.h"] = "Headers/**" } + prepare() + test.isequal("Headers/myproject/hello.h", project.getvpath(prj, "src/myproject/hello.h")) + end