Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@@ -0,0 +1,239 @@
---
-- base/validation.lua
--
-- Verify the contents of the project object before handing them off to
-- the action/exporter.
--
-- Copyright (c) 2002-2015 Jason Perkins and the Premake project
---
local p = premake
p.validation = {}
local m = p.validation
m.elements = {}
---
-- Validate the global container and all of its contents.
---
m.elements.global = function(glb)
return {
}
end
function p.global.validate(self)
p.callArray(m.elements.global, self)
p.container.validateChildren(self)
end
---
-- Validate a workspace and its projects.
---
m.elements.workspace = function(wks)
return {
m.workspaceHasConfigs,
m.uniqueProjectIds,
}
end
function p.workspace.validate(self)
p.callArray(m.elements.workspace, self)
p.container.validateChildren(self)
end
---
-- Validate a project and its configurations.
---
m.elements.project = function(prj)
return {
m.projectHasLanguage,
m.actionSupportsLanguage,
m.actionSupportsKind,
m.projectRulesExist,
m.projectValuesInScope,
}
end
function p.project.validate(self)
p.callArray(m.elements.project, self)
for cfg in p.project.eachconfig(self) do
p.config.validate(cfg)
end
end
---
-- Validate a project configuration.
---
m.elements.config = function(cfg)
return {
m.configHasKind,
m.configSupportsKind,
m.configValuesInScope,
}
end
function p.config.validate(self)
p.callArray(m.elements.config, self)
end
---
-- Validate a rule.
---
m.elements.rule = function(rule)
return {
-- TODO: fill this in
}
end
function p.rule.validate(self)
p.callArray(m.elements.rule, self)
end
---
-- Check the values stored in a configuration for values that might have
-- been set out of scope.
--
-- @param container
-- The container being validated; will only check fields which are
-- scoped to this container's class hierarchy.
-- @param expectedScope
-- The expected scope of values in this object, i.e. "project", "config".
-- Values that appear unexpectedly get checked to be sure they match up
-- with the values in the expected scope, and an error is raised if they
-- are not the same.
---
function p.config.validateScopes(self, container, expected)
for f in p.field.each() do
-- If this field scoped to the target container class? If not
-- I can skip over it (config scope applies to everything).
local scope
for i = 1, #f.scopes do
if f.scopes[i] == "config" or p.container.classIsA(container.class, f.scopes[i]) then
scope = f.scopes[i]
break
end
end
local okay = (not scope or scope == "config")
-- Skip over fields that are at or below my expected scope.
okay = okay or scope == expected
-- Skip over fields that bubble up to their parent containers anyway;
-- these can't be out of scope for that reason
okay = okay or p.oven.bubbledFields[f.name]
-- this one needs to checked
okay = okay or p.field.compare(f, self[scope][f.name], self[f.name])
-- found a problem?
if not okay then
local key = "validate." .. f.name
p.warnOnce(key, "'%s' on %s '%s' differs from %s '%s'; may be set out of scope", f.name, expected, self.name, scope, self[scope].name)
end
end
end
---------------------------------------------------------------------------
--
-- Handlers for individual checks
--
---------------------------------------------------------------------------
function m.actionSupportsKind(prj)
if not p.action.supports(prj.kind) then
p.warn("Unsupported kind '%s' used for project '%s'", prj.kind, prj.name)
end
end
function m.actionSupportsLanguage(prj)
if not p.action.supports(prj.language) then
p.warn("Unsupported language '%s' used for project '%s'", prj.language, prj.name)
end
end
function m.configHasKind(cfg)
if not cfg.kind then
p.error("Project '%s' needs a kind in configuration '%s'", cfg.project.name, cfg.name)
end
end
function m.configSupportsKind(cfg)
if not p.action.supports(cfg.kind) then
p.warn("Unsupported kind '%s' used in configuration '%s'", cfg.kind, cfg.name)
end
-- makefile configuration can only appear in C++ projects; this is the
-- default now, so should only be a problem if overridden.
if (cfg.kind == p.MAKEFILE or cfg.kind == p.NONE) and p.project.isdotnet(cfg.project) then
p.error("Project '%s' uses '%s' kind in configuration '%s'; language must not be C#", cfg.project.name, cfg.kind, cfg.name)
end
end
function m.configValuesInScope(cfg)
p.config.validateScopes(cfg, cfg.project, "config")
end
function m.projectHasLanguage(prj)
if not prj.language then
p.error("project '%s' does not have a language", prj.name)
end
end
function m.projectRulesExist(prj)
for i = 1, #prj.rules do
local rule = prj.rules[i]
if not p.global.getRule(rule) then
p.error("project '%s' uses missing rule '%s'", prj.name, rule)
end
end
end
function m.projectValuesInScope(prj)
p.config.validateScopes(prj, prj, "project")
end
function m.uniqueProjectIds(wks)
local uuids = {}
for prj in p.workspace.eachproject(wks) do
if uuids[prj.uuid] then
p.error("projects '%s' and '%s' have the same UUID", uuids[prj.uuid], prj.name)
end
uuids[prj.uuid] = prj.name
end
end
function m.workspaceHasConfigs(wks)
if not wks.configurations or #wks.configurations == 0 then
p.error("workspace '%s' does not contain any configurations", wks.name)
end
end