Open
Description
Context
I was building a simple Ruby CNB when I came across this behavior. I prepended /layers/heroku_ruby/ruby/bin
to the PATH, but found that echo $PATH
ended up being the whole layer path twice:
$ docker run --entrypoint='/cnb/lifecycle/launcher' my-image 'echo $PATH'
/layers/heroku_ruby/ruby/bin/layers/heroku_ruby/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
That was confusing. I thought perhaps it was expecting a relative path instead of absolute, so I tried pretending bin
and got this output:
$ docker run --entrypoint='/cnb/lifecycle/launcher' my-image 'echo $PATH'
bin/layers/heroku_ruby/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
That behavior was also confusing. After a lot of debugging, the cause was that I was pretending to PATH without specifying a delimiter.
Observations
- In https://github.com/buildpacks/spec/blob/main/buildpack.md#delimiter, the spec does not describe what happens when there is no delimiter set
- The spec on the lifecycle seems to indicate that
<layerpath>/bin
will always be on the PATH. However, it's possible to modify the PATH by accident, so that's no longer true https://github.com/buildpacks/spec/blob/main/buildpack.md#layer-paths - In the spec "The lifecycle MUST separate each path with the OS path list separator (e.g. : on Linux, ; on Windows)." this behavior does not hold for PATH values in prepend.
Paths forward
- The specification should state what behavior we expect when there's no delimiter as this behavior is currently undefined (by the spec)
In addition, I would like to propose some possible future changes to the spec:
- Make env vars using
prepend
andappend
an error unless a delimiter is specified. - Possibly: Default the delimiter for PATH environment variables when none is present.
- Possibly: Always place
bin
of a layer on thePATH
even if a CNB modifies the PATH.