monkey_butler 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.bundle/config +2 -0
- data/.gitignore +3 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +28 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +122 -0
- data/Guardfile +8 -0
- data/LICENSE +202 -0
- data/README.md +221 -0
- data/Rakefile +16 -0
- data/bin/mb +6 -0
- data/lib/monkey_butler.rb +1 -0
- data/lib/monkey_butler/actions.rb +38 -0
- data/lib/monkey_butler/cli.rb +354 -0
- data/lib/monkey_butler/databases/abstract_database.rb +49 -0
- data/lib/monkey_butler/databases/cassandra_database.rb +69 -0
- data/lib/monkey_butler/databases/sqlite_database.rb +105 -0
- data/lib/monkey_butler/migrations.rb +52 -0
- data/lib/monkey_butler/project.rb +90 -0
- data/lib/monkey_butler/targets/base.rb +85 -0
- data/lib/monkey_butler/targets/cassandra/cassandra_target.rb +72 -0
- data/lib/monkey_butler/targets/cassandra/create_schema_migrations.cql.erb +16 -0
- data/lib/monkey_butler/targets/cassandra/migration.cql.erb +0 -0
- data/lib/monkey_butler/targets/cocoapods/cocoapods_target.rb +43 -0
- data/lib/monkey_butler/targets/cocoapods/podspec.erb +12 -0
- data/lib/monkey_butler/targets/maven/maven_target.rb +60 -0
- data/lib/monkey_butler/targets/maven/project/.gitignore +6 -0
- data/lib/monkey_butler/targets/maven/project/MonkeyButler.iml +19 -0
- data/lib/monkey_butler/targets/maven/project/build.gradle +54 -0
- data/lib/monkey_butler/targets/sqlite/create_monkey_butler_tables.sql.erb +15 -0
- data/lib/monkey_butler/targets/sqlite/migration.sql.erb +11 -0
- data/lib/monkey_butler/targets/sqlite/sqlite_target.rb +91 -0
- data/lib/monkey_butler/templates/Gemfile.erb +4 -0
- data/lib/monkey_butler/templates/gitignore.erb +1 -0
- data/lib/monkey_butler/util.rb +71 -0
- data/lib/monkey_butler/version.rb +3 -0
- data/logo.jpg +0 -0
- data/monkey_butler.gemspec +33 -0
- data/spec/cli_spec.rb +700 -0
- data/spec/databases/cassandra_database_spec.rb +241 -0
- data/spec/databases/sqlite_database_spec.rb +181 -0
- data/spec/migrations_spec.rb +4 -0
- data/spec/project_spec.rb +128 -0
- data/spec/sandbox/cassandra/.gitignore +2 -0
- data/spec/sandbox/cassandra/.monkey_butler.yml +7 -0
- data/spec/sandbox/cassandra/migrations/20140523123443021_create_sandbox.cql.sql +14 -0
- data/spec/sandbox/cassandra/sandbox.cql +0 -0
- data/spec/sandbox/sqlite/.gitignore +2 -0
- data/spec/sandbox/sqlite/.monkey_butler.yml +7 -0
- data/spec/sandbox/sqlite/migrations/20140523123443021_create_sandbox.sql +14 -0
- data/spec/sandbox/sqlite/sandbox.sql +0 -0
- data/spec/spec_helper.rb +103 -0
- data/spec/targets/cassandra_target_spec.rb +191 -0
- data/spec/targets/cocoapods_target_spec.rb +197 -0
- data/spec/targets/maven_target_spec.rb +156 -0
- data/spec/targets/sqlite_target_spec.rb +103 -0
- data/spec/util_spec.rb +13 -0
- metadata +260 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
/* Create Monkey Butler Tables */
|
2
|
+
|
3
|
+
-- Maintains list of applied migrations
|
4
|
+
CREATE TABLE schema_migrations(
|
5
|
+
version INTEGER UNIQUE NOT NULL
|
6
|
+
);
|
7
|
+
|
8
|
+
/* Create application tables */
|
9
|
+
/*
|
10
|
+
CREATE TABLE table_name (
|
11
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
12
|
+
...
|
13
|
+
);
|
14
|
+
*/
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/* Create Monkey Butler Tables */
|
2
|
+
|
3
|
+
-- Maintains list of applied migrations
|
4
|
+
CREATE TABLE schema_migrations(
|
5
|
+
version INTEGER UNIQUE NOT NULL
|
6
|
+
);
|
7
|
+
|
8
|
+
/* Create application tables */
|
9
|
+
/*
|
10
|
+
CREATE TABLE table_name (
|
11
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
12
|
+
...
|
13
|
+
);
|
14
|
+
*/
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'monkey_butler'
|
5
|
+
|
6
|
+
require 'rspec/core/shared_context'
|
7
|
+
require 'tempfile'
|
8
|
+
require 'digest'
|
9
|
+
require 'byebug'
|
10
|
+
|
11
|
+
module GlobalContext
|
12
|
+
extend RSpec::Core::SharedContext
|
13
|
+
|
14
|
+
# Assume that most specs will describe a Thor subclass
|
15
|
+
let(:thor_class) { subject.class }
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.before do
|
20
|
+
ARGV.replace []
|
21
|
+
MonkeyButler::Project.clear
|
22
|
+
end
|
23
|
+
|
24
|
+
config.include GlobalContext
|
25
|
+
|
26
|
+
def capture(stream)
|
27
|
+
begin
|
28
|
+
stream = stream.to_s
|
29
|
+
eval "$#{stream} = StringIO.new"
|
30
|
+
yield
|
31
|
+
result = eval("$#{stream}").string
|
32
|
+
ensure
|
33
|
+
eval("$#{stream} = #{stream.upcase}")
|
34
|
+
end
|
35
|
+
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
def capture_output(proc, &block)
|
40
|
+
error = nil
|
41
|
+
content = capture(:stdout) do
|
42
|
+
error = capture(:stderr) do
|
43
|
+
proc.call
|
44
|
+
end
|
45
|
+
end
|
46
|
+
yield content, error if block_given?
|
47
|
+
{ stdout: content, stderr: error }
|
48
|
+
end
|
49
|
+
|
50
|
+
# def source_root
|
51
|
+
# File.join(File.dirname(__FILE__), "fixtures")
|
52
|
+
# end
|
53
|
+
|
54
|
+
def sandbox_root
|
55
|
+
Pathname.new File.join(File.dirname(__FILE__), "sandbox")
|
56
|
+
end
|
57
|
+
|
58
|
+
def clone_temp_sandbox(database = :sqlite)
|
59
|
+
Dir.mktmpdir.tap do |path|
|
60
|
+
FileUtils.cp_r Dir.glob(sandbox_root + "#{database}/."), path
|
61
|
+
Dir.chdir(path) do
|
62
|
+
system("git init -q .")
|
63
|
+
system("git remote add origin git@github.com:layerhq/monkey_butler_sandbox.git")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def random_migration_name
|
69
|
+
timestamp = MonkeyButler::Util.migration_timestamp + rand(1..1000)
|
70
|
+
MonkeyButler::Util.migration_named(Digest::SHA256.hexdigest(Time.now.to_s), timestamp)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Requires `thor_class` and `project_root`
|
74
|
+
def invoke!(args = [], options = {:capture => true})
|
75
|
+
output = nil
|
76
|
+
# Some commands work with a directory that doesn't yet exist
|
77
|
+
dir = File.exists?(project_root) ? project_root : '.'
|
78
|
+
Dir.chdir(dir) do
|
79
|
+
if options[:capture]
|
80
|
+
output = capture_output(proc { thor_class.start(args) })
|
81
|
+
else
|
82
|
+
thor_class.start(args)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def invoke_target!(command, options = {})
|
88
|
+
output = nil
|
89
|
+
# Some commands work with a directory that doesn't yet exist
|
90
|
+
dir = File.exists?(project_root) ? project_root : '.'
|
91
|
+
Dir.chdir(dir) do
|
92
|
+
if options.delete(:capture)
|
93
|
+
output = capture_output proc do
|
94
|
+
target = thor_class.new([], options)
|
95
|
+
target.invoke(command)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
target = thor_class.new([], options)
|
99
|
+
target.invoke(command)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'monkey_butler/targets/cassandra/cassandra_target'
|
3
|
+
require 'monkey_butler/databases/cassandra_database'
|
4
|
+
|
5
|
+
describe MonkeyButler::Targets::CassandraTarget do
|
6
|
+
let(:thor_class) { MonkeyButler::CLI }
|
7
|
+
let!(:project_root) { clone_temp_sandbox(:cassandra) }
|
8
|
+
let(:project) { MonkeyButler::Project.load(project_root) }
|
9
|
+
let(:database) { MonkeyButler::Databases::CassandraDatabase.new(project.database_url) }
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
database.drop
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#init" do
|
16
|
+
let(:path) do
|
17
|
+
Dir.mktmpdir.tap { |path| FileUtils.remove_entry(path) }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "generates a new migration with the given name" do
|
21
|
+
invoke!(["init", "-d", "cassandra://localhost:9170/sandbox", path])
|
22
|
+
migration = Dir.entries(File.join(path, 'migrations')).detect { |f| f =~ /\d{15}_create_.+\.cql/ }
|
23
|
+
migration.should_not be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#new" do
|
28
|
+
it "generates a new migration with the given name" do
|
29
|
+
invoke!(%w{new add_column_to_table})
|
30
|
+
migration = Dir.entries(File.join(project_root, 'migrations')).detect { |f| f =~ /add_column_to_table\.cql/ }
|
31
|
+
migration.should_not be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#dump" do
|
36
|
+
before(:each) do
|
37
|
+
database = MonkeyButler::Databases::CassandraDatabase.new(project.database_url)
|
38
|
+
database.create_migrations_table
|
39
|
+
database.insert_version(123)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "dumps the database" do
|
43
|
+
invoke!(%w{dump})
|
44
|
+
content = File.read(File.join(project_root, project.schema_path))
|
45
|
+
content.should =~ /CREATE KEYSPACE sandbox/
|
46
|
+
end
|
47
|
+
|
48
|
+
it "dumps the schema_migrations rows" do
|
49
|
+
invoke!(%w{dump})
|
50
|
+
content = File.read(File.join(project_root, project.schema_path))
|
51
|
+
content.should =~ /INSERT INTO schema_migrations\(partition_key, version\) VALUES \(0, 123\);/
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when there are extra keyspaces specified" do
|
55
|
+
before(:each) do
|
56
|
+
database.client.execute "CREATE KEYSPACE IF NOT EXISTS extra1 WITH replication = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"
|
57
|
+
database.client.execute "CREATE KEYSPACE IF NOT EXISTS extra2 WITH replication = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "dumps the additional keyspaces" do
|
61
|
+
project.config['cassandra.keyspaces'] = %w{extra1 extra2}
|
62
|
+
project.save!(project_root)
|
63
|
+
invoke!(%w{dump})
|
64
|
+
content = File.read(File.join(project_root, project.schema_path))
|
65
|
+
content.should =~ /CREATE KEYSPACE extra1/
|
66
|
+
content.should =~ /CREATE KEYSPACE extra2/
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#load" do
|
72
|
+
before(:each) do
|
73
|
+
@database = MonkeyButler::Databases::CassandraDatabase.new(project.database_url)
|
74
|
+
@database.create_migrations_table
|
75
|
+
invoke!(%w{dump})
|
76
|
+
@database.drop
|
77
|
+
end
|
78
|
+
|
79
|
+
it "loads the database" do
|
80
|
+
expect(@database.migrations_table?).to be_false
|
81
|
+
invoke!(%w{load})
|
82
|
+
expect(@database.migrations_table?).to be_true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#status" do
|
87
|
+
context "when the database is empty" do
|
88
|
+
before(:each) do
|
89
|
+
database.drop
|
90
|
+
end
|
91
|
+
|
92
|
+
it "shows status" do
|
93
|
+
output = invoke!(%w{status})
|
94
|
+
output[:stdout].should =~ /New database/
|
95
|
+
output[:stdout].should =~ /The database at 'cassandra:\/\/localhost:9042\/sandbox' does not have a 'schema_migrations' table./
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when the database is up to date" do
|
100
|
+
before(:each) do
|
101
|
+
database.create_migrations_table
|
102
|
+
database.insert_version(12345)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "tells the user the database is up to date" do
|
106
|
+
output = invoke!(%w{status})
|
107
|
+
output[:stdout].should =~ /Current version: 12345/
|
108
|
+
output[:stdout].should =~ /Database is up to date./
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when there are migrations to apply" do
|
113
|
+
before(:each) do
|
114
|
+
File.open(File.join(project_root, 'migrations/20140523123443021_add_another_table.cql'), 'w') do |f|
|
115
|
+
f << "CREATE TABLE IF NOT EXISTS sandbox.another_table (some_column VARINT, PRIMARY KEY (some_column));"
|
116
|
+
end
|
117
|
+
database.create_migrations_table
|
118
|
+
database.insert_version(12345)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "tells the user there is a migration to apply" do
|
122
|
+
output = invoke!(%w{status})
|
123
|
+
output[:stdout].should =~ /The database at 'cassandra:\/\/localhost:9042\/sandbox' is 1 version behind 20140523123443021/
|
124
|
+
output[:stdout].should =~ /pending migration: migrations\/20140523123443021_add_another_table.cql/
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "#migrate" do
|
130
|
+
context "when the database is empty" do
|
131
|
+
before(:each) do
|
132
|
+
database.drop
|
133
|
+
end
|
134
|
+
|
135
|
+
it "shows migrate" do
|
136
|
+
output = invoke!(%w{migrate})
|
137
|
+
output[:stdout].should =~ /Database is up to date./
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "when the database is up to date" do
|
142
|
+
before(:each) do
|
143
|
+
database.create_migrations_table
|
144
|
+
database.insert_version(12345)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "tells the user the database is up to date" do
|
148
|
+
output = invoke!(%w{migrate})
|
149
|
+
output[:stdout].should =~ /Database is up to date./
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when there are migrations to apply" do
|
154
|
+
before(:each) do
|
155
|
+
File.open(File.join(project_root, 'migrations/20140523123443021_add_another_table.cql'), 'w') do |f|
|
156
|
+
f << "CREATE TABLE IF NOT EXISTS sandbox.another_table (some_column VARINT, PRIMARY KEY (some_column));"
|
157
|
+
end
|
158
|
+
database.create_migrations_table
|
159
|
+
database.insert_version(12345)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "tells the user there is a migration to apply" do
|
163
|
+
output = invoke!(%w{migrate})
|
164
|
+
output[:stdout].should =~ /applying migration: migrations\/20140523123443021_add_another_table.cql/
|
165
|
+
output[:stdout].should =~ /Migration to version 20140523123443021 complete./
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "#drop" do
|
171
|
+
before(:each) do
|
172
|
+
database.create_migrations_table
|
173
|
+
database.insert_version(123)
|
174
|
+
database.client.execute "CREATE KEYSPACE IF NOT EXISTS extra1 WITH replication = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"
|
175
|
+
database.client.execute "CREATE KEYSPACE IF NOT EXISTS extra2 WITH replication = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"
|
176
|
+
project.config['cassandra.keyspaces'] = %w{extra1 extra2}
|
177
|
+
project.save!(project_root)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "drops all keyspaces" do
|
181
|
+
invoke!(%w{drop})
|
182
|
+
database.client.use(:system)
|
183
|
+
rows = database.client.execute('SELECT keyspace_name FROM schema_columnfamilies')
|
184
|
+
keyspaces = []
|
185
|
+
rows.each { |row| keyspaces << row['keyspace_name'] }
|
186
|
+
keyspaces.should_not include('sandbox')
|
187
|
+
keyspaces.should_not include('extra1')
|
188
|
+
keyspaces.should_not include('extra2')
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'monkey_butler/targets/cocoapods/cocoapods_target'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Spec
|
6
|
+
attr_accessor :name, :version, :summary, :homepage, :author, :source, :license, :resource_bundles, :requires_arc
|
7
|
+
|
8
|
+
def initialize(hash = {})
|
9
|
+
yield self if block_given?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe MonkeyButler::Targets::CocoapodsTarget do
|
15
|
+
let(:thor_class) { MonkeyButler::Targets::CocoapodsTarget }
|
16
|
+
let!(:project_root) { clone_temp_sandbox }
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
Dir.chdir(project_root) do
|
20
|
+
system("git config user.email developer@layer.com")
|
21
|
+
system("git config user.name 'Layer Developer'")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#init" do
|
26
|
+
it "asks for the name of the cocoapods repository" do
|
27
|
+
remove_cocoapods_repo_from_config
|
28
|
+
expect(Thor::LineEditor).to receive(:readline).with("What is the name of your Cocoapods specs repo? ", {}).and_return("layerhq")
|
29
|
+
invoke!(['init'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#generate' do
|
34
|
+
let!(:podspec) do
|
35
|
+
invoke!(['generate'])
|
36
|
+
eval(File.read(File.join(project_root, 'sandbox.podspec')))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has name" do
|
40
|
+
expect(podspec.name).to eq('sandbox')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has version" do
|
44
|
+
expect(podspec.version).to eq('20140523123443021')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has summary" do
|
48
|
+
expect(podspec.summary).to eq('Packages the database schema and migrations for sandbox')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has homepage" do
|
52
|
+
expect(podspec.homepage).to eq('http://github.com/layerhq')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has author" do
|
56
|
+
expect(podspec.author).to eq({"Layer Developer"=>"developer@layer.com"})
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has source" do
|
60
|
+
expect(podspec.source).to eq({:git=>"git@github.com:layerhq/monkey_butler_sandbox.git", :tag=>"20140523123443021"})
|
61
|
+
end
|
62
|
+
|
63
|
+
it "has license" do
|
64
|
+
expect(podspec.license).to eq('Commercial')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has resource_bundles" do
|
68
|
+
expect(podspec.resource_bundles).to eq({"sandbox"=>["migrations/*", "sandbox.sql"]})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#push" do
|
73
|
+
context "when cocoapods.repo is not configured" do
|
74
|
+
it "fails with an error" do
|
75
|
+
remove_cocoapods_repo_from_config
|
76
|
+
output = invoke!(['push'])
|
77
|
+
output[:stderr].should =~ /Invalid configuration: cocoapods.repo is not configured./
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when cocoapods.repo is configured" do
|
82
|
+
it "invokes pod push" do
|
83
|
+
output = invoke!(['push', '--pretend'])
|
84
|
+
output[:stdout].should =~ /run\s+pod repo push --allow-warnings example_specs_repo sandbox.podspec/
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#validate" do
|
90
|
+
context "when the cocoapods repo is not configured" do
|
91
|
+
before(:each) do
|
92
|
+
remove_cocoapods_repo_from_config
|
93
|
+
end
|
94
|
+
|
95
|
+
it "fails with error" do
|
96
|
+
output = invoke!(['validate'])
|
97
|
+
output[:stderr].should =~ /Invalid configuration: cocoapods.repo is not configured./
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#push" do
|
103
|
+
context "when there is no repo configured" do
|
104
|
+
before(:each) do
|
105
|
+
remove_cocoapods_repo_from_config
|
106
|
+
end
|
107
|
+
|
108
|
+
it "fails validation" do
|
109
|
+
output = invoke!(['push'])
|
110
|
+
output[:stderr].should =~ /Invalid configuration: cocoapods.repo is not configured./
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when there is a repo configured" do
|
115
|
+
def with_temporary_cocoapods_repo
|
116
|
+
path = Dir.mktmpdir
|
117
|
+
temp_specs_repo_at_path(File.join(path, 'master'))
|
118
|
+
temp_specs_repo_at_path(File.join(path, 'example_specs_repo'))
|
119
|
+
|
120
|
+
ENV['CP_REPOS_DIR'] = path
|
121
|
+
yield path
|
122
|
+
ENV.delete('CP_REPOS_DIR')
|
123
|
+
end
|
124
|
+
|
125
|
+
it "pushes to cocoapods" do
|
126
|
+
git_repo_path = path_for_temp_bare_git_repo
|
127
|
+
Dir.chdir(project_root) do
|
128
|
+
`git remote set-url origin file://#{git_repo_path}`
|
129
|
+
end
|
130
|
+
|
131
|
+
# Generate the podspec
|
132
|
+
invoke!(['generate'])
|
133
|
+
|
134
|
+
Dir.chdir(project_root) do
|
135
|
+
`git remote set-url origin file://#{git_repo_path}`
|
136
|
+
`git add .`
|
137
|
+
`git commit --no-status -m 'Adding files' .`
|
138
|
+
`git tag 20140523123443021`
|
139
|
+
`git push -q origin master --tags`
|
140
|
+
end
|
141
|
+
|
142
|
+
with_temporary_cocoapods_repo do |repo_path|
|
143
|
+
output = invoke!(%w{push --quiet})
|
144
|
+
|
145
|
+
Dir.chdir(repo_path) do
|
146
|
+
pushed_podspec_path = File.join(repo_path, 'example_specs_repo', 'sandbox', '20140523123443021', 'sandbox.podspec')
|
147
|
+
File.exists?(pushed_podspec_path).should be_true
|
148
|
+
content = File.read(pushed_podspec_path)
|
149
|
+
content.should =~ /20140523123443021/
|
150
|
+
content.should =~ /resource_bundles/
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def remove_cocoapods_repo_from_config
|
158
|
+
yaml_path = File.join(project_root, '.monkey_butler.yml')
|
159
|
+
project = YAML.load(File.read(yaml_path))
|
160
|
+
project['config'].delete 'cocoapods.repo'
|
161
|
+
File.open(yaml_path, 'w') { |f| f << YAML.dump(project) }
|
162
|
+
end
|
163
|
+
|
164
|
+
def path_for_temp_bare_git_repo
|
165
|
+
git_repo_path = Dir.mktmpdir
|
166
|
+
Dir.chdir(git_repo_path) do
|
167
|
+
`git init --bare`
|
168
|
+
end
|
169
|
+
git_repo_path
|
170
|
+
end
|
171
|
+
|
172
|
+
def temp_specs_repo_at_path(path)
|
173
|
+
FileUtils.mkdir_p path
|
174
|
+
Dir.chdir(path) do
|
175
|
+
run("git init -q .")
|
176
|
+
raise "Failed to init git repo" unless $?.exitstatus.zero?
|
177
|
+
run("echo '' > README.md")
|
178
|
+
run("git add README.md")
|
179
|
+
run("git commit --no-status -m 'Add README.md' .")
|
180
|
+
raise "Failed to touch README.md" unless $?.exitstatus.zero?
|
181
|
+
remote_url = "file://#{path_for_temp_bare_git_repo}"
|
182
|
+
run("git remote add origin #{remote_url}")
|
183
|
+
raise "Failed to set origin remote url" unless $?.exitstatus.zero?
|
184
|
+
run("git push -q -u origin master")
|
185
|
+
raise "Failed to push to temp repo" unless $?.exitstatus.zero?
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def run(command, echo = false)
|
190
|
+
if echo
|
191
|
+
puts "Executing `#{command}`"
|
192
|
+
system(command)
|
193
|
+
else
|
194
|
+
`#{command}`
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|