engineyard 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/engineyard.rb +1 -17
- data/lib/engineyard/account.rb +13 -49
- data/lib/engineyard/account/app.rb +18 -0
- data/lib/engineyard/account/app_master.rb +12 -0
- data/lib/engineyard/account/environment.rb +31 -0
- data/lib/engineyard/account/log.rb +18 -0
- data/lib/engineyard/api.rb +4 -2
- data/lib/engineyard/cli.rb +34 -11
- data/lib/engineyard/cli/ui.rb +1 -1
- data/spec/engineyard/api_spec.rb +6 -6
- data/spec/engineyard/cli/api_spec.rb +1 -1
- data/spec/engineyard/config_spec.rb +9 -9
- data/spec/ey/deploy_spec.rb +40 -21
- data/spec/ey/logs_spec.rb +28 -0
- data/spec/spec_helper.rb +12 -13
- data/spec/support/fake_awsm.ru +251 -0
- data/spec/support/helpers.rb +50 -38
- data/spec/support/ruby_ext.rb +29 -0
- metadata +52 -102
- data/lib/vendor/thor.rb +0 -244
- data/lib/vendor/thor/actions.rb +0 -275
- data/lib/vendor/thor/actions/create_file.rb +0 -103
- data/lib/vendor/thor/actions/directory.rb +0 -91
- data/lib/vendor/thor/actions/empty_directory.rb +0 -134
- data/lib/vendor/thor/actions/file_manipulation.rb +0 -223
- data/lib/vendor/thor/actions/inject_into_file.rb +0 -104
- data/lib/vendor/thor/base.rb +0 -540
- data/lib/vendor/thor/core_ext/file_binary_read.rb +0 -9
- data/lib/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -75
- data/lib/vendor/thor/core_ext/ordered_hash.rb +0 -100
- data/lib/vendor/thor/error.rb +0 -30
- data/lib/vendor/thor/group.rb +0 -271
- data/lib/vendor/thor/invocation.rb +0 -180
- data/lib/vendor/thor/parser.rb +0 -4
- data/lib/vendor/thor/parser/argument.rb +0 -67
- data/lib/vendor/thor/parser/arguments.rb +0 -150
- data/lib/vendor/thor/parser/option.rb +0 -128
- data/lib/vendor/thor/parser/options.rb +0 -169
- data/lib/vendor/thor/rake_compat.rb +0 -66
- data/lib/vendor/thor/runner.rb +0 -314
- data/lib/vendor/thor/shell.rb +0 -83
- data/lib/vendor/thor/shell/basic.rb +0 -239
- data/lib/vendor/thor/shell/color.rb +0 -108
- data/lib/vendor/thor/task.rb +0 -102
- data/lib/vendor/thor/util.rb +0 -230
- data/lib/vendor/thor/version.rb +0 -3
data/lib/engineyard.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module EY
|
2
|
-
VERSION = "0.2.
|
2
|
+
VERSION = "0.2.10"
|
3
3
|
|
4
4
|
autoload :Account, 'engineyard/account'
|
5
5
|
autoload :API, 'engineyard/api'
|
@@ -24,21 +24,5 @@ module EY
|
|
24
24
|
@config ||= EY::Config.new
|
25
25
|
end
|
26
26
|
|
27
|
-
def config=(config)
|
28
|
-
@config = config
|
29
|
-
end
|
30
|
-
|
31
|
-
def library(libname)
|
32
|
-
begin
|
33
|
-
require libname
|
34
|
-
rescue LoadError
|
35
|
-
unless @tried_rubygems
|
36
|
-
require 'rubygems' rescue LoadError nil
|
37
|
-
@tried_rubygems = true
|
38
|
-
retry
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
27
|
end
|
44
28
|
end
|
data/lib/engineyard/account.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'engineyard/account/app'
|
2
|
+
require 'engineyard/account/app_master'
|
3
|
+
require 'engineyard/account/environment'
|
4
|
+
require 'engineyard/account/log'
|
5
|
+
|
1
6
|
module EY
|
2
7
|
class Account
|
3
8
|
|
@@ -5,10 +10,14 @@ module EY
|
|
5
10
|
@api = api
|
6
11
|
end
|
7
12
|
|
13
|
+
def request(path, options = { })
|
14
|
+
@api.request(path, {:method => :get}.merge(options))
|
15
|
+
end
|
16
|
+
|
8
17
|
def environments
|
9
18
|
return @environments if @environments
|
10
|
-
data =
|
11
|
-
@environments = Environment.from_array(data || [])
|
19
|
+
data = request('/environments')["environments"]
|
20
|
+
@environments = Environment.from_array(data || [], self)
|
12
21
|
end
|
13
22
|
|
14
23
|
def environment_named(name)
|
@@ -17,8 +26,8 @@ module EY
|
|
17
26
|
|
18
27
|
def apps
|
19
28
|
return @apps if @apps
|
20
|
-
data = @api.request('/apps'
|
21
|
-
@apps = App.from_array(data || [])
|
29
|
+
data = @api.request('/apps')["apps"]
|
30
|
+
@apps = App.from_array(data || [], self)
|
22
31
|
end
|
23
32
|
|
24
33
|
def app_named(name)
|
@@ -29,50 +38,5 @@ module EY
|
|
29
38
|
apps.find{|a| repo.urls.include?(a.repository_url) }
|
30
39
|
end
|
31
40
|
|
32
|
-
# Classes to represent the returned data
|
33
|
-
class Environment < Struct.new(:name, :instances_count, :apps, :app_master, :username)
|
34
|
-
def self.from_hash(hash)
|
35
|
-
new(
|
36
|
-
hash["name"],
|
37
|
-
hash["instances_count"],
|
38
|
-
App.from_array(hash["apps"]),
|
39
|
-
AppMaster.from_hash(hash["app_master"]),
|
40
|
-
hash["ssh_username"]
|
41
|
-
) if hash && hash != "null"
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.from_array(array)
|
45
|
-
array.map{|n| from_hash(n) } if array && array != "null"
|
46
|
-
end
|
47
|
-
|
48
|
-
def configuration
|
49
|
-
EY.config.environments[self.name]
|
50
|
-
end
|
51
|
-
alias_method :config, :configuration
|
52
|
-
end
|
53
|
-
|
54
|
-
class App < Struct.new(:name, :repository_url, :environments)
|
55
|
-
def self.from_hash(hash)
|
56
|
-
new(
|
57
|
-
hash["name"],
|
58
|
-
hash["repository_uri"], # We use url canonically in the ey gem
|
59
|
-
Environment.from_array(hash["environments"])
|
60
|
-
) if hash && hash != "null"
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.from_array(array)
|
64
|
-
array.map{|n| from_hash(n) } if array && array != "null"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class AppMaster < Struct.new(:status, :public_hostname)
|
69
|
-
def self.from_hash(hash)
|
70
|
-
new(
|
71
|
-
hash["status"],
|
72
|
-
hash["public_hostname"]
|
73
|
-
) if hash && hash != "null"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
41
|
end # Account
|
78
42
|
end # EY
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EY
|
2
|
+
class Account
|
3
|
+
class App < Struct.new(:name, :repository_url, :environments, :account)
|
4
|
+
def self.from_hash(hash, account)
|
5
|
+
new(
|
6
|
+
hash["name"],
|
7
|
+
hash["repository_uri"], # We use url canonically in the ey gem
|
8
|
+
Environment.from_array(hash["environments"], account),
|
9
|
+
account
|
10
|
+
) if hash && hash != "null"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_array(array, account)
|
14
|
+
array.map{|n| from_hash(n, account) } if array && array != "null"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EY
|
2
|
+
class Account
|
3
|
+
class Environment < Struct.new(:id, :name, :instances_count, :apps, :app_master, :username, :account)
|
4
|
+
def self.from_hash(hash, account)
|
5
|
+
new(
|
6
|
+
hash["id"],
|
7
|
+
hash["name"],
|
8
|
+
hash["instances_count"],
|
9
|
+
App.from_array(hash["apps"], account),
|
10
|
+
AppMaster.from_hash(hash["app_master"]),
|
11
|
+
hash["ssh_username"],
|
12
|
+
account
|
13
|
+
) if hash && hash != "null"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_array(array, account)
|
17
|
+
array.map{|n| from_hash(n, account) } if array && array != "null"
|
18
|
+
end
|
19
|
+
|
20
|
+
def logs
|
21
|
+
data = account.request("/environments/#{id}/logs")['logs']
|
22
|
+
Log.from_array(data || [])
|
23
|
+
end
|
24
|
+
|
25
|
+
def configuration
|
26
|
+
EY.config.environments[self.name]
|
27
|
+
end
|
28
|
+
alias_method :config, :configuration
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Log < Struct.new(:id, :role, :main, :custom)
|
2
|
+
def self.from_hash(hash)
|
3
|
+
new(
|
4
|
+
hash["id"],
|
5
|
+
hash["role"],
|
6
|
+
hash["main"],
|
7
|
+
hash["custom"]
|
8
|
+
) if hash && hash != "null"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_array(array)
|
12
|
+
array.map{|n| from_hash(n) } if array && array != "null"
|
13
|
+
end
|
14
|
+
|
15
|
+
def instance_name
|
16
|
+
"#{role} #{id}"
|
17
|
+
end
|
18
|
+
end
|
data/lib/engineyard/api.rb
CHANGED
@@ -24,8 +24,8 @@ module EY
|
|
24
24
|
class RequestFailed < EY::Error; end
|
25
25
|
|
26
26
|
def self.request(path, opts={})
|
27
|
-
|
28
|
-
|
27
|
+
require 'rest_client'
|
28
|
+
require 'json'
|
29
29
|
|
30
30
|
url = EY.config.endpoint + "api/v2#{path}"
|
31
31
|
method = ((meth = opts.delete(:method)) && meth.to_s || "get").downcase.to_sym
|
@@ -50,6 +50,8 @@ module EY
|
|
50
50
|
raise RequestFailed, "The requested resource could not be found"
|
51
51
|
rescue RestClient::RequestFailed => e
|
52
52
|
raise RequestFailed, "#{e.message}"
|
53
|
+
rescue OpenSSL::SSL::SSLError
|
54
|
+
raise RequestFailed, "SSL is misconfigured on your cloud"
|
53
55
|
end
|
54
56
|
raise RequestFailed, "Response body was empty" if resp.body.empty?
|
55
57
|
|
data/lib/engineyard/cli.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
$:.unshift File.expand_path('../../vendor', __FILE__)
|
2
1
|
require 'thor'
|
3
|
-
|
4
2
|
require 'engineyard'
|
5
3
|
require 'engineyard/cli/error'
|
6
4
|
|
7
5
|
module EY
|
8
6
|
class CLI < Thor
|
9
|
-
EYSD_VERSION = "~>0.2.
|
7
|
+
EYSD_VERSION = "~>0.2.5"
|
10
8
|
|
11
9
|
autoload :API, 'engineyard/cli/api'
|
12
10
|
autoload :UI, 'engineyard/cli/ui'
|
@@ -22,6 +20,7 @@ module EY
|
|
22
20
|
method_option :force, :type => :boolean, :aliases => %w(-f),
|
23
21
|
:desc => "Force a deploy of the specified branch"
|
24
22
|
method_option :migrate, :type => :string, :aliases => %w(-m),
|
23
|
+
:default => 'rake db:migrate',
|
25
24
|
:desc => "Run migrations via [MIGRATE], defaults to 'rake db:migrate'"
|
26
25
|
method_option :install_eysd, :type => :boolean, :aliases => %(-s),
|
27
26
|
:desc => "Force remote install of eysd"
|
@@ -39,7 +38,7 @@ module EY
|
|
39
38
|
invalid_branch = default_branch && (branch != default_branch) && !options[:force]
|
40
39
|
raise BranchMismatch.new(default_branch, branch) if invalid_branch
|
41
40
|
|
42
|
-
if env_name
|
41
|
+
if env_name && app.environments
|
43
42
|
env = app.environments.find{|e| e.name == env_name }
|
44
43
|
else
|
45
44
|
env = app.environments.first
|
@@ -84,12 +83,8 @@ module EY
|
|
84
83
|
deploy_cmd << " --config '#{escaped_config_option}'"
|
85
84
|
end
|
86
85
|
|
87
|
-
if options
|
88
|
-
|
89
|
-
deploy_cmd << " --migrate='#{options[:migrate]}'"
|
90
|
-
else
|
91
|
-
deploy_cmd << " --no-migrate"
|
92
|
-
end
|
86
|
+
if options['migrate']
|
87
|
+
deploy_cmd << " --migrate='#{options[:migrate]}'"
|
93
88
|
end
|
94
89
|
|
95
90
|
EY.ui.info "Running deploy on server..."
|
@@ -129,6 +124,30 @@ module EY
|
|
129
124
|
end
|
130
125
|
end
|
131
126
|
|
127
|
+
desc "logs environment", "Retrieve the latest logs for an enviornment"
|
128
|
+
def logs(environment)
|
129
|
+
env = account.environment_named(environment)
|
130
|
+
|
131
|
+
if env.nil?
|
132
|
+
raise EnvironmentError, "Environment '#{env_name}' can't be found\n" +
|
133
|
+
"You can create it at #{EY.config.endpoint}"
|
134
|
+
else
|
135
|
+
env.logs.each do |log|
|
136
|
+
EY.ui.info log.instance_name
|
137
|
+
|
138
|
+
if log.main
|
139
|
+
EY.ui.info "Main logs:"
|
140
|
+
EY.ui.say log.main
|
141
|
+
end
|
142
|
+
|
143
|
+
if log.custom
|
144
|
+
EY.ui.info "Custom logs:"
|
145
|
+
EY.ui.say log.custom
|
146
|
+
end
|
147
|
+
end # logs_for_environment(env).each
|
148
|
+
end # env.nil?
|
149
|
+
end
|
150
|
+
|
132
151
|
desc "version", "Print the version of the engineyard gem"
|
133
152
|
def version
|
134
153
|
EY.ui.say %{engineyard version #{EY::VERSION}}
|
@@ -167,7 +186,11 @@ module EY
|
|
167
186
|
cmd << %{ &> /dev/null} unless output
|
168
187
|
EY.ui.debug(cmd)
|
169
188
|
puts cmd if output
|
170
|
-
|
189
|
+
unless ENV["NO_SSH"]
|
190
|
+
system cmd
|
191
|
+
else
|
192
|
+
true
|
193
|
+
end
|
171
194
|
end
|
172
195
|
|
173
196
|
end # CLI
|
data/lib/engineyard/cli/ui.rb
CHANGED
data/spec/engineyard/api_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe EY::API do
|
4
4
|
it "gets the api token from ~/.eyrc if possible" do
|
5
|
-
|
5
|
+
write_yaml({"api_token" => "asdf"}, '~/.eyrc')
|
6
6
|
EY::API.new.should == EY::API.new("asdf")
|
7
7
|
end
|
8
8
|
|
@@ -17,7 +17,7 @@ describe EY::API do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "puts the api token into .eyrc" do
|
20
|
-
|
20
|
+
read_yaml('~/.eyrc')["api_token"].should == "asdf"
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -25,18 +25,18 @@ describe EY::API do
|
|
25
25
|
context "without a custom endpoint" do
|
26
26
|
it "saves the api token at the root of the data" do
|
27
27
|
EY::API.save_token("asdf")
|
28
|
-
|
28
|
+
read_yaml('~/.eyrc')["api_token"].should == "asdf"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context "with a custom endpoint" do
|
33
|
-
before do
|
34
|
-
|
33
|
+
before(:each) do
|
34
|
+
write_yaml({"endpoint" => "http://localhost/"}, 'ey.yml')
|
35
35
|
EY::API.save_token("asdf")
|
36
36
|
end
|
37
37
|
|
38
38
|
it "saves the api token" do
|
39
|
-
|
39
|
+
read_yaml('~/.eyrc').should == {"http://localhost/" => {"api_token" => "asdf"}}
|
40
40
|
end
|
41
41
|
|
42
42
|
it "reads the api token" do
|
@@ -22,7 +22,7 @@ describe EY::CLI::API do
|
|
22
22
|
before(:each) do
|
23
23
|
FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :body => %|{"api_token": "asdf"}|)
|
24
24
|
|
25
|
-
|
25
|
+
capture_stdio("\n\n") do
|
26
26
|
@token = EY::CLI::API.new
|
27
27
|
end
|
28
28
|
end
|
@@ -4,12 +4,12 @@ require 'uri'
|
|
4
4
|
describe EY::Config do
|
5
5
|
describe "environments" do
|
6
6
|
it "get loaded from the config file" do
|
7
|
-
|
7
|
+
write_yaml("environments" => {"production" => {"default" => true}})
|
8
8
|
EY::Config.new.environments["production"]["default"].should be_true
|
9
9
|
end
|
10
10
|
|
11
11
|
it "are present when the config file has no environments key" do
|
12
|
-
|
12
|
+
write_yaml("endpoint" => "http://localhost/")
|
13
13
|
EY::Config.new.environments.should == {}
|
14
14
|
end
|
15
15
|
end
|
@@ -20,36 +20,36 @@ describe EY::Config do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "gets loaded from the config file" do
|
23
|
-
|
23
|
+
write_yaml("endpoint" => "http://localhost/")
|
24
24
|
EY::Config.new.endpoint.should == URI.parse("http://localhost/")
|
25
25
|
end
|
26
26
|
|
27
27
|
it "raises on an invalid endpoint" do
|
28
|
-
|
28
|
+
write_yaml("endpoint" => "non/absolute")
|
29
29
|
lambda { EY::Config.new.endpoint }.
|
30
30
|
should raise_error(EY::Config::ConfigurationError)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
it "provides default_endpoint?" do
|
35
|
-
|
35
|
+
write_yaml("endpoint" => "http://localhost/")
|
36
36
|
EY::Config.new.default_endpoint?.should_not be_true
|
37
37
|
end
|
38
38
|
|
39
39
|
describe "files" do
|
40
40
|
it "looks for config/ey.yml" do
|
41
|
-
|
42
|
-
|
41
|
+
write_yaml({"endpoint" => "http://something/"}, "ey.yml")
|
42
|
+
write_yaml({"endpoint" => "http://localhost/"}, "config/ey.yml")
|
43
43
|
EY::Config.new.endpoint.should == URI.parse("http://localhost/")
|
44
44
|
end
|
45
45
|
|
46
46
|
it "looks for ey.yml" do
|
47
|
-
|
47
|
+
write_yaml({"endpoint" => "http://foo/"}, "ey.yml")
|
48
48
|
EY::Config.new.endpoint.should == URI.parse("http://foo/")
|
49
49
|
end
|
50
50
|
|
51
51
|
it "looks for the file given" do
|
52
|
-
|
52
|
+
write_yaml({"endpoint" => "http://bar/"}, "summat.yml")
|
53
53
|
EY::Config.new("summat.yml").endpoint.should == URI.parse("http://bar/")
|
54
54
|
end
|
55
55
|
end
|
data/spec/ey/deploy_spec.rb
CHANGED
@@ -2,14 +2,16 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "ey deploy" do
|
4
4
|
before(:all) do
|
5
|
-
ENV['EYRC'] = "/tmp/eyrc"
|
6
|
-
ENV['CLOUD_URL'] = "http://localhost:4000"
|
7
5
|
FakeFS.deactivate!
|
6
|
+
ENV['EYRC'] = "/tmp/eyrc"
|
7
|
+
ENV['CLOUD_URL'] = EY.fake_awsm
|
8
|
+
FakeWeb.allow_net_connect = true
|
8
9
|
end
|
9
10
|
|
10
11
|
after(:all) do
|
11
12
|
ENV['CLOUD_URL'] = nil
|
12
13
|
FakeFS.activate!
|
14
|
+
FakeWeb.allow_net_connect = false
|
13
15
|
end
|
14
16
|
|
15
17
|
describe "without an eyrc file" do
|
@@ -18,10 +20,11 @@ describe "ey deploy" do
|
|
18
20
|
end
|
19
21
|
|
20
22
|
it "prompts for authentication" do
|
21
|
-
ey("deploy") do |input|
|
22
|
-
input.puts("
|
23
|
-
input.puts("
|
23
|
+
ey("deploy", :hide_err => true) do |input|
|
24
|
+
input.puts("test@test.test")
|
25
|
+
input.puts("test")
|
24
26
|
end
|
27
|
+
|
25
28
|
@out.should include("We need to fetch your API token, please login")
|
26
29
|
@out.should include("Email:")
|
27
30
|
@out.should include("Password:")
|
@@ -36,30 +39,46 @@ describe "ey deploy" do
|
|
36
39
|
end
|
37
40
|
|
38
41
|
it "complains when there is no app" do
|
39
|
-
|
42
|
+
api_scenario "empty"
|
40
43
|
ey "deploy", :hide_err => true
|
41
|
-
@err.should include
|
44
|
+
@err.should include(%|no application configured|)
|
42
45
|
end
|
43
46
|
|
44
|
-
it "complains when there is no environment" do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@out.should match(/no environment/i)
|
47
|
+
it "complains when there is no environment for the app" do
|
48
|
+
api_scenario "one app, one environment, not linked"
|
49
|
+
ey "deploy giblets master", :hide_err => true
|
50
|
+
@err.should match(/doesn't run this application/i)
|
49
51
|
end
|
50
52
|
|
51
53
|
it "runs when environment is known" do
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@
|
54
|
+
api_scenario "one app, one environment"
|
55
|
+
ey "deploy", :hide_err => true
|
56
|
+
@out.should match(/running deploy/i)
|
57
|
+
@err.should be_empty
|
56
58
|
end
|
57
59
|
|
58
60
|
it "complains when environment is ambiguous" do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
api_scenario "one app, two environments"
|
62
|
+
ey "deploy", :hide_err => true
|
63
|
+
@err.should match(/was called incorrectly/i)
|
64
|
+
end
|
65
|
+
|
66
|
+
context "migration command" do
|
67
|
+
before(:each) do
|
68
|
+
api_scenario "one app, one environment"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "defaults to 'rake db:migrate'" do
|
72
|
+
ey "deploy"
|
73
|
+
@ssh_commands.size.should == 1
|
74
|
+
@ssh_commands.first.should =~ /--migrate='rake db:migrate'/
|
75
|
+
end
|
76
|
+
|
77
|
+
it "can be disabled with --no-migrate" do
|
78
|
+
ey "deploy --no-migrate"
|
79
|
+
@ssh_commands.size.should == 1
|
80
|
+
@ssh_commands.first.should_not =~ /--migrate/
|
81
|
+
end
|
63
82
|
end
|
64
83
|
end
|
65
|
-
end
|
84
|
+
end
|