mirror of
https://github.com/89luca89/distrobox.git
synced 2026-08-17 16:34:42 -05:00
fix(enter): reorder PATH so /usr/local/{s,}bin precede /usr/{s,}bin
Signed-off-by: Luca Di Maio <luca.dimaio1@gmail.com>
This commit is contained in:
@@ -155,11 +155,44 @@ func BuildContainerPath(cleanPath bool, hostPath string, containerPath string) s
|
||||
}
|
||||
}
|
||||
|
||||
merged := hostPath
|
||||
if len(additionalPaths) > 0 {
|
||||
return hostPath + ":" + strings.Join(additionalPaths, ":")
|
||||
merged = hostPath + ":" + strings.Join(additionalPaths, ":")
|
||||
}
|
||||
|
||||
return hostPath
|
||||
return reorderFHSPath(merged)
|
||||
}
|
||||
|
||||
// reorderFHSPath ensures /usr/local/bin precedes /usr/bin and /usr/local/sbin
|
||||
// precedes /usr/sbin, so distrobox wrappers in /usr/local/* win — mirroring the
|
||||
// reference shell (distrobox-enter:478-512).
|
||||
func reorderFHSPath(path string) string {
|
||||
var reordered []string
|
||||
for _, p := range strings.Split(path, ":") {
|
||||
switch p {
|
||||
case "/usr/local/bin", "/usr/local/sbin":
|
||||
// Skip here; re-inserted right before its /usr counterpart.
|
||||
case "/usr/bin":
|
||||
reordered = append(reordered, "/usr/local/bin", "/usr/bin")
|
||||
case "/usr/sbin":
|
||||
reordered = append(reordered, "/usr/local/sbin", "/usr/sbin")
|
||||
default:
|
||||
reordered = append(reordered, p)
|
||||
}
|
||||
}
|
||||
|
||||
result := strings.Join(reordered, ":")
|
||||
|
||||
// If /usr/bin or /usr/sbin were absent, their local counterparts were
|
||||
// skipped above; re-add any that went missing (prepended, like the shell).
|
||||
for _, lp := range []string{"/usr/local/bin", "/usr/local/sbin"} {
|
||||
pattern := regexp.MustCompile(`(:|^)` + regexp.QuoteMeta(lp) + `(:|$)`)
|
||||
if !pattern.MatchString(result) {
|
||||
result = lp + ":" + result
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func BuildXDGPaths(envVar string, standardPaths []string) string {
|
||||
|
||||
@@ -148,21 +148,21 @@ func TestBuildContainerPath(t *testing.T) {
|
||||
cleanPath: false,
|
||||
hostPath: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
containerPath: "/container/path",
|
||||
want: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
want: "/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
{
|
||||
name: "hostPath missing some standard paths - adds them",
|
||||
cleanPath: false,
|
||||
hostPath: "/usr/bin:/bin",
|
||||
containerPath: "/container/path",
|
||||
want: "/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin",
|
||||
want: "/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin",
|
||||
},
|
||||
{
|
||||
name: "hostPath with custom paths and missing standard paths",
|
||||
cleanPath: false,
|
||||
hostPath: "/custom/bin:/usr/bin:/another/path",
|
||||
containerPath: "/container/path",
|
||||
want: "/custom/bin:/usr/bin:/another/path:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/bin",
|
||||
want: "/custom/bin:/usr/local/bin:/usr/bin:/another/path:/usr/local/sbin:/usr/sbin:/sbin:/bin",
|
||||
},
|
||||
{
|
||||
name: "empty hostPath - returns containerPath",
|
||||
@@ -181,32 +181,32 @@ func TestBuildContainerPath(t *testing.T) {
|
||||
name: "hostPath with standard paths at beginning",
|
||||
cleanPath: false,
|
||||
hostPath: "/bin:/usr/bin:/custom/path",
|
||||
want: "/bin:/usr/bin:/custom/path:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin",
|
||||
want: "/bin:/usr/local/bin:/usr/bin:/custom/path:/usr/local/sbin:/usr/sbin:/sbin",
|
||||
},
|
||||
{
|
||||
name: "hostPath with standard paths at end",
|
||||
cleanPath: false,
|
||||
hostPath: "/custom/path:/bin:/usr/bin",
|
||||
want: "/custom/path:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin",
|
||||
want: "/custom/path:/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin",
|
||||
},
|
||||
{
|
||||
name: "hostPath with similar but not exact standard paths",
|
||||
cleanPath: false,
|
||||
hostPath: "/usr/binary:/binfo",
|
||||
want: "/usr/binary:/binfo:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
want: "/usr/binary:/binfo:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
{
|
||||
name: "single custom path in hostPath",
|
||||
cleanPath: false,
|
||||
hostPath: "/opt/custom/bin",
|
||||
containerPath: "/container/path",
|
||||
want: "/opt/custom/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
want: "/opt/custom/bin:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
{
|
||||
name: "empty containerPath with non-empty hostPath",
|
||||
cleanPath: false,
|
||||
hostPath: "/custom/path",
|
||||
want: "/custom/path:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
want: "/custom/path:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
{
|
||||
name: "empty containerPath with empty hostPath",
|
||||
|
||||
Reference in New Issue
Block a user