tddium-preview 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -49,3 +49,5 @@ nbproject
49
49
  #
50
50
  # For vim:
51
51
  *.swp
52
+ *.swo
53
+ .tddium.staging
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tddium-preview (0.5.5)
4
+ tddium-preview (0.5.6)
5
5
  bundler
6
6
  highline
7
7
  json
@@ -13,6 +13,7 @@ module TddiumConstant
13
13
  ENVIRONMENT = "production"
14
14
  SSH_FILE = "~/.ssh/id_rsa.pub"
15
15
  TEST_PATTERN = "spec/**/*_spec.rb"
16
+ SUITE_TEST_PATTERN = "features/*.feature, spec/**/*_spec.rb, test/**/test_*.rb"
16
17
  end
17
18
 
18
19
  module Git
@@ -57,6 +58,15 @@ module TddiumConstant
57
58
  PASSWORD_CONFIRMATION = "Confirm your password: "
58
59
  INVITATION_TOKEN = "Enter your invitation token:"
59
60
  USE_EXISTING_SUITE = "A suite exists '%%s' (branch %s). Enter '#{Response::YES}' to use it, or enter a new repo name:"
61
+ TEST_PATTERN = "Default test pattern: "
62
+ ENABLE_CI = "Do you want to configure Hosted Continuous Integration?"
63
+ UPDATE_SUITE = "Do you want to edit settings for this suite?"
64
+ CI_PULL_URL = "git URL to pull from:"
65
+ CI_PUSH_URL = "git URL to push on passing tests (blank to disable):"
66
+ ENABLE_CAMPFIRE = "Setup Campfire CI notifications?"
67
+ CAMPFIRE_SUBDOMAIN = "Campfire Subdomain:"
68
+ CAMPFIRE_ROOM = "Campfire Room:"
69
+ CAMPFIRE_TOKEN = "Campfire API Token:"
60
70
  end
61
71
 
62
72
  module Process
@@ -67,8 +77,9 @@ module TddiumConstant
67
77
  CHECK_TEST_STATUS = "Use 'tddium status' to check on pending jobs"
68
78
  FINISHED_TEST = "Finished in %s seconds"
69
79
  CHECK_TEST_REPORT = "Test report: %s"
70
- EXISTING_SUITE = "Current suite: %s"
71
- CREATING_SUITE = "Creating suite '%s'. This will take a few seconds."
80
+ EXISTING_SUITE = "Current suite...\n\n%s"
81
+ CREATING_SUITE = "Creating suite '%s/%s'. This will take a few seconds."
82
+ CREATED_SUITE = "Created suite...\n\n%s"
72
83
  PASSWORD_CONFIRMATION_INCORRECT = "Password confirmation incorrect"
73
84
  PASSWORD_CHANGED = "Your password has been changed."
74
85
  ACCOUNT_CREATED = "
@@ -116,7 +127,15 @@ with Tddium.
116
127
  SESSION_TITLE = " Session %s:"
117
128
  ATTRIBUTE_DETAIL = " %s: %s"
118
129
  SEPARATOR = "====="
119
- USING_SUITE = "Using suite: '%s' on branch: '%s'"
130
+ USING_SUITE = "Using suite...\n\n%s"
131
+ USER_DETAILS =<<EOF;
132
+ Username: <%=user["email"]%>
133
+ Account Created: <%=user["created_at"]%>
134
+ Recurly Management URL: <%=user["recurly_url"]%>
135
+ <% if user["heroku"] %>
136
+ Heroku Account Linked: <%=user["heroku_activation_done"]%>
137
+ <% end %>
138
+ EOF
120
139
  HEROKU_CONFIG = "
121
140
  Tddium is configured to work with your Heroku app.
122
141
 
@@ -131,6 +150,27 @@ $ tddium suite
131
150
  $ tddium spec
132
151
 
133
152
  "
153
+ SUITE_DETAILS =<<EOF;
154
+ Repo: <%=suite["repo_name"]%>/<%=suite["branch"]%>
155
+ Default Test Pattern: <%=suite["test_pattern"]%>
156
+ <% if suite["ci_pull_url"] %>
157
+ Tddium Hosted CI is enabled with the following parameters:
158
+
159
+ Pull URL: <%=suite["ci_pull_url"]%>
160
+ Push URL: <%=suite["ci_push_url"]%>
161
+
162
+ Notifications:
163
+ <%=suite["ci_notifications"]%>
164
+
165
+ Authorize the following SSH key to let Tddium's pulls and pushes through:
166
+
167
+ <%=suite["ci_ssh_pubkey"]%>
168
+
169
+ To trigger CI builds, POST to the following URL from a post-commit hook:
170
+
171
+ <%=suite["hook_uri"]%>
172
+ <% end %>
173
+ EOF
134
174
  end
135
175
 
136
176
  module Error
@@ -3,5 +3,5 @@ Copyright (c) 2011 Solano Labs All Rights Reserved
3
3
  =end
4
4
 
5
5
  module TddiumVersion
6
- VERSION = "0.5.6"
6
+ VERSION = "0.6.0"
7
7
  end
data/lib/tddium.rb CHANGED
@@ -8,6 +8,7 @@ require "highline/import"
8
8
  require "json"
9
9
  require "tddium_client"
10
10
  require "base64"
11
+ require 'erb'
11
12
  require File.expand_path("../tddium/constant", __FILE__)
12
13
  require File.expand_path("../tddium/heroku", __FILE__)
13
14
 
@@ -297,6 +298,9 @@ class Tddium < Thor
297
298
 
298
299
  desc "suite", "Register the suite for this project, or manage its settings"
299
300
  method_option :name, :type => :string, :default => nil
301
+ method_option :pull_url, :type => :string, :default => nil
302
+ method_option :push_url, :type => :string, :default => nil
303
+ method_option :test_pattern, :type => :string, :default => nil
300
304
  method_option :environment, :type => :string, :default => nil
301
305
  def suite
302
306
  set_default_environment(options[:environment])
@@ -307,45 +311,20 @@ class Tddium < Thor
307
311
  if current_suite_id
308
312
  current_suite = call_api(:get, current_suite_path)["suite"]
309
313
 
310
- say Text::Process::EXISTING_SUITE % "#{current_suite["repo_name"]}/#{current_suite["branch"]}"
314
+ say Text::Process::EXISTING_SUITE % format_suite_details(current_suite)
315
+ #prompt_update_suite(current_suite, options)
311
316
  else
312
317
  params[:branch] = current_git_branch
313
318
  default_suite_name = File.basename(Dir.pwd)
314
319
  params[:repo_name] = options[:name] || default_suite_name
315
320
 
316
- existing_suite = nil
317
- use_existing_suite = false
318
- suite_name_resolved = false
319
- while !suite_name_resolved
320
- # Check to see if there is an existing suite
321
- current_suites = call_api(:get, Api::Path::SUITES, params)
322
- existing_suite = current_suites["suites"].first
323
-
324
- # Get the suite name
325
- current_suite_name = params[:repo_name]
326
- if existing_suite
327
- # Prompt for using existing suite (unless suite name is passed from command line) or entering new one
328
- params[:repo_name] = prompt(Text::Prompt::USE_EXISTING_SUITE % params[:branch], options[:name], current_suite_name)
329
- if options[:name] || params[:repo_name] == Text::Prompt::Response::YES
330
- # Use the existing suite, so assign the value back and exit the loop
331
- params[:repo_name] = current_suite_name
332
- use_existing_suite = true
333
- suite_name_resolved = true
334
- end
335
- elsif current_suite_name == default_suite_name
336
- # Prompt for using default suite name or entering new one
337
- params[:repo_name] = prompt(Text::Prompt::SUITE_NAME, options[:name], current_suite_name)
338
- suite_name_resolved = true if params[:repo_name] == default_suite_name
339
- else
340
- # Suite name does not exist yet and already prompted
341
- suite_name_resolved = true
342
- end
343
- end
321
+ use_existing_suite, existing_suite = resolve_suite_name(options, params, default_suite_name)
344
322
 
345
323
  if use_existing_suite
346
324
  # Write to file and exit when using the existing suite
347
325
  write_suite(existing_suite["id"])
348
- say Text::Status::USING_SUITE % [existing_suite["repo_name"], existing_suite["branch"]]
326
+ say Text::Status::USING_SUITE % format_suite_details(existing_suite)
327
+ #prompt_update_suite(existing_suite, options)
349
328
  return
350
329
  end
351
330
 
@@ -353,17 +332,21 @@ class Tddium < Thor
353
332
  params[:bundler_version] = dependency_version(:bundle)
354
333
  params[:rubygems_version] = dependency_version(:gem)
355
334
 
335
+ prompt_suite_params(options, params)
356
336
 
357
337
  # Create new suite if it does not exist yet
358
- say Text::Process::CREATING_SUITE % params[:repo_name]
338
+ say Text::Process::CREATING_SUITE % [params[:repo_name], params[:branch]]
359
339
  new_suite = call_api(:post, Api::Path::SUITES, {:suite => params})
360
340
  # Save the created suite
361
341
  write_suite(new_suite["suite"]["id"])
362
342
 
363
343
  # Manage git
364
344
  update_git_remote_and_push(new_suite)
345
+
346
+ say Text::Process::CREATED_SUITE % format_suite_details(new_suite["suite"])
365
347
  end
366
348
  rescue TddiumClient::Error::Base
349
+ exit_failure
367
350
  end
368
351
  end
369
352
 
@@ -517,6 +500,55 @@ class Tddium < Thor
517
500
  data
518
501
  end
519
502
 
503
+ def prompt_suite_params(options, params)
504
+ params[:test_pattern] = prompt(Text::Prompt::TEST_PATTERN, options[:test_pattern], Default::SUITE_TEST_PATTERN)
505
+ if prompt(Text::Prompt::ENABLE_CI, options[:pull_url] ? 'y' : nil, 'n') == Text::Prompt::Response::YES
506
+ params[:ci_pull_url] = prompt(Text::Prompt::CI_PULL_URL, options[:pull_url], nil)
507
+ params[:ci_push_url] = prompt(Text::Prompt::CI_PUSH_URL, options[:push_url], nil)
508
+ if prompt(Text::Prompt::ENABLE_CAMPFIRE, nil, 'n') == Text::Prompt::Response::YES
509
+ params[:campfire_subdomain] = prompt(Text::Prompt::CAMPFIRE_SUBDOMAIN, options[:campfire_subdomain], nil)
510
+ params[:campfire_token] = prompt(Text::Prompt::CAMPFIRE_TOKEN, options[:campfire_token], nil)
511
+ params[:campfire_room] = prompt(Text::Prompt::CAMPFIRE_ROOM, options[:campfire_room], nil)
512
+ end
513
+ end
514
+ end
515
+
516
+ def prompt_update_suite(api_response, options)
517
+ say Text::Prompt::UPDATE_SUITE
518
+ end
519
+
520
+ def resolve_suite_name(options, params, default_suite_name)
521
+ # XXX updates params
522
+ existing_suite = nil
523
+ use_existing_suite = false
524
+ suite_name_resolved = false
525
+ while !suite_name_resolved
526
+ # Check to see if there is an existing suite
527
+ current_suites = call_api(:get, Api::Path::SUITES, params)
528
+ existing_suite = current_suites["suites"].first
529
+
530
+ # Get the suite name
531
+ current_suite_name = params[:repo_name]
532
+ if existing_suite
533
+ # Prompt for using existing suite (unless suite name is passed from command line) or entering new one
534
+ params[:repo_name] = prompt(Text::Prompt::USE_EXISTING_SUITE % params[:branch], options[:name], current_suite_name)
535
+ if options[:name] || params[:repo_name] == Text::Prompt::Response::YES
536
+ # Use the existing suite, so assign the value back and exit the loop
537
+ params[:repo_name] = current_suite_name
538
+ use_existing_suite = true
539
+ suite_name_resolved = true
540
+ end
541
+ elsif current_suite_name == default_suite_name
542
+ # Prompt for using default suite name or entering new one
543
+ params[:repo_name] = prompt(Text::Prompt::SUITE_NAME, options[:name], current_suite_name)
544
+ suite_name_resolved = true if params[:repo_name] == default_suite_name
545
+ else
546
+ # Suite name does not exist yet and already prompted
547
+ suite_name_resolved = true
548
+ end
549
+ end
550
+ [use_existing_suite, existing_suite]
551
+ end
520
552
 
521
553
  def set_default_environment(env)
522
554
  if env.nil?
@@ -549,15 +581,15 @@ class Tddium < Thor
549
581
  # Given the user is logged in, she should be able to use "tddium account" to display information about her account:
550
582
  # Email address
551
583
  # Account creation date
552
- say "Username: "+api_response["user"]["email"]
553
- say "Account Created: " + api_response["user"]["created_at"]
554
- say "Recurly Management URL: " + api_response["user"]["recurly_url"]
555
- say "CI Public Key: " + api_response["user"]["ci_ssh_pubkey"] if api_response["user"]["ci_ssh_pubkey"]
556
- say "Suites: " + api_response["user"]["suites"] if api_response["user"]["suites"]
557
- say "Heroku Account Linked: #{api_response["user"]["heroku_activation_done"]}" if api_response["user"]["heroku"]
584
+ user = api_response["user"]
585
+ say ERB.new(Text::Status::USER_DETAILS).result(binding)
558
586
  end
559
587
 
560
- def show_ci_info(api_response)
588
+ def format_suite_details(suite)
589
+ # Given an API response containing a "suite" key, compose a string with
590
+ # important information about the suite
591
+ details = ERB.new(Text::Status::SUITE_DETAILS).result(binding)
592
+ details
561
593
  end
562
594
 
563
595
  def suite_for_current_branch?
data/spec/tddium_spec.rb CHANGED
@@ -33,9 +33,16 @@ describe Tddium do
33
33
  SAMPLE_SUITE_ID = 1
34
34
  SAMPLE_USER_ID = 1
35
35
  DEFAULT_TEST_PATTERN = Tddium::Default::TEST_PATTERN
36
+ SAMPLE_SUITE_PATTERN = "features/*.feature, spec/**/*_spec.rb"
36
37
  CUSTOM_TEST_PATTERN = "**/cat_spec.rb"
37
- SAMPLE_SUITE_RESPONSE = {"repo_name" => SAMPLE_APP_NAME, "branch" => SAMPLE_BRANCH_NAME, "id" => SAMPLE_SUITE_ID, "ruby_version"=>SAMPLE_RUBY_VERSION, "git_repo_uri" => SAMPLE_GIT_REPO_URI}
38
+ SAMPLE_SUITE_RESPONSE = {"repo_name" => SAMPLE_APP_NAME,
39
+ "branch" => SAMPLE_BRANCH_NAME,
40
+ "id" => SAMPLE_SUITE_ID,
41
+ "ruby_version"=>SAMPLE_RUBY_VERSION,
42
+ "git_repo_uri" => SAMPLE_GIT_REPO_URI,
43
+ "test_pattern" => SAMPLE_SUITE_PATTERN}
38
44
  SAMPLE_SUITES_RESPONSE = {"suites" => [SAMPLE_SUITE_RESPONSE]}
45
+ SAMPLE_SUITE_OUTPUT = "Repo: #{SAMPLE_APP_NAME}/#{SAMPLE_BRANCH_NAME}\nDefault Test Pattern: #{SAMPLE_SUITE_PATTERN}\n\n"
39
46
  SAMPLE_TDDIUM_CONFIG_FILE = ".tddium.test"
40
47
  SAMPLE_TEST_EXECUTION_STATS = "total 1, notstarted 0, started 1, passed 0, failed 0, pending 0, error 0", "start_time"
41
48
  SAMPLE_USER_RESPONSE = {"status"=>0, "user"=>
@@ -1439,8 +1446,8 @@ describe Tddium do
1439
1446
 
1440
1447
  it_should_behave_like "writing the suite to file"
1441
1448
 
1442
- it "should show the user: '#{Tddium::Text::Status::USING_SUITE % [SAMPLE_APP_NAME, SAMPLE_BRANCH_NAME]}'" do
1443
- tddium.should_receive(:say).with(Tddium::Text::Status::USING_SUITE % [SAMPLE_APP_NAME, SAMPLE_BRANCH_NAME])
1449
+ it "should show the user: '#{Tddium::Text::Status::USING_SUITE % SAMPLE_SUITE_OUTPUT}'" do
1450
+ tddium.should_receive(:say).with(Tddium::Text::Status::USING_SUITE % SAMPLE_SUITE_OUTPUT)
1444
1451
  run_suite(tddium)
1445
1452
  end
1446
1453
  end
@@ -1481,13 +1488,36 @@ describe Tddium do
1481
1488
  context "interactive mode" do
1482
1489
  before do
1483
1490
  tddium.stub(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_BRANCH_NAME % SAMPLE_APP_NAME).and_return("foobar")
1491
+ tddium.stub(:ask).with(Tddium::Text::Prompt::TEST_PATTERN).and_return(SAMPLE_SUITE_PATTERN)
1484
1492
  stub_default_suite_name
1485
1493
  end
1486
1494
 
1487
- it "should POST the user's entered values to the API" do
1488
- tddium.should_receive(:say).with(Tddium::Text::Process::CREATING_SUITE % "foobar")
1489
- call_api_should_receive(:method => :post, :params => {:suite => hash_including(:repo_name => "foobar")})
1490
- run_suite(tddium)
1495
+ context "no ci url" do
1496
+ it "should POST the user's entered values to the API" do
1497
+ tddium.should_receive(:say).with(Tddium::Text::Process::CREATING_SUITE % ["foobar", SAMPLE_BRANCH_NAME])
1498
+ call_api_should_receive(:method => :post, :params => {:suite => hash_including(:repo_name => "foobar", :test_pattern=>SAMPLE_SUITE_PATTERN)})
1499
+ run_suite(tddium)
1500
+ end
1501
+ end
1502
+
1503
+ context "enable ci and campfire" do
1504
+ before do
1505
+ tddium.stub(:ask).with(Tddium::Text::Prompt::ENABLE_CI).and_return(Tddium::Text::Prompt::Response::YES)
1506
+ tddium.stub(:ask).with(Tddium::Text::Prompt::ENABLE_CAMPFIRE).and_return(Tddium::Text::Prompt::Response::YES)
1507
+ end
1508
+
1509
+ it "should prompt for URLs" do
1510
+ tddium.should_receive(:ask).with(Tddium::Text::Prompt::CI_PULL_URL)
1511
+ tddium.should_receive(:ask).with(Tddium::Text::Prompt::CI_PUSH_URL)
1512
+ run_suite(tddium)
1513
+ end
1514
+
1515
+ it "should prompt for campfire" do
1516
+ tddium.should_receive(:ask).with(Tddium::Text::Prompt::CAMPFIRE_SUBDOMAIN)
1517
+ tddium.should_receive(:ask).with(Tddium::Text::Prompt::CAMPFIRE_TOKEN)
1518
+ tddium.should_receive(:ask).with(Tddium::Text::Prompt::CAMPFIRE_ROOM)
1519
+ run_suite(tddium)
1520
+ end
1491
1521
  end
1492
1522
  end
1493
1523
 
@@ -1513,14 +1543,7 @@ describe Tddium do
1513
1543
 
1514
1544
  context "'GET #{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}' is successful" do
1515
1545
  before(:each) do
1516
- response = {
1517
- "suite" => {
1518
- "id" => SAMPLE_SUITE_ID,
1519
- "repo_name" => SAMPLE_APP_NAME,
1520
- "branch" => SAMPLE_BRANCH_NAME
1521
- }
1522
- }
1523
- stub_call_api_response(:get, "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}", response)
1546
+ stub_call_api_response(:get, "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}", {"suite"=>SAMPLE_SUITE_RESPONSE})
1524
1547
  end
1525
1548
 
1526
1549
  it "should not ask for a suite name" do
@@ -1535,7 +1558,7 @@ describe Tddium do
1535
1558
  end
1536
1559
 
1537
1560
  it "should display '#{Tddium::Text::Process::EXISTING_SUITE}'" do
1538
- tddium.should_receive(:say).with(Tddium::Text::Process::EXISTING_SUITE % "#{SAMPLE_APP_NAME}/#{SAMPLE_BRANCH_NAME}")
1561
+ tddium.should_receive(:say).with(Tddium::Text::Process::EXISTING_SUITE % SAMPLE_SUITE_OUTPUT)
1539
1562
  run_suite(tddium)
1540
1563
  end
1541
1564
 
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tddium-preview
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 5
9
- - 6
10
- version: 0.5.6
5
+ version: 0.6.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Solano Labs
@@ -15,7 +10,7 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-06-14 00:00:00 -07:00
13
+ date: 2011-06-15 00:00:00 -07:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
@@ -26,9 +21,6 @@ dependencies:
26
21
  requirements:
27
22
  - - ">="
28
23
  - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
24
  version: "0"
33
25
  type: :runtime
34
26
  version_requirements: *id001
@@ -40,9 +32,6 @@ dependencies:
40
32
  requirements:
41
33
  - - ">="
42
34
  - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
35
  version: "0"
47
36
  type: :runtime
48
37
  version_requirements: *id002
@@ -54,9 +43,6 @@ dependencies:
54
43
  requirements:
55
44
  - - ">="
56
45
  - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
46
  version: "0"
61
47
  type: :runtime
62
48
  version_requirements: *id003
@@ -68,11 +54,6 @@ dependencies:
68
54
  requirements:
69
55
  - - ">="
70
56
  - !ruby/object:Gem::Version
71
- hash: 19
72
- segments:
73
- - 0
74
- - 0
75
- - 6
76
57
  version: 0.0.6
77
58
  type: :runtime
78
59
  version_requirements: *id004
@@ -84,9 +65,6 @@ dependencies:
84
65
  requirements:
85
66
  - - ">="
86
67
  - !ruby/object:Gem::Version
87
- hash: 3
88
- segments:
89
- - 0
90
68
  version: "0"
91
69
  type: :runtime
92
70
  version_requirements: *id005
@@ -98,9 +76,6 @@ dependencies:
98
76
  requirements:
99
77
  - - ">="
100
78
  - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 0
104
79
  version: "0"
105
80
  type: :development
106
81
  version_requirements: *id006
@@ -112,9 +87,6 @@ dependencies:
112
87
  requirements:
113
88
  - - ">="
114
89
  - !ruby/object:Gem::Version
115
- hash: 3
116
- segments:
117
- - 0
118
90
  version: "0"
119
91
  type: :development
120
92
  version_requirements: *id007
@@ -126,9 +98,6 @@ dependencies:
126
98
  requirements:
127
99
  - - ">="
128
100
  - !ruby/object:Gem::Version
129
- hash: 3
130
- segments:
131
- - 0
132
101
  version: "0"
133
102
  type: :development
134
103
  version_requirements: *id008
@@ -140,9 +109,6 @@ dependencies:
140
109
  requirements:
141
110
  - - ">="
142
111
  - !ruby/object:Gem::Version
143
- hash: 3
144
- segments:
145
- - 0
146
112
  version: "0"
147
113
  type: :development
148
114
  version_requirements: *id009
@@ -192,18 +158,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
158
  requirements:
193
159
  - - ">="
194
160
  - !ruby/object:Gem::Version
195
- hash: 3
196
- segments:
197
- - 0
198
161
  version: "0"
199
162
  required_rubygems_version: !ruby/object:Gem::Requirement
200
163
  none: false
201
164
  requirements:
202
165
  - - ">="
203
166
  - !ruby/object:Gem::Version
204
- hash: 3
205
- segments:
206
- - 0
207
167
  version: "0"
208
168
  requirements: []
209
169