Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: William Hubbs <williamh@g.o>
Subject: Re: [gentoo-dev] [PATCH 1/1] go-module.eclass: new eclass for go modules
Date: Wed, 25 Sep 2019 20:02:43
Message-Id: 0cc7941079ba4ec9149f2a76b0a1bfd20649304e.camel@gentoo.org
In Reply to: [gentoo-dev] [PATCH 1/1] go-module.eclass: new eclass for go modules by William Hubbs
1 On Tue, 2019-09-24 at 13:08 -0500, William Hubbs wrote:
2 > This eclass includes the basic settings and src_unpack/pkg_postinst
3 > functions for Go modules.
4 >
5 > Signed-off-by: William Hubbs <williamh@g.o>
6 > ---
7 > eclass/go-module.eclass | 164 ++++++++++++++++++++++++++++++++++++++++
8 > 1 file changed, 164 insertions(+)
9 > create mode 100644 eclass/go-module.eclass
10 >
11 > diff --git a/eclass/go-module.eclass b/eclass/go-module.eclass
12 > new file mode 100644
13 > index 00000000000..fcfa5ba643c
14 > --- /dev/null
15 > +++ b/eclass/go-module.eclass
16 > @@ -0,0 +1,164 @@
17 > +# Copyright 2019 gentoo authors
18
19 Sentence case here.
20
21 > +# Distributed under the terms of the GNU General Public License v2
22 > +
23 > +# @ECLASS: go-module.eclass
24 > +# @MAINTAINER:
25 > +# William Hubbs <williamh@g.o>
26 > +# @SUPPORTED_EAPIS: 7
27 > +# @BLURB: basic eclass for building software written in the go
28 > +# programming language that uses go modules.
29
30 @BLURB must be one line.
31
32 > +# @DESCRIPTION:
33 > +# This eclass provides basic settings and functions
34 > +# needed by all software written in the go programming language that uses
35 > +# go modules.
36 > +#
37 > +# You will know the software you are packaging uses modules because
38 > +# it will have files named go.sum and go.mod in its top-level source
39 > +# directory. If it does not have these files, use the golang-* eclasses.
40
41 Hmm, don't we want to eventually have one eclass that fits all packages?
42 I mean, if you can automatically determine whether modules are present
43 via go.mod file, can't you just make one eclass that determines that
44 and passes correct flags for both cases?
45
46 > +#
47 > +# If it has these files and a directory named vendor in its top-level
48 > +# source directory, you only need to inherit the eclass since upstream
49 > +# is vendoring the dependencies.
50 > +#
51 > +# If it does not have a vendor directory, you should use the EGO_VENDOR
52 > +# variable and the go-module_vendor_uris function as shown in the
53 > +# example below to handle dependencies.
54 > +#
55 > +# Since Go programs are statically linked, it is important that your ebuild's
56 > +# LICENSE= setting includes the licenses of all statically linked
57 > +# dependencies. So please make sure it is accurate.
58 > +#
59 > +# @EXAMPLE:
60 > +#
61 > +# @CODE
62 > +#
63 > +# inherit go-module
64 > +#
65 > +# EGO_VENDOR=(
66 > +# "github.com/xenolf/lego 6cac0ea7d8b28c889f709ec7fa92e92b82f490dd"
67 > +# "golang.org/x/crypto 453249f01cfeb54c3d549ddb75ff152ca243f9d8 github.com/golang/crypto"
68 > +# )
69 > +#
70 > +# SRC_URI="https://github.com/example/${PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz
71 > +# $(go-module_vendor_uris)"
72 > +#
73 > +# @CODE
74 > +
75 > +case ${EAPI:-0} in
76 > + 7) ;;
77 > + *) die "${ECLASS} API in EAPI ${EAPI} not yet established."
78 > +esac
79 > +
80 > +if [[ -z ${_GO_MODULE} ]]; then
81 > +
82 > +_GO_MODULE_=1
83 > +
84 > +BDEPEND=">=dev-lang/go-1.12"
85 > +
86 > +# Force go to build in module mode.
87 > +# In this mode the GOPATH environment variable is ignored.
88 > +# this will become the default in the future.
89 > +export GO111MODULE=on
90 > +
91 > +# The following go flags should be used for all builds.
92 > +# -mod=vendor stopps downloading of dependencies from the internet.
93 > +# -v prints the names of packages as they are compiled
94 > +# -x prints commands as they are executed
95 > +export GOFLAGS="-mod=vendor -v -x"
96 > +
97 > +# Do not complain about CFLAGS etc since go projects do not use them.
98 > +QA_FLAGS_IGNORED='.*'
99 > +
100 > +# Go packages should not be stripped with strip(1).
101 > +RESTRICT="strip"
102 > +
103 > +EXPORT_FUNCTIONS src_unpack pkg_postinst
104 > +
105 > +# @ECLASS-VARIABLE: EGO_VENDOR
106 > +# @DESCRIPTION:
107 > +# This variable contains a list of vendored packages.
108 > +# The items of this array are strings that contain the
109 > +# import path and the git commit hash for a vendored package.
110 > +# If the import path does not start with github.com, the third argument
111 > +# can be used to point to a github repository.
112 > +
113 > +# @FUNCTION: go-module_vendor_uris
114 > +# @DESCRIPTION:
115 > +# Convert the information in EGO_VENDOR to a format suitable for
116 > +# SRC_URI.
117 > +# A call to this function should be added to SRC_URI in your ebuild if
118 > +# the upstream package does not vendor dependencies.
119
120 I would go for 'does not include vendored dependencies'. If you fetch
121 them for the package, I'd still call it vendoring.
122
123 > +go-module_vendor_uris() {
124 > + local hash import line repo
125
126 You want to make '_' local as well.
127
128 > + for line in "${EGO_VENDOR[@]}"; do
129 > + read -r import hash repo _ <<< "${line}"
130
131 Don't you want to error out on extraneous args (i.e. when '_' is non-
132 empty)?
133
134 > + if [[ -n ${repo} ]]; then
135
136 I told you already that you can simplify this by doing:
137
138 : "${repo:=${import}}"
139
140 and then always using the first echo.
141
142 > + echo "https://${repo}/archive/${hash}.tar.gz -> ${repo//\//-}-${hash}.tar.gz"
143 > + else
144 > + echo "https://${import}/archive/${hash}.tar.gz -> ${import//\//-}-${hash}.tar.gz"
145 > + fi
146 > + done
147 > +}
148 > +
149 > +# @FUNCTION: go-module_src_unpack
150 > +# @DESCRIPTION:
151 > +# Extract all archives in ${a} which are not nentioned in ${EGO_VENDOR}
152 > +# to their usual locations then extract all archives mentioned in
153 > +# ${EGO_VENDOR} to ${S}/vendor.
154 > +go-module_src_unpack() {
155 > + debug-print-function ${FUNCNAME} "$@"
156 > + local f hash import line repo tarball vendor_uri
157
158 Same, you're not making '_' local.
159
160 > + vendor_uri="$(go-module_vendor_uris)"
161 > + for f in $A; do
162 > + [[ $vendor_uri == *"$f"* ]] && continue
163
164 That's a cheap, ugly hack that's going to randomly fail if $f occurs
165 somewhere in the URI. Even if that's unlikely to happen, it's not how
166 you're supposed to do things.
167
168 You should really get all filenames here, and compare them separately.
169 You can use has() to search a list for a matching filename. But you
170 need to get a proper filename list first, either by processing
171 EGO_VENDOR again or searching through generated SRC_URI properly (taking
172 just filenames, skipping URIs and arrows). The former will probably be
173 more readable.
174
175 > + unpack $f
176 > + done
177 > +
178 > + for line in "${EGO_VENDOR[@]}"; do
179 > + read -r import hash repo _ <<< "${line}"
180
181 Same, check for non-empty '_'.
182
183 > + if [[ -n ${repo} ]]; then
184 > + tarball=${repo//\//-}-${hash}.tar.gz
185
186 Same, you can simplify it to one branch. Also, I suppose if you move
187 this part earlier, you can get the list of tarballs you need for $A
188 filtering.
189
190 > + else
191 > + tarball=${import//\//-}-${hash}.tar.gz
192 > + fi
193 > + einfo "Vendoring ${import} ${tarball}"
194
195 ebegin/eend maybe?
196
197 > + rm -fr "${S}/vendor/${import}" || die
198 > + mkdir -p "${S}/vendor/${import}" || die
199 > + tar -C "${S}/vendor/${import}" -x --strip-components 1\
200
201 As I've pointed out in earlier iteration of your eclasses, you're
202 missing space before backslash.
203
204 > + -f "${DISTDIR}/${tarball}" || die
205 > + done
206 > +}
207 > +
208 > +# @FUNCTION: go-module_live_vendor
209 > +# @DESCRIPTION:
210 > +# This function is used in live ebuilds to vendor the dependencies when
211 > +# upstream doesn't vendor them.
212 > +go-module_live_vendor() {
213 > + debug-print-function ${FUNCNAME} "$@"
214 > +
215 > + [[ "${PV}" == *9999* ]] ||
216 > + die "${FUNCNAME} only allowed in live/9999 ebuilds"
217
218 We use PROPERTIES=live these days.
219
220 > + [[ "${EBUILD_PHASE}" == unpack ]] ||
221 > + die "${FUNCNAME} only allowed in src_unpack"
222 > + [[ -d "${S}"/vendor ]] ||
223 > + die "${FUNCNAME} only allowed when upstream isn't vendoring"
224 > +
225 > + cd "${S}" || die
226
227 Isn't it potentially confusing that calling this function in src_unpack
228 silently changes working directory? pushd/popd may be preferable.
229
230 > + go mod vendor || die
231 > +}
232 > +
233 > +# @FUNCTION: go-module_pkg_postinst
234 > +# @DESCRIPTION:
235 > +# Display a warning about security updates for Go programs.
236 > +go-module_pkg_postinst() {
237 > + debug-print-function ${FUNCNAME} "$@"
238 > + ewarn "${PN} is written in the Go programming language."
239 > + ewarn "Since this language is statically linked, security"
240 > + ewarn "updates will be handled in individual packages and will be"
241 > + ewarn "difficult for us to track as a distribution."
242 > + ewarn "For this reason, please update any go packages asap when new"
243 > + ewarn "versions enter the tree or go stable if you are running the"
244 > + ewarn "stable tree."
245
246 This message really sounds like those packages should never become
247 stable.
248
249 > +}
250 > +
251 > +fi
252
253 --
254 Best regards,
255 Michał Górny

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies