e2-build-numbers e2-cf e2-help
LOCALLUALIBS= digest.lua e2build.lua e2tool.lua environment.lua \
- policy.lua scm.lua licence.lua chroot.lua
+ policy.lua scm.lua licence.lua chroot.lua project.lua
LOCALTOOLS = $(LOCALLUATOOLS)
.PHONY: all install uninstall local install-local doc install-doc
local policy = require("policy")
local scm = require("scm")
local chroot = require("chroot")
+local project = require("project")
local function e2_ls_project(arg)
local rc, re = e2lib.init()
if opts.dot or opts["dot-sources"] then
local arrow = "->"
- console.infof("digraph \"%s\" {\n", info.project.name)
+ console.infof("digraph \"%s\" {\n", project.name())
for _, r in pairs(results) do
local res = info.results[r]
local deps, re = e2tool.dlist(info, r)
--------------- project name
local s1 = "|"
local s2 = "|"
- p0(s1, s2, info.project.name)
+ p0(s1, s2, project.name())
--------------- servers
local s1 = "|"
local tools = require("tools")
local transport = require("transport")
local chroot = require("chroot")
+local project = require("project")
-- Table driving the build process, see documentation at the bottom.
local build_process = {}
local e = err.new("creating link to last results")
-- calculate the path to the result
local server, location = res.build_mode.storage(info.project_location,
- info.project.release_id)
+ project.release_id())
local buildid, re = e2tool.buildid(info, r)
if not buildid then
return true, nil
end
local server, location =
- res.build_mode.storage(info.project_location, info.project.release_id)
+ res.build_mode.storage(info.project_location, project.release_id())
local dep_set = res.build_mode.dep_set(buildid)
-- cache the result
buildconfig.PATCHLEVEL, e2lib.globals.osenv["USER"])
local builddir = "tmp/e2"
- bc.base = e2lib.join(tmpdir, info.project.name, r)
+ bc.base = e2lib.join(tmpdir, project.name(), r)
bc.c = e2lib.join(bc.base, "chroot")
bc.chroot_marker = e2lib.join(bc.base, "e2factory-chroot")
bc.chroot_lock = e2lib.join(bc.base, "e2factory-chroot-lock")
- bc.T = e2lib.join(tmpdir, info.project.name, r, "chroot", builddir)
+ bc.T = e2lib.join(tmpdir, project.name(), r, "chroot", builddir)
bc.Tc = e2lib.join("/", builddir)
bc.r = r
- if info.chroot_call_prefix[info.project.chroot_arch] == "" then
- -- escape only if non-empty, otherwise we fail to start "''"
- tab.chroot_call_prefix = ""
- else
- tab.chroot_call_prefix =
- e2lib.shquote(info.chroot_call_prefix[info.project.chroot_arch])
- end
+ bc.chroot_call_prefix = info.chroot_call_prefix[project.chroot_arch()]
bc.buildlog = string.format("%s/log/build.%s.log", info.root, r)
bc.scriptdir = "script"
bc.build_driver = ""
bc.builtin_env = environment.new()
bc.builtin_env:set("E2_TMPDIR", bc.Tc)
bc.builtin_env:set("E2_RESULT", r)
- bc.builtin_env:set("E2_RELEASE_ID", info.project.release_id)
- bc.builtin_env:set("E2_PROJECT_NAME", info.project.name)
+ bc.builtin_env:set("E2_RELEASE_ID", project.release_id())
+ bc.builtin_env:set("E2_PROJECT_NAME", project.name())
bc.builtin_env:set("E2_BUILDID", buildid)
bc.builtin_env:set("T", bc.Tc)
bc.builtin_env:set("r", r)
end
cmd = {
- res.build_config.chroot_call_prefix,
e2_su,
"chroot_2_3",
res.build_config.base,
}
+ if #res.build_config.chroot_call_prefix > 0 then
+ table.insert(cmd, 1, res.build_config.chroot_call_prefix)
+ end
+
if chroot_command then
table.insert(cmd, "/bin/sh")
table.insert(cmd, "-c")
e2tool.set_umask(info)
local cmd = {
- res.build_config.chroot_call_prefix,
e2_su,
"chroot_2_3",
res.build_config.base,
res.build_config.build_driver_file)
}
+ if #res.build_config.chroot_call_prefix > 0 then
+ table.insert(cmd, 1, res.build_config.chroot_call_prefix)
+ end
+
rc, re = e2lib.callcmd_capture(cmd, logto)
if not rc then
eio.fclose(out)
local dep_set = d.build_mode.dep_set(buildid)
local server, location =
- d.build_mode.storage(info.project_location, info.project.release_id)
+ d.build_mode.storage(info.project_location, project.release_id())
e2lib.logf(3, "searching for dependency %s in %s:%s", dep, server, location)
local location1 = e2lib.join(location, dep, dep_set, "result.tar")
local cache_flags = {}
end
table.insert(files, "checksums")
local server, location = res.build_mode.deploy_storage(
- info.project_location, info.project.release_id)
+ info.project_location, project.release_id())
-- do not re-deploy if this release was already done earlier
local location1 = e2lib.join(location, r, "checksums")
return false, e:cat(re)
end
local server, location = res.build_mode.storage(info.project_location,
- info.project.release_id)
+ project.release_id())
local buildid, re = e2tool.buildid(info, r)
if not buildid then
local transport = require("transport")
local url = require("url")
local chroot = require("chroot")
+local project = require("project")
-- Build function table, see end of file for details.
local e2tool_ftab = {}
end
end
end
- for _,r in ipairs(info.project.deploy_results) do
+ for r in project.deploy_results_iter() do
if r == resultname then
res._deploy = true
break
return true
end
---- Read project configuration file.
--- @return True on success, false on error.
--- @return Error object on failure.
-local function read_project_config(info)
-
- --- Project configuration table (e2project).
- -- @table info.project
- -- @field release_id Release identifier, usually a git tag (string).
- -- @field name Name of project (string).
- -- @field deploy_results List of results that should be archived on
- -- --release builds (table containing strings).
- -- @field default_results List of results that are built by default
- -- (table containing strings).
- -- @field chroot_arch Chroot architecture (string).
-
- local rc, re, e
-
- rc, re = load_user_config(info, e2lib.join(info.root, "proj/config"),
- info, "project", "e2project")
- if not rc then
- return false, re
- end
-
- e = err.new("in project configuration:")
- if not info.project.release_id then
- e:append("key is not set: release_id")
- end
- if not info.project.name then
- e:append("key is not set: name")
- end
- if not info.project.default_results then
- e2lib.warnf("WDEFAULT", "in project configuration:")
- e2lib.warnf("WDEFAULT",
- "default_results is not set. Defaulting to empty list.")
- info.project.default_results = {}
- end
- rc, re = e2lib.vrfy_listofstrings(info.project.deploy_results,
- "deploy_results", true, true)
- if not rc then
- e:append("deploy_results is not a valid list of strings")
- e:cat(re)
- end
- rc, re = e2lib.vrfy_listofstrings(info.project.default_results,
- "default_results", true, false)
- if not rc then
- e:append("default_results is not a valid list of strings")
- e:cat(re)
- end
- if not info.project.chroot_arch then
- e2lib.warnf("WDEFAULT", "in project configuration:")
- e2lib.warnf("WDEFAULT", " chroot_arch defaults to x86_32")
- info.project.chroot_arch = "x86_32"
- end
- if not info.chroot_call_prefix[info.project.chroot_arch] then
- e:append("chroot_arch is set to an invalid value")
- end
- local host_system_arch, re = e2lib.get_sys_arch()
- if not host_system_arch then
- e:cat(re)
- elseif info.project.chroot_arch == "x86_64" and
- host_system_arch ~= "x86_64" then
- e:append("running on x86_32: switching to x86_64 mode is impossible.")
- end
- if e:getcount() > 1 then
- return false, e
- end
-
- return true
-end
-
--- check source.
local function check_source(info, sourcename)
local src = info.sources[sourcename]
if not rc then
return false, e:cat(re)
end
- for _, r in ipairs(info.project.default_results) do
+ for r in project.default_results_iter() do
if not info.results[r] then
e:append("default_results: No such result: %s", r)
end
end
- for _, r in ipairs(info.project.deploy_results) do
+ for r in project.deploy_results_iter() do
if not info.results[r] then
e:append("deploy_results: No such result: %s", r)
end
end
-- read project configuration
- rc, re = read_project_config(info)
+ rc, re = project.load_project_config(info)
if not rc then
return false, e:cat(re)
end
local dirty, mismatch
rc, re, mismatch = generic_git.verify_head_match_tag(info.root,
- info.project.release_id)
+ project.release_id())
if not rc then
if mismatch then
e:append("project repository tag does not match " ..
if e2option.opts["check-remote"] then
rc, re = generic_git.verify_remote_tag(
- e2lib.join(info.root, ".git"), info.project.release_id)
+ e2lib.join(info.root, ".git"), project.release_id())
if not rc then
e:append("verifying remote tag failed")
return false, e:cat(re)
-- @return Error object on failure.
-- @see e2tool.dlist_recursive
function e2tool.dsort(info)
- return e2tool.dlist_recursive(info, info.project.default_results)
+ local dr = {}
+ for r in project.default_results_iter() do
+ table.insert(dr, r)
+ end
+ return e2tool.dlist_recursive(info, dr)
end
--- verify that a file addressed by server name and location matches the
if not rc then return false, re end
end
end
- rc, re = hash.hash_line(hc, info.project.release_id)
+ rc, re = hash.hash_line(hc, project.release_id())
if not rc then return false, re end
- rc, re = hash.hash_line(hc, info.project.name)
+ rc, re = hash.hash_line(hc, project.name())
if not rc then return false, re end
- rc, re = hash.hash_line(hc, info.project.chroot_arch)
+ rc, re = hash.hash_line(hc, project.chroot_arch())
if not rc then return false, re end
rc, re = hash.hash_line(hc, buildconfig.VERSION)
if not rc then return false, re end
--- /dev/null
+--- Project module. Handle e2project configuration.
+-- @module local.project
+
+-- Copyright (C) 2007-2014 emlix GmbH, see file AUTHORS
+--
+-- This file is part of e2factory, the emlix embedded build system.
+-- For more information see http://www.e2factory.org
+--
+-- e2factory is a registered trademark of emlix GmbH.
+--
+-- e2factory is free software: you can redistribute it and/or modify it under
+-- the terms of the GNU General Public License as published by the
+-- Free Software Foundation, either version 3 of the License, or (at your
+-- option) any later version.
+--
+-- This program is distributed in the hope that it will be useful, but WITHOUT
+-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+-- more details.
+
+local project = {}
+local e2lib = require("e2lib")
+local e2tool = require("e2tool")
+local err = require("err")
+local strict = require("strict")
+
+local _prj = {}
+local _config_loaders = {}
+
+--- Check and load e2project callback function signature.
+-- @function load_project_config_cb
+-- @param prj Unchecked e2project table. Remove all keys that are private
+-- to your use.
+-- @return True on success, false on error
+-- @return Error object on failure.
+
+--- Register a function that gets called when the project config is
+-- loaded. Functions get called in order of registration.
+-- @param func load_project_config_cb function.
+-- @return True on success, false on error.
+-- @return Error object on failure.
+-- @see load_project_config_cb
+function project.register_load_project_config(func)
+ assert(type(func) == "function")
+ table.insert(_config_loaders, func)
+
+ return true
+end
+
+--- Main e2project config check and init callback.
+-- @param prj e2project table.
+-- @return True on success, false on error.
+-- @return Error object on failure.
+local function load_prj_cfg(prj)
+ local rc, re, e, info
+
+ info = e2tool.info()
+ assert(info)
+
+ rc, re = e2lib.vrfy_dict_exp_keys(prj, "e2project",
+ { "name", "release_id", "deploy_results",
+ "default_results", "chroot_arch" })
+ if not rc then
+ return false, re
+ end
+
+ if not prj.release_id then
+ return false, err.new("key is not set: release_id")
+ end
+ if not prj.name then
+ return false, err.new("key is not set: name")
+ end
+ if not prj.default_results then
+ e2lib.warnf("WDEFAULT", "in project configuration:")
+ e2lib.warnf("WDEFAULT",
+ "default_results is not set. Defaulting to empty list.")
+ prj.default_results = {}
+ end
+ rc, re = e2lib.vrfy_listofstrings(prj.deploy_results,
+ "deploy_results", true, true)
+ if not rc then
+ e = err.new("deploy_results is not a valid list of strings")
+ e:cat(re)
+ return false, e
+ end
+
+ rc, re = e2lib.vrfy_listofstrings(prj.default_results,
+ "default_results", true, false)
+ if not rc then
+ e = err.new("default_results is not a valid list of strings")
+ e:cat(re)
+ return false, e
+ end
+
+ if not prj.chroot_arch then
+ e2lib.warnf("WDEFAULT", "in project configuration:")
+ e2lib.warnf("WDEFAULT", " chroot_arch defaults to x86_32")
+ prj.chroot_arch = "x86_32"
+ end
+ if not info.chroot_call_prefix[prj.chroot_arch] then
+ return false, err.new("chroot_arch is set to an invalid value")
+ end
+ if prj.chroot_arch == "x86_64" and e2lib.host_system_arch ~= "x86_64" then
+ return false,
+ err.new("running on x86_32: switching to x86_64 mode is impossible.")
+ end
+
+ _prj = prj
+ return true
+end
+
+--- Initialise the project module, load and check proj/config. Needs to be
+-- called before using name() etc.
+-- @param info Info table.
+-- @return True on success, false on error.
+-- @return Error object on failure.
+function project.load_project_config(info)
+ local rc, re, e
+ local path, prj
+
+ -- register the main e2project load_project_config function last
+ rc, re = project.register_load_project_config(load_prj_cfg)
+ if not rc then
+ return false, re
+ end
+
+ path = e2lib.join(info.root, "proj/config")
+
+ prj = nil
+ local g = {
+ e2project = function(data) prj = data end,
+ env = info.env,
+ string = e2lib.safe_string_table(),
+ }
+
+ rc, re = e2lib.dofile2(path, g)
+ if not rc then
+ return false, re
+ end
+
+ e = err.new("in project configuration:")
+
+ if type(prj) ~= "table" then
+ return false, e:append("Invalid or empty e2project configuration")
+ end
+
+ for _,load_project_config_cb in ipairs(_config_loaders) do
+ rc, re = load_project_config_cb(prj)
+ if not rc then
+ return false, e:cat(re)
+ end
+ end
+
+ return true
+end
+
+--- Get project name.
+-- @return Name.
+function project.name()
+ assert(type(_prj.name) == "string")
+ return _prj.name
+end
+
+--- Get project ReleaseID.
+-- @return ReleaseID as a string.
+function project.release_id()
+ assert(type(_prj.release_id) == "string")
+ return _prj.release_id
+end
+
+--- Get chroot architecture. For multi-arch systems.
+-- @return Chroot architecture as a string.
+function project.chroot_arch()
+ assert(type(_prj.chroot_arch) == "string")
+ return _prj.chroot_arch
+end
+
+--- Iterator that returns the deploy results as string.
+-- @return Iterator function.
+function project.deploy_results_iter()
+ assert(type(_prj.deploy_results) == "table")
+ local i = 0
+
+ return function ()
+ i = i + 1
+ return _prj.deploy_results[i]
+ end
+end
+
+--- Iterator that returns the default results as string.
+-- @return Iterator function.
+function project.default_results_iter()
+ assert(type(_prj.default_results) == "table")
+ local i = 0
+
+ return function ()
+ i = i + 1
+ return _prj.default_results[i]
+ end
+end
+
+return strict.lock(project)
+
+-- vim:sw=4:sts=4:et:
local strict = require("strict")
local licence = require("licence")
local chroot = require("chroot")
+local project = require("project")
--- Collect_project result config. This result config table lives in
-- info.results[resultname]. The fields are merged with e2tool.result
-- write project configuration
out = {
- string.format("name='%s'\n", info.project.name),
- string.format("release_id='%s'\n", info.project.release_id),
+ string.format("name='%s'\n", project.name()),
+ string.format("release_id='%s'\n", project.release_id()),
string.format("default_results='%s'\n",
res.collect_project_default_result),
- string.format("chroot_arch='%s'\n", info.project.chroot_arch)
+ string.format("chroot_arch='%s'\n", project.chroot_arch())
}
local file, destdir