Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sort rubies versions properly #277

Closed
wants to merge 3 commits into from
Closed

Conversation

grimm26
Copy link

@grimm26 grimm26 commented Jul 10, 2014

Having rbx-2.2.9 and rbx-2.2.10 in rubies and specifying "chruby rbx" would choose rbx-2.2.9 because chruby.sh just globs the contents of the rubies directories and so the members of the RUBIES array are sorted in ascii order: rbx-2.2.9 > rbx-2.2.10.

Using ls -v instead sorts the ruby versions properly.

@havenwood
Copy link
Collaborator

A problem with using GNU's ls -v is that the -v option isn't portable to BSD or OS X. In BSD there is no -v so you get an illegal option -- V. In OS X there is a -v option but instead of natural version sorting it Force(s) unedited printing of non-graphic characters.

@postmodern
Copy link
Owner

I wonder if we could get away with falling back to normal ls? Although the difference in functionality would confuse OSX/Linux users.

@grimm26
Copy link
Author

grimm26 commented Jul 12, 2014

I think that doing a check for proper ls -v support and then falling back to the current fileglob might be the only way to go. I've tried piping through sort to try to sort properly without using sort -V (also GNU only) and it is problematic. A custom sorting shell function would need to be written to cover all platforms and I'm not sure the issue warrants that kind of development time. I'll make another commit that includes a check for ls function and a fallback.

@aprescott
Copy link

Can we get away with sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n and trust that 5 hierarchies of versioning won't happen here?

@havenwood
Copy link
Collaborator

@aprescott Yeah, @mpapis suggested about the same and I think it may be viable. We do need to sort after the last slash because ~/.rubies matches the . field separator and borks the order. Worth exploring I think.

@grimm26
Copy link
Author

grimm26 commented Jul 12, 2014

Yes, it is more complicated than using sort. Witness:

% \ls -d /tmp/rubies/* | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n
/tmp/rubies/ruby-2.1.0
/tmp/rubies/rbx-2.2.7
/tmp/rubies/rbx-2.2.10
/tmp/rubies/ruby-1.9.1
/tmp/rubies/ruby-1.9.3-p152

Sorting the first field numerically doesn't order these example rubies correctly. We can change the first sort to numeric:

% \ls -d /tmp/rubies/* | sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n
/tmp/rubies/rbx-2.2.7
/tmp/rubies/rbx-2.2.10
/tmp/rubies/ruby-1.9.1
/tmp/rubies/ruby-1.9.3-p152
/tmp/rubies/ruby-2.1.0

Looks much better, right? Until a ruby goes double digits:

% \ls -d /tmp/rubies/* | sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n
/tmp/rubies/rbx-10.0.5
/tmp/rubies/rbx-2.2.7
/tmp/rubies/rbx-2.2.10
/tmp/rubies/ruby-1.9.1
/tmp/rubies/ruby-1.9.3-p152
/tmp/rubies/ruby-2.1.0

The sort needs to be by ruby type (rbi vs ruby, etc) and then sorted on just the isolated version. Without GNU coreutils or perl or something, this is difficult :)

@mpapis
Copy link
Contributor

mpapis commented Jul 12, 2014

$ ls -1d ~/.rvm/rubies/* | 
  sed 'h; s/-/./g ;; s/.*\///g ;; G ; s/\n/ /' | 
  LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n | 
  awk '{print $2}'
/home/mpapis/.rvm/rubies/current
/home/mpapis/.rvm/rubies/default
/home/mpapis/.rvm/rubies/rbx-1.3.3
/home/mpapis/.rvm/rubies/rbx-2.0.0
/home/mpapis/.rvm/rubies/rbx-10.0.0
/home/mpapis/.rvm/rubies/ruby-1.9.3-p545
/home/mpapis/.rvm/rubies/ruby-1.9.3-p547
/home/mpapis/.rvm/rubies/ruby-2.0.0-p481
/home/mpapis/.rvm/rubies/ruby-2.1.2

or

$ ls -1d ~/.rvm/rubies/* | 
  sed 's/.*\///g ;; h; s/-/./g ;; G ; s/\n/ /' | 
  LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n | 
  awk '{print $2}'
current
default
rbx-1.3.3
rbx-2.0.0
rbx-10.0.0
ruby-1.9.3-p545
ruby-1.9.3-p547
ruby-2.0.0-p481
ruby-2.1.2

the whole magic is in sed 'h; s/-/./ ;; s/.*\///g ;; G ; s/\n/ /':

  • h - store current line in "hold space"
  • s/-/./g - replace - with . for better sorting (g all occurrences)
  • ;; - double required to fix a bug on OSX for undetermined results
  • s/.*\///g - remove path from "pattern space"
  • G - add the unchanged path from "hold space" to "pattern space"
  • s/\n/ / - replace the new line that is between strings
  • sed will automatically print "pattern space" after processing all commands

this works because:

$ ls -1d ~/.rvm/rubies/* | 
  sed -n 'h; s/-/./g ;; s/.*\///g ;; G ; s/\n/ / ;; p ' | 
  LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n
current /home/mpapis/.rvm/rubies/current
default /home/mpapis/.rvm/rubies/default
rbx.1.3.3 /home/mpapis/.rvm/rubies/rbx-1.3.3
rbx.2.0.0 /home/mpapis/.rvm/rubies/rbx-2.0.0
rbx.10.0.0 /home/mpapis/.rvm/rubies/rbx-10.0.0
ruby.1.9.3.p545 /home/mpapis/.rvm/rubies/ruby-1.9.3-p545
ruby.1.9.3.p547 /home/mpapis/.rvm/rubies/ruby-1.9.3-p547
ruby.2.0.0.p481 /home/mpapis/.rvm/rubies/ruby-2.0.0-p481
ruby.2.1.2 /home/mpapis/.rvm/rubies/ruby-2.1.2

and we use awk '{print $2}' to get the full path from second place (could be done with sed too for consistency).

@grimm26
Copy link
Author

grimm26 commented Jul 12, 2014

Brilliant! Should have know there was some sed or awk magic that could save the day. I tried this on Linux, darwin, and FreeBSD with success.

@grimm26
Copy link
Author

grimm26 commented Jul 15, 2014

sed magic sort now incorporated.

@havenwood
Copy link
Collaborator

@grimm26 I also opened #278, which is an alternative variant of this that creates the sorted RUBIES array by piping find command output to the sed magic sort.

@ghost
Copy link

ghost commented Dec 10, 2014

Is this or #278 sufficient to be merged?

@grimm26
Copy link
Author

grimm26 commented Jan 20, 2015

closing in deference to #278 since more development has been done.

@grimm26 grimm26 closed this Jan 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants