tokuhirom / plenv

Perl binary manager
Other
514 stars 70 forks source link

sort "plenv versions" more naturally #96

Open rjbs opened 9 years ago

rjbs commented 9 years ago

If plenv-versions was written in Perl, I'd use Sort::Naturally or something like that. When I run plenv versions I see something like:

~$ plenv versions
  system
  10.0
  18.2
  20.2
  22.0
  6.2
  8.5

I'd prefer if these sorted numerically, so 8.5 came before 10.0. (This would be just as much of a problem if it was 5.8.5.)

On GNU systems, ls -v would sort this out, but we can't rely on that either. I'm not sure how we want to fix this, but it would be nice.

laubster commented 8 years ago

Try this (works for me, but YMMV).

diff --git a/libexec/plenv-versions b/libexec/plenv-versions
index ffe2530..75894db 100755
--- a/libexec/plenv-versions
+++ b/libexec/plenv-versions
@@ -32,8 +32,10 @@ if [ -n "$include_system" ] && PLENV_VERSION=system plenv-which perl >/dev/null
   print_version system
 fi

-for path in "${PLENV_ROOT}/versions/"*; do
-  if [ -d "$path" ]; then
-    print_version "${path##*/}"
+for entry in $(ls "${PLENV_ROOT}/versions/" \
+    | sort -t. -k1,1n -k2,2n -k3,3n)
+do
+  if [ -d "${PLENV_ROOT}/versions/$entry" ]; then
+    print_version "$entry"
   fi
 done
Grinnz commented 8 years ago

is sort -V any more portable than ls -v ?

laubster commented 8 years ago

Didn't know about "sort -V" or "ls -v" until now - thanks. Code is changed to use "sort -V". If there are portability concerns, I can have the code try either of those, and if not available, fall back to the hack I originally submitted.

Grinnz commented 8 years ago

according to http://www.unixwerk.eu/unix/sort.html it seems that your original hack may be the "best" approach.

ghost commented 7 years ago

Indeed, sort -V is not portable. +1 for laubster's original approach, except that for should not be used to read lines and ls(1) should not be used for parsing. Instead, it can be written as:

while IFS= read -r path; do
  [[ -d $path ]] || continue
  print_version "${path##*/}"
done < <(printf '%s\n' "${PLENV_ROOT}/versions/"* | sort -t. -k1,1n -k2,2n -k3,3n)

NOTE: refraining from quoting $path within [[ ]] may appear to be a mistake but it is not.