# Copyright © 2015-2019 Jan Chaloupka , # Nicolas Mailhot # # This program 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. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # This file contains macros needed at %build %install and %check # stage by Golang packages. # # The macros necessary at %setup and srpm stage are in the sister file # macros.go-srpm # # SPDX-License-Identifier: GPL-3.0-or-later # Default filtering policy # Complete or replace the following variables in your spec file if this policy # does not apply to your project # # Specific example matching rule. # The average Go project example code is incomplete and obsolete. It will # fail to compile as-is, or even panic. It will poison the dependency # generator with bogus or legacy import path requirements. Even when it it # clean and up to date, it will require many third party components not needed # in production. Therefore: # – never install Go project example code in %{gopath}. Publish is as %doc. # — ask politely projects that publish example code in some other directory # than _examples to rename it. # – never rely on third party examples being available or working in another # project. This is *not* production code. Ask upstreams politely to remove # tests or code that import other project examples. %goignoreflags_examples -r '.*example.*' # Default flags to apply in all stages %godefaultflags %{goignoreflags_examples} # Default flags to apply in Go install (%goinstall) %goinstallflags %{godefaultflags} # Default flags to apply in Go checks (%gochecks) %gocheckflags %{godefaultflags} # Default flags to apply in Go autoprovides %goprovflags %{godefaultflags} # Default flags to apply in Go autorequires %goreqflags %{godefaultflags} # The default filelist name generated by %goinstall %gofilelist devel.file-list # Sets environment variables suitable for a Go source archive. Optional arguments: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -i use the specified import path value instead of the one # found in %{goipath} # -v be verbose # -V Should only be specified when creating subpackages with # distinct versions # default: %{version}.%{release} # -T default: %{tag} # -C default: %{commit} # -B default: %{branch} %goenv(z:i:vV:T:C:B:) %{lua: local go = require "fedora.rpm.go" local suffix = rpm.expand("%{?-z*}") local goipath = rpm.expand("%{?-i*}") local verbose = (rpm.expand("%{-v}") ~= "") local margs = { version = "V", tag = "T", commit = "C", branch = "B", } local mvalues = {} for m,_ in pairs(margs) do local v = rpm.expand("%{?-" .. margs[m] .. "*}") if (v ~= "") then mvalues[m] = v end end go.env(suffix, goipath, verbose, mvalues) } # Create default Go directories. Arguments: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -i use the specified import path value instead of the one # found in %{goipath} # can not be repeated # -b use as build directory # binaries will be produced in /bin # expanded Go sources will be symlinked in /src # -s symlink expanded Go sources from # default: %{_builddir}/%{?extractdir} # -k keep the vendor directory, do not delete it # -v be verbose %gomkdir(z:i:b:s:kv) %{expand: %goenv %{?-z} %{?-i} %{?-v} %define mybuilddir %{?-b*}%{!-b:%{gobuilddir}} %define mygoipath %{?-i*}%{!-i:%{currentgoipath}} %define mysourcedir %{?-s*}%{!-s:%{currentgosourcedir}} %{!?-k:rm -fr "%{mysourcedir}/vendor"} if [[ ! -e "%{mybuilddir}/bin" ]] ; then install -m 0755 -vd "%{mybuilddir}/bin" export GOPATH="%{mybuilddir}:${GOPATH:+${GOPATH}:}%{?gopath}" fi if [[ ! -e "%{mybuilddir}/src/%{mygoipath}" ]] ; then install -m 0755 -vd "$(dirname %{mybuilddir}/src/%{mygoipath})" ln -fs "%{mysourcedir}" "%{mybuilddir}/src/%{mygoipath}" fi cd "%{mybuilddir}/src/%{mygoipath}" } # Perform usual Go source preparation steps. Optional arguments: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -a process all sources in one go, instead of using separate # -z calls # -i use the specified import path value instead of the one # found in %{goipath} # -b use as build directory # binaries will be produced in /bin # expanded Go sources will be symlinked in /src # -s symlink expanded Go sources from # default: %{_builddir}/%{?extractdir} # -k keep the vendor directory, do not delete it # -e use extracted archives, do not perform %setup-like # operations # -v be verbose %goprep(z:ai:b:s:kerv) %{lua: local fedora = require "fedora.common" local extract = (rpm.expand("%{-e}") == "") local installdeps = (rpm.expand("%{-r}") == "") local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local setupflags = rpm.expand("%{!-v:-q}") local gomkdirflags = rpm.expand("%{?-i} %{?-b} %{?-s} %{-k} %{-v}") local buildrequires = {} local function process(suffix) local zsuffix = "" if (suffix ~= "") and (suffix ~= nil) then zsuffix = "-z " .. suffix .. " " end if extract then print(rpm.expand("%setup " .. setupflags .. " %{?forgesetupargs" .. suffix .. "}\\n")) end print( rpm.expand("%gomkdir " .. zsuffix .. gomkdirflags .. "\\n")) end -- Main loop if processall then for _,s in pairs(fedora.getsuffixes("goipath")) do process(s) end else process(rpm.expand("%{?-z*}")) end } # Computes BuildRequires for a given import path. Arguments: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -a process all sources in one go, instead of using separate # -z calls # -i use the specified import path value instead of the one # found in %{goipath} %go_generate_buildrequires(z:ai:) %{lua: local fedora = require "fedora.common" local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local forcedgoipath = rpm.expand("%{?-i}") local golistargs = "" if processall then for _, s in pairs(fedora.getsuffixes("goipath")) do golistargs = golistargs .. " --package-path %{goipath" .. s .. "}" end golistargs = string.gsub(golistargs, "^ ", "") elseif forcedgoipath ~= "" then golistargs = "--package-path " .. forcedgoipath else golistargs = "--package-path %{goipath" .. rpm.expand("%{?-z*}") .. "}" end print(rpm.expand('GOPATH="%{?gobuilddir:%{gobuilddir}:}${GOPATH:+${GOPATH}:}%{?gopath}" ' .. 'GO111MODULE=off ' .. "golist --imported " .. golistargs .. " --template 'golang({{.}})\\\\n'" .. " --with-tests --skip-self\\n")) } # Try to install Go package files in sensible locations, with strict directory # ownership and lockfile creation as required by Go autodeps. # # Simple arguments, that can not be repeated: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -a process all sources in one go, instead of using separate # -z calls # -i use the specified import path value # default: %{goipath} # -b read binaries already produced in # default: %{gobuilddir}/bin # -s read expanded and prepared Go sources in /src # should be populated in %prep # default: %{gobuilddir} # -o output installed file list in # default: %{gofilelist} # -O output in # -l add those flags to LDFLAGS when building unit tests # -v be verbose # # Inclusion arguments, that can be repeated: # -e include files with the provided extension # # Exclusion arguments, that can be repeated, relative to the go import path root: # -d exclude the files contained in # not recursive (subdirectories are not excluded) # -t exclude the files contained in # recursive (subdirectories are excluded) # -r exclude files matching , # # Optional versionning metadata, that can not be repeated: # -V Should only be specified when creating subpackages with # distinct versions # default: %{version}.%{release} # -T default: %{tag} # -C default: %{commit} # -B default: %{branch} # # When invoked several times with the same import path goinstall will append to # the existing file list if versionning and exclusion arguments are identical to # previous calls, and error out otherwise. # When invoked several times with different file list names, it will attribute # directories to the first file list that makes use of them. %goinstall(z:ai:b:s:o:O:ve:d:t:rV:T:C:B:p:g:) %{lua: local fedora = require "fedora.common" local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local myenvflags = rpm.expand('%{?-i} %{?-v} %{?-V} %{?-T} %{?-C} %{?-B}') local myinstallflags = rpm.expand('%{!-i:-i "%%{currentgoipath}" }' .. '%{!-b:-b "%%{gobuilddir}/bin" }' .. '%{!-s:-s "%%{gobuilddir}" }' .. '%{!-o:-o "%%{thisgofilelist}" }' .. '%{!-O:-O "%%{goworkdir}" }' .. '%{!-V:-V "%{version}-%{release}" }' .. '%{!-T:%%{?currenttag: -T "%%{?currenttag}" }}' .. '%{!-C:%%{?currentcommit: -C "%%{?currentcommit}" }}' .. '%{!-B:%%{?currentbranch: -B "%%{?currentbranch}" }}' .. '%{!-p:-p "%{buildroot}" }' .. '%{!-g:-g "%{gopath}" }' .. '%{?goinstallflags} %{?**}') -- Main function local function process(suffix) local zsuffix = "" if (suffix ~= "") and (suffix ~= nil) then zsuffix = "-z " .. suffix .. " " end print(rpm.expand('%goenv ' .. zsuffix .. myenvflags .. '\\n' .. 'go-rpm-integration install ' .. myinstallflags .. '\\n')) end -- Main loop if processall then for _,s in pairs(fedora.getsuffixes("goipath")) do process(s) end else process(rpm.expand("%{-z*}")) end } # Perform the %install tasks of every known kind of Go subpackage. Arguments: # -v be verbose %gopkginstall(av) %{expand: %godevelinstall -a %{-v} %goaltinstall -a %{-v} } # Perform the %install tasks of a golang-*-devel subpackage. Arguments: # -z read the zth block of definitions, for example # %{goipaths} # -a process all blocks in one go, instead of using separate # -z calls # -v be verbose %godevelinstall(z:av) %{lua: local go = require "fedora.rpm.go" local suffix = rpm.expand("%{-z*}") local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local verbose = (rpm.expand("%{-v}") ~= "") go.install("devel", suffix, processall, verbose) } # Perform the %install tasks of a compat-golang-*-devel subpackage. Arguments: # -z read the zth block of definitions, for example # %{goaltipaths} # -a process all blocks in one go, instead of using separate # -z calls # -v be verbose %goaltinstall(z:av) %{lua: local go = require "fedora.rpm.go" local suffix = rpm.expand("%{-z*}") local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local verbose = (rpm.expand("%{-v}") ~= "") go.install("alt", suffix, processall, verbose) } # Run go test with Fedora flags on all subdirectories except for those filtered out # THIS MACRO IS OPT-OUT. # # Simple arguments, that can not be repeated: # -z read the zth block of definitions, for example # %{goipath}, %{commit}… # derived from the import path value if not specified # -a process all sources in one go, instead of using separate # -z calls # -i use the specified import path value # default: %{goipath} # -b read binaries already produced in # default: %{gobuilddir}/bin # -s read expanded and prepared Go sources in /src # should be populated in %prep # default: %{gobuilddir} # -v be verbose # Exclusion arguments, that can be repeated, relative to the go import path root: # -d exclude the files contained in # not recursive (subdirectories are not excluded) # -t exclude the files contained in # recursive (subdirectories are excluded) # -r exclude files matching , %gocheck(z:ai:b:s:vd:t:rV:T:C:B:p:g:w) %{lua: rpm.undefine('_auto_set_build_flags') local fedora = require "fedora.common" local processall = (rpm.expand("%{-a}") ~= "") and (rpm.expand("%{-z}") == "") local myenvflags = rpm.expand('%{?-i} %{?-v} %{?-V} %{?-T} %{?-C} %{?-B}') local mycheckflags = rpm.expand('%{!-i:-i "%%{currentgoipath}" }' .. '%{!-b:-b "%%{gobuilddir}/bin" }' .. '%{!-s:-s "%%{gobuilddir}" }' .. '%{!-V:-V "%{version}-%{release}" }' .. '%{!-T:%%{?currenttag: -T "%%{?currenttag}" }}' .. '%{!-C:%%{?currentcommit: -C "%%{?currentcommit}" }}' .. '%{!-B:%%{?currentbranch: -B "%%{?currentbranch}" }}' .. '%{!-p:-p "%{buildroot}" }' .. '%{!-g:-g "%{gopath}" }' .. '%{?gocheckflags} %{?**}') -- Main function local function process(suffix) local zsuffix = "" if (suffix ~= "") and (suffix ~= nil) then zsuffix = "-z " .. suffix .. " " end print(rpm.expand('%goenv ' .. zsuffix .. myenvflags .. '\\n' .. '%{?currentgoldflags:LDFLAGS="${LDFLAGS} %{?currentgoldflags}" }' .. '%{?gotestflags:GO_TEST_FLAGS="%{gotestflags}" }' .. '%{?gotestextldflags:GO_TEST_EXT_LD_FLAGS="%{gotestextldflags}" }' .. 'go-rpm-integration check ' .. mycheckflags .. '\\n')) end -- Main loop if processall then for _,s in pairs(fedora.getsuffixes("goipath")) do process(s) end else process(rpm.expand("%{-z*}")) end }