elasticity 2.1 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in elasticity.gemspec
4
4
  gemspec
data/HISTORY.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.1.1 - July 22, 2012
2
+
3
+ + ```JobFlow::from_jobflow_id``` factory method added so that you can operate on running job flows (add steps, shutdown, status, etc.) that you didn't start in the same Ruby instance.
4
+ + Updated to rspec-2.11.
5
+
1
6
  ## 2.1 - July 7, 2012
2
7
 
3
8
  + TASK instance group support added.
data/README.md CHANGED
@@ -59,7 +59,7 @@ Job flows are the center of the EMR universe. The general order of operations i
59
59
  1. (optional) Add additional steps.
60
60
  1. (optional) Shutdown the job flow.
61
61
 
62
- ## 1 - Creating Job Flows
62
+ ## 1 - Create a Job Flow
63
63
 
64
64
  Only your AWS credentials are needed.
65
65
 
@@ -67,6 +67,14 @@ Only your AWS credentials are needed.
67
67
  jobflow = Elasticity::JobFlow.new('AWS access key', 'AWS secret key')
68
68
  ```
69
69
 
70
+ If you want to access a job flow that's already running:
71
+
72
+ ```
73
+ jobflow = Elasticity::JobFlow.from_jobflow_id('AWS access key', 'AWS secret key', 'jobflow ID')
74
+ ```
75
+
76
+ This is useful if you'd like to attach to a running job flow and add more steps, etc.
77
+
70
78
  ## 2 - Specifying Job Flow Options
71
79
 
72
80
  Configuration job flow options, shown below with default values. Note that these defaults are subject to change - they are reasonable defaults at the time(s) I work on them (e.g. the latest version of Hadoop).
@@ -1,24 +1,24 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "elasticity/version"
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'elasticity/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = "elasticity"
6
+ s.name = 'elasticity'
7
7
  s.version = Elasticity::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Robert Slifka"]
10
- s.homepage = "http://www.github.com/rslifka/elasticity"
9
+ s.authors = ['Robert Slifka']
10
+ s.homepage = 'http://www.github.com/rslifka/elasticity'
11
11
  s.summary = %q{Streamlined, programmatic access to Amazon's Elastic Map Reduce service.}
12
12
  s.description = %q{Streamlined, Programmatic access to Amazon's Elastic Map Reduce service, driven by the Sharethrough team's requirements for belting out EMR jobs.}
13
13
 
14
- s.add_dependency("rest-client")
15
- s.add_dependency("nokogiri")
14
+ s.add_dependency('rest-client')
15
+ s.add_dependency('nokogiri')
16
16
 
17
- s.add_development_dependency("rake")
18
- s.add_development_dependency("rspec", "~> 2.10.0")
17
+ s.add_development_dependency('rake')
18
+ s.add_development_dependency('rspec', '~> 2.11.0')
19
19
 
20
20
  s.files = `git ls-files`.split("\n")
21
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
22
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
- s.require_paths = ["lib"]
23
+ s.require_paths = %w(lib)
24
24
  end
@@ -41,6 +41,13 @@ module Elasticity
41
41
  @emr = Elasticity::EMR.new(access, secret)
42
42
  end
43
43
 
44
+ def self.from_jobflow_id(access, secret, jobflow_id)
45
+ JobFlow.new(access, secret).tap do |j|
46
+ j.instance_variable_set(:@jobflow_id, jobflow_id)
47
+ j.instance_variable_set(:@installed_steps, j.status.installed_steps)
48
+ end
49
+ end
50
+
44
51
  def instance_count=(count)
45
52
  raise ArgumentError, 'Instance count cannot be set to less than 2 (requested 1)' unless count > 1
46
53
  @instance_groups[:core].count = count - 1
@@ -80,8 +87,8 @@ module Elasticity
80
87
  def add_step(jobflow_step)
81
88
  if is_jobflow_running?
82
89
  jobflow_steps = []
83
- if jobflow_step.class.send(:requires_installation?) && !@installed_steps.include?(jobflow_step.class)
84
- jobflow_steps << jobflow_step.class.send(:aws_installation_step)
90
+ if jobflow_step.requires_installation? && !@installed_steps.include?(jobflow_step.class)
91
+ jobflow_steps << jobflow_step.aws_installation_step
85
92
  end
86
93
  jobflow_steps << jobflow_step.to_aws_step(self)
87
94
  @emr.add_jobflow_steps(@jobflow_id, {:steps => jobflow_steps})
@@ -93,7 +100,7 @@ module Elasticity
93
100
  def run
94
101
  raise_if @jobflow_steps.empty?, JobFlowMissingStepsError, 'Cannot run a job flow without adding steps. Please use #add_step.'
95
102
  raise_if is_jobflow_running?, JobFlowRunningError, 'Cannot run a job flow multiple times. To do more with this job flow, please use #add_step.'
96
- @jobflow_id ||= @emr.run_job_flow(jobflow_config)
103
+ @jobflow_id = @emr.run_job_flow(jobflow_config)
97
104
  end
98
105
 
99
106
  def shutdown
@@ -109,7 +116,7 @@ module Elasticity
109
116
  private
110
117
 
111
118
  def is_jobflow_running?
112
- @jobflow_id
119
+ !@jobflow_id.nil?
113
120
  end
114
121
 
115
122
  def jobflow_config
@@ -13,28 +13,42 @@ module Elasticity
13
13
  attr_accessor :master_instance_type
14
14
  attr_accessor :slave_instance_type
15
15
  attr_accessor :last_state_change_reason
16
+ attr_accessor :installed_steps
16
17
 
17
18
  def initialize
18
19
  @steps = []
20
+ @installed_steps = []
19
21
  end
20
22
 
21
23
  # Create a jobflow from an AWS <member> (Nokogiri::XML::Element):
22
24
  # /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member
23
25
  def self.from_member_element(xml_element)
24
26
  jobflow = JobFlowStatus.new
27
+
25
28
  jobflow.name = xml_element.xpath('./Name').text.strip
26
29
  jobflow.jobflow_id = xml_element.xpath('./JobFlowId').text.strip
27
30
  jobflow.state = xml_element.xpath('./ExecutionStatusDetail/State').text.strip
28
31
  jobflow.last_state_change_reason = xml_element.xpath('./ExecutionStatusDetail/LastStateChangeReason').text.strip
32
+
29
33
  jobflow.steps = JobFlowStatusStep.from_members_nodeset(xml_element.xpath('./Steps/member'))
34
+
35
+ step_names = jobflow.steps.map(&:name)
36
+ Elasticity::JobFlowStep.steps_requiring_installation.each do |step|
37
+ jobflow.installed_steps << step if step_names.include?(step.aws_installation_step[:name])
38
+ end
39
+
30
40
  jobflow.created_at = Time.parse(xml_element.xpath('./ExecutionStatusDetail/CreationDateTime').text.strip)
41
+
31
42
  started_at = xml_element.xpath('./ExecutionStatusDetail/StartDateTime').text.strip
32
43
  jobflow.started_at = (started_at == '') ? (nil) : (Time.parse(started_at))
44
+
33
45
  ready_at = xml_element.xpath('./ExecutionStatusDetail/ReadyDateTime').text.strip
34
46
  jobflow.ready_at = (ready_at == '') ? (nil) : (Time.parse(ready_at))
47
+
35
48
  jobflow.instance_count = xml_element.xpath('./Instances/InstanceCount').text.strip
36
49
  jobflow.master_instance_type = xml_element.xpath('./Instances/MasterInstanceType').text.strip
37
50
  jobflow.slave_instance_type = xml_element.xpath('./Instances/SlaveInstanceType').text.strip
51
+
38
52
  jobflow
39
53
  end
40
54
 
@@ -11,11 +11,11 @@ module Elasticity
11
11
  # /DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member/Steps/member
12
12
  def self.from_member_element(xml_element)
13
13
  job_flow_step = JobFlowStatusStep.new
14
- job_flow_step.name = xml_element.xpath("./StepConfig/Name").text.strip
15
- job_flow_step.state = xml_element.xpath("./ExecutionStatusDetail/State").text.strip
16
- started_at = xml_element.xpath("./ExecutionStatusDetail/StartDateTime").text.strip
17
- job_flow_step.started_at = (started_at == "") ? (nil) : (Time.parse(started_at))
18
- ended_at = xml_element.xpath("./ExecutionStatusDetail/EndDateTime").text.strip
14
+ job_flow_step.name = xml_element.xpath('./StepConfig/Name').text.strip
15
+ job_flow_step.state = xml_element.xpath('./ExecutionStatusDetail/State').text.strip
16
+ started_at = xml_element.xpath('./ExecutionStatusDetail/StartDateTime').text.strip
17
+ job_flow_step.started_at = (started_at == '') ? (nil) : (Time.parse(started_at))
18
+ ended_at = xml_element.xpath('./ExecutionStatusDetail/EndDateTime').text.strip
19
19
  job_flow_step.ended_at = (ended_at == "") ? (nil) : (Time.parse(ended_at))
20
20
  job_flow_step
21
21
  end
@@ -2,10 +2,20 @@ module Elasticity
2
2
 
3
3
  module JobFlowStep
4
4
 
5
+ @@step_klasses = []
6
+
5
7
  def to_aws_step(jobflow_step)
6
8
  raise RuntimeError, '#to_aws_step is required to be defined on all job flow steps.'
7
9
  end
8
10
 
11
+ def requires_installation?
12
+ self.class.requires_installation?
13
+ end
14
+
15
+ def aws_installation_step
16
+ self.class.aws_installation_step
17
+ end
18
+
9
19
  module ClassMethods
10
20
 
11
21
  def requires_installation?
@@ -20,6 +30,11 @@ module Elasticity
20
30
 
21
31
  def self.included(base)
22
32
  base.extend(ClassMethods)
33
+ @@step_klasses << base
34
+ end
35
+
36
+ def self.steps_requiring_installation
37
+ @@step_klasses.select{|klass| klass.requires_installation?}
23
38
  end
24
39
 
25
40
  end
@@ -1,3 +1,3 @@
1
1
  module Elasticity
2
- VERSION = '2.1'
2
+ VERSION = '2.1.1'
3
3
  end
@@ -483,4 +483,48 @@ describe Elasticity::JobFlow do
483
483
 
484
484
  end
485
485
 
486
+ describe '.from_jobflow_id' do
487
+ before do
488
+ Elasticity::JobFlow.any_instance.stub_chain(:status, :installed_steps => [])
489
+ end
490
+
491
+ let(:jobflow) { Elasticity::JobFlow.from_jobflow_id('ACCESS', 'SECRET', 'JOBFLOW_ID') }
492
+
493
+ it 'should create a jobflow with the specified credentials' do
494
+ Elasticity::EMR.should_receive(:new).with('ACCESS', 'SECRET')
495
+ Elasticity::JobFlow.from_jobflow_id('ACCESS', 'SECRET', '_')
496
+ end
497
+
498
+ it 'should create a jobflow' do
499
+ jobflow.should be_a Elasticity::JobFlow
500
+ end
501
+
502
+ it 'should create a running jobflow' do
503
+ jobflow.send(:is_jobflow_running?).should == true
504
+ end
505
+
506
+ it 'should remember the jobflow ID' do
507
+ jobflow.instance_variable_get(:@jobflow_id).should == 'JOBFLOW_ID'
508
+ end
509
+
510
+ context 'when no steps have been installed' do
511
+ before do
512
+ Elasticity::JobFlow.any_instance.should_receive(:status).and_return(double('Elasticity::JobFlowStatus', :installed_steps => []))
513
+ end
514
+ it 'should show that no steps are installed' do
515
+ jobflow.instance_variable_get(:@installed_steps).should == []
516
+ end
517
+ end
518
+
519
+ context 'when steps have been installed do' do
520
+ before do
521
+ Elasticity::JobFlow.any_instance.should_receive(:status).and_return(double('Elasticity::JobFlowStatus', :installed_steps => [Elasticity::HiveStep, Elasticity::PigStep]))
522
+ end
523
+ it 'should show that no steps are installed' do
524
+ jobflow.instance_variable_get(:@installed_steps).should =~ [Elasticity::PigStep, Elasticity::HiveStep]
525
+ end
526
+ end
527
+
528
+ end
529
+
486
530
  end
@@ -1,13 +1,43 @@
1
1
  describe Elasticity::JobFlowStatus do
2
2
 
3
- before do
4
- describe_jobflows_xml = <<-JOBFLOWS
3
+ let(:hive_setup_config) do
4
+ <<-XML
5
+ <member>
6
+ <StepConfig>
7
+ <Name>Elasticity - Install Hive</Name>
8
+ </StepConfig>
9
+ <ExecutionStatusDetail>
10
+ <State>FAILED</State>
11
+ </ExecutionStatusDetail>
12
+ </member>
13
+ XML
14
+ end
15
+
16
+ let(:pig_setup_config) do
17
+ <<-XML
18
+ <member>
19
+ <StepConfig>
20
+ <Name>Elasticity - Install Pig</Name>
21
+ </StepConfig>
22
+ <ExecutionStatusDetail>
23
+ <State>FAILED</State>
24
+ </ExecutionStatusDetail>
25
+ </member>
26
+ XML
27
+ end
28
+
29
+ let(:setup_config) do
30
+ hive_setup_config
31
+ end
32
+
33
+ let(:describe_jobflows_xml) do
34
+ <<-XML
5
35
  <DescribeJobFlowsResponse xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
6
36
  <DescribeJobFlowsResult>
7
37
  <JobFlows>
8
38
  <member>
9
39
  <JobFlowId>j-p</JobFlowId>
10
- <Name>Pig Job</Name>
40
+ <Name>Hive Job 1</Name>
11
41
  <ExecutionStatusDetail>
12
42
  <CreationDateTime>
13
43
  2011-10-04T21:49:16Z
@@ -24,14 +54,7 @@ describe Elasticity::JobFlowStatus do
24
54
  <State>TERMINATED</State>
25
55
  </ExecutionStatusDetail>
26
56
  <Steps>
27
- <member>
28
- <StepConfig>
29
- <Name>Setup Hive</Name>
30
- </StepConfig>
31
- <ExecutionStatusDetail>
32
- <State>FAILED</State>
33
- </ExecutionStatusDetail>
34
- </member>
57
+ #{setup_config}
35
58
  <member>
36
59
  <StepConfig>
37
60
  <Name>Run Hive Script</Name>
@@ -63,7 +86,7 @@ describe Elasticity::JobFlowStatus do
63
86
  </member>
64
87
  <member>
65
88
  <JobFlowId>j-h</JobFlowId>
66
- <Name>Hive Job</Name>
89
+ <Name>Hive Job 2</Name>
67
90
  <ExecutionStatusDetail>
68
91
  <CreationDateTime>
69
92
  2011-10-04T22:49:16Z
@@ -104,43 +127,79 @@ describe Elasticity::JobFlowStatus do
104
127
  </JobFlows>
105
128
  </DescribeJobFlowsResult>
106
129
  </DescribeJobFlowsResponse>
107
- JOBFLOWS
130
+ XML
131
+ end
132
+
133
+ let(:members_nodeset) do
108
134
  describe_jobflows_document = Nokogiri::XML(describe_jobflows_xml)
109
135
  describe_jobflows_document.remove_namespaces!
110
- @members_nodeset = describe_jobflows_document.xpath('/DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member')
136
+ describe_jobflows_document.xpath('/DescribeJobFlowsResponse/DescribeJobFlowsResult/JobFlows/member')
111
137
  end
112
138
 
113
- describe ".from_xml" do
114
- it "should return a JobFlow with the appropriate fields initialized" do
115
- jobflow = Elasticity::JobFlowStatus.from_member_element(@members_nodeset[0])
116
- jobflow.name.should == "Pig Job"
117
- jobflow.jobflow_id.should == "j-p"
118
- jobflow.state.should == "TERMINATED"
119
- jobflow.steps.map(&:name).should == ["Setup Hive", "Run Hive Script"]
120
- jobflow.steps.map(&:state).should == ["FAILED", "PENDING"]
121
- jobflow.created_at.should == Time.parse("2011-10-04T21:49:16Z")
122
- jobflow.started_at.should == Time.parse("2011-10-04T21:49:17Z")
123
- jobflow.ready_at.should == Time.parse("2011-10-04T21:49:18Z")
124
- jobflow.master_instance_type.should == "m1.small"
125
- jobflow.slave_instance_type.should == "m1.small"
126
- jobflow.instance_count.should == "4"
127
- jobflow.last_state_change_reason.should == "Steps completed with errors"
139
+ let(:single_jobflow) { Elasticity::JobFlowStatus.from_member_element(members_nodeset[0]) }
140
+
141
+ let(:multiple_jobflows) { Elasticity::JobFlowStatus.from_members_nodeset(members_nodeset) }
142
+
143
+ describe '.from_xml' do
144
+ it 'should return a JobFlow with the appropriate fields initialized' do
145
+ single_jobflow.name.should == 'Hive Job 1'
146
+ single_jobflow.jobflow_id.should == 'j-p'
147
+ single_jobflow.state.should == 'TERMINATED'
148
+ single_jobflow.steps.map(&:name).should == ['Elasticity - Install Hive', 'Run Hive Script']
149
+ single_jobflow.steps.map(&:state).should == %w(FAILED PENDING)
150
+ single_jobflow.created_at.should == Time.parse('2011-10-04T21:49:16Z')
151
+ single_jobflow.started_at.should == Time.parse('2011-10-04T21:49:17Z')
152
+ single_jobflow.ready_at.should == Time.parse('2011-10-04T21:49:18Z')
153
+ single_jobflow.master_instance_type.should == 'm1.small'
154
+ single_jobflow.slave_instance_type.should == 'm1.small'
155
+ single_jobflow.instance_count.should == '4'
156
+ single_jobflow.last_state_change_reason.should == 'Steps completed with errors'
128
157
  end
129
158
  end
130
159
 
131
- describe ".from_jobflows_nodeset" do
132
- it "should return JobFlows with the appropriate fields initialized" do
133
- jobflow = Elasticity::JobFlowStatus.from_members_nodeset(@members_nodeset)
134
- jobflow.map(&:name).should == ["Pig Job", "Hive Job"]
135
- jobflow.map(&:jobflow_id).should == ["j-p", "j-h"]
136
- jobflow.map(&:state).should == ["TERMINATED", "TERMINATED"]
137
- jobflow.map(&:created_at).should == [Time.parse("2011-10-04T21:49:16Z"), Time.parse("2011-10-04T22:49:16Z")]
138
- jobflow.map(&:started_at).should == [Time.parse("2011-10-04T21:49:17Z"), nil]
139
- jobflow.map(&:ready_at).should == [Time.parse("2011-10-04T21:49:18Z"), nil]
140
- jobflow.map(&:master_instance_type).should == ["m1.small","c1.medium"]
141
- jobflow.map(&:slave_instance_type).should == ["m1.small", "c1.medium"]
142
- jobflow.map(&:instance_count).should == ["4","2"]
143
- jobflow.map(&:last_state_change_reason).should == ["Steps completed with errors", "Steps completed"]
160
+ describe '.from_jobflows_nodeset' do
161
+ it 'should return JobFlows with the appropriate fields initialized' do
162
+ multiple_jobflows.map(&:name).should == ['Hive Job 1', 'Hive Job 2']
163
+ multiple_jobflows.map(&:jobflow_id).should == %w(j-p j-h)
164
+ multiple_jobflows.map(&:state).should == %w(TERMINATED TERMINATED)
165
+ multiple_jobflows.map(&:created_at).should == [Time.parse('2011-10-04T21:49:16Z'), Time.parse('2011-10-04T22:49:16Z')]
166
+ multiple_jobflows.map(&:started_at).should == [Time.parse('2011-10-04T21:49:17Z'), nil]
167
+ multiple_jobflows.map(&:ready_at).should == [Time.parse('2011-10-04T21:49:18Z'), nil]
168
+ multiple_jobflows.map(&:master_instance_type).should == %w(m1.small c1.medium)
169
+ multiple_jobflows.map(&:slave_instance_type).should == %w(m1.small c1.medium)
170
+ multiple_jobflows.map(&:instance_count).should == %w(4 2)
171
+ multiple_jobflows.map(&:last_state_change_reason).should == ['Steps completed with errors', 'Steps completed']
172
+ end
173
+ end
174
+
175
+ describe '#installed_steps' do
176
+
177
+ context 'when nothing has been installed' do
178
+ let(:setup_config) { }
179
+ it 'should be empty' do
180
+ single_jobflow.installed_steps.should == []
181
+ end
182
+ end
183
+
184
+ context 'when Hive has been installed by Elasticity' do
185
+ let(:setup_config) { hive_setup_config }
186
+ it 'should include HiveStep' do
187
+ single_jobflow.installed_steps.should == [Elasticity::HiveStep]
188
+ end
189
+ end
190
+
191
+ context 'when Pig has been installed by Elasticity' do
192
+ let(:setup_config) { pig_setup_config }
193
+ it 'should include PigStep' do
194
+ single_jobflow.installed_steps.should == [Elasticity::PigStep]
195
+ end
196
+ end
197
+
198
+ context 'when more than one step has been installed by Elasticity' do
199
+ let(:setup_config) { hive_setup_config + pig_setup_config }
200
+ it 'should include all of them' do
201
+ single_jobflow.installed_steps.should =~ [Elasticity::HiveStep, Elasticity::PigStep]
202
+ end
144
203
  end
145
204
  end
146
205
 
@@ -20,6 +20,13 @@ describe Elasticity::JobFlowStep do
20
20
 
21
21
  end
22
22
 
23
+ describe '#requires_installation?' do
24
+ it 'should delegate to the class method' do
25
+ FakeStep.should_receive(:requires_installation?).and_return(true)
26
+ subject.requires_installation?.should == true
27
+ end
28
+ end
29
+
23
30
  describe '.requires_installation?' do
24
31
  it 'should be false by default' do
25
32
  FakeStep.requires_installation?.should be_false
@@ -34,4 +41,17 @@ describe Elasticity::JobFlowStep do
34
41
  end
35
42
  end
36
43
 
44
+ describe '#aws_installation_step' do
45
+ it 'should delegate to the class method' do
46
+ FakeStep.should_receive(:aws_installation_step).and_return('AWS_INSTALLATION_STEP')
47
+ subject.aws_installation_step.should == 'AWS_INSTALLATION_STEP'
48
+ end
49
+ end
50
+
51
+ describe '.steps_requiring_installation' do
52
+ it 'should list all of the steps requiring installation' do
53
+ Elasticity::JobFlowStep.steps_requiring_installation.should =~ [Elasticity::PigStep, Elasticity::HiveStep]
54
+ end
55
+ end
56
+
37
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticity
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.1'
4
+ version: 2.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-07 00:00:00.000000000 Z
12
+ date: 2012-07-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 2.10.0
69
+ version: 2.11.0
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 2.10.0
77
+ version: 2.11.0
78
78
  description: Streamlined, Programmatic access to Amazon's Elastic Map Reduce service,
79
79
  driven by the Sharethrough team's requirements for belting out EMR jobs.
80
80
  email:
@@ -133,18 +133,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
133
  - - ! '>='
134
134
  - !ruby/object:Gem::Version
135
135
  version: '0'
136
- segments:
137
- - 0
138
- hash: -3013863256678255822
139
136
  required_rubygems_version: !ruby/object:Gem::Requirement
140
137
  none: false
141
138
  requirements:
142
139
  - - ! '>='
143
140
  - !ruby/object:Gem::Version
144
141
  version: '0'
145
- segments:
146
- - 0
147
- hash: -3013863256678255822
148
142
  requirements: []
149
143
  rubyforge_project:
150
144
  rubygems_version: 1.8.24