| |
@@ -1,17 +1,77 @@
|
| |
-- Convenience Lua functions that can be used within rpm macros
|
| |
|
| |
- -- Reads an rpm variable. Unlike a basic rpm.expand("{?foo}"), returns nil if
|
| |
- -- the variable is unset, which is convenient in lua tests and enables
|
| |
- -- differentiating unset variables from variables set to ""
|
| |
- local function read(rpmvar)
|
| |
+ -- Reads an rpm variable reference. Returns "%{" .. rpmvar.. "}" if rpmvar is
|
| |
+ -- set to something, and nil otherwise. This is convenient in lua tests and to
|
| |
+ -- distinguish between an unset variable and a variable set to something that
|
| |
+ -- expands to "" at this point of the spec file.
|
| |
+ local function ref(rpmvar)
|
| |
if not rpmvar or
|
| |
(rpm.expand("%{" .. rpmvar .. "}") == "%{" .. rpmvar .. "}") then
|
| |
return nil
|
| |
else
|
| |
- return rpm.expand("%{?" .. rpmvar .. "}")
|
| |
+ return "%{" .. rpmvar .. "}"
|
| |
end
|
| |
end
|
| |
|
| |
+ -- Expands <run> till there is no expansion left to do
|
| |
+ local function expand(run)
|
| |
+ if not run then
|
| |
+ return nil
|
| |
+ end
|
| |
+ run = run:gsub("%%%%", "\029")
|
| |
+ local expanded = rpm.expand(run)
|
| |
+ while run ~= expanded do
|
| |
+ run = expanded
|
| |
+ expanded = rpm.expand(run)
|
| |
+ end
|
| |
+ expanded = expanded:gsub("\029", "%%%%")
|
| |
+ return expanded
|
| |
+ end
|
| |
+
|
| |
+ -- Reads an rpm variable (reads the variable reference, and evaluates it).
|
| |
+ -- Unlike a basic rpm.expand("{?" .. rpmvar .. "}"), returns nil if the
|
| |
+ -- variable is unset, which is convenient in lua tests.
|
| |
+ local function read(rpmvar)
|
| |
+ local ref = ref(rpmvar)
|
| |
+ if ref then
|
| |
+ return expand(ref)
|
| |
+ else
|
| |
+ return ref
|
| |
+ end
|
| |
+ end
|
| |
+
|
| |
+ -- Sometimes it is convenient to distinguish between an unset variable and a
|
| |
+ -- variable explicitly set to false. Unlike read, readbool returns a tristate,
|
| |
+ -- true, false or nil
|
| |
+ local function readbool(rpmvar)
|
| |
+ local value = read(rpmvar)
|
| |
+ if value then
|
| |
+ if (value:lower() == "false") then
|
| |
+ return false
|
| |
+ else
|
| |
+ return true
|
| |
+ end
|
| |
+ else
|
| |
+ return value
|
| |
+ end
|
| |
+ end
|
| |
+
|
| |
+ -- Builds a list of un-commented and non-empty lines from a multiline rpm
|
| |
+ -- variable. This allows using multiline expands for private %sourcelist-like
|
| |
+ -- containers.
|
| |
+ local function readlines(rpmvar)
|
| |
+ local lines = read(rpmvar)
|
| |
+ local L = {}
|
| |
+ if lines then
|
| |
+ for line in string.gmatch(lines,'[^\r\n]+') do
|
| |
+ if string.match(line, '^[^#]') then
|
| |
+ table.insert(L, line)
|
| |
+ end
|
| |
+ end
|
| |
+ end
|
| |
+ return L
|
| |
+ end
|
| |
+
|
| |
-- Returns true if the macro that called this function had flag set
|
| |
-- – for example, hasflag("z") would give the following results:
|
| |
-- %foo -z bar → true
|
| |
@@ -40,114 +100,420 @@
|
| |
end
|
| |
end
|
| |
|
| |
- -- Sets a spec variable; echoes the result if verbose
|
| |
- local function explicitset(rpmvar, value, verbose)
|
| |
- local value = value
|
| |
- if (value == nil) or (value == "") then
|
| |
- value = "%{nil}"
|
| |
+ -- %wordwrap core
|
| |
+ local function wordwrap(text)
|
| |
+ text = expand(text .. "\n")
|
| |
+ text = text:gsub("%%%%", "\029")
|
| |
+ text = text:gsub("\t", " ")
|
| |
+ text = text:gsub("\r", "\n")
|
| |
+ text = text:gsub(" +\n", "\n")
|
| |
+ text = text:gsub("\n+\n", "\n\n")
|
| |
+ text = text:gsub("^\n", "")
|
| |
+ text = text:gsub("\n( *)[-*—][ ]+", "\n%1– ")
|
| |
+ output = ""
|
| |
+ for line in text:gmatch("[^\n]*\n") do
|
| |
+ local pos = 0
|
| |
+ local advance = ""
|
| |
+ for word in line:gmatch("%s*[^%s]*\n?") do
|
| |
+ local wl, bad = utf8.len(word)
|
| |
+ if not wl then
|
| |
+ -- Can not use warning in wordwrap since warning uses wordwrap
|
| |
+ rpm.expand([[
|
| |
+ %{warn:Invalid UTF-8 sequence detected in:}
|
| |
+ %{warn:]] .. word .. [[}
|
| |
+ %{warn:It may produce unexpected results.}
|
| |
+ ]])
|
| |
+ wl = bad
|
| |
+ end
|
| |
+ if (pos == 0) then
|
| |
+ advance, n = word:gsub("^(%s*– ).*", "%1")
|
| |
+ if (n == 0) then
|
| |
+ advance = word:gsub("^(%s*).*", "%1")
|
| |
+ end
|
| |
+ advance = advance:gsub("– ", " ")
|
| |
+ pos = pos + wl
|
| |
+ elseif (pos + wl < 81) or
|
| |
+ ((pos + wl == 81) and word:match("\n$")) then
|
| |
+ pos = pos + wl
|
| |
+ else
|
| |
+ word = advance .. word:gsub("^%s*", "")
|
| |
+ output = output .. "\n"
|
| |
+ pos = utf8.len(word)
|
| |
+ end
|
| |
+ output = output .. word
|
| |
+ if pos > 80 then
|
| |
+ pos = 0
|
| |
+ if not word:match("\n$") then
|
| |
+ output = output .. "\n"
|
| |
+ end
|
| |
+ end
|
| |
+ end
|
| |
end
|
| |
- rpm.define(rpmvar .. " " .. value)
|
| |
- if verbose then
|
| |
- rpm.expand("%{warn:Setting %%{" .. rpmvar .. "} = " .. value .. "}")
|
| |
+ output = output:gsub("^\n*", "")
|
| |
+ output = output:gsub("\n*$", "\n")
|
| |
+ -- Escape %’s – we want macros that were preserved from wordwrap expansion to
|
| |
+ -- be preserved at the next stage too
|
| |
+ output = output:gsub("\029", "%%%%")
|
| |
+ return output
|
| |
+ end
|
| |
+
|
| |
+ -- Reformats text and outputs it using a built-in rpm verb such as echo, warn
|
| |
+ -- or error
|
| |
+ local function message(verb, text)
|
| |
+ rpm.expand("%{" .. verb .. ":" .. wordwrap(text):gsub("\n*$", "") .. "}")
|
| |
+ end
|
| |
+
|
| |
+ -- Writes some text to stdout
|
| |
+ local function echo(text)
|
| |
+ message("echo", text)
|
| |
+ end
|
| |
+
|
| |
+ -- Writes the list of z-suffixed rpmvars to the console, if set
|
| |
+ local function echovars(rpmvars, z)
|
| |
+ for _, rpmvar in ipairs(rpmvars) do
|
| |
+ local suffixed = rpmvar .. z
|
| |
+ local header = string.sub(" " .. suffixed .. ": ",1,24)
|
| |
+ local v = ref(suffixed)
|
| |
+ if v then
|
| |
+ echo(header .. v)
|
| |
+ end
|
| |
end
|
| |
end
|
| |
|
| |
- -- Unsets a spec variable if it is defined; echoes the result if verbose
|
| |
- local function explicitunset(rpmvar, verbose)
|
| |
- if (rpm.expand("%{" .. rpmvar .. "}") ~= "%{" .. rpmvar .. "}") then
|
| |
- rpm.define(rpmvar .. " %{nil}")
|
| |
- if verbose then
|
| |
- rpm.expand("%{warn:Unsetting %%{" .. rpmvar .. "}}")
|
| |
+ -- Writes some text as a warning
|
| |
+ local function warning(text)
|
| |
+ message("warn", text)
|
| |
+ end
|
| |
+
|
| |
+ -- Writes some text as an error
|
| |
+ local function err(text)
|
| |
+ message("error", text)
|
| |
+ end
|
| |
+
|
| |
+ -- Returns a table of <radical> = <value>, for all <radical>s in <radicals>,
|
| |
+ -- with <value> = reference of <namespace>_<radical><suffix> if
|
| |
+ -- <namespace>_<radical><suffix> is set. Radicals for which
|
| |
+ -- <namespace>_<radical><suffix> is not set are omitted in results.
|
| |
+ local function mread(radicals, namespace, suffix, resolve)
|
| |
+ local R = {}
|
| |
+ for _, radical in ipairs(radicals) do
|
| |
+ local name = radical
|
| |
+ if namespace and (namespace ~= "") then
|
| |
+ name = namespace .. "_" .. name
|
| |
+ end
|
| |
+ local ref = ref(name .. suffix)
|
| |
+ if ref then
|
| |
+ if resolve then
|
| |
+ ref = expand(ref)
|
| |
+ end
|
| |
+ R[radical] = ref
|
| |
+ end
|
| |
+ end
|
| |
+ return R
|
| |
+ end
|
| |
+
|
| |
+ -- Sets a spec variable; echoes the result if verbose
|
| |
+ local function set(rpmvar, value, verbose)
|
| |
+ if rpmvar then
|
| |
+ -- Empty the stack state
|
| |
+ while read(rpmvar) do
|
| |
+ rpm.undefine(rpmvar)
|
| |
+ end
|
| |
+ if (value == nil) then
|
| |
+ if ref(rpmvar) then
|
| |
+ if verbose then
|
| |
+ -- Already did it, white lie
|
| |
+ warning("Unsetting " .. rpmvar)
|
| |
+ end
|
| |
+ end
|
| |
+ else
|
| |
+ if (value == false) then
|
| |
+ value = "false"
|
| |
+ elseif (value == true) then
|
| |
+ value = "true"
|
| |
+ end
|
| |
+ if verbose then
|
| |
+ warning("Setting " .. rpmvar .. " = " .. value)
|
| |
+ end
|
| |
+ rpm.define(rpmvar .. " %{expand:" .. value .. "}")
|
| |
end
|
| |
end
|
| |
end
|
| |
|
| |
+ -- Unsets a spec variable if it is defined; echoes the result if verbose
|
| |
+ local function unset(rpmvar, verbose)
|
| |
+ set(rpmvar, nil, verbose)
|
| |
+ end
|
| |
+
|
| |
-- Sets a spec variable, if not already set; echoes the result if verbose
|
| |
local function safeset(rpmvar, value, verbose)
|
| |
- if (rpm.expand("%{" .. rpmvar .. "}") == "%{" .. rpmvar .. "}") then
|
| |
- explicitset(rpmvar,value,verbose)
|
| |
+ if not ref(rpmvar) then
|
| |
+ set(rpmvar, value, verbose)
|
| |
end
|
| |
end
|
| |
|
| |
- -- Aliases a list of rpm variables to the same variables suffixed with 0 (and
|
| |
- -- vice versa); echoes the result if verbose
|
| |
- local function zalias(rpmvars, verbose)
|
| |
- for _, sfx in ipairs({{"","0"},{"0",""}}) do
|
| |
- for _, rpmvar in ipairs(rpmvars) do
|
| |
- local toalias = "%{?" .. rpmvar .. sfx[1] .. "}"
|
| |
- if (rpm.expand(toalias) ~= "") then
|
| |
- safeset(rpmvar .. sfx[2], toalias, verbose)
|
| |
+ -- Sets the <namespace>_<radical><suffix> variable for all <radical>s in
|
| |
+ -- <radicals>, to a <value> taken in the <stack> list of <radical> = <value>
|
| |
+ -- tables. When <radical> exists in multiple tables, only its first <value> is
|
| |
+ -- taken into account. When <radical> does not exist in any table, no
|
| |
+ -- <namespace>_<radical><suffix> is set.
|
| |
+ -- <stack> is usually constructed with multiple mread calls, taking
|
| |
+ -- domain-specific fallback needs into consideration.
|
| |
+ -- If <force> set via set (and unset variables with no matches), otherwise set
|
| |
+ -- via safeset.
|
| |
+ -- mset is a complex function; its specializations like alias, bialias, zalias
|
| |
+ -- and set_current are sufficient for many needs.
|
| |
+ local function mset(radicals, namespace, suffix, stack, verbose, force)
|
| |
+ for _, radical in ipairs(radicals) do
|
| |
+ local value = nil
|
| |
+ local found = false
|
| |
+ for _, values in ipairs(stack) do
|
| |
+ for k, v in pairs(values) do
|
| |
+ if k == radical then
|
| |
+ value = v
|
| |
+ found = true
|
| |
+ break
|
| |
+ end
|
| |
+ end
|
| |
+ if found then
|
| |
+ break
|
| |
end
|
| |
end
|
| |
+ local name = radical
|
| |
+ if namespace and (namespace ~= "") then
|
| |
+ name = namespace .. "_" .. name
|
| |
+ end
|
| |
+ if force then
|
| |
+ set( name .. suffix, value, verbose)
|
| |
+ else
|
| |
+ safeset(name .. suffix, value, verbose)
|
| |
+ end
|
| |
end
|
| |
end
|
| |
|
| |
- -- Takes a list of rpm variable roots and a suffix and alias current<root> to
|
| |
- -- <root><suffix> if it resolves to something not empty
|
| |
- local function setcurrent(rpmvars, suffix, verbose)
|
| |
- for _, rpmvar in ipairs(rpmvars) do
|
| |
- if (rpm.expand("%{?" .. rpmvar .. suffix .. "}") ~= "") then
|
| |
- explicitset( "current" .. rpmvar, "%{" .. rpmvar .. suffix .. "}", verbose)
|
| |
- else
|
| |
- explicitunset("current" .. rpmvar, verbose)
|
| |
+ -- Sets the <namespace>_<radical><suffix> variable for all <radical>s in
|
| |
+ -- <radicals>, to a reference to <from_namespace>_<radical><from_suffix>,
|
| |
+ -- if <from_namespace>_<radical><from_suffix> is set.
|
| |
+ -- inherit_from is recursive: the next <from_suffix> is read in
|
| |
+ -- <from_namespace>_<from_key><from_suffix>
|
| |
+ local function inherit_from (radicals, namespace, suffix, from_namespace,
|
| |
+ from_suffix, from_key, verbose)
|
| |
+ local seen = {}
|
| |
+ local stack = {}
|
| |
+ local function icopy(z)
|
| |
+ if not z or seen[z] then
|
| |
+ return
|
| |
+ end
|
| |
+ seen[z] = true
|
| |
+ table.insert(stack, mread(radicals, from_namespace, z, false))
|
| |
+ if from_key and (from_key ~= "") then
|
| |
+ local new_key = from_key .. z
|
| |
+ if from_namespace and (from_namespace ~= "") then
|
| |
+ new_key = from_namespace .. "_" .. new_key
|
| |
+ end
|
| |
+ icopy(read(new_key))
|
| |
end
|
| |
end
|
| |
+ icopy(from_suffix)
|
| |
+ mset(radicals, namespace, suffix, stack, verbose, false, false)
|
| |
end
|
| |
|
| |
- -- Echo the list of rpm variables, with suffix, if set
|
| |
- local function echovars(rpmvars, suffix)
|
| |
- for _, rpmvar in ipairs(rpmvars) do
|
| |
- rpmvar = rpmvar .. suffix
|
| |
- local header = string.sub(" " .. rpmvar .. ": ",1,21)
|
| |
- rpm.expand("%{?" .. rpmvar .. ":%{echo:" .. header .. "%{?" .. rpmvar .. "}}}")
|
| |
+ -- Sets the <namespace>_<radical><suffix> variable for all <radical>s in
|
| |
+ -- <radicals>, to a reference to <namespace>_<radical><from_suffix>,
|
| |
+ -- if <namespace>_<radical><from_suffix> is set.
|
| |
+ -- <from_suffix> is read in <namespace>_<from_key><suffix>
|
| |
+ -- inherit is recursive, and will also process <from_key> at the next level
|
| |
+ local function inherit(radicals, namespace, suffix, key, verbose)
|
| |
+ local k = key .. suffix
|
| |
+ if namespace and (namespace ~= "") then
|
| |
+ k = namespace .. "_" .. k
|
| |
end
|
| |
+ local from_suffix = read(k)
|
| |
+ inherit_from(radicals, namespace, suffix, namespace, from_suffix, key,
|
| |
+ verbose)
|
| |
end
|
| |
|
| |
- -- Returns an array, indexed by suffix, containing the non-empy values of
|
| |
- -- <rpmvar><suffix>, with suffix an integer string or the empty string
|
| |
- local function getsuffixed(rpmvar)
|
| |
- local suffixes = {}
|
| |
- zalias({rpmvar})
|
| |
- for suffix=0,9999 do
|
| |
- local value = rpm.expand("%{?" .. rpmvar .. suffix .. "}")
|
| |
- if (value ~= "") then
|
| |
- suffixes[tostring(suffix)] = value
|
| |
+ -- for each radical in radicals, safeset <to_namespace><radical><to_suffix>
|
| |
+ -- to %{<from_namespace><radical><from_suffix>} if
|
| |
+ -- <from_namespace><radical><from_suffix> is set to something
|
| |
+ local function alias(radicals, from_namespace, from_suffix,
|
| |
+ to_namespace, to_suffix, verbose)
|
| |
+ mset(radicals, to_namespace, to_suffix,
|
| |
+ {mread(radicals, from_namespace, from_suffix, false)},
|
| |
+ verbose, false)
|
| |
+ end
|
| |
+
|
| |
+ -- Alias back and forth
|
| |
+ local function bialias(radicals, namespace1, suffix1,
|
| |
+ namespace2, suffix2, verbose)
|
| |
+ alias(radicals, namespace1, suffix1, namespace2, suffix2, verbose)
|
| |
+ alias(radicals, namespace2, suffix2, namespace1, suffix1, verbose)
|
| |
+ end
|
| |
+
|
| |
+ -- Aliases a list of rpm variables to the same variables suffixed with 0 (and
|
| |
+ -- vice versa); echoes the result if verbose
|
| |
+ local function zalias(rpmvars, verbose)
|
| |
+ bialias(rpmvars, "", "", "", "0", verbose)
|
| |
+ end
|
| |
+
|
| |
+ -- Takes a list of rpm variable roots and a suffix and alias __current_<rpmvar>
|
| |
+ -- to <rpmvar><suffix> if it resolves to something not empty
|
| |
+ local function set_current(rpmvars, suffix, verbose)
|
| |
+ mset(rpmvars, "__current", "",
|
| |
+ {mread(rpmvars, "", suffix, false)}, verbose, true)
|
| |
+ end
|
| |
+
|
| |
+ -- Sets the usual verbosity variables in a generic way
|
| |
+ local function set_verbose(verbose)
|
| |
+ if verbose then
|
| |
+ set( "__current_verbose", "-v", verbose)
|
| |
+ unset("__current_quiet", verbose)
|
| |
+ unset("__current_shell_quiet", verbose)
|
| |
+ unset("__current_shell_verbose", verbose)
|
| |
+ else
|
| |
+ unset("__current_verbose", verbose)
|
| |
+ set( "__current_quiet", "-q", verbose)
|
| |
+ set( "__current_shell_quiet", "set +x", verbose)
|
| |
+ set( "__current_shell_verbose", "set -x", verbose)
|
| |
+ end
|
| |
+ end
|
| |
+
|
| |
+ -- Returns an array of <namespace>_<radical>
|
| |
+ local function qualify(radicals, namespace)
|
| |
+ local R = {}
|
| |
+ if (namespace ~= "") then
|
| |
+ namespace = namespace .. "_"
|
| |
+ end
|
| |
+ for _, radical in ipairs(radicals) do
|
| |
+ table.insert(R, namespace .. radical)
|
| |
+ end
|
| |
+ return R
|
| |
+ end
|
| |
+
|
| |
+ -- Merges two lists, removing duplicates and ordering the result
|
| |
+ -- The result is a list containing an ordered set of values
|
| |
+ local function mergelists(list_of_lists)
|
| |
+ local S = {}
|
| |
+ local L = {}
|
| |
+ for _, l in ipairs(list_of_lists) do
|
| |
+ for _, v in ipairs(l) do
|
| |
+ S[v] = true
|
| |
+ end
|
| |
+ end
|
| |
+ for k, _ in pairs(S) do
|
| |
+ table.insert(L, k)
|
| |
+ end
|
| |
+ table.sort(L)
|
| |
+ return L
|
| |
+ end
|
| |
+
|
| |
+ -- Returns a list of suffixes, for which <rpmvar><suffix> is set to something
|
| |
+ local function suffixes(rpmvar)
|
| |
+ local S = {}
|
| |
+ for z=0,9999 do
|
| |
+ if ref(rpmvar .. z) then
|
| |
+ table.insert(S, tostring(z))
|
| |
end
|
| |
end
|
| |
-- rpm convention is to alias no suffix to zero suffix
|
| |
-- only add no suffix if zero suffix is different
|
| |
- local value = rpm.expand("%{?" .. rpmvar .. "}")
|
| |
- if (value ~= "") and (value ~= suffixes["0"]) then
|
| |
- suffixes[""] = value
|
| |
+ local value = read(rpmvar)
|
| |
+ if value and not (value == read(rpmvar .. "0")) then
|
| |
+ table.insert(S, "")
|
| |
end
|
| |
- return suffixes
|
| |
+ return S
|
| |
end
|
| |
|
| |
-- Returns the list of suffixes, including the empty string, for which
|
| |
- -- <rpmvar><suffix> is set to a non empty value
|
| |
- local function getsuffixes(rpmvar)
|
| |
- suffixes = {}
|
| |
- for suffix in pairs(getsuffixed(rpmvar)) do
|
| |
- table.insert(suffixes,suffix)
|
| |
+ -- <rpmvar><suffix> is set to a non empty value, for any rpmvar in rpmvars
|
| |
+ local function all_suffixes(rpmvars)
|
| |
+ local SL = {}
|
| |
+ local S = {}
|
| |
+ for _, rpmvar in ipairs(rpmvars) do
|
| |
+ table.insert(SL, suffixes(rpmvar))
|
| |
end
|
| |
- table.sort(suffixes,
|
| |
+ S = mergelists(SL)
|
| |
+ table.sort(S,
|
| |
function(a,b) return (tonumber(a) or 0) < (tonumber(b) or 0) end)
|
| |
- return suffixes
|
| |
+ return S
|
| |
end
|
| |
|
| |
- -- Returns the suffix for which <rpmvar><suffix> has a non-empty value that
|
| |
- -- matches best the beginning of the value string
|
| |
- local function getbestsuffix(rpmvar, value)
|
| |
- local best = nil
|
| |
- local currentmatch = ""
|
| |
- for suffix, setvalue in pairs(getsuffixed(rpmvar)) do
|
| |
- if (string.len(setvalue) > string.len(currentmatch)) and
|
| |
- (string.find(value, "^" .. setvalue)) then
|
| |
- currentmatch = setvalue
|
| |
- best = suffix
|
| |
+ local function suffix_new(set, verbose)
|
| |
+ local s = 0
|
| |
+ local used = false
|
| |
+ repeat
|
| |
+ z = tostring(s)
|
| |
+ used = false
|
| |
+ for k, _ in pairs(set) do
|
| |
+ used = used or ref(k .. z)
|
| |
end
|
| |
+ s = s + 1
|
| |
+ until (not used)
|
| |
+ for k, v in pairs(set) do
|
| |
+ safeset(k .. z, v, verbose)
|
| |
end
|
| |
- return best
|
| |
+ return z
|
| |
+ end
|
| |
+
|
| |
+ local function suffix_reuse(set, verbose)
|
| |
+ for s = 0, 9999 do
|
| |
+ z = tostring(s)
|
| |
+ local matches = true
|
| |
+ for k, v in pairs(set) do
|
| |
+ matches = matches and (read(k .. z) == v)
|
| |
+ end
|
| |
+ if matches then
|
| |
+ return z
|
| |
+ end
|
| |
+ end
|
| |
+ return suffix_new(set, verbose)
|
| |
+ end
|
| |
+
|
| |
+ -- Takes a set[key] = <value> table and returns a suffix for which all the
|
| |
+ -- <key><suffix> rpm variables have the corresponding <value> set.
|
| |
+ -- If reuse attempts to find an existing suffix that matches, otherwise,
|
| |
+ -- takes an available suffix and creates the variable set from scratch
|
| |
+ local function suffix(set, reuse, verbose)
|
| |
+ if reuse then
|
| |
+ return suffix_reuse(set, verbose)
|
| |
+ else
|
| |
+ return suffix_new(set, verbose)
|
| |
+ end
|
| |
+ end
|
| |
+
|
| |
+ -- Returns the suffix/number of a source/patch filename
|
| |
+ -- We could do it with source_num/patch_num but those are dependant on a
|
| |
+ -- specific rpm version and are not available for all the other variables we
|
| |
+ -- use suffixes() with
|
| |
+ local function sourcedir_suffix(filename, radical)
|
| |
+ if not filename then
|
| |
+ return nil
|
| |
+ end
|
| |
+ filename = expand(filename)
|
| |
+ if not filename then
|
| |
+ return nil
|
| |
+ end
|
| |
+ filename = filename:match("[^/]+$")
|
| |
+ if not filename then
|
| |
+ return nil
|
| |
+ end
|
| |
+ filename = expand("%{_sourcedir}/" .. filename)
|
| |
+ for _, z in ipairs(suffixes(radical)) do
|
| |
+ if expand('%{' .. radical .. z .. "}") == filename then
|
| |
+ return z
|
| |
+ end
|
| |
+ end
|
| |
+ return nil
|
| |
+ end
|
| |
+
|
| |
+ -- Returns the source suffix/number of a filename
|
| |
+ local function source_suffix(filename)
|
| |
+ return sourcedir_suffix(filename, "SOURCE")
|
| |
+ end
|
| |
+
|
| |
+ -- Returns the patch suffix/number of a filename
|
| |
+ local function patch_suffix(filename)
|
| |
+ return sourcedir_suffix(filename, "PATCH")
|
| |
end
|
| |
|
| |
-- %writevars core
|
| |
@@ -159,136 +525,93 @@
|
| |
end
|
| |
end
|
| |
|
| |
- -- https://github.com/rpm-software-management/rpm/issues/566
|
| |
- -- Reformat a text intended to be used used in a package description, removing
|
| |
- -- rpm macro generation artefacts.
|
| |
- -- – remove leading and ending empty lines
|
| |
- -- – trim intermediary empty lines to a single line
|
| |
- -- – fold on spaces
|
| |
- -- Should really be a %%{wordwrap:…} verb
|
| |
- local function wordwrap(text)
|
| |
- text = rpm.expand(text .. "\n")
|
| |
- text = string.gsub(text, "\t", " ")
|
| |
- text = string.gsub(text, "\r", "\n")
|
| |
- text = string.gsub(text, " +\n", "\n")
|
| |
- text = string.gsub(text, "\n+\n", "\n\n")
|
| |
- text = string.gsub(text, "^\n", "")
|
| |
- text = string.gsub(text, "\n( *)[-*—][ ]+", "\n%1– ")
|
| |
- output = ""
|
| |
- for line in string.gmatch(text, "[^\n]*\n") do
|
| |
- local pos = 0
|
| |
- local advance = ""
|
| |
- for word in string.gmatch(line, "%s*[^%s]*\n?") do
|
| |
- local wl, bad = utf8.len(word)
|
| |
- if not wl then
|
| |
- print("%{warn:Invalid UTF-8 sequence detected in:}" ..
|
| |
- "%{warn:" .. word .. "}" ..
|
| |
- "%{warn:It may produce unexpected results.}")
|
| |
- wl = bad
|
| |
- end
|
| |
- if (pos == 0) then
|
| |
- advance, n = string.gsub(word, "^(%s*– ).*", "%1")
|
| |
- if (n == 0) then
|
| |
- advance = string.gsub(word, "^(%s*).*", "%1")
|
| |
- end
|
| |
- advance = string.gsub(advance, "– ", " ")
|
| |
- pos = pos + wl
|
| |
- elseif (pos + wl < 81) or
|
| |
- ((pos + wl == 81) and string.match(word, "\n$")) then
|
| |
- pos = pos + wl
|
| |
- else
|
| |
- word = advance .. string.gsub(word, "^%s*", "")
|
| |
- output = output .. "\n"
|
| |
- pos = utf8.len(word)
|
| |
- end
|
| |
- output = output .. word
|
| |
- if pos > 80 then
|
| |
- pos = 0
|
| |
- if not string.match(word, "\n$") then
|
| |
- output = output .. "\n"
|
| |
- end
|
| |
- end
|
| |
+
|
| |
+
|
| |
+ -- deprecated graveyard
|
| |
+ -- those can be removed as soon as a port of fonts-rpm-macros and go-rpm-macros
|
| |
+ -- to the new API lands in koji
|
| |
+
|
| |
+ local function setcurrent(rpmvars, suffix, verbose)
|
| |
+ warning("setcurrent is deprecated, replace it with set_current")
|
| |
+ for _, rpmvar in ipairs(rpmvars) do
|
| |
+ local suffixed = rpmvar .. suffix
|
| |
+ if ref(suffixed) then
|
| |
+ set( "current" .. rpmvar, "%{?" .. suffixed .. "}", verbose)
|
| |
+ else
|
| |
+ unset("current" .. rpmvar, verbose)
|
| |
end
|
| |
end
|
| |
- output = string.gsub(output, "\n*$", "\n")
|
| |
- return output
|
| |
end
|
| |
|
| |
- -- Because rpmbuild will fail if a subpackage is declared before the source
|
| |
- -- package itself, provide a source package declaration shell as fallback.
|
| |
- local function srcpkg(verbose)
|
| |
- if verbose then
|
| |
- rpm.expand([[
|
| |
- %{echo:Creating a header for the SRPM from %%{source_name}, %%{source_summary} and}
|
| |
- %{echo:%%{source_description}. If that is not the intended result, please declare the}
|
| |
- %{echo:SRPM header and set %%{source_name} in your spec file before calling a macro}
|
| |
- %{echo:that creates other package headers.}
|
| |
- ]])
|
| |
- end
|
| |
- print(rpm.expand([[
|
| |
- Name: %{source_name}
|
| |
- Summary: %{source_summary}
|
| |
- %description
|
| |
- %wordwrap -v source_description
|
| |
- ]]))
|
| |
- explicitset("currentname", "%{source_name}", verbose)
|
| |
- end
|
| |
-
|
| |
- -- %new_package core
|
| |
- local function new_package(source_name, pkg_name, name_suffix, first, verbose)
|
| |
- -- Safety net when the wrapper is used in conjunction with traditional syntax
|
| |
- if (not first) and (not source_name) then
|
| |
- rpm.expand([[
|
| |
- %{warn:Something already set a package name. However, %%{source_name} is not set.}
|
| |
- %{warn:Please set %%{source_name} to the SRPM name to ensure reliable processing.}
|
| |
- ]])
|
| |
- if name_suffix then
|
| |
- print(rpm.expand("%package " .. name_suffix))
|
| |
- else
|
| |
- print(rpm.expand("%package -n " .. pkg_name))
|
| |
+ local function getsuffixed(rpmvar)
|
| |
+ local S = {}
|
| |
+ zalias({rpmvar}, false)
|
| |
+ for z=0,9999 do
|
| |
+ local value = read(rpmvar .. z)
|
| |
+ if value then
|
| |
+ S[tostring(z)] = value
|
| |
end
|
| |
- return
|
| |
end
|
| |
- -- New processing
|
| |
- if not (pkg_name or name_suffix or source_name) then
|
| |
- rpm.expand([[
|
| |
- %{error:You need to set %%{source_name} or provide explicit package naming!}
|
| |
- ]])
|
| |
+ -- rpm convention is to alias no suffix to zero suffix
|
| |
+ -- only add no suffix if zero suffix is different
|
| |
+ local value = read(rpmvar)
|
| |
+ if value and (value ~= S["0"]) then
|
| |
+ S[""] = value
|
| |
end
|
| |
- if name_suffix then
|
| |
- print(rpm.expand("%package " .. name_suffix))
|
| |
- explicitset("currentname", "%{source_name}-" .. name_suffix, verbose)
|
| |
- else
|
| |
- if not source_name then
|
| |
- source_name = pkg_name
|
| |
- end
|
| |
- if (pkg_name == source_name) then
|
| |
- safeset("source_name", source_name, verbose)
|
| |
- print(rpm.expand("Name: %{source_name}"))
|
| |
- else
|
| |
- if source_name and first then
|
| |
- srcpkg(verbose)
|
| |
- end
|
| |
- print(rpm.expand("%package -n " .. pkg_name))
|
| |
+ return S
|
| |
+ end
|
| |
+
|
| |
+ local function getbestsuffix(rpmvar, value)
|
| |
+ local best = nil
|
| |
+ local currentmatch = ""
|
| |
+ for z, setvalue in pairs(getsuffixed(rpmvar)) do
|
| |
+ if ((not best) or (string.len(setvalue) < string.len(currentmatch))) and
|
| |
+ (string.find(setvalue, "^" .. value)) then
|
| |
+ currentmatch = setvalue
|
| |
+ best = z
|
| |
end
|
| |
- explicitset("currentname", pkg_name, verbose)
|
| |
end
|
| |
+ return best
|
| |
end
|
| |
|
| |
return {
|
| |
- read = read,
|
| |
- hasflag = hasflag,
|
| |
- readflag = readflag,
|
| |
- explicitset = explicitset,
|
| |
- explicitunset = explicitunset,
|
| |
- safeset = safeset,
|
| |
- zalias = zalias,
|
| |
- setcurrent = setcurrent,
|
| |
- echovars = echovars,
|
| |
- getsuffixed = getsuffixed,
|
| |
- getsuffixes = getsuffixes,
|
| |
- getbestsuffix = getbestsuffix,
|
| |
- writevars = writevars,
|
| |
- wordwrap = wordwrap,
|
| |
- new_package = new_package,
|
| |
+ ref = ref,
|
| |
+ expand = expand,
|
| |
+ read = read,
|
| |
+ readbool = readbool,
|
| |
+ readlines = readlines,
|
| |
+ hasflag = hasflag,
|
| |
+ readflag = readflag,
|
| |
+ wordwrap = wordwrap,
|
| |
+ echo = echo,
|
| |
+ echovars = echovars,
|
| |
+ warning = warning,
|
| |
+ error = err,
|
| |
+ mread = mread,
|
| |
+ set = set,
|
| |
+ unset = unset,
|
| |
+ safeset = safeset,
|
| |
+ mset = mset,
|
| |
+ inherit_from = inherit_from,
|
| |
+ inherit = inherit,
|
| |
+ alias = alias,
|
| |
+ bialias = bialias,
|
| |
+ zalias = zalias,
|
| |
+ set_current = set_current,
|
| |
+ set_verbose = set_verbose,
|
| |
+ qualify = qualify,
|
| |
+ mergelists = mergelists,
|
| |
+ suffixes = suffixes,
|
| |
+ all_suffixes = all_suffixes,
|
| |
+ suffix = suffix,
|
| |
+ source_suffix = source_suffix,
|
| |
+ patch_suffix = patch_suffix,
|
| |
+ writevars = writevars,
|
| |
+ -- deprecated aliases
|
| |
+ explicitset = set,
|
| |
+ explicitunset = unset,
|
| |
+ getsuffixes = suffixes,
|
| |
+ setcurrent = setcurrent,
|
| |
+ getsuffixed = getsuffixed,
|
| |
+ getbestsuffix = getbestsuffix,
|
| |
}
|
| |