1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
---
GLEP: 55
Title: Use EAPI-suffixed ebuilds (.ebuild-EAPI)
Author: Piotr Jaroszyński <peper@gentoo.org>
Type: Standards Track
Status: Rejected
Version: 1
Created: 2007-12-17
Last-Modified: 2014-01-23
Post-History: 2007-12-17, 2007-12-22, 2009-05-17
Content-Type: text/x-rst
---
"A little learning is a dangerous thing; drink deep, or taste not the Pierian
spring: there shallow draughts intoxicate the brain, and drinking largely
sobers us again."
-- Alexander Pope, An Essay on Criticism
Status
======
This GLEP was voted down by the Council in its meeting on 2010-08-23.
The Council rejected it again in its meeting on 2012-05-08, in favour
of parsing the EAPI from the bash assignment statement in ebuilds.
Abstract
========
This GLEP proposes usage of EAPI-suffixed file extensions for ebuilds (for
example, foo-1.2.3.ebuild-1).
Problem
=======
The current way of specifying the EAPI in ebuilds is flawed. In order to get the
EAPI the package manager needs to source the ebuild, which itself needs the EAPI
in the first place. Otherwise it imposes a serious limitation, namely every ebuild,
using any of the future EAPIs, will have to be sourceable by old package
managers and hence there is no way to do any of the following:
* Change the behaviour of inherit in any way (for example, to extend or change
eclass functionality).
* Add new global scope functions in any sane way.
* Extend versioning rules in an EAPI - for example, addition of the scm
suffix - GLEP54 [#GLEP54]_ or allowing more sensible version formats like
``1-rc1``, ``1-alpha`` etc. to match upstream more closely.
* Use newer bash features.
Current behaviour
=================
Following subsections show what happens if you introduce any of the mentioned
changes in an ebuild and try to install it with portage 2.1.6.13.
Incompatible change of inherit (e.g. make it look in the package dir too)
-------------------------------------------------------------------------
``sys-apps/foo-1.ebuild``::
EAPI="5"
inherit "foo"
DESCRIPTION=""
HOMEPAGE=""
SRC_URI=""
...
Result::
*
* ERROR: sys-apps/foo-1 failed.
* Call stack:
* ebuild.sh, line 1879: Called _source_ebuild
* ebuild.sh, line 1818: Called source '/var/lib/gentoo/repositories/peper/sys-apps/foo/foo-1.ebuild'
* foo-1.ebuild, line 6: Called inherit 'foo'
* ebuild.sh, line 1218: Called die
* The specific snippet of code:
* [ ! -e "$location" ] && die "${1}.eclass could not be found by inherit()"
* The die message:
* foo.eclass could not be found by inherit()
*
* If you need support, post the topmost build error, and the call stack if relevant.
* This ebuild is from an overlay: '/var/lib/gentoo/repositories/peper/'
*
!!! All ebuilds that could satisfy "sys-apps/foo" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/foo-1 (masked by: corruption)
Current portage looks for eclasses only in the ``eclass`` directory of a
repository. This results in a fatal error and ebuild being masked by corruption
- might be pretty confusing to users.
New global scope function
-------------------------
``sys-apps/foo-1.ebuild``::
EAPI="5"
new_global_scope_function "foo"
DESCRIPTION=""
HOMEPAGE=""
SRC_URI=""
...
Result::
/var/lib/gentoo/repositories/peper/sys-apps/foo/foo-1.ebuild: line 7: new_global_scope_function: command not found
!!! All ebuilds that could satisfy "sys-apps/foo" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/foo-1 (masked by: EAPI 5)
The current version of portage supports EAPI '2'. You must upgrade to a
newer version of portage before EAPI masked packages can be installed.
Not that bad as user is advised to upgrade portage.
New version format
------------------
``sys-apps/foo-2-rc1.ebuild``::
Invalid ebuild name: /var/lib/gentoo/repositories/peper/sys-apps/foo/foo-2-rc1.ebuild
emerge: there are no ebuilds to satisfy "sys-apps/foo"
Not the best error message, especially if there are lots of them.
Use newer bash features
-----------------------
``|&`` is a new type of redirection added in bash-4. It cannot be used even in
local scope as bash still parses the whole ebuild.
``sys-apps/foo-1.ebuild``::
EAPI="5"
foo() {
echo "foo" |& cat
}
Result::
/var/lib/gentoo/repositories/peper/sys-apps/foo/foo-1.ebuild: line 8: syntax error near unexpected token `&'
/var/lib/gentoo/repositories/peper/sys-apps/foo/foo-1.ebuild: line 8: ` echo "foo" |& cat'
*
* ERROR: sys-apps/foo-1 failed.
* Call stack:
* ebuild.sh, line 1879: Called _source_ebuild
* ebuild.sh, line 1818: Called die
* The specific snippet of code:
* source "${EBUILD}" || die "error sourcing ebuild"
* The die message:
* error sourcing ebuild
*
* If you need support, post the topmost build error, and the call stack if relevant.
* This ebuild is from an overlay: '/var/lib/gentoo/repositories/peper/'
* ... done!
!!! All ebuilds that could satisfy "sys-apps/foo" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/foo-1 (masked by: corruption)
Again, not the best error.
Abstract solution
=================
A solution to this problem has to lift those limitations and the only way to do
it is to make the EAPI of an ebuild available to the package managers in a way
that doesn't require them to source the ebuild. Another important requirement is
for the solution to be backward compatible, which has the pleasant side-effect
of making the solution applicable in the Gentoo tree right away. Opposed to
waiting an arbitrary amount of time, which is never long enough anyway, as the
issues listed on the common portage problems page - [#PortageProblems]_ - show.
Proposed solution
=================
The proposed solution is to use EAPI-suffixed file extensions for ebuilds. This
allows package managers to trivially read the EAPI from the ebuild filename. It
is also backwards compatible, because currently ebuilds are recognised by the
``.ebuild`` file extension and hence EAPI-suffixed ebuilds are simply ignored by
the package managers.
Specification
=============
Ebuild filename extension syntax: ``ebuild[-<EAPI>]``, where ``[]`` denotes an
optional part, and ``<EAPI>`` is the EAPI of the ebuild.
The EAPI used by the ebuild is the EAPI included in the filename if it is set.
Otherwise the EAPI set inside the ebuild is used, which defaults to 0 (this is
the current behaviour).
Ebuilds with unsupported EAPIs are masked.
It should be considered an error to set the EAPI both in the filename and in the
ebuild.
Examples:
* ``pkg-1.ebuild``, no EAPI set inside the ebuild
EAPI defaults to 0.
* ``pkg-2.ebuild-1``, no EAPI set inside the ebuild
EAPI 1 is used.
* ``pkg-3.ebuild-1``, ``EAPI="1"``
EAPI set in both places - error.
Note that it is still not permitted to have more than one ebuild with equal
category, package name, and version. Although it would have the advantage of
allowing authors to provide backwards compatible ebuilds, it would introduce
problems too. The first is the requirement to have strict EAPI ordering, the
second is ensuring that all the ebuilds for a single category/package-version
are equivalent, i.e. installing any of them has exactly the same effect on a
given system.
Also note that it is not a new restriction. It is already possible to illegally
have multiple versions with different EAPIs as e.g. ``1.0 == 1.00 == 1.00-r0``
and hence you could have ``foo-1.0.ebuild`` with EAPI X and ``foo-1.00.ebuild``
with EAPI Y.
Summary of ideas
================
EAPI-suffixed ebuilds (proposed solution)
-----------------------------------------
Properties:
* Can be used right away: yes
* Hurts performance: no
Some say it is clear and simple, others that it is ugly and unintuitive.
EAPI in the filename with one-time extension change
---------------------------------------------------
One of the proposed filename formats:
``<PKG>-<VER>.eapi-<EAPI>.eb``
Properties:
* Can be used right away: yes
* Hurts performance: no
This is equivalent to the proposed solution.
Some say it is better because the extension is static.
Easily fetchable EAPI inside the ebuild
---------------------------------------
Properties:
* Can be used right away: no
* Hurts performance: yes
Cannot be used right away as it would trigger the errors shown in Current
behaviour section for old package managers.
Performance decrease comes from the fact that with version format changes in the
picture package managers need EAPI to parse the ebuild's version. That means that merely
picking the best version of a package requires loading EAPI (from cache or the
ebuild) for each available ebuild.
Here is more or less how the package manager figures out the best available
version for a package with N versions available.
* EAPI in the filename
* Read the directory containing the package - readdir()
* For each ebuild, read its EAPI and using that parse its version - no I/O
* Sort the versions - no I/O
* Going down from the highest to the lowest version
* Get the metadata from cache - 2 x stat() + read()
* break if the version is visible
* EAPI in the ebuild
* Read the directory containing the package - readdir()
* For each ebuild load its metadata from cache to get its EAPI - N x (2 x stat() + read())
* Sort the versions - no I/O
* Going down from the highest to the lowest version
* (metadata is already loaded) - no I/O
* break if the version is visible - no I/O
The difference is in for how many versions the package manager needs to hit
cache. With EAPI in the ebuild it needs to do that for all versions, with EAPI
in the filename it depends on versions visibility.
For example, package foo has versions 1, 2, 3, 4, 5 and 6. 6 is masked, 5 is
~arch and 1,2,3 and 4 are arch. Say, the user accepts only arch for this
package. With EAPI in the filename it will read metadata only for versions
6, 5 and 4. With EAPI in the ebuild it needs to load metadata for all versions.
It's hard to say what's the average case, but surely the worst case scenario
(when only the lowest version is visible) is uncommon.
Easily fetchable EAPI inside the ebuild and one-time extension change
---------------------------------------------------------------------
Properties:
* Can be used right away: yes
* Hurts performance: yes
Performance decrease as described in the previous section.
Some say it is clear and simple, others that it is confusing and unintuitive,
because of the arbitrary format restrictions in what is a bash script otherwise.
Use different subdirectories for different EAPIs, i.e. cat/pkg/eapiX/
---------------------------------------------------------------------
Properties:
* Can be used right away: yes
* Hurts performance: yes
Performance decrease comes from the fact that it adds several more directory
reads.
Some say that it makes it much harder for maintainers to see what they have.
References
==========
.. [#GLEP54] GLEP 54, scm package version suffix
(https://www.gentoo.org/glep/glep-0054.html)
.. [#PortageProblems] Common portage problems
(https://wiki.gentoo.org/wiki/Project:Portage/Common_problems)
Copyright
=========
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
Unported License. To view a copy of this license, visit
https://creativecommons.org/licenses/by-sa/3.0/.
.. vim: set tw=80 fileencoding=utf-8 spell spelllang=en et :
|