Blame build-aux/mkrockspecs

Packit 437b5e
#!/bin/sh
Packit 437b5e
SH=--[[                                             # -*- mode: lua; -*-
Packit 437b5e
## Slingshot rockspec generator.
Packit 437b5e
##
Packit 437b5e
## This file is distributed with Slingshot, and licensed under the
Packit 437b5e
## terms of the MIT license reproduced below.
Packit 437b5e
Packit 437b5e
## ====================================================================
Packit 437b5e
## Copyright (C) 2013-2015 Gary V. Vaughan
Packit 437b5e
##
Packit 437b5e
## Permission is hereby granted, free of charge, to any person
Packit 437b5e
## obtaining a copy of this software and associated documentation
Packit 437b5e
## files (the "Software"), to deal in the Software without restriction,
Packit 437b5e
## including without limitation the rights to use, copy, modify, merge,
Packit 437b5e
## publish, distribute, sublicense, and/or sell copies of the Software,
Packit 437b5e
## and to permit persons to whom the Software is furnished to do so,
Packit 437b5e
## subject to the following conditions:
Packit 437b5e
##
Packit 437b5e
## The above copyright notice and this permission notice shall be
Packit 437b5e
## included in  all copies or substantial portions of the Software.
Packit 437b5e
##
Packit 437b5e
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit 437b5e
## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 437b5e
## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE-
Packit 437b5e
## MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
Packit 437b5e
## FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Packit 437b5e
## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Packit 437b5e
## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit 437b5e
## ====================================================================
Packit 437b5e
Packit 437b5e
Packit 437b5e
_lua_version_re='"Lua 5."[123]*'
Packit 437b5e
_lua_binaries='lua lua5.3 lua53 lua5.2 lua52 luajit lua5.1 lua51'
Packit 437b5e
Packit 437b5e
export LUA
Packit 437b5e
export LUA_INIT
Packit 437b5e
export LUA_INIT_5_2
Packit 437b5e
export LUA_INIT_5_3
Packit 437b5e
export LUA_PATH
Packit 437b5e
export LUA_CPATH
Packit 437b5e
Packit 437b5e
# Be Bourne compatible
Packit 437b5e
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
Packit 437b5e
  emulate sh
Packit 437b5e
  NULLCMD=:
Packit 437b5e
  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
Packit 437b5e
  # is contrary to our usage.  Disable this feature.
Packit 437b5e
  alias -g '${1+"$@"}'='"$@"'
Packit 437b5e
  setopt NO_GLOB_SUBST
Packit 437b5e
else
Packit 437b5e
  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
Packit 437b5e
fi
Packit 437b5e
Packit 437b5e
# If LUA is not set, search PATH for something suitable.
Packit 437b5e
test -n "$LUA" || {
Packit 437b5e
  # Check that the supplied binary is executable and returns a compatible
Packit 437b5e
  # Lua version number.
Packit 437b5e
  func_vercheck ()
Packit 437b5e
  {
Packit 437b5e
    test -x "$1" && {
Packit 437b5e
      eval 'case `'$1' -e "print (_VERSION)" 2>/dev/null` in
Packit 437b5e
        '"$_lua_version_re"') LUA='$1' ;;
Packit 437b5e
      esac'
Packit 437b5e
    }
Packit 437b5e
  }
Packit 437b5e
Packit 437b5e
  progname=`echo "$0" |${SED-sed} 's|.*/||'`
Packit 437b5e
Packit 437b5e
  save_IFS="$IFS"
Packit 437b5e
  LUA=
Packit 437b5e
  for x in $_lua_binaries; do
Packit 437b5e
    IFS=:
Packit 437b5e
    for dir in $PATH; do
Packit 437b5e
      IFS="$save_IFS"
Packit 437b5e
      func_vercheck "$dir/$x"
Packit 437b5e
      test -n "$LUA" && break
Packit 437b5e
    done
Packit 437b5e
    IFS="$save_IFS"
Packit 437b5e
    test -n "$LUA" && break
Packit 437b5e
    e="${e+$e\n}$progname: command not found on PATH: $x"
Packit 437b5e
  done
Packit 437b5e
}
Packit 437b5e
Packit 437b5e
test -n "$LUA" || {
Packit 437b5e
  printf "${e+$e\n}$progname: retry after 'export LUA=/path/to/lua'\n" >&2
Packit 437b5e
  exit 1
Packit 437b5e
}
Packit 437b5e
Packit 437b5e
LUA_INIT=
Packit 437b5e
LUA_INIT_5_2=
Packit 437b5e
LUA_INIT_5_3=
Packit 437b5e
Packit 437b5e
# Reexecute using the interpreter suppiled in LUA, or found above.
Packit 437b5e
exec "$LUA" "$0" "$@"
Packit 437b5e
]]SH
Packit 437b5e
Packit 437b5e
Packit 437b5e
--[[ ============== ]]--
Packit 437b5e
--[[ Parse options. ]]--
Packit 437b5e
--[[ ============== ]]--
Packit 437b5e
Packit 437b5e
local usage = 'Usage: mkrockspecs [OPTIONS] PACKAGE VERSION [REVISION] [FILE]\n'
Packit 437b5e
Packit 437b5e
prog = {
Packit 437b5e
  name = arg[0] and arg[0]:gsub (".*/", "") or "mkrockspecs",
Packit 437b5e
Packit 437b5e
  opts = {},
Packit 437b5e
}
Packit 437b5e
Packit 437b5e
-- Print an argument processing error message, and return non-zero exit
Packit 437b5e
-- status.
Packit 437b5e
local function opterr (msg)
Packit 437b5e
  io.stderr:write (usage)
Packit 437b5e
  io.stderr:write (prog.name .. ": error: " .. msg .. ".\n")
Packit 437b5e
  io.stderr:write (prog.name .. ": Try '" .. prog.name .. " --help' for help,\n")
Packit 437b5e
  os.exit (2)
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local function setopt (optname, arglist, i)
Packit 437b5e
  local opt = arglist[i]
Packit 437b5e
  if i + 1 > #arglist then
Packit 437b5e
    opterr ("option '" .. opt .. "' requires an argument")
Packit 437b5e
  end
Packit 437b5e
  prog.opts[optname] = arglist[i + 1]
Packit 437b5e
  return i + 1
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local function die (msg)
Packit 437b5e
  msg:gsub ("([^\n]+)\n?",
Packit 437b5e
            function ()
Packit 437b5e
              io.stderr:write (prog.name .. ": error: " .. msg.. "\n")
Packit 437b5e
	    end)
Packit 437b5e
  os.exit (1)
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
prog["--help"] = function ()
Packit 437b5e
  print (usage .. [[
Packit 437b5e
Packit 437b5e
Convert a YAML configuration file into a full rockspec.
Packit 437b5e
Packit 437b5e
If FILE is provided, load it as the base configuration, otherwise if
Packit 437b5e
there is a 'rockspec.conf' in the current directory use that, or else
Packit 437b5e
wait for input on stdin.  If FILE is '-', force reading base config-
Packit 437b5e
uration from stdin.
Packit 437b5e
Packit 437b5e
PACKAGE and VERSION are the package name and version number as defined
Packit 437b5e
by 'configure.ac' or similar. REVISION is only required for a revised
Packit 437b5e
rockspec if the default "-1" revision was released with errors.
Packit 437b5e
Packit 437b5e
  -b, --branch=BRANCH    make git rockspec use BRANCH
Packit 437b5e
  -m, --module-dir=ROOT  directory of lua-files for builtin build type
Packit 437b5e
  -r, --repository=REPO  set the repository name (default=PACKAGE)
Packit 437b5e
      --help             print this help, then exit
Packit 437b5e
      --version          print version number, then exit
Packit 437b5e
Packit 437b5e
Report bugs to http://github.com/gvvaughan/slingshot/issues.]])
Packit 437b5e
    os.exit (0)
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
prog["--version"] = function ()
Packit 437b5e
  print [[mkrockspecs (slingshot) 8.0.0
Packit 437b5e
Written by Gary V. Vaughan <gary@gnu.org>, 2013
Packit 437b5e
Packit 437b5e
Copyright (C) 2013, Gary V. Vaughan
Packit 437b5e
Slingshot comes with ABSOLUTELY NO WARRANTY.
Packit 437b5e
See source files for individual license conditions.]]
Packit 437b5e
  os.exit (0)
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
prog["-b"] = function (argl, i) return setopt ("branch", argl, i) end
Packit 437b5e
prog["--branch"] = prog["-b"]
Packit 437b5e
Packit 437b5e
prog["-m"] = function (argl, i) return setopt ("module_root", argl, i) end
Packit 437b5e
prog["--module-dir"] = prog["-m"]
Packit 437b5e
Packit 437b5e
prog["-r"] = function (argl, i) return setopt ("repository", argl, i) end
Packit 437b5e
prog["--repository"] = prog["-r"]
Packit 437b5e
Packit 437b5e
local nonopts
Packit 437b5e
local i = 0
Packit 437b5e
while i < #arg do
Packit 437b5e
  i = i + 1
Packit 437b5e
  local opt = arg[i]
Packit 437b5e
Packit 437b5e
  -- Collect remaining arguments not nonopts to save back into _G.arg later.
Packit 437b5e
  if type (nonopts) == "table" then
Packit 437b5e
    table.insert (nonopts, opt)
Packit 437b5e
Packit 437b5e
  -- Run prog.option handler.
Packit 437b5e
  elseif opt:sub (1,1) == "-" and type (prog[opt]) == "function" then
Packit 437b5e
    i = prog[opt] (arg, i)
Packit 437b5e
Packit 437b5e
  -- End of option arguments.
Packit 437b5e
  elseif opt == "--" then
Packit 437b5e
    nonopts = {}
Packit 437b5e
Packit 437b5e
  -- Diagnose unknown command line options.
Packit 437b5e
  elseif opt:sub (1, 1) == "-" then
Packit 437b5e
    opterr ("unrecognized option '" .. opt .. "'")
Packit 437b5e
Packit 437b5e
  -- First non-option argument marks the end of options.
Packit 437b5e
  else
Packit 437b5e
    nonopts = { opt }
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
-- put non-option args back into global arg table.
Packit 437b5e
nonopts = nonopts or {}
Packit 437b5e
nonopts[0] = arg[0]
Packit 437b5e
_G.arg = nonopts
Packit 437b5e
Packit 437b5e
if select ("#", ...) < 2 then
Packit 437b5e
  opterr ("only " .. select ("#", ...) .. " arguments provided")
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local package  = arg[1]
Packit 437b5e
local version  = arg[2]
Packit 437b5e
local revision = arg[3] or "1"
Packit 437b5e
local conf     = arg[4] or "rockspec.conf"
Packit 437b5e
Packit 437b5e
-- Unless set explicity, assume the repo is named after the package.
Packit 437b5e
if prog.opts.repository == nil then
Packit 437b5e
  prog.opts.repository = package
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
Packit 437b5e
--[[ ================= ]]--
Packit 437b5e
--[[ Helper functions. ]]--
Packit 437b5e
--[[ ================= ]]--
Packit 437b5e
Packit 437b5e
local ok, posix = pcall (require, "posix")
Packit 437b5e
Packit 437b5e
files = {}
Packit 437b5e
Packit 437b5e
if ok then
Packit 437b5e
  -- faster version if luaposix is available
Packit 437b5e
  function tree (root)
Packit 437b5e
    for f in posix.files (root) do
Packit 437b5e
      local path = root .. "/" .. f
Packit 437b5e
      if f:match ("%.lua$") then
Packit 437b5e
        table.insert (files, path)
Packit 437b5e
      elseif f == "." or f == ".." then
Packit 437b5e
        -- don't go into a loop
Packit 437b5e
      elseif posix.stat (path, "type") == "directory" then
Packit 437b5e
        tree (path)
Packit 437b5e
      end
Packit 437b5e
    end
Packit 437b5e
  end
Packit 437b5e
else
Packit 437b5e
  -- fallback version that executes ls in subshells
Packit 437b5e
  function tree (root)
Packit 437b5e
    local p = io.popen ("ls -1 " .. root .. " 2>/dev/null")
Packit 437b5e
Packit 437b5e
    if p ~= nil then
Packit 437b5e
      local f = p:read "*l"
Packit 437b5e
      while f ~= nil do
Packit 437b5e
        if f:match ("%.lua$") then
Packit 437b5e
          table.insert (files, root .. "/" .. f)
Packit 437b5e
        else
Packit 437b5e
          tree (root .. "/" .. f)
Packit 437b5e
        end
Packit 437b5e
        f = p:read "*l"
Packit 437b5e
      end
Packit 437b5e
    end
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local function escape_pattern (s)
Packit 437b5e
  return (string.gsub (s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0"))
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local function loadmap (root)
Packit 437b5e
  local map = {}
Packit 437b5e
  tree (root)
Packit 437b5e
  for _, f in ipairs (files) do
Packit 437b5e
    local m = f:match ("^" .. escape_pattern (root) .. "/(.*)%.lua")
Packit 437b5e
    map [m:gsub ("/", "."):gsub ("%.init$", "")] = f:gsub ("^%./", "")
Packit 437b5e
  end
Packit 437b5e
  return map
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
Packit 437b5e
--[[ =================== ]]--
Packit 437b5e
--[[ Load configuration. ]]--
Packit 437b5e
--[[ =================== ]]--
Packit 437b5e
Packit 437b5e
local yaml = require "lyaml"
Packit 437b5e
Packit 437b5e
-- Slurp io.input ().
Packit 437b5e
local function slurp ()
Packit 437b5e
  h = io.input ()
Packit 437b5e
  if h then
Packit 437b5e
    local s = h:read "*a"
Packit 437b5e
    h:close ()
Packit 437b5e
    return s
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
if conf == "-" then
Packit 437b5e
  io.input (io.stdin)
Packit 437b5e
else
Packit 437b5e
  local h = io.open (conf)
Packit 437b5e
  if h then
Packit 437b5e
    io.input (conf)
Packit 437b5e
    h:close ()
Packit 437b5e
  else
Packit 437b5e
    io.input (io.stdin)
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
local spec = yaml.load (slurp ())
Packit 437b5e
local default = { source = {} }
Packit 437b5e
Packit 437b5e
-- url needn't be given if it is identical to homepage.
Packit 437b5e
local url
Packit 437b5e
if spec.source ~= nil then
Packit 437b5e
  url = spec.source.url
Packit 437b5e
elseif spec.description ~= nil then
Packit 437b5e
  url = spec.description.homepage
Packit 437b5e
else
Packit 437b5e
  die (conf .. ": could not find source.url or description.homepage")
Packit 437b5e
end
Packit 437b5e
url = url:gsub ("^[a-z]*://", ""):gsub ("%.git$", "")
Packit 437b5e
Packit 437b5e
-- Interpolate default values.
Packit 437b5e
default.package = package
Packit 437b5e
default.version = version .. "-" .. revision
Packit 437b5e
Packit 437b5e
configure_flags = ""
Packit 437b5e
if type (spec.external_dependencies) == "table" then
Packit 437b5e
  CPPFLAGS, LDFLAGS = "", ""
Packit 437b5e
  for name, vars in pairs (spec.external_dependencies) do
Packit 437b5e
    if vars.library then
Packit 437b5e
      CPPFLAGS = CPPFLAGS .. " -I$(" .. name .. "_INCDIR)"
Packit 437b5e
      LDFLAGS  = LDFLAGS  .. " -L$(" .. name .. "_LIBDIR)"
Packit 437b5e
    end
Packit 437b5e
  end
Packit 437b5e
Packit 437b5e
  if string.len (CPPFLAGS) > 0 then
Packit 437b5e
    configure_flags = configure_flags ..
Packit 437b5e
        "CPPFLAGS='" .. CPPFLAGS:gsub ("^%s", "") .. "'" ..
Packit 437b5e
        " LDFLAGS='" ..  LDFLAGS:gsub ("^%s", "") .. "'" ..
Packit 437b5e
        " "
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
-- If we have a module root, use the luarocks "builtin" type.
Packit 437b5e
if version ~= "scm" and version ~= "git" then
Packit 437b5e
  if prog.opts.module_root ~= nil then
Packit 437b5e
    default.build = {
Packit 437b5e
      type = "builtin",
Packit 437b5e
      modules = loadmap (prog.opts.module_root),
Packit 437b5e
    }
Packit 437b5e
  elseif spec.build ~= nil and spec.build.modules ~= nil then
Packit 437b5e
    default.build = { type = "builtin" }
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
default.build = default.build or {
Packit 437b5e
  type = "command",
Packit 437b5e
  build_command = "./configure " ..
Packit 437b5e
    "LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' " .. configure_flags ..
Packit 437b5e
    "--prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' " ..
Packit 437b5e
    "--datarootdir='$(PREFIX)' && make clean all",
Packit 437b5e
  install_command = "make install luadir='$(LUADIR)' luaexecdir='$(LIBDIR)'",
Packit 437b5e
  copy_directories = {},
Packit 437b5e
}
Packit 437b5e
Packit 437b5e
-- Additional spec-type dependent values.
Packit 437b5e
spec.source = spec.source or {}
Packit 437b5e
spec.build  = spec.build  or {}
Packit 437b5e
if version ~= "scm" and version ~= "git" then
Packit 437b5e
  spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip"
Packit 437b5e
  spec.source.dir = prog.opts.repository .. "-release-v" .. version
Packit 437b5e
else
Packit 437b5e
  spec.source.url = "git://" .. url .. ".git"
Packit 437b5e
  spec.source.branch = prog.opts.branch
Packit 437b5e
  spec.build.modules = nil
Packit 437b5e
  default.build.build_command =  "./bootstrap && " .. default.build.build_command
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
Packit 437b5e
-- Recursive merge, settings from spec take precedence.  Elements of src
Packit 437b5e
-- overwrite equivalent keys in dest.
Packit 437b5e
local function merge (dest, src)
Packit 437b5e
  for k, v in pairs (src) do
Packit 437b5e
    if type (v) == "table" then
Packit 437b5e
      dest[k] = merge (dest[k] or {}, src[k])
Packit 437b5e
    else
Packit 437b5e
      dest[k] = src[k]
Packit 437b5e
    end
Packit 437b5e
  end
Packit 437b5e
  return dest
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
spec = merge (default, spec)
Packit 437b5e
Packit 437b5e
Packit 437b5e
--[[ ======= ]]--
Packit 437b5e
--[[ Output. ]]--
Packit 437b5e
--[[ ======= ]]--
Packit 437b5e
Packit 437b5e
-- Recursively format X, with pretty printing.
Packit 437b5e
local function format (x, indent)
Packit 437b5e
  indent = indent or ""
Packit 437b5e
  if type (x) == "table" then
Packit 437b5e
    if next (x) == nil then
Packit 437b5e
      return "{}"
Packit 437b5e
    else
Packit 437b5e
      local s = "{\n"
Packit 437b5e
Packit 437b5e
      -- Collect and sort non-numeric keys first.
Packit 437b5e
      keys = {}
Packit 437b5e
      for k in pairs (x) do
Packit 437b5e
        if type (k) ~= "number" then table.insert (keys, k) end
Packit 437b5e
      end
Packit 437b5e
      table.sort (keys, function (a, b) return tostring (a) < tostring (b) end)
Packit 437b5e
Packit 437b5e
      -- Display non-numeric key pairs in sort order.
Packit 437b5e
      for _, k in ipairs (keys) do
Packit 437b5e
        s = s .. indent
Packit 437b5e
        if k:match ("[^_%w]") then
Packit 437b5e
          -- wrap keys with non-%w chars in square brackets
Packit 437b5e
          s = s .. '["' .. k .. '"]'
Packit 437b5e
        else
Packit 437b5e
          s = s .. k
Packit 437b5e
        end
Packit 437b5e
        s = s .. " = " .. format (x[k], indent .. "  ") .. ",\n"
Packit 437b5e
      end
Packit 437b5e
Packit 437b5e
      -- And numeric key pairs last.
Packit 437b5e
      for i, v in ipairs (x) do
Packit 437b5e
        s = s .. indent .. format (v, indent .. "  ") .. ",\n"
Packit 437b5e
      end
Packit 437b5e
      return s..indent:sub (1, -3).."}"
Packit 437b5e
    end
Packit 437b5e
  elseif type (x) == "string" then
Packit 437b5e
    return string.format ("%q", x)
Packit 437b5e
  else
Packit 437b5e
    return tostring (x)
Packit 437b5e
  end
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
-- Use the standard order for known keys.
Packit 437b5e
for _, k in ipairs {
Packit 437b5e
  "package",
Packit 437b5e
  "version",
Packit 437b5e
  "description",
Packit 437b5e
  "source",
Packit 437b5e
  "dependencies",
Packit 437b5e
  "external_dependencies",
Packit 437b5e
  "build",
Packit 437b5e
} do
Packit 437b5e
  print (k .. " = " .. format (spec[k], "  "))
Packit 437b5e
  spec[k] = nil
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
-- Output anything left in the table at the end.
Packit 437b5e
for i, v in pairs (spec) do
Packit 437b5e
  print (i .. " = " .. format (v, "  "))
Packit 437b5e
end
Packit 437b5e
Packit 437b5e
os.exit (0)