Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Respect the specified order of environment variables in the remote co…

…mmand line

Ruby <= v1.8.7 did not preserve the insertion order of Hash keys.
  • Loading branch information...
commit 5e36eddd016b99b529c42ff34b3b64550cc380ea 1 parent 2a815bb
@njonsson authored
View
3  lib/cape/capistrano.rb
@@ -1,3 +1,4 @@
+require 'cape/hash_list'
require 'cape/rake'
require 'cape/util'
@@ -112,7 +113,7 @@ def implement(task, capistrano_context, options, &env_block)
else
arguments = "[#{arguments.join ','}]"
end
- env_hash = {}
+ env_hash = HashList.new
env_block.call(env_hash) if env_block
env_hash.reject! do |var_name, var_value|
var_name.nil? || var_value.nil?
View
80 lib/cape/hash_list.rb
@@ -0,0 +1,80 @@
+module Cape
+
+ # A HashList is a collection of key-value pairs. It is similar to an Array,
+ # except that indexing is done via arbitrary keys of any object type, not an
+ # integer index. Hashes enumerate their values in the order that the
+ # corresponding keys were inserted.
+ #
+ # This class exists because in Ruby v1.8.7 and earlier, Hash did not preserve
+ # the insertion order of keys.
+ class HashList < ::Array
+
+ # Constructs a new HashList using the specified _arguments_.
+ #
+ # @param [Hash] arguments attribute values
+ def initialize(*arguments)
+ super Hash[*arguments].to_a
+ end
+
+ # Compares a HashList to another object.
+ #
+ # @param [Object] other another object
+ #
+ # @return [true] the HashList has the same number of keys as _other_, and
+ # each key-value pair is equal (according to Object#==)
+ # @return [false] the HashList is not equal to _other_
+ def ==(other)
+ other.is_a?(::Hash) ? (other == to_hash) : super(other)
+ end
+
+ # Retrieves a value from the HashList.
+ #
+ # @param [Object] key a key
+ #
+ # @return [Object] the value for _key_
+ # @return [nil] if there is no value for _key_
+ def [](key)
+ entry = find do |pair|
+ Array(pair).first == key
+ end
+ entry ? Array(entry).last : nil
+ end
+
+ # Sets a value in the HashList.
+ #
+ # @param [Object] key a key
+ # @param [Object] value a value for _key_
+ #
+ # @return [HashList] the HashList
+ def []=(key, value)
+ index = find_index do |pair|
+ Array(pair).first == key
+ end
+ if index
+ super key, value
+ else
+ self << [key, value]
+ end
+ self
+ end
+
+ # Provides a string representation of the HashList.
+ #
+ # @return [String] a string representation of the HashList
+ def inspect
+ entries = collect do |pair|
+ Array(pair).collect(&:inspect).join '=>'
+ end
+ "{#{entries.join ', '}}"
+ end
+
+ # Converts the HashList to a Hash.
+ #
+ # @return [Hash] a hash
+ def to_hash
+ ::Hash[to_a]
+ end
+
+ end
+
+end
View
48 spec/cape/hash_list_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+require 'cape/hash_list'
+
+describe Cape::HashList do
+ describe 'that is empty' do
+ it { should be_empty }
+
+ its(:inspect) { should == '{}' }
+
+ its(:to_a) { should == [] }
+
+ its(:to_hash) { should == {} }
+
+ describe 'when values are added out of order' do
+ before :each do
+ subject['foo'] = 'bar'
+ subject['baz'] = 'qux'
+ end
+
+ it { should == {'foo' => 'bar', 'baz' => 'qux'} }
+
+ its(:inspect) { should == '{"foo"=>"bar", "baz"=>"qux"}' }
+
+ its(:to_a) { should == [%w(foo bar), %w(baz qux)] }
+
+ its(:to_hash) { should == {'foo' => 'bar', 'baz' => 'qux'} }
+ end
+ end
+
+ describe 'that has values out of order' do
+ subject { described_class.new 'foo' => 'bar', 'baz' => 'qux' }
+
+ it { should == {'foo' => 'bar', 'baz' => 'qux'} }
+
+ it 'should index the values as expected' do
+ subject['foo'].should == 'bar'
+ subject['baz'].should == 'qux'
+ end
+
+ describe 'when sent #clear' do
+ before :each do
+ subject.clear
+ end
+
+ it { should be_empty }
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.