Skip to content

Instantly share code, notes, and snippets.

@NickLaMuro
Last active April 26, 2016 16:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NickLaMuro/dd35ea9241bfb7e651037ec3bae7f8b3 to your computer and use it in GitHub Desktop.
Save NickLaMuro/dd35ea9241bfb7e651037ec3bae7f8b3 to your computer and use it in GitHub Desktop.
Ruby Default File Sorting on different Operating systems

Depending on the operating system, calls to Dir#[] and Dir.glob will return the order of the directory in different order for the same directory.

So given the following directory structure:

app
└── admin
    ├── a.rb
    ├── concerns
    │   ├── hd.rb
    │   └── hu.rb
    ├── d.rb
    ├── f.rb
    ├── g.rb
    └── v.rb

The order of the following command:

# Note, this current example is taken from the `activeadmin` project
#
#   https://github.com/NickLaMuro/activeadmin/blob/4101263/lib/active_admin/application.rb#L219-L221
#
puts %w[app/admin].flatten.compact.uniq.flat_map {|path| Dir[\"#{path}/**/*.rb\"] }

Will be different for each OS, regardless of the ruby version.

Using the script

The Vagrantfile and vagrant_test.sh files are examples of how this inconsistency can be shown in practice. Simply put both of these files in the same directory, make the vagrant_test.sh file executable, and run:

$ ./vagrant_test.sh

This basically run the following three commands for each vm defined in the Vagrantfile:

$ vagrant up [VM_NAME]
$ vagrant ssh -c /opt/rubies/[RUBY_VERSION]/bin/ruby -e 'puts %w[/home/vagrant/app/admin].flatten.compact.uniq.flat_map {|path| Dir[\"#{path}/**/*.rb\"] }'
$ vagrant halt [VM_NAME]

Replacing [VM_NAME] and [RUBY_VERSION] with those specific for the vm being run against. The script just modifies the output so the differences are easier to be noticed.

To test a possible fix for this script, you can run ./vagrant_test.sh corrected to use a slightly modified version of the ruby script that then sorts the files properly in ruby across all OS's.

Running on Windows

The above script is meant for unix based systems (OSX and Linux), so to run this on Windows, you will have to use the seperated ssh commands provided above with an ssh client installed. I would recommend cmder as a possible console emulator that has a great ssh client built in.

Test for ubuntu1204_ruby_21 using ruby-2.1.9...
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> ubuntu1204_ruby_21: Attempting graceful shutdown of VM...
Test for ubuntu1204_ruby_22 using ruby-2.2.4...
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> ubuntu1204_ruby_22: Attempting graceful shutdown of VM...
Test for ubuntu1204_ruby_23 using ruby-2.3.0...
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> ubuntu1204_ruby_23: Attempting graceful shutdown of VM...
Test for cent66_ruby_21 using ruby-2.1.9...
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/v.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/f.rb
Connection to 127.0.0.1 closed.
==> cent66_ruby_21: Attempting graceful shutdown of VM...
Test for cent66_ruby_22 using ruby-2.2.4...
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/v.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/f.rb
Connection to 127.0.0.1 closed.
==> cent66_ruby_22: Attempting graceful shutdown of VM...
Test for cent66_ruby_23 using ruby-2.3.0...
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/v.rb
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/f.rb
Connection to 127.0.0.1 closed.
==> cent66_ruby_23: Attempting graceful shutdown of VM...
Test for cent67_ruby_21 using ruby-2.1.9...
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> cent67_ruby_21: Attempting graceful shutdown of VM...
Test for cent67_ruby_22 using ruby-2.2.4...
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> cent67_ruby_22: Attempting graceful shutdown of VM...
Test for cent67_ruby_23 using ruby-2.3.0...
/home/vagrant/app/admin/g.rb
/home/vagrant/app/admin/concerns/hu.rb
/home/vagrant/app/admin/concerns/hd.rb
/home/vagrant/app/admin/d.rb
/home/vagrant/app/admin/a.rb
/home/vagrant/app/admin/f.rb
/home/vagrant/app/admin/v.rb
Connection to 127.0.0.1 closed.
==> cent67_ruby_23: Attempting graceful shutdown of VM...
#!/bin/bash
TEST_CMD="puts %w[/home/vagrant/app/admin].flatten.compact.uniq.flat_map {|path| Dir[\"#{path}/**/*.rb\"] }"
test_for_ruby() {
local vm_name=$1
local ruby_version="ruby-$2"
vagrant up $vm_name --provision &> /tmp/$vm_name.log
echo "Test for $vm_name using $ruby_version..."
vagrant ssh $vm_name -c "/opt/rubies/$ruby_version/bin/ruby -e '$TEST_CMD'"
vagrant halt $vm_name
}
test_for_each_ruby() {
local linux_flavor=$1
test_for_ruby "${linux_flavor}_ruby_21" "2.1.9"
test_for_ruby "${linux_flavor}_ruby_22" "2.2.4"
test_for_ruby "${linux_flavor}_ruby_23" "2.3.0"
}
if [[ "$1" == "corrected" ]]; then
TEST_CMD="puts %w[/home/vagrant/app/admin].flatten.compact.uniq.flat_map {|path| Dir[\"#{path}/**/*.rb\"].sort }.uniq"
fi
test_for_each_ruby "ubuntu1204"
test_for_each_ruby "cent66"
test_for_each_ruby "cent67"
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
install_ruby_script = lambda { |ruby_version|
<<-SHELL
if [[ -e /opt/rubies/ruby-#{ruby_version} ]]; then exit 0; fi
cd /tmp
wget -O ruby-install-0.6.0.tar.gz https://github.com/postmodern/ruby-install/archive/v0.6.0.tar.gz
tar -xzvf ruby-install-0.6.0.tar.gz
cd ruby-install-0.6.0/
make install
cd /tmp
rm -rf ruby-install-0.6.0*
cd /tmp
wget -O chruby-0.3.9.tar.gz https://github.com/postmodern/chruby/archive/v0.3.9.tar.gz
tar -xzvf chruby-0.3.9.tar.gz
cd chruby-0.3.9/
make install
cd /tmp
rm -rf chruby-0.3.9*
/usr/local/bin/ruby-install ruby-#{ruby_version}
SHELL
}
setup_test_dir = <<-SHELL
mkdir -p /home/vagrant/app/admin/concerns
touch /home/vagrant/app/admin/a.rb
touch /home/vagrant/app/admin/concerns/hd.rb
touch /home/vagrant/app/admin/concerns/hu.rb
touch /home/vagrant/app/admin/d.rb
touch /home/vagrant/app/admin/f.rb
touch /home/vagrant/app/admin/g.rb
touch /home/vagrant/app/admin/v.rb
SHELL
config.vm.define "cent66_ruby_21" do |machine|
machine.vm.box = "box-cutter/centos66"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.1.9")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "cent66_ruby_22" do |machine|
machine.vm.box = "box-cutter/centos66"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.2.4")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "cent66_ruby_23" do |machine|
machine.vm.box = "box-cutter/centos66"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.3.0")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "cent67_ruby_21" do |machine|
machine.vm.box = "box-cutter/centos67"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.1.9")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "cent67_ruby_22" do |machine|
machine.vm.box = "box-cutter/centos67"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.2.4")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "cent67_ruby_23" do |machine|
machine.vm.box = "box-cutter/centos67"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.3.0")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "ubuntu1204_ruby_21" do |machine|
machine.vm.box = "box-cutter/ubuntu1204"
machine.vm.provision "shell", :inline => "sudo apt-get update"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.1.9")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "ubuntu1204_ruby_22" do |machine|
machine.vm.box = "box-cutter/ubuntu1204"
machine.vm.provision "shell", :inline => "sudo apt-get update"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.2.4")
machine.vm.provision "shell", :inline => setup_test_dir
end
config.vm.define "ubuntu1204_ruby_23" do |machine|
machine.vm.box = "box-cutter/ubuntu1204"
machine.vm.provision "shell", :inline => "sudo apt-get update"
machine.vm.provision "shell", :inline => install_ruby_script.call("2.3.0")
machine.vm.provision "shell", :inline => setup_test_dir
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment