d5de5f60ccdfe914888abd2e553054d0d91a55fc
[gentoo.git] / eclass / go-module.eclass
1 # Copyright 2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: go-module.eclass
5 # @MAINTAINER:
6 # William Hubbs <williamh@gentoo.org>
7 # @SUPPORTED_EAPIS: 7
8 # @BLURB: basic eclass for building software written as go modules
9 # @DESCRIPTION:
10 # This eclass provides basic settings and functions
11 # needed by all software written in the go programming language that uses
12 # go modules.
13 #
14 # You will know the software you are packaging uses modules because
15 # it will have files named go.sum and go.mod in its top-level source
16 # directory. If it does not have these files, use the golang-* eclasses.
17 #
18 # If it has these files and a directory named vendor in its top-level
19 # source directory, you only need to inherit the eclass since upstream
20 # is vendoring the dependencies.
21 #
22 # If it does not have a vendor directory, you should use the EGO_VENDOR
23 # variable and the go-module_vendor_uris function as shown in the
24 # example below to handle dependencies.
25 #
26 # Since Go programs are statically linked, it is important that your ebuild's
27 # LICENSE= setting includes the licenses of all statically linked
28 # dependencies. So please make sure it is accurate.
29 #
30 # @EXAMPLE:
31 #
32 # @CODE
33 #
34 # inherit go-module
35 #
36 # EGO_VENDOR=(
37 #       "github.com/xenolf/lego 6cac0ea7d8b28c889f709ec7fa92e92b82f490dd"
38 # "golang.org/x/crypto 453249f01cfeb54c3d549ddb75ff152ca243f9d8 github.com/golang/crypto"
39 # )
40 #
41 # SRC_URI="https://github.com/example/${PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz
42 # $(go-module_vendor_uris)"
43 #
44 # @CODE
45
46 case ${EAPI:-0} in
47         7) ;;
48         *) die "${ECLASS} API in EAPI ${EAPI} not yet established."
49 esac
50
51 if [[ -z ${_GO_MODULE} ]]; then
52
53 _GO_MODULE=1
54
55 BDEPEND=">=dev-lang/go-1.12"
56
57 # Force go to build in module mode.
58 # In this mode the GOPATH environment variable is ignored.
59 # this will become the default in the future.
60 export GO111MODULE=on
61
62 # Set the default for the go build cache
63 # See "go help environment" for information on this setting
64 export GOCACHE="${T}/go-build"
65
66 # The following go flags should be used for all builds.
67 # -mod=vendor stopps downloading of dependencies from the internet.
68 # -v prints the names of packages as they are compiled
69 # -x prints commands as they are executed
70 export GOFLAGS="-mod=vendor -v -x"
71
72 # Do not complain about CFLAGS etc since go projects do not use them.
73 QA_FLAGS_IGNORED='.*'
74
75 # Go packages should not be stripped with strip(1).
76 RESTRICT="strip"
77
78 EXPORT_FUNCTIONS src_unpack pkg_postinst
79
80 # @ECLASS-VARIABLE: EGO_VENDOR
81 # @DESCRIPTION:
82 # This variable contains a list of vendored packages.
83 # The items of this array are strings that contain the
84 # import path and the git commit hash for a vendored package.
85 # If the import path does not start with github.com, the third argument
86 # can be used to point to a github repository.
87
88 # @FUNCTION: go-module_vendor_uris
89 # @DESCRIPTION:
90 # Convert the information in EGO_VENDOR to a format suitable for
91 # SRC_URI.
92 # A call to this function should be added to SRC_URI in your ebuild if
93 # the upstream package does not include vendored dependencies.
94 go-module_vendor_uris() {
95         local hash import line repo x
96         for line in "${EGO_VENDOR[@]}"; do
97                 read -r import hash repo x <<< "${line}"
98                 if [[ -n $x ]]; then
99                         eerror "Trailing information in EGO_VENDOR in ${P}.ebuild"
100                         eerror "${line}"
101                         eerror "Trailing information is: \"$x\""
102                         die "Invalid EGO_VENDOR format"
103                 fi
104                 : "${repo:=${import}}"
105                 echo "https://${repo}/archive/${hash}.tar.gz -> ${repo//\//-}-${hash}.tar.gz"
106         done
107 }
108
109 # @FUNCTION: go-module_src_unpack
110 # @DESCRIPTION:
111 # Extract all archives in ${a} which are not nentioned in ${EGO_VENDOR}
112 # to their usual locations then extract all archives mentioned in
113 # ${EGO_VENDOR} to ${S}/vendor.
114 go-module_src_unpack() {
115         debug-print-function ${FUNCNAME} "$@"
116         local f hash import line repo tarball vendor_tarballs x
117         vendor_tarballs=()
118         for line in "${EGO_VENDOR[@]}"; do
119                 read -r import hash repo x <<< "${line}"
120                 if [[ -n $x ]]; then
121                         eerror "Trailing information in EGO_VENDOR in ${P}.ebuild"
122                         eerror "${line}"
123                         die "Invalid EGO_VENDOR format"
124                 fi
125                 : "${repo:=${import}}"
126                 vendor_tarballs+=("${repo//\//-}-${hash}.tar.gz")
127         done
128         for f in $A; do
129                 [[ -n ${vendor_tarballs[*]} ]] && has "$f" "${vendor_tarballs[@]}" &&
130                         continue
131                 unpack "$f"
132         done
133
134         [[ -z ${vendor_tarballs[*]} ]] && return
135         for line in "${EGO_VENDOR[@]}"; do
136                 read -r import hash repo _ <<< "${line}"
137                 : "${repo:=${import}}"
138                 tarball=${repo//\//-}-${hash}.tar.gz
139                 ebegin "Vendoring ${import} ${tarball}"
140                 rm -fr "${S}/vendor/${import}" || die
141                 mkdir -p "${S}/vendor/${import}" || die
142                 tar -C "${S}/vendor/${import}" -x --strip-components 1 \
143                         -f "${DISTDIR}/${tarball}" || die
144                 eend
145         done
146 }
147
148 # @FUNCTION: go-module_live_vendor
149 # @DESCRIPTION:
150 # This function is used in live ebuilds to vendor the dependencies when
151 # upstream doesn't vendor them.
152 go-module_live_vendor() {
153         debug-print-function ${FUNCNAME} "$@"
154
155         has live ${PROPERTIES} ||
156                 die "${FUNCNAME} only allowed in live ebuilds"
157         [[ "${EBUILD_PHASE}" == unpack ]] ||
158                 die "${FUNCNAME} only allowed in src_unpack"
159         [[ -d "${S}"/vendor ]] ||
160                 die "${FUNCNAME} only allowed when upstream isn't vendoring"
161
162         pushd "${S}" >& /dev/null || die
163         go mod vendor || die
164         popd >& /dev/null || die
165 }
166
167 # @FUNCTION: go-module_pkg_postinst
168 # @DESCRIPTION:
169 # Display a warning about security updates for Go programs.
170 go-module_pkg_postinst() {
171         debug-print-function ${FUNCNAME} "$@"
172         [[ -n ${REPLACING_VERSIONS} ]] && return 0
173         ewarn "${PN} is written in the Go programming language."
174         ewarn "Since this language is statically linked, security"
175         ewarn "updates will be handled in individual packages and will be"
176         ewarn "difficult for us to track as a distribution."
177         ewarn "For this reason, please update any go packages asap when new"
178         ewarn "versions enter the tree or go stable if you are running the"
179         ewarn "stable tree."
180 }
181
182 fi