nim / rpms / go-compilers

Forked from rpms/go-compilers 6 years ago
Clone

Blame macros.go-rpm

63f006a
# Copyright (c) 2018 Nicolas Mailhot <nim@fedoraproject.org>
63f006a
#
63f006a
# This file is distributed under the terms of GNU GPL license version 3, or
63f006a
# any later version.
63f006a
#
63f006a
# This file contains macros needed at %%build %%install and %%check
63f006a
# stage by Golang packages.
63f006a
# The macros necessary at %%setup and srpm stage are in the sister file
63f006a
# macros.go-srpm
63f006a
63f006a
# find directory filter to remove elements usually not needed to build other Go projects
63f006a
%gofinddirfilter  -regextype egrep \! -iregex '.*/(.*[._-])?(example(s)?|test([._-])?data)/.*' \! -ipath '*/vendor/*'
63f006a
63f006a
# find filter to identify resources usually needed to build other Go projects
63f006a
%gofindfilter     -regextype egrep -iregex '(.*\\.(go|c|h|s|tmpl|proto)|./Gopkg\\.(toml|lock))' \! -iname '*_test.go' \! -iregex  '.*/(.*[._-])?test(([._-])?case)?(s)?/.*' \! -iregex  '.*/[._].*' %{gofinddirfilter}
63f006a
63f006a
# find filter to identify unit tests
63f006a
%gofindtestfilter                  -iname '*.go' %{gofinddirfilter}
63f006a
63f006a
# Collect md files spread in subdirectories
63f006a
%gocollectmd %{expand:
63f006a
for mdfile in $(find . -iname '*.md' %{gofinddirfilter}) ; do
63f006a
  suffix=$(dirname $mdfile | sed 's+^\./++g' | sed 's+/+·+g')
63f006a
  if [[ $suffix != '.' ]] ; then
63f006a
    cp -p "$mdfile" "$(echo $(basename $mdfile) | sed 's+\.md$++g')·${suffix}.md"
63f006a
  fi
63f006a
done}
63f006a
63f006a
# Try to install Go package files in sensible locations, with strict directory
63f006a
# ownership as required by Go autodeps
63f006a
#
63f006a
# %%goinstall takes a list of files as argument.
63f006a
#
63f006a
# %%goinstall will generate a file list that can be used in a %%files spec
63f006a
# section. The default file list name is devel.file-list. It can be overriden
63f006a
# by passing the -f argument to the macro with another filename.
63f006a
#
63f006a
# When invoked several times it will append to existing file lists not create
63f006a
# a new one.
63f006a
#
63f006a
# When invoked several times with different file list names, it will attribute
63f006a
# directories to the first file list that makes use of them only. This is
63f006a
# intentional, to avoid triggering Go autodeps on the same Go directory in
63f006a
# different subpackages. Therefore, splitting code in several subpackages
63f006a
# requires careful though about %%goinstall invocation order.
63f006a
%goinstall(f:) %{expand:
63f006a
%global file_list %{?-f*}%{!?-f*:devel.file-list}
63f006a
install -m 0755 -vd "%{buildroot}%{gopath}/src"
63f006a
for file in %* ; do
63f006a
  file="${file#./}"
63f006a
  [[ -d "${file}" && ! -L "${file}" ]] && srcdir="${file}" || srcdir=$(dirname "${file}")
63f006a
  destdir="%{buildroot}%{gopath}/src/%{goipath}/${srcdir}"
63f006a
  destdir="${destdir%/.}"
63f006a
  dir="${destdir}"
63f006a
  dirs=()
63f006a
  while [[ ! -e "${dir}" ]] ; do
63f006a
    dirs=("$dir" "${dirs[@]}")
63f006a
    dir=$(dirname "${dir}")
63f006a
  done
63f006a
  for dir in "${dirs[@]}" ; do
63f006a
    install -m 0755 -vd "${dir}"
63f006a
    if $(echo "${dir}" | grep -q "^%{buildroot}%{gopath}/src/%{goipath}") ; then
63f006a
      touch -r             ".${dir#%{buildroot}%{gopath}/src/%{goipath}}" "${dir}"
63f006a
    fi
63f006a
    echo "%%dir \"${dir#%{buildroot}}\"" >> %{file_list}
63f006a
  done
63f006a
  if [[ -L "$file" ]] ; then
63f006a
    ln -s $(readlink "${file}") "${destdir}/$(basename ${file})"
63f006a
    touch -h      -r "${file}"  "${destdir}/$(basename ${file})"
63f006a
  fi
63f006a
  [[ -f "$file" && ! -L "$file" ]] && install -m 0644 -vp  "${file}" "${destdir}/"
54f7983
  [[ -f "$file" ||   -L "$file" ]] && echo "%%{gopath}/src/%%{goipath}/${file}" >> %{file_list} || :
63f006a
done}
63f006a
63f006a
# Create a local Go build root
63f006a
# Useful in %%build and %%check
63f006a
%gobuildroot() %{expand:
63f006a
  GO_BUILD_PATH="$PWD/_build"
63f006a
  %global gobuildpath "$GO_BUILD_PATH"
63f006a
  install -m 0755 -vd "$(dirname %{gobuildpath}/src/%{goipath})"
63f006a
  ln -fs "$PWD" "%{gobuildpath}/src/%{goipath}"
e09f757
  cd "%{gobuildpath}/src/%{goipath}"
63f006a
  install -m 0755 -vd _bin
63f006a
  export GOPATH="%{gobuildpath}:%{gopath}"
988dc53
  export LDFLAGS="${LDFLAGS:-}%{?commit: -X %{goipath}/version.commit=%{commit}}%{?tag: -X %{goipath}/version.tag=%{tag}}%{?version: -X %{goipath}/version=%{version}}"
63f006a
}
63f006a
63f006a
# Run %%{gotest} on all subdirectories except for those provided in parameters.
63f006a
# THIS MACRO IS OPT-OUT.
63f006a
# It only allows excluding specific subdirectories from the test run, with the
63f006a
# following syntax :
63f006a
#  — to exclude the tests in a specific subdirectory, not recursively:
63f006a
#    pass it as parameter. Use . for the project root.
63f006a
#    Example:
c066be8
#      %gochecks . subdir1 sub2/dir
63f006a
#  — to exclude the tests in a whole subtree:
63f006a
#    use the -R or --root switch with the subtree root as argument.
63f006a
#    Example:
c066be8
#      %gochecks -R sub1/tree/root -root 'sub2/fixtures'
c066be8
#  — to exclude using free-form egrep-style regexes:
63f006a
#    use the -r or --regex switch with the regex as argument.
63f006a
#    Example:
63f006a
#      %gochecks --regex '.*/(.*[._-])?test(([._-])?case)?(s)?/.*'
63f006a
#  — you can mix and match:
63f006a
#      %gochecks . subdir1 -R sub/tree/root sub/dir2 -r './testcase(s)?/.*'
63f006a
#  — arguments containing spaces or escaped quotes are not supported
63f006a
%gochecks(rotegxR-) %{expand:%{lua:
63f006a
local parameters = {}
63f006a
-- Quite sufficient for our needs, otherwise look at rex.gmatch
63f006a
for p in string.gmatch(rpm.expand("%**"), "%S+") do
63f006a
--  p = string.gsub(p, '"(%S+)"', '%1')
63f006a
--  p = string.gsub(p, "'(%S+)'", '%1')
63f006a
  table.insert(parameters, p)
63f006a
end
c066be8
local function notsubpath(path)
61eac3b
  if not string.match(path, "^%./") then
c066be8
    path = "./" .. path
7c609c2
  end
c066be8
  return "\! -regex '" .. path .. "'"
c066be8
end
63f006a
local function regexfilter(regex)
63f006a
  return "\! -regex '" .. regex .. "'"
63f006a
end
63f006a
local function rootfilter(root)
c066be8
  return notsubpath(root .. "/.*")
63f006a
end
63f006a
local function dirfilter(dir)
c066be8
  return notsubpath(dir .. "/[^/]*")
63f006a
end
63f006a
local argparse = require "argparse"
63f006a
local parser = argparse()
63f006a
parser:option   ("-r --regex")
63f006a
      :count    ("*")
63f006a
      :args     ("1")
63f006a
      :convert  (regexfilter)
63f006a
parser:option   ("-R --root")
63f006a
      :count    ("*")
63f006a
      :args     ("1")
63f006a
      :convert  (rootfilter)
63f006a
parser:argument ("dir")
63f006a
      :args     ("*")
63f006a
      :convert  (dirfilter)
63f006a
local args = parser:parse(parameters)
63f006a
local gofindtestfilter = rpm.expand("%{?gofindtestfilter}")
63f006a
gofindtestfilter = gofindtestfilter .. " -regextype egrep " ..
63f006a
                   table.concat(args.regex, " ") .. " " ..
63f006a
                   table.concat(args.root, " ")  .. " " ..
63f006a
                   table.concat(args.dir, " ")
63f006a
rpm.define("checkfilter " .. gofindtestfilter)
63f006a
}
63f006a
# The following relies on things like environment variable and other macros
63f006a
# easier to use in shell
63f006a
%gobuildroot
63f006a
export PATH=$PATH:%{buildroot}%{_bindir}
63f006a
find . %{checkfilter} -exec dirname '\{\}' \\;|sort|uniq|while read sub ; do
63f006a
  set +x
63f006a
  sub="${sub#./}"
63f006a
  echo "Testing ${sub}…"
63f006a
  pushd "%{gobuildpath}/src/%{goipath}/${sub}" >/dev/null
63f006a
  set -x
63f006a
  %{gotest}
63f006a
  set +x
63f006a
  popd >/dev/null
63f006a
done
63f006a
}