Hokay, this is pretty much my response to the string vs int stuff, slammed into one email.
First clarifying the assumption I'm after a max test for eapi testing;
not the case- stated so already in this thread.
Restating it again, for stable, a check of if it's > 0 (with int
conversion failures being knocked up to 1 fex) is effectively the same
thing as if str(portage_const.EAPI) in ("", "0"). Stated also that
for rewrite, this approach won't work, and you're stuck specifying
either a range of supported EAPI (max *and* min), or specifying every
single individual eapi identifier, which I'll clarify before is going
to burn any maintainer of such code.
On Wed, Aug 31, 2005 at 12:52:53PM +0200, Marius Mauch wrote:
> On 08/30/05 Brian Harring wrote:
>
> > Why am I being so damned stubborn about numbers for this? Cause I
> > don't want users having to dink around with knowing that eapi="really
> > cool version" somehow maps out to 3.1. Further, eapi version *likely*
> > will wind up as the slotting for any split out portage-ebuild package,
> > and slots traditionally have always been ints.
>
> Thanks for that last comment, it actually prooves our point ;)
> Yes, SLOTs are *generally* numeric strings, as they are generally tied
> to major versions. But as soon as more than the major part of the
> version is important ints don't work anymore (and never ever mention
> float again, version numbers aren't floats), and in some cases you find
> non-version data in SLOT (like $CTARGET).
Summation of string based failings.
First off, a modifier of an EAPI, say EAPI=3-strict isn't valid; why?
strict is most likely a restriction, a specific negation of some
aspect of eapi3.
Restrict is the place for it, or a similar metadata key. Yes this
doesn't hold across all cases (someone could've just decided 3-strict
was a cool name fex), but throwing it out there to point out that eapi
is ebuild templates, not restrictions.
Further, any deviation where loss of backwards compatibility would
occur (limiting or extending bash syntax) is implicitly another
format, thus beyond eapi's keen. EAPI is ebuild (the format) spec/api
*only*, see comments below re: format support for further explanation.
Re: tagging EAPI at the top of a file, infra would probably shoot me
for doing such- till a live, fully compatible and *roughly* equivalent
parser is available, portage would have to do a bit of grepping,
jacking up the regen times.
One thing I'm going to clarify also, is that the rewrite *does not*
make it hard to tag new formats in. There's no reason to jam
everything into ebuilds, especially considering we are bound by
existing definitions, and a body of 20,000 live ebuilds users/devs
would get rather pissed off about if we forced a change across it.
If it's not an adjustment, a tweak, an extension/subtraction of ebuild
functionality, eapi isn't applicable imo, and a seperate format is the
route to go (one that could easily live alongside in the tree).
EAPI is just for ebuild format. alt formats (whether sh based or
otherwise) would be wise to version their version also.
Either way, getting to the point of why strings suck badly in the
point where it matters- as format version identifiers for the code
that does the actual work.
Example code for numeric, say we have eapi 0-5 at this point.
def configure(self):
if self.pkg.eapi > 0:
...call configure phase...
return
example code for strings
def configure(self):
if self.pkg.eapi in ("0", "1", "2", "3", "4", "5"):
...call configure phase...
return
This sucks.
the response is "well, stick it into a list somewhere". Can do, but
you have to mangle each list everytime you add a new eapi. That's a
good way to lead to dumb ass bugs when tinkering with a new eapi
level.
or... capabilities, as suggested.
capabilities = {"0":["configure"],
"1":["configure"],
"2":["configure"],
"3":["configure"],
"4":["configure"],
"5":["configure"],}
def has_capability(eapi, capability):
try: return capability in capabilities[eapi]:
except KeyError: return False
def configure(self):
if has_capability(self.pkg.eapi, "configure"):
...call configure phase...
return
or (slightly nastier example)
# eapi5 being eapi4, just with bash side changes. implicit is that
# their is bash side changes between each eapi, just stating it
# explicitly to avoid the 'wtf'
capabilities = {"0":["configure"],
"1":["configure", "test_src_uri"],
"2":["configure", "test_src_uri"],
"3":["configure", "test_src_uri", "full_depriving"],
"4":["configure", "test_src_uri", "full_depriving",
"user_management"],
"5":["configure", "test_src_uri", "full_depriving",
"user_management"],}
def configure(self):
if "configure" in capabilities.get(eapi, []):
...call configure phase...
return
Suggestions regarding using enumerations still dodge that point that
via strings, you're building a finite set of matching strings to
execute a block of code under, rather then establishing a min/max
during which an int eapi should execute a block of code. Latter's a
helluva lot simpler then the former.
The arguement here is that it's somehow cleaner; it's not really. You
still have magic strings ("configure"), and a massive table of
capabilities. I used a single capability; if you're doing
"has_capability" for every logic check, you're going to get into some
very ugly terrain of magic const's all over the place.
Further, if attempting to map out what has changed between each eapi
version, it's the wrong place to do so; that's implementation right
there, specifically python side knowledge of how to support that
version.
Proper design would actually use a magic constant at the top of the
file, CONFIGURE_REQUIRED = 1 or something of the sort.
If I want to work on the next extension of eapi, I create an ebuild
that has the new incremented #, and I can *already* have that eapi up
and running, usurping the previous eapi definition. No forced
manual redefinition of stuff that is an easy way to induce bugs
(increased manual work == bugs). I can start extending the previous
definition, tweaking it to I want without having to gut half of the
controlling code.
Yes, I'm talking about it from the code perspective, but remember that
this is the area that ultimately *matters*; control of the ebuild env
is via the python side of things. Keeping that as bug free, and clean
as possible is what matters from where I sit; we can extend the ebuild
env/template without issue, but swiveling from template to template is
totally controlled by python side portage, which means that bit of
code best be clean and robust.
That said, if you dig through my earlier patch, and comments about
needing to handle int conversion better rather then flattening it to
0, the code *is* forwards compatible if someone decides to stick strings
into EAPI. In other words, it's a moot debate due to the fact that
the internal representation of eapi (is it a string, or is it an int?)
is specific to that portage version; whatever version supports an eapi
with strings tagged into has the fun of addressing the issues I've
brought up above.
So basically the debate over string vs int can be left to when someone
tries to add a non int eapi; forewarning: I'll bring up these points
again when it's raised. It's a Bad Idea (tm), and there is a damn
good reason you don't see it elsewhere when dealing with versions of
something :)
Final comment on this; there's a reason pkgs are release with
major/minor as numeric; detection of capabilities, handling
capabilities is *much* cleaner via such an approach.
~harring
pgpBnPZplMyYf.pgp
Description: PGP signature
