Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 465772 - [Future EAPI] Make all directory variables *not* end with a trailing slash
Summary: [Future EAPI] Make all directory variables *not* end with a trailing slash
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: PMS/EAPI (show other bugs)
Hardware: All Linux
: Normal major
Assignee: Package Manager Specification
URL: http://thread.gmane.org/gmane.linux.g...
Whiteboard: in-eapi-7
Keywords:
: 174408 (view as bug list)
Depends on:
Blocks: future-eapi
  Show dependency tree
 
Reported: 2013-04-13 12:25 UTC by Michał Górny
Modified: 2018-04-30 22:46 UTC (History)
11 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
PMS patch: drop the trailing slash guarantee (0001-Do-not-guarantee-trailing-slash-in-path-variables.patch,2.39 KB, patch)
2013-04-27 16:07 UTC, Michał Górny
Details | Diff
repoman: check for [[ $ROOT == / and similar (0001-repoman-check-for-ROOT-tests.patch,1.21 KB, patch)
2013-04-27 21:19 UTC, Michał Górny
Details | Diff
repoman: check for ${D}[a-z] and ${ROOT}[a-z] (0002-repoman-check-for-D-foo-and-ROOT-foo-paths.patch,1.28 KB, patch)
2013-04-27 21:19 UTC, Michał Górny
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-13 12:25:40 UTC
Shortly saying, this is close to insane and even PMS itself gets it wrong. We should do the hard work, fix all the ebuilds which were adjusted to this irrational requirement and then lift it.

1) "${D}usr/bin/foo" is just ridiculous. "${D}"/usr/bin/foo is far more popular in the tree and some people fix the double-slash problem by using "${D%/}"/usr/bin/foo when they notice it.

2) emake install DESTDIR="${D%/}" is even more ridiculous. And some ebuilds even do that. Others and the default phase functions defined by PMS just pass the unexpectedly-slash-ended path which has caused trouble in the past.

3) and then we actually have "${D}${foo#/}". Since ${foo}, like any reasonable variable containing path starts with a slash. Hey, even all '*into' functions take paths starting with a slash. So we end up either having to strip the slashes or use two variables for the same path. One sane, and one for the insane ${D} declaration.

Looking at the historical context, the change was made retroactively to match a few ebuilds. I won't comment on that since you yourself can see how much trouble this behavior causes, and how much of the tree is semi-broken.

A few people actually use ${D} correctly or even fix ebuilds to do that. But if the wall is sloping, should we bend the furniture to match it?
Comment 1 Ciaran McCreesh 2013-04-13 12:35:41 UTC
Multiple slashes in a path are valid in Unix. Missing slashes aren't.
Comment 2 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-13 12:40:39 UTC
(In reply to comment #1)
> Multiple slashes in a path are valid in Unix. Missing slashes aren't.

That's why I'm suggesting fixing it to a sane state.
Comment 3 Greg Turner 2013-04-14 08:10:05 UTC
(In reply to comment #1)
> Multiple slashes in a path are valid in Unix. Missing slashes aren't.

Valid, perhaps, depending on what follows the multiple slashes, and where and how many multiple slashes you have.  But not equivalent.  At least, not always.  There is one major exception and it is not a theoretical problem: two slashes at the beginning of a path have an implementation-defined meaning.

Don't believe me?  Ask the Open Group:  The following is from POSIX 1-2008[4.12]:

"A pathname consisting of a single <slash> shall resolve to the root directory of the process. A null pathname shall not be successfully resolved. A pathname that begins with two successive <slash> characters may be interpreted in an implementation-defined manner, although more than two leading <slash> characters shall be treated as a single <slash> character."

Gentoo is infuriatingly cavalier about this.  I can barely file bugs fast enough to keep up with the steady stream of new abuses, the plurality of which appear as a sole consequence of ${D}'s trailing slash.

Not that I blame people for forgetting that ${D} has a slash at the end, nor, by extension, for appending another slash to it -- I'd do that myself, if it didn't break my pet platform at every turn (of course ${D}/foo doesn't break anything  until additional path-processing arithmetic is applied -- but, trust me, this is happening ubiquitously.  In a default '@system' emptytree package set, I'd guess about 1/3 of the ebuilds suffer from some kind of //foo path reference.  And many more -- perhaps all -- wind up using ${D}/foo , without managing to trigger //foo references.

That stated, solving this is pretty hard.  Personally, I'd love a QAwarn on ${D}/foo paths flowing through helper functions and //*foo symlink targets pre-merge, ideally with automagical fixing where convenient.  But, I'm pessimistic about actually getting such patches accepted, since, basically, nobody seems to give a shit.  Many seem almost to take pride in their ability to jam their path strings so full of superfluous slashes that they start to resemble some kind of obscure ascii-art.
Comment 4 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 08:22:14 UTC
(In reply to comment #3)
> Gentoo is infuriatingly cavalier about this.  I can barely file bugs fast
> enough to keep up with the steady stream of new abuses, the plurality of
> which appear as a sole consequence of ${D}'s trailing slash.
> 
> Not that I blame people for forgetting that ${D} has a slash at the end,
> nor, by extension, for appending another slash to it -- I'd do that myself,
> if it didn't break my pet platform at every turn (of course ${D}/foo doesn't
> break anything  until additional path-processing arithmetic is applied --
> but, trust me, this is happening ubiquitously.

Would you mind if we decided to fix this once and for all by removing the trailing slash? The breakage would reach its peak in the interim period, however, when every package will have to be 'unfixed' to assume ${D} not to contain trailing slash.

Alternatively, we could just go for ${D%/} in all 'correct' packages for now. That wouldn't increase the breakage but I don't know if that actually helps you.
Comment 5 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 11:26:36 UTC
Some stats grepping the tree for *.ebuild, *.eclass and the *.eblit awful thing.

[note: packages = matching two first path components, e.g. real packages or eclasses]

${D}usr, ${D}$(get_libdir), ${D}bin, ${D}sbin with ${D} being quoted and unquoted: round 94 packages (+ 1 in sunrise overlay).

${D}/ and "${D}"/: 1734 packages (not counting overlays) + skel.ebuild.

${D%/}: 18 packages.

DESTDIR="${D}": 3099 packages (vs 4 using "${D%/}").

${D}${ and ${ED}${: 211 packages (most of them suffer the double slash issue).

Those are really quick and dirty but I think they gave a semi-accurate measure of the scale. Does anyone want to discuss that?
Comment 6 Ciaran McCreesh 2013-04-14 11:49:13 UTC
Looks like an awful lot of work, if you want to change it... If all this is doing is breaking one obscure unsupported arch, I suggest we leave it...
Comment 7 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 12:17:30 UTC
(In reply to comment #6)
> Looks like an awful lot of work, if you want to change it... If all this is
> doing is breaking one obscure unsupported arch, I suggest we leave it...

Awful lot? Round 200 ebuilds, I think. It would be awfully hard to find other 'correct' uses of ${D} to fix though.

I am ready to do the hard work but I'd like to get all the agreement and some blessing first. Potentially also remove the D requirement from PMS and leave it unspecified for now.
Comment 8 Ciaran McCreesh 2013-04-14 12:51:48 UTC
Well, it's 200 that you know about... Can you come up with some clever way of detecting this accurately?
Comment 9 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 13:19:29 UTC
(In reply to comment #8)
> Well, it's 200 that you know about... Can you come up with some clever way
> of detecting this accurately?

It's less that I know about, I've assumed a bit of unknown too. Well, I think I'll find some other potential uses while fixing the known ones. Then a tinderbox run would be helpful, or a live test with p.masked portage version.
Comment 10 Greg Turner 2013-04-14 13:56:00 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > Gentoo is infuriatingly cavalier about this.  I can barely file bugs fast
> > enough to keep up with the steady stream of new abuses, the plurality of
> > which appear as a sole consequence of ${D}'s trailing slash.
> > 
> > Not that I blame people for forgetting that ${D} has a slash at the end,
> > nor, by extension, for appending another slash to it -- I'd do that myself,
> > if it didn't break my pet platform at every turn (of course ${D}/foo doesn't
> > break anything  until additional path-processing arithmetic is applied --
> > but, trust me, this is happening ubiquitously.
> 
> Would you mind if we decided to fix this once and for all by removing the
> trailing slash?

Lord, no, it'd be a dream come true!  That is to say, once we "get there."  But I think the concerns folks have raised about effort-to-fix vs. net benefit to actual real-world creatures seem legitimate.

Also, I have my doubts as to whether Zac would swing for it, given that it entails backward-incompatible behavior in portage.  But, obviously, I should let Zac speak for himself; anyhow I don't know the full reasoning behind his aversion to backward-incompatible EAPI changes, I have always simply presumed on faith that there is a good one.

> The breakage would reach its peak in the interim period,
> however, when every package will have to be 'unfixed' to assume ${D} not to
> contain trailing slash.
> 
> Alternatively, we could just go for ${D%/} in all 'correct' packages for
> now. That wouldn't increase the breakage but I don't know if that actually
> helps you.

What about the possibility of deprecating D and encouraging ebuilds and other portage-y scripts to migrate to a new variable, say, "I"?  This way we could slowly get out of the ${D%/} business without a painful inflection point and associated mind-numbing tasks of mentally dry-running bazillions of lines of bash script, not to mention rooting it out of non-ebuild places, overlays, and so forth.

I guess it's a bit extreme to dirty up a time-honored one-letter variable, but it provides a way out of the situation without any backward incompatibility issue and without any frustrating day-of-reckoning.

A huge majority of incorrect usages, i.e., anything matching the (untested extended) regex:
  
  ("?)\$\{E?D\}\1\/(usr|lib|\$\(libdir\)|bin)

and also many of the correct usages, like as those matching:

  \$\{E?D\%\/\}

could be auto-migrated to the new variable by scripted means, leaving the remaining stuff, requiring human auditing, to be performed at a more leisurely pace.

I guess it could also provide an easy final mop-up phase, since, at some point, we could just sic some QA instrumentation on any usage of D and call the problem "solved".
Comment 11 Greg Turner 2013-04-14 14:16:57 UTC
(In reply to comment #6)
> Looks like an awful lot of work, if you want to change it... If all this is
> doing is breaking one obscure unsupported arch, I suggest we leave it...

Agreed in principle, even if it is my pet arch.  However, as Michał has pointed out, this quirk leads to a lot of inelegant, hard-to-read bash code and also a lot of code that works more by accident than by design.  It leads to an ever-increasing need to assume that superfluous slashes abound all over the place.  I have definitely seen ebuilds create symbolic links beginning with insane numbers of slashes, for example, and then seen eselect code designed to mangle the paths those links point to wind up doing aberrant stuff after assuming that striping a single slash would yield something that could be treated as a relative path.

Historically, we have hand-waved this away by insisting that "//" == "/", which, by and large, it does.  But it would be hard to argue, say, if we were to build Gentoo II from scratch, that the trailing slash should be retained, say, due to all of the needless keystrokes it is saving ebuild developers :)

In short, it's a Bad Thing (tm), although reasonable people could disagree as to whether the cost-benefit of fixing it adds up to a net benefit.
Comment 12 Ciaran McCreesh 2013-04-14 14:22:16 UTC
Haaaaaaang on. I think I remember why the wording is the way that it is. It's for consistency with ROOT. So it's not insane at all, and the way it is is right.
Comment 13 Greg Turner 2013-04-14 16:11:41 UTC
(In reply to comment #12)
> Haaaaaaang on. I think I remember why the wording is the way that it is.
> It's for consistency with ROOT. So it's not insane at all, and the way it is
> is right.

I don't doubt there were clever and well-meaning reasons this decision was made.  No doubt, some thought was put into it or it wouldn't be there.  But don't you think the numbers in comment #5 make a pretty compelling rebuttal to any argument that in April 2013, this is more feature than flaw?

Bear in mind, I'm not even here to argue we should fix it (although, I must admit, my id is clearly rooting for it and my superego is at best agnostic).

Change it or leave it, the simple fact is, it's a minor pain in Gentoo's collective butt, as implemented, even if there is a case to be made that it's somehow more elegant or more theoretically correct.
Comment 14 Ulrich Müller gentoo-dev 2013-04-14 16:30:58 UTC
(In reply to comment #11)
> I have definitely seen ebuilds create symbolic links beginning with insane
> numbers of slashes, for example, and then seen eselect code designed to
> mangle the paths those links point to wind up doing aberrant stuff after
> assuming that striping a single slash would yield something that could be
> treated as a relative path.

Hm. eselect's path manipulation functions (basename, dirname, canonicalise, and relative_name) *should* handle an arbitrary number of slashes correctly. I had verified this some time ago, using the unit tests from GNU coreutils. See bug 280598 comment #10.

Can you please file a bug report for eselect if you see any such failure?
Comment 15 Ciaran McCreesh 2013-04-14 16:42:54 UTC
(In reply to comment #13)
> I don't doubt there were clever and well-meaning reasons this decision was
> made.  No doubt, some thought was put into it or it wouldn't be there.  But
> don't you think the numbers in comment #5 make a pretty compelling rebuttal
> to any argument that in April 2013, this is more feature than flaw?

I think consistency in how path values are exported is a Good Thing, and that if developers aren't making use of this, we should educate them. So we should either provide a trailing / everywhere or nowhere, and empty ROOT strikes me as being a very bad idea.
Comment 16 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 17:00:23 UTC
(In reply to comment #15)
> (In reply to comment #13)
> > I don't doubt there were clever and well-meaning reasons this decision was
> > made.  No doubt, some thought was put into it or it wouldn't be there.  But
> > don't you think the numbers in comment #5 make a pretty compelling rebuttal
> > to any argument that in April 2013, this is more feature than flaw?
> 
> I think consistency in how path values are exported is a Good Thing, and
> that if developers aren't making use of this, we should educate them. So we
> should either provide a trailing / everywhere or nowhere, and empty ROOT
> strikes me as being a very bad idea.

We're talking about a loss-loss here. Many developers expect ${ROOT} == /, and then they append a slash to it... Generally saying, ${ROOT} issue is similar to ${D}. Just that some ebuilds are even self-inconsistent.

But the difference would be that I don't think PMS made any guarantees about ROOT, and people had to guess what is right...
Comment 17 Ciaran McCreesh 2013-04-14 17:04:18 UTC
\t{ROOT} must be non-empty and end in a trailing slash.
Comment 18 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-14 17:23:16 UTC
(In reply to comment #17)
> \t{ROOT} must be non-empty and end in a trailing slash.

Hmm, then EPREFIX was the one, I guess.

Anyway, I agree that having it consistent is good. And the:

  [[ ${ROOT} == / ]]

check is probably cleaner than:

 [[ ! ${ROOT} ]]

or a similar one. Yet appending a trailing slash implies that we can't have a complete consistency over all variables since we will simply have too many slashes.

That said, I think we could sacrifice that in order to apply the no-trailing-slash logic. The amount of work increases, but I'm ready to work on it if other developers agree on the goal.
Comment 19 Greg Turner 2013-04-14 21:10:12 UTC
(In reply to comment #18)
> (In reply to comment #17)
> > \t{ROOT} must be non-empty and end in a trailing slash.
> 
> Hmm, then EPREFIX was the one, I guess.

Yes, EPREFIX=/ is reduced to EPREFIX= by portage setup code.

> Anyway, I agree that having it consistent is good. And the:
> 
>   [[ ${ROOT} == / ]]
> 
> check is probably cleaner than:
> 
>  [[ ! ${ROOT} ]]
> 
> or a similar one. Yet appending a trailing slash implies that we can't have
> a complete consistency over all variables since we will simply have too many
> slashes.

Of course, there is no law that the only rules we can consistently follow are "all paths end in slash" and "all paths do not end in slash".

For example, "all absolute or relative-to-CWD filesystem path variables inherited by the default ebuild environment end in slash, but and all other such path variables do not end in a slash, even if this means emptying them out" is somewhat closer to what we have now.  In this case, {E,}ROOT, {E,}PREFIX, and {E,}D would be rule-compliant, but, for example, FILESDIR, S, WORKDIR and others still would not.  But, of course, we could further complicate "the rule" until we compy with it :)

I guess my points are:

o Consistency as to whether or not path variables inherited by ebuilds contain trailing slashes or not does not exist right now.

o We are probably not going to go "fix" /all/ those variables whether we think they should or shouldn't end in a slash.  Instead the conclusion we kinda have to draw is that whether or not to tack on trailing slashes has been made according to utilitarian concerns about how the variable will be used.

o We seem to have made the wrong guess as to what form of D is the most utilitarian.

o If we are alarmed by this lack of consistency, we can fix the problem by explicitly stating what the rule and/or rules are.  If we aren't following the rules, we can change our behavior, change the rules, or change nothing and break the rules.  Or some combination of those three :P

> That said, I think we could sacrifice that in order to apply the
> no-trailing-slash logic. The amount of work increases, but I'm ready to work
> on it if other developers agree on the goal.

I'm still more concerned about the backward-incompatibility issue than the difficulty of the work.  Essentially, we're talking about going back and changing all EAPI's in a backward-incompatible way, which AFAICS goes against the premise of EAPI's in general, which, IIUC, is supposed to cement the contract package managers offer to ebuilds "forever."

Wouldn't it constitute bad citizenship in the community of portage-based package management systems?  Create upgrade crises for ancient systems?  Break tons of overlays?  Gentoo could certainly change it for all future EAPIs, but I am pretty doubtful that changing the semantics of D for existing EAPI's is going to happen.

That still leaves options to fix the problem elegantly, but mostly they are harder than "just change D":

  o make a new variable & deprecate D

  o fix in subsequent EAPIs.  For old EAPI's, perhaps add noisy QA instrumentation to root out existing mistakes.

  o keep it as it is, but add noisy QA instrumentation and some helpful hints like white-on-red "bad developer!" syntax-highlighting in vim/emacs for common erroneous uses of D, and, perhaps, add some easy path-canonicalization features that eclasses and eselect scripts can scrub their inputs with.

So I guess my final point is, although it would be wonderful to have this slash just "disappear" and then just patch up whatever ebuild code breaks in the tree, I'm not so sure it can be that simple of a fix.  I'd say, at least to my innocent eyes, it appears that slightly more careful thought about the consequences of such a change may be called for before we can just dive in and fix it :(
Comment 20 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-19 13:13:07 UTC
My idea is to:

1. Retroactively drop the 'must end with trailing slash' statement from
PMS. Therefore, make the thing undefined and require developers to
handle both cases.

2. Establish a QA policy that developers:

a) must support both cases in conditionals (e.g. [[ -z ${ROOT%/} ]]),

b) may end up with multiple slashes when constructing paths
(e.g. ${D}/usr/bin/foo is fine).

3. Add a few easy-to-have QA checks to repoman:

a) for '[[ ${ROOT} == /*',

b) for '${D}[a-z]', '${ROOT}[a-z]'.

Those won't be perfect but should catch the majority of current
and future issues.


Then, in a future EAPI (or some other way):

1. State that all path-related variables set by PM will never end with
a trailing slash. Emphasize that ${ROOT} may be empty (instead of '/').

2. Establish a QA check for '${ROOT%/}' and similar.


If there's agreement on the first steps, I'm ready to work on updating the tree. Just commit the change to PMS, and I'll start. But please don't wait with this to the moment I won't have the time anymore.
Comment 21 Ciaran McCreesh 2013-04-19 14:31:16 UTC
I'd rather we stuck with the currently-required behaviour, and just educated developers...
Comment 22 Zac Medico gentoo-dev 2013-04-19 14:55:25 UTC
The idea of changing this retroactively for existing EAPIs sounds scary to me, since it would effectively break a large number of ebuilds/eclasses (including those in user overlays that we don't control).

On the other hand, doing it as an EAPI extension seems quite doable. Code that needs to be compatible with both new and old EAPIs could use paths like "${D%/}/foo".
Comment 23 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-19 15:25:59 UTC
(In reply to comment #21)
> I'd rather we stuck with the currently-required behaviour, and just educated
> developers...

Educating to do something that is stupid usually doesn't really work.

(In reply to comment #22)
> The idea of changing this retroactively for existing EAPIs sounds scary to
> me, since it would effectively break a large number of ebuilds/eclasses
> (including those in user overlays that we don't control).

I don't mean changing the behavior. Just restating the spec so that future-proof code can and should be written while keeping the old behavior in PMs.
Comment 24 Ciaran McCreesh 2013-04-19 15:28:00 UTC
It's not stupid at all. It's just not immediately obvious why it's the right thing to do.
Comment 25 Steve L 2013-04-26 19:28:52 UTC
Oh please, just get on with it and get rid of trailing slashes on all directory variables in ebuild-space. Any shell-scripter would do the same, and it's a trivial bit of code in ebuild.sh.

Do it in a new EAPI as there is no reason on Earth to mess with backward compatibility. We want to move to a better state where ebuilds are easier to write, not give ourselves a maintenance nightmare.
Comment 26 Ciaran McCreesh 2013-04-26 19:35:14 UTC
Is that including empty ROOT?
Comment 27 Ulrich Müller gentoo-dev 2013-04-26 19:41:52 UTC
(In reply to comment #26)
> Is that including empty ROOT?

That seems to be the consequence. But I'd guess that ROOT is most often used in combinations like ${ROOT}/some/path that would profit from it?
Comment 28 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-27 16:07:00 UTC
Created attachment 346712 [details, diff]
PMS patch: drop the trailing slash guarantee

This patch drops all the guarantees related to trailing slashes. If it's committed, we can establish the QA policies and start fixing ebuilds.
Comment 29 Ciaran McCreesh 2013-04-27 16:13:14 UTC
This is a breaking change: ROOT == / tests aren't uncommon. This needs EAPI control.
Comment 30 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-27 16:15:56 UTC
(In reply to comment #29)
> This is a breaking change: ROOT == / tests aren't uncommon. This needs EAPI
> control.

The 'breaking' part will be handled by a QA policy.
Comment 31 Ciaran McCreesh 2013-04-27 16:24:29 UTC
(In reply to comment #30)
> (In reply to comment #29)
> > This is a breaking change: ROOT == / tests aren't uncommon. This needs EAPI
> > control.
> 
> The 'breaking' part will be handled by a QA policy.

...that can't be validated except by checking everything by hand.
Comment 32 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-27 21:19:03 UTC
Created attachment 346732 [details, diff]
repoman: check for [[ $ROOT == / and similar
Comment 33 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-04-27 21:19:22 UTC
Created attachment 346734 [details, diff]
repoman: check for ${D}[a-z] and ${ROOT}[a-z]
Comment 34 Ulenrich 2013-04-30 13:55:19 UTC
(In reply to comment #12)
> Haaaaaaang on. I think I remember why the wording is the way that it is.
> It's for consistency with ROOT. So it's not insane at all, 

I remember root is "/." as the point holds the name. 
Though you everywhere can and should: cd /.
Also does what it should:            cat /./etc/fstab
Also does what it should:        cat /./././etc/fstab
Couldn't a new rule add a hint that ROOT should end with a dot?
Comment 35 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-08-30 10:19:58 UTC
Let's consider this change for EAPI 6 then.
Comment 36 Ulrich Müller gentoo-dev 2014-09-01 03:13:23 UTC
(In reply to Michał Górny from comment #20)
> Then, in a future EAPI (or some other way):
> 
> 1. State that all path-related variables set by PM will never end with
> a trailing slash. Emphasize that ${ROOT} may be empty (instead of '/').

The problem with this is that ROOT is the "absolute path to the root directory" and therefore must be a valid path.

A null path is explicitly forbidden by POSIX:
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11
Comment 37 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-09-01 06:56:12 UTC
(In reply to Ulrich Müller from comment #36)
> (In reply to Michał Górny from comment #20)
> > Then, in a future EAPI (or some other way):
> > 
> > 1. State that all path-related variables set by PM will never end with
> > a trailing slash. Emphasize that ${ROOT} may be empty (instead of '/').
> 
> The problem with this is that ROOT is the "absolute path to the root
> directory" and therefore must be a valid path.

Then we redefine it as 'absolute path to the root directory if the package is installed in alternate root (!= /)'.
Comment 38 Ulrich Müller gentoo-dev 2014-09-01 07:31:06 UTC
(In reply to Michał Górny from comment #37)
> Then we redefine it as 'absolute path to the root directory if the package
> is installed in alternate root (!= /)'.

So we replace the current mess by another. Why can't we do it properly, without introducing another special case?
Comment 39 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-09-01 08:16:34 UTC
If wording is the main problem, then find a better wording... this is the same case as EPREFIX.
Comment 40 Ulrich Müller gentoo-dev 2014-09-01 08:44:01 UTC
It's not a matter of wording, but an empty pathname is a problem.

I've done this very exercise in eselect, by changing the definition of EROOT from "${ROOT}${EPREFIX}" to "${ROOT%/}${EPREFIX}" (commit 45646c7, in 2012). This caused breakage in several modules and I had to partially revert the change.
Comment 41 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-09-01 16:19:38 UTC
As I see it, our paths are built using 1-3 components:

  [ ROOT / D ] [ EPREFIX ] < PATH >

With <PATH> being the canonical, absolute path. That said, ROOT, D and EPREFIX should work as prefixes for it.

If you really want to keep the slash in some of the directories but not the others, I suggest making the whole thing undefined/implementation-dependent and requiring developers to support both possibilities.

That is, require both:

  ${D%/}${EPREFIX}/usr/bin/foo

and

  [[ ${ROOT:-/} == / ]]

But I'd honestly prefer if we agreed on one common convention that requires minimal number of operations.
Comment 42 Ulrich Müller gentoo-dev 2014-09-02 07:30:37 UTC
(In reply to Michał Górny from comment #41)
> As I see it, our paths are built using 1-3 components:
> 
>   [ ROOT / D ] [ EPREFIX ] < PATH >
> 
> With <PATH> being the canonical, absolute path. That said, ROOT, D and
> EPREFIX should work as prefixes for it.

This is not entirely accurate, because also PATH is optional. So in addition to the above, there can be paths formed like: 

   < ROOT / D > [ EPREFIX ]

Like in these examples used in the tree:

   emake DESTDIR="${D}" install
   "${EROOT}"/usr/bin/rpmdb --rebuilddb --root="${EROOT}"

> If you really want to keep the slash in some of the directories but not the
> others, I suggest making the whole thing undefined/implementation-dependent
> and requiring developers to support both possibilities.

This would make no sense. We should go for something well-defined.
Comment 43 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-09-02 07:41:43 UTC
(In reply to Ulrich Müller from comment #42)
> (In reply to Michał Górny from comment #41)
> > As I see it, our paths are built using 1-3 components:
> > 
> >   [ ROOT / D ] [ EPREFIX ] < PATH >
> > 
> > With <PATH> being the canonical, absolute path. That said, ROOT, D and
> > EPREFIX should work as prefixes for it.
> 
> This is not entirely accurate, because also PATH is optional. So in addition
> to the above, there can be paths formed like: 
> 
>    < ROOT / D > [ EPREFIX ]
> 
> Like in these examples used in the tree:
> 
>    emake DESTDIR="${D}" install
>    "${EROOT}"/usr/bin/rpmdb --rebuilddb --root="${EROOT}"

But in the end, those programs use those paths as prefixes... in fact, as I already pointed out, DESTDIR must not end with trailing slash. As for rpmdb, I have no idea what it does but sounds like ${EROOT:-/} is an acceptable solution.
Comment 44 Ulrich Müller gentoo-dev 2014-09-02 16:18:12 UTC
(In reply to Greg Turner from comment #3)
> "A pathname consisting of a single <slash> shall resolve to the root
> directory of the process. A null pathname shall not be successfully
> resolved. A pathname that begins with two successive <slash> characters may
> be interpreted in an implementation-defined manner, although more than two
> leading <slash> characters shall be treated as a single <slash> character."

Are there any platforms where ROOT="//" is legal? Because disguishing "/" from "//" seems impossible if ROOT cannot end with a slash.

If no such platforms exist, this is a non-issue of course.
Comment 45 Ulrich Müller gentoo-dev 2014-10-02 19:11:13 UTC
(In reply to Ulrich Müller from comment #44)
> Are there any platforms where ROOT="//" is legal? Because disguishing "/"
> from "//" seems impossible if ROOT cannot end with a slash.
> 
> If no such platforms exist, this is a non-issue of course.

No answer since one month. On the platforms I know of, "//" introduces a network path and must be followed by a hostname, so a bare ROOT="//" is not allowed.

I lift my reservations against empty ROOT then. However, we must clarify in our documentation (devmanual etc.) that ROOT is only a prefix and must never be used as a full path.
Comment 46 Ulrich Müller gentoo-dev 2014-10-02 19:15:04 UTC
*** Bug 174408 has been marked as a duplicate of this bug. ***
Comment 47 Larry the Git Cow gentoo-dev 2018-03-12 20:12:41 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/portage.git/commit/?id=6cb70f9ef0e790050b1d85b2f41d5c1988e5d57d

commit 6cb70f9ef0e790050b1d85b2f41d5c1988e5d57d
Author:     Michał Górny <mgorny@gentoo.org>
AuthorDate: 2018-02-21 08:55:11 +0000
Commit:     Michał Górny <mgorny@gentoo.org>
CommitDate: 2018-03-12 20:12:18 +0000

    Strip trailing slash from D, ED, ROOT, EROOT in EAPI 7
    
    Bug: https://bugs.gentoo.org/465772
    Reviewed-by: Zac Medico <zmedico@gentoo.org>

 pym/portage/eapi.py                  | 7 +++++++
 pym/portage/package/ebuild/config.py | 5 +++++
 2 files changed, 12 insertions(+)}
Comment 48 Larry the Git Cow gentoo-dev 2018-04-30 22:14:56 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/pms.git/commit/?id=14657b2f67477e4dec43d8f41b9fe664b07ea65c

commit 14657b2f67477e4dec43d8f41b9fe664b07ea65c
Author:     Michał Górny <mgorny@gentoo.org>
AuthorDate: 2017-09-28 16:20:11 +0000
Commit:     Ulrich Müller <ulm@gentoo.org>
CommitDate: 2018-03-30 16:35:43 +0000

    EAPI 7 no longer adds trailing slash to ROOT, EROOT, D, ED.
    
    Bug: https://bugs.gentoo.org/465772

 eapi-differences.tex |  5 +++++
 ebuild-env-vars.tex  | 58 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 52 insertions(+), 11 deletions(-)}