From 2e278af5e2a74060827e5e62758256cb256cb154 Mon Sep 17 00:00:00 2001 From: Jason Perkins Date: Fri, 15 Feb 2013 18:57:34 -0500 Subject: [PATCH] Cleaned up implementation of solution(), project(), configuration(); now activate scope when called without arguments --- src/base/api.lua | 244 ++++++------------ src/base/solution.lua | 18 +- src/project/project.lua | 1 + .../vstudio/sln2005/test_platforms.lua | 32 +-- tests/api/test_containers.lua | 70 +++++ tests/premake4.lua | 1 + 6 files changed, 184 insertions(+), 182 deletions(-) create mode 100644 tests/api/test_containers.lua diff --git a/src/base/api.lua b/src/base/api.lua index c5246a0e..f36bf0fe 100644 --- a/src/base/api.lua +++ b/src/base/api.lua @@ -972,96 +972,25 @@ } - - ------------------------------------------------------------------------------ --- Everything below this point is a candidate for deprecation ------------------------------------------------------------------------------ - api.reset() - premake.CurrentContainer = api.scope.root - -- --- Retrieve the current object of a particular type from the session. The --- type may be "solution", "container" (the last activated solution or --- project), or "config" (the last activated configuration). Returns the --- requested container, or nil and an error message. --- - - function premake.getobject(t) - local container - - if (t == "container" or t == "solution") then - container = premake.CurrentContainer - else - container = premake.CurrentConfiguration - end - - if t == "solution" then - if type(container) == "project" then - container = container.solution - end - if type(container) ~= "solution" then - container = nil - end - end - - local msg - if (not container) then - if (t == "container") then - msg = "no active solution or project" - elseif (t == "solution") then - msg = "no active solution" - else - msg = "no active solution, project, or configuration" - end - end - - return container, msg - end - - --- --- Project object constructors. +-- Start a new block of configuration settings. -- function configuration(terms) if not terms then - return premake.CurrentConfiguration + return api.scope.configuration end - -- OLD APPROACH: - -- TODO: Phase this out ASAP - local container, err = premake.getobject("container") - if (not container) then - error(err, 2) - end - - local cfg = { } - cfg.terms = table.flatten({terms}) - cfg.basedir = os.getcwd() - cfg.configset = container.configset - - table.insert(container.blocks, cfg) - premake.CurrentConfiguration = cfg - - -- create a keyword list using just the indexed keyword items. This is a little - -- confusing: "terms" are what the user specifies in the script, "keywords" are - -- the Lua patterns that result. I'll refactor to better names. - cfg.keywords = { } - for _, word in ipairs(cfg.terms) do - table.insert(cfg.keywords, path.wildcards(word):lower()) - end - - -- this is the new place for storing scoped objects - api.scope.configuration = cfg - - - -- NEW APPROACH: + local container = api.scope.project or api.scope.solution or api.scope.root configset.addblock(container.configset, {terms}, os.getcwd()) + local cfg = {} + cfg.configset = container.configset + api.scope.configuration = cfg + return cfg end @@ -1075,108 +1004,57 @@ end - local function createproject(name, sln, isUsage) - local prj = premake5.project.new(sln, name) - - -- add to master list keyed by both name and index - table.insert(sln.projects, prj) - if(isUsage) then - --If we're creating a new usage project, and there's already a project - --with our name, then set us as the usage project for that project. - --Otherwise, set us as the project in that slot. - if(sln.projects[name]) then - sln.projects[name].usageProj = prj; - else - sln.projects[name] = prj - end - else - --If we're creating a regular project, and there's already a project - --with our name, then it must be a usage project. Set it as our usage project - --and set us as the project in that slot. - if(sln.projects[name]) then - prj.usageProj = sln.projects[name]; - end - - sln.projects[name] = prj - end - - prj.script = _SCRIPT - prj.usage = isUsage; - prj.group = api.scope.group or "" - - return prj; - end - +-- +-- Set the current configuration scope to a project. +-- +-- @param name +-- The name of the project. If a project with this name already +-- exists, it is made current, otherwise a new project is created +-- with this name. If no name is provided, the most recently defined +-- project is made active. +-- @return +-- The active project object. +-- function project(name) - if (not name) then - --Only return non-usage projects - if(type(premake.CurrentContainer) ~= "project") then return nil end - if(premake.CurrentContainer.usage) then return nil end - return premake.CurrentContainer - end - - -- identify the parent solution - local sln - if (type(premake.CurrentContainer) == "project") then - sln = premake.CurrentContainer.solution - else - sln = premake.CurrentContainer - end - if (type(sln) ~= "solution") then - error("no active solution", 2) - end - - -- if this is a new project, or the old project is a usage project, create it - if((not sln.projects[name]) or sln.projects[name].usage) then - premake.CurrentContainer = createproject(name, sln) - else - premake.CurrentContainer = sln.projects[name]; - end - - -- add an empty, global configuration to the project - configuration {} - - -- this is the new place for storing scoped objects - api.scope.project = premake.CurrentContainer - - return premake.CurrentContainer - end - - --- --- Define a new solution object. --- - - function solution(name) if not name then - if type(premake.CurrentContainer) == "project" then - return premake.CurrentContainer.solution + if api.scope.project then + name = api.scope.project.name else - return premake.CurrentContainer + return nil end end - premake.CurrentContainer = premake.solution.get(name) - if (not premake.CurrentContainer) then - local sln = premake.solution.new(name) - premake.CurrentContainer = sln + local sln = api.scope.solution + if not sln then + error("no active solution", 2) end - -- add an empty, global configuration + local prj = sln.projects[name] + if not prj then + prj = premake5.project.new(sln, name) + prj.group = api.scope.group or "" + premake.solution.addproject(sln, prj) + end + + api.scope.project = prj + configuration {} - -- this is the new place for storing scoped objects - api.scope.solution = premake.CurrentContainer - api.scope.project = nil - api.scope.group = nil - - return premake.CurrentContainer + return prj end -- --- Creates a reference to an external, non-Premake generated project. +-- Activates a reference to an external, non-Premake generated project. +-- +-- @param name +-- The name of the project. If a project with this name already +-- exists, it is made current, otherwise a new project is created +-- with this name. If no name is provided, the most recently defined +-- project is made active. +-- @return +-- The active project object. -- function external(name) @@ -1186,6 +1064,42 @@ end +-- +-- Set the current configuration scope to a solution. +-- +-- @param name +-- The name of the solution. If a solution with this name already +-- exists, it is made current, otherwise a new solution is created +-- with this name. If no name is provided, the most recently defined +-- solution is made active. +-- @return +-- The active solution object. +-- + + function solution(name) + if not name then + if api.scope.solution then + name = api.scope.solution.name + else + return nil + end + end + + local sln = premake.solution.get(name) + if not sln then + sln = premake.solution.new(name) + end + + api.scope.solution = sln + api.scope.project = nil + api.scope.group = nil + + configuration {} + + return sln + end + + -- -- Define a new action. -- diff --git a/src/base/solution.lua b/src/base/solution.lua index c0d5f0d2..a16afb59 100644 --- a/src/base/solution.lua +++ b/src/base/solution.lua @@ -1,7 +1,7 @@ -- -- solution.lua -- Work with the list of solutions loaded from the script. --- Copyright (c) 2002-2012 Jason Perkins and the Premake project +-- Copyright (c) 2002-2013 Jason Perkins and the Premake project -- premake.solution = { } @@ -58,6 +58,22 @@ end +-- +-- Add a new project to the solution. +-- +-- @param sln +-- The solution to contain the project. +-- @param prj +-- The new project object. +-- + + function solution.addproject(sln, prj) + -- add keyed by array index AND name + table.insert(sln.projects, prj) + sln.projects[prj.name] = prj + end + + -- -- Creates a new project, which the given -- diff --git a/src/project/project.lua b/src/project/project.lua index 89afb263..0ba31de4 100755 --- a/src/project/project.lua +++ b/src/project/project.lua @@ -27,6 +27,7 @@ prj.name = name prj.solution = sln + prj.script = _SCRIPT prj.blocks = {} local cwd = os.getcwd() diff --git a/tests/actions/vstudio/sln2005/test_platforms.lua b/tests/actions/vstudio/sln2005/test_platforms.lua index bfc6b131..d1b212af 100644 --- a/tests/actions/vstudio/sln2005/test_platforms.lua +++ b/tests/actions/vstudio/sln2005/test_platforms.lua @@ -10,18 +10,18 @@ -- --- Setup +-- Setup -- local sln, prj - + function suite.setup() _ACTION = "vs2008" sln = solution("MySolution") configurations { "Debug", "Release" } language "C++" end - + local function prepare(lang) uuid "C9135098-6047-8142-B10E-D27E7F73FCB3" sln = premake.solution.bake(sln) @@ -72,7 +72,7 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - + project "MyProject2" prepare() test.capture [[ @@ -153,7 +153,7 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - + project "MyProject2" prepare() test.capture [[ @@ -232,8 +232,8 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - - project "MyProject2" + + project "MyProject2" prepare() test.capture [[ GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -254,7 +254,7 @@ end --- +-- -- If the projects contain a mix of architectures, handle that. -- @@ -262,8 +262,8 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - - project "MyProject2" + + project "MyProject2" architecture "x64" prepare() test.capture [[ @@ -332,8 +332,8 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - - project "MyProject2" + + project "MyProject2" prepare() test.capture [[ GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -427,7 +427,7 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - + project "MyProject2" prepare() test.capture [[ @@ -460,7 +460,7 @@ -- --- If the platform identifier matches a system or architecture, omit it +-- If the platform identifier matches a system or architecture, omit it -- from the configuration description. -- @@ -518,7 +518,7 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - + project "MyProject2" prepare() test.capture [[ @@ -596,7 +596,7 @@ project "MyProject1" language "C#" uuid "52AD9329-0D74-4F66-A213-E649D8CCD737" - + project "MyProject2" prepare() test.capture [[ diff --git a/tests/api/test_containers.lua b/tests/api/test_containers.lua new file mode 100644 index 00000000..c792bd21 --- /dev/null +++ b/tests/api/test_containers.lua @@ -0,0 +1,70 @@ +-- +-- tests/api/test_containers.lua +-- Tests the API's solution() and project() container definitions. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + local suite = test.declare("api_containers") + local api = premake.api + + +-- +-- Setup and teardown +-- + + local sln + + function suite.setup() + sln = solution("MySolution") + end + + +-- +-- The first time a name is encountered, a new container should be created. +-- + + function suite.solution_createsOnFirstUse() + test.isnotnil(premake.solution.get("MySolution")) + end + + function suite.project_createsOnFirstUse() + project("MyProject") + test.isnotnil(premake.solution.getproject_ng(sln, "MyProject")) + end + + +-- +-- When a container is created, it should become the active scope. +-- + + function suite.solution_setsActiveScope() + test.isequal(api.scope.solution, sln) + end + + function suite.project_setsActiveScope() + local prj = project("MyProject") + test.isequal(api.scope.project, prj) + end + + +-- +-- When container function is called with no arguments, that should +-- become the current scope. +-- + + function suite.solution_setsActiveScope_onNoArgs() + project("MyProject") + group("MyGroup") + solution() + test.isequal(sln, api.scope.solution) + test.isnil(api.scope.project) + test.isnil(api.scope.group) + end + + function suite.project_setsActiveScope_onNoArgs() + local prj = project("MyProject") + group("MyGroup") + project() + test.isequal(prj, api.scope.project) + end + diff --git a/tests/premake4.lua b/tests/premake4.lua index a06e3dcb..6633fb08 100644 --- a/tests/premake4.lua +++ b/tests/premake4.lua @@ -76,6 +76,7 @@ -- API tests dofile("api/test_array_kind.lua") dofile("api/test_callback.lua") + dofile("api/test_containers.lua") dofile("api/test_list_kind.lua") dofile("api/test_path_kind.lua") dofile("api/test_register.lua")