duple 0.0.1 → 0.0.2
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/CHANGES.md +13 -0
- data/README.md +6 -6
- data/lib/duple/cli/config.rb +20 -0
- data/lib/duple/cli/copy.rb +16 -2
- data/lib/duple/cli/helpers.rb +28 -20
- data/lib/duple/cli/init.rb +8 -0
- data/lib/duple/cli/refresh.rb +16 -3
- data/lib/duple/cli/root.rb +2 -0
- data/lib/duple/cli/structure.rb +12 -2
- data/lib/duple/configuration.rb +24 -10
- data/lib/duple/heroku_runner.rb +3 -0
- data/lib/duple/pg_runner.rb +11 -8
- data/lib/duple/runner.rb +2 -0
- data/lib/duple/version.rb +1 -1
- data/spec/duple/cli/copy_spec.rb +5 -5
- data/spec/duple/cli/structure_spec.rb +4 -4
- data/spec/duple/configuration_spec.rb +48 -0
- metadata +3 -2
data/CHANGES.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## 0.0.2 (October 21, 2012) - Fix local db config
|
2
|
+
|
3
|
+
* Load db connection details from the config file.
|
4
|
+
* Added some minimal class-level documentation.
|
5
|
+
|
6
|
+
## 0.0.1 (October 19, 2012) - Initial release
|
7
|
+
|
8
|
+
* Implemented refresh from local to heroku and from heroku to local
|
9
|
+
* Implemented heroku to heroku refresh
|
10
|
+
* Implemented structure command
|
11
|
+
* Implemented config tasks
|
12
|
+
* Implemented copy command
|
13
|
+
* Added dry-run flag
|
data/README.md
CHANGED
@@ -26,31 +26,31 @@ figure the application. Read and modify it, or clear it out and write your own.
|
|
26
26
|
|
27
27
|
# Resets the stage database
|
28
28
|
# Loads the latest production snapshot into the stage database
|
29
|
-
$ duple refresh production stage
|
29
|
+
$ duple refresh -s production -t stage
|
30
30
|
|
31
31
|
# Downloads the latest full snapshot from production
|
32
32
|
# Resets the development database
|
33
33
|
# Loads the snapshot into the development database
|
34
|
-
$ duple refresh production development
|
34
|
+
$ duple refresh -s production -t development
|
35
35
|
|
36
36
|
# Captures a new production database snapshot
|
37
37
|
# Downloads the latest full snapshot from production
|
38
38
|
# Resets the development database
|
39
39
|
# Loads the snapshot into the development database
|
40
|
-
$ duple refresh production development --capture
|
40
|
+
$ duple refresh -s production -t development --capture
|
41
41
|
|
42
42
|
# Downloads the schema and a subset of data from stage
|
43
43
|
# Resets the backstage database
|
44
44
|
# Loads the structure and the subset into the backstage database
|
45
|
-
$ duple refresh stage backstage --group minimal
|
45
|
+
$ duple refresh -s stage -t backstage --group minimal
|
46
46
|
|
47
47
|
# Downloads the data from the specified tables from the stage database
|
48
48
|
# Loads the data into the backstage database
|
49
|
-
$ duple copy stage backstage --tables products categories
|
49
|
+
$ duple copy -s stage -t backstage --tables products categories
|
50
50
|
|
51
51
|
## Future
|
52
52
|
|
53
|
-
*
|
53
|
+
* Pre- and post- refresh hooks
|
54
54
|
* Support for skipping pre- and post- refresh steps.
|
55
55
|
* Support for running pre- and post- refresh steps by themselves.
|
56
56
|
* Support for other data stores.
|
data/lib/duple/cli/config.rb
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
module Duple
|
2
2
|
module CLI
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
# duple config [COMMAND]
|
6
|
+
#
|
7
|
+
# Options:
|
8
|
+
# -c, [--config=CONFIG] # The location of the config file.
|
9
|
+
#
|
10
|
+
# Manage your configuration.
|
11
|
+
#
|
12
|
+
# Tasks:
|
13
|
+
# duple config all # Prints the current configuration.
|
14
|
+
# duple config environments # Prints the environment configurations.
|
15
|
+
# duple config groups # Prints the group configurations.
|
16
|
+
# duple config help [COMMAND] # Describe subcommands or one specific subcommand
|
17
|
+
# duple config other # Prints other options.
|
18
|
+
# duple config post-refresh # Prints the post-refresh tasks.
|
19
|
+
# duple config pre-refresh # Prints the pre-refresh tasks.
|
20
|
+
|
21
|
+
# Options:
|
22
|
+
# -c, [--config=CONFIG] # The location of the config file.
|
3
23
|
class Config < Thor
|
4
24
|
include Duple::CLI::Helpers
|
5
25
|
|
data/lib/duple/cli/copy.rb
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
module Duple
|
2
2
|
module CLI
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
# duple copy
|
6
|
+
#
|
7
|
+
# Options:
|
8
|
+
# -c, [--config=CONFIG] # The location of the config file.
|
9
|
+
# -s, [--source=SOURCE] # The name of the source environment.
|
10
|
+
# -t, [--target=TARGET] # The name of the target environment.
|
11
|
+
# -g, [--group=GROUP] # The group configuration to use when dumping source data.
|
12
|
+
# [--capture] # Capture a new source snapshot before refreshing.
|
13
|
+
# --dry-run, [--dry-run] # Perform a dry run of the command. No data will be moved.
|
14
|
+
# -t, [--tables=one two three] # A list of tables to include when dumping source data.
|
15
|
+
#
|
16
|
+
# Copies data from a source to a target database.
|
3
17
|
class Copy < Thor::Group
|
4
18
|
include Duple::CLI::Helpers
|
5
19
|
|
@@ -18,11 +32,11 @@ module Duple
|
|
18
32
|
end
|
19
33
|
|
20
34
|
def dump_data
|
21
|
-
postgres.pg_dump(dump_flags, data_file_path,
|
35
|
+
postgres.pg_dump(dump_flags, data_file_path, source_db_config)
|
22
36
|
end
|
23
37
|
|
24
38
|
def restore_data
|
25
|
-
postgres.pg_restore('-e -v --no-acl -O -a', data_file_path,
|
39
|
+
postgres.pg_restore('-e -v --no-acl -O -a', data_file_path, target_db_config)
|
26
40
|
end
|
27
41
|
end
|
28
42
|
end
|
data/lib/duple/cli/helpers.rb
CHANGED
@@ -38,7 +38,7 @@ module Duple
|
|
38
38
|
|
39
39
|
def group_option
|
40
40
|
class_option :group,
|
41
|
-
desc: '
|
41
|
+
desc: 'The group configuration to use when dumping source data.',
|
42
42
|
type: :string,
|
43
43
|
aliases: '-g'
|
44
44
|
end
|
@@ -119,16 +119,40 @@ module Duple
|
|
119
119
|
@structure_file_path ||= File.join(dump_dir_path, filename)
|
120
120
|
end
|
121
121
|
|
122
|
-
def
|
122
|
+
def source_db_config
|
123
|
+
@source_db_config ||= if config.heroku_source?
|
124
|
+
fetch_heroku_db_config(source_appname)
|
125
|
+
else
|
126
|
+
config.db_config(config.source_name)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def target_db_config
|
131
|
+
@target_db_config ||= if config.heroku_target?
|
132
|
+
fetch_heroku_db_config(target_appname)
|
133
|
+
else
|
134
|
+
config.db_config(config.target_name)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def fetch_heroku_db_config(appname)
|
139
|
+
# Run the heroku config command first, even if it's a dry run. So
|
140
|
+
# that the command to get the config will show up in the dry run log.
|
123
141
|
config_vars = heroku.capture(appname, "config")
|
124
142
|
|
125
|
-
|
143
|
+
if config.dry_run?
|
144
|
+
config.db_config(appname, dry_run: true)
|
145
|
+
else
|
146
|
+
parse_heroku_config(config_vars)
|
147
|
+
end
|
148
|
+
end
|
126
149
|
|
150
|
+
def parse_heroku_config(config_vars)
|
127
151
|
db_url = config_vars.split("\n").detect { |l| l =~ /DATABASE_URL/ }
|
128
152
|
raise ArgumentError.new("Missing DATABASE_URL variable for #{appname}") if db_url.nil?
|
129
153
|
|
130
154
|
db_url.match(
|
131
|
-
/postgres:\/\/(?<
|
155
|
+
/postgres:\/\/(?<username>.*):(?<password>.*)@(?<host>.*):(?<port>\d*)\/(?<database>.*)/
|
132
156
|
)
|
133
157
|
end
|
134
158
|
|
@@ -159,22 +183,6 @@ module Duple
|
|
159
183
|
flags = [ '-Fc -a', include_flags, exclude_flags ].flatten.compact.join(' ')
|
160
184
|
end
|
161
185
|
|
162
|
-
def source_credentials
|
163
|
-
@source_credentials ||= if config.heroku_source?
|
164
|
-
fetch_heroku_credentials(source_appname)
|
165
|
-
else
|
166
|
-
config.local_credentials
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def target_credentials
|
171
|
-
@target_credentials ||= if config.heroku_target?
|
172
|
-
fetch_heroku_credentials(target_appname)
|
173
|
-
else
|
174
|
-
config.local_credentials
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
186
|
def config
|
179
187
|
@config ||= parse_config
|
180
188
|
end
|
data/lib/duple/cli/init.rb
CHANGED
data/lib/duple/cli/refresh.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
module Duple
|
2
2
|
module CLI
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
# duple refresh
|
6
|
+
#
|
7
|
+
# Options:
|
8
|
+
# -c, [--config=CONFIG] # The location of the config file.
|
9
|
+
# -s, [--source=SOURCE] # The name of the source environment.
|
10
|
+
# -t, [--target=TARGET] # The name of the target environment.
|
11
|
+
# -g, [--group=GROUP] # The group configuration to use when dumping source data.
|
12
|
+
# [--capture] # Capture a new source snapshot before refreshing.
|
13
|
+
# -t, [--tables=one two three] # A list of tables to include when dumping source data.
|
14
|
+
#
|
15
|
+
# Resets and copies schema and data from a source to a target database
|
3
16
|
class Refresh < Thor::Group
|
4
17
|
include Duple::CLI::Helpers
|
5
18
|
|
@@ -54,7 +67,7 @@ module Duple
|
|
54
67
|
def dump_data
|
55
68
|
return unless dump_data?
|
56
69
|
|
57
|
-
postgres.pg_dump(dump_flags, data_file_path,
|
70
|
+
postgres.pg_dump(dump_flags, data_file_path, source_db_config)
|
58
71
|
end
|
59
72
|
|
60
73
|
def reset_target
|
@@ -63,9 +76,9 @@ module Duple
|
|
63
76
|
|
64
77
|
def restore_database
|
65
78
|
if download_snapshot?
|
66
|
-
postgres.pg_restore('-e -v --no-acl -O -a', @snapshot_path,
|
79
|
+
postgres.pg_restore('-e -v --no-acl -O -a', @snapshot_path, target_db_config)
|
67
80
|
elsif dump_data?
|
68
|
-
postgres.pg_restore('-e -v --no-acl -O -a', data_file_path,
|
81
|
+
postgres.pg_restore('-e -v --no-acl -O -a', data_file_path, target_db_config)
|
69
82
|
else
|
70
83
|
heroku.run(target_appname, "pgbackups:restore DATABASE #{@source_snapshot_url}")
|
71
84
|
end
|
data/lib/duple/cli/root.rb
CHANGED
data/lib/duple/cli/structure.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
module Duple
|
2
2
|
module CLI
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
# duple structure
|
6
|
+
#
|
7
|
+
# Options:
|
8
|
+
# -c, [--config=CONFIG] # The location of the config file.
|
9
|
+
# -s, [--source=SOURCE] # The name of the source environment.
|
10
|
+
# -t, [--target=TARGET] # The name of the target environment.
|
11
|
+
#
|
12
|
+
# Copies structure from a source to a target database.
|
3
13
|
class Structure < Thor::Group
|
4
14
|
include Duple::CLI::Helpers
|
5
15
|
|
@@ -8,7 +18,7 @@ module Duple
|
|
8
18
|
target_option
|
9
19
|
|
10
20
|
def dump_structure
|
11
|
-
postgres.pg_dump('-Fc --no-acl -O -s', structure_file_path,
|
21
|
+
postgres.pg_dump('-Fc --no-acl -O -s', structure_file_path, source_db_config)
|
12
22
|
end
|
13
23
|
|
14
24
|
def reset_target
|
@@ -16,7 +26,7 @@ module Duple
|
|
16
26
|
end
|
17
27
|
|
18
28
|
def load_structure
|
19
|
-
postgres.pg_restore('-v --no-acl -O -s', structure_file_path,
|
29
|
+
postgres.pg_restore('-v --no-acl -O -s', structure_file_path, target_db_config)
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/duple/configuration.rb
CHANGED
@@ -125,24 +125,38 @@ module Duple
|
|
125
125
|
tables
|
126
126
|
end
|
127
127
|
|
128
|
-
def
|
128
|
+
def db_config(appname, options = nil)
|
129
|
+
options ||= {}
|
130
|
+
options = {dry_run: false}.merge(options)
|
131
|
+
|
132
|
+
if options[:dry_run]
|
133
|
+
db_config_for_dry_run(appname)
|
134
|
+
else
|
135
|
+
db_config_for_app(appname)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def db_config_for_dry_run(appname)
|
129
140
|
{
|
130
|
-
|
141
|
+
username: "[#{envname}.USER]",
|
131
142
|
password: "[#{envname}.PASS]",
|
132
143
|
host: "[#{envname}.HOST]",
|
133
144
|
port: "[#{envname}.PORT]",
|
134
|
-
|
145
|
+
database: "[#{envname}.DB]"
|
135
146
|
}
|
136
147
|
end
|
137
148
|
|
138
|
-
def
|
139
|
-
|
149
|
+
def db_config_for_app(appname)
|
150
|
+
env = environments[appname]
|
151
|
+
if env['database'].nil?
|
152
|
+
raise ArgumentError.new('Invalid config: "database" is required for a local environment.')
|
153
|
+
end
|
140
154
|
{
|
141
|
-
|
142
|
-
password: '',
|
143
|
-
host: 'localhost',
|
144
|
-
port: '5432',
|
145
|
-
|
155
|
+
username: env['username'] || 'postgres',
|
156
|
+
password: env['password'] || '',
|
157
|
+
host: env['host'] || 'localhost',
|
158
|
+
port: env['port'] || '5432',
|
159
|
+
database: env['database']
|
146
160
|
}
|
147
161
|
end
|
148
162
|
|
data/lib/duple/heroku_runner.rb
CHANGED
data/lib/duple/pg_runner.rb
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
module Duple
|
2
|
+
|
3
|
+
# Decorates a Duple::Runner instance with helper methods for executing
|
4
|
+
# PostgreSQL commands.
|
2
5
|
class PGRunner
|
3
6
|
def initialize(runner)
|
4
7
|
@runner = runner
|
5
8
|
end
|
6
9
|
|
7
|
-
def pg_dump(flags, dump_file,
|
8
|
-
pg_command('pg_dump', flags,
|
10
|
+
def pg_dump(flags, dump_file, db_config)
|
11
|
+
pg_command('pg_dump', flags, db_config, nil, "> #{dump_file}")
|
9
12
|
end
|
10
13
|
|
11
|
-
def pg_restore(flags, dump_file,
|
12
|
-
pg_command('pg_restore', flags,
|
14
|
+
def pg_restore(flags, dump_file, db_config)
|
15
|
+
pg_command('pg_restore', flags, db_config, '-d', "< #{dump_file}")
|
13
16
|
end
|
14
17
|
|
15
|
-
def pg_command(pg_command, flags,
|
18
|
+
def pg_command(pg_command, flags, db_config, db_flag, tail = nil)
|
16
19
|
command = []
|
17
|
-
command << %{PGPASSWORD="#{
|
20
|
+
command << %{PGPASSWORD="#{db_config[:password]}"}
|
18
21
|
command << pg_command
|
19
22
|
command << flags
|
20
|
-
command << %{-h #{
|
23
|
+
command << %{-h #{db_config[:host]} -U #{db_config[:username]} -p #{db_config[:port]}}
|
21
24
|
command << db_flag if db_flag
|
22
|
-
command <<
|
25
|
+
command << db_config[:database]
|
23
26
|
command << tail if tail
|
24
27
|
@runner.run(command.join(' '))
|
25
28
|
end
|
data/lib/duple/runner.rb
CHANGED
data/lib/duple/version.rb
CHANGED
data/spec/duple/cli/copy_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe Duple::CLI::Copy do
|
|
16
16
|
}
|
17
17
|
|
18
18
|
context 'with neither tables nor group option' do
|
19
|
-
it 'fetches the source
|
19
|
+
it 'fetches the source db config' do
|
20
20
|
expect {
|
21
21
|
invoke_copy(tables: nil)
|
22
22
|
}.to raise_error(ArgumentError, 'One of --group or --tables options is required.')
|
@@ -27,7 +27,7 @@ describe Duple::CLI::Copy do
|
|
27
27
|
let(:source) { 'stage' }
|
28
28
|
let(:target) { 'development' }
|
29
29
|
|
30
|
-
it 'fetches the source
|
30
|
+
it 'fetches the source db config' do
|
31
31
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
32
32
|
.and_return(heroku_config_response)
|
33
33
|
|
@@ -53,14 +53,14 @@ describe Duple::CLI::Copy do
|
|
53
53
|
let(:source) { 'production' }
|
54
54
|
let(:target) { 'stage' }
|
55
55
|
|
56
|
-
it 'fetches the source
|
56
|
+
it 'fetches the source db config' do
|
57
57
|
runner.should_receive(:capture).with("heroku config -a duple-production")
|
58
58
|
.and_return(heroku_config_response)
|
59
59
|
|
60
60
|
invoke_copy
|
61
61
|
end
|
62
62
|
|
63
|
-
it 'fetches the target
|
63
|
+
it 'fetches the target db config' do
|
64
64
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
65
65
|
.and_return(heroku_config_response)
|
66
66
|
|
@@ -86,7 +86,7 @@ describe Duple::CLI::Copy do
|
|
86
86
|
let(:source) { 'development' }
|
87
87
|
let(:target) { 'stage' }
|
88
88
|
|
89
|
-
it 'fetches the target
|
89
|
+
it 'fetches the target db config' do
|
90
90
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
91
91
|
.and_return(heroku_config_response)
|
92
92
|
|
@@ -18,7 +18,7 @@ describe Duple::CLI::Structure do
|
|
18
18
|
let(:source) { 'stage' }
|
19
19
|
let(:target) { 'development' }
|
20
20
|
|
21
|
-
it 'fetches the source
|
21
|
+
it 'fetches the source db config' do
|
22
22
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
23
23
|
.and_return(heroku_config_response)
|
24
24
|
|
@@ -57,14 +57,14 @@ describe Duple::CLI::Structure do
|
|
57
57
|
let(:source) { 'production' }
|
58
58
|
let(:target) { 'stage' }
|
59
59
|
|
60
|
-
it 'fetches the source
|
60
|
+
it 'fetches the source db config' do
|
61
61
|
runner.should_receive(:capture).with("heroku config -a duple-production")
|
62
62
|
.and_return(heroku_config_response)
|
63
63
|
|
64
64
|
invoke_structure
|
65
65
|
end
|
66
66
|
|
67
|
-
it 'fetches the target
|
67
|
+
it 'fetches the target db config' do
|
68
68
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
69
69
|
.and_return(heroku_config_response)
|
70
70
|
|
@@ -103,7 +103,7 @@ describe Duple::CLI::Structure do
|
|
103
103
|
let(:source) { 'development' }
|
104
104
|
let(:target) { 'stage' }
|
105
105
|
|
106
|
-
it 'fetches the target
|
106
|
+
it 'fetches the target db config' do
|
107
107
|
runner.should_receive(:capture).with("heroku config -a duple-stage")
|
108
108
|
.and_return(heroku_config_response)
|
109
109
|
|
@@ -2,6 +2,54 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Duple::Configuration do
|
4
4
|
|
5
|
+
|
6
|
+
describe '#db_config' do
|
7
|
+
let(:config_hash) { YAML.load(File.read('spec/config/simple.yml'))}
|
8
|
+
|
9
|
+
it 'supplies default database values for a local environment' do
|
10
|
+
config = Duple::Configuration.new(config_hash, {})
|
11
|
+
c = config.db_config('development')
|
12
|
+
c[:username].should == 'postgres'
|
13
|
+
c[:password].should == ''
|
14
|
+
c[:host].should == 'localhost'
|
15
|
+
c[:port].should == '5432'
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with all db config parameters' do
|
19
|
+
let(:db_config_hash) {
|
20
|
+
db_hash = config_hash['environments']['development']
|
21
|
+
db_hash['username'] = 'config_username'
|
22
|
+
db_hash['password'] = 'config_password'
|
23
|
+
db_hash['host'] = 'config_host'
|
24
|
+
db_hash['port'] = '6022'
|
25
|
+
db_hash['database'] = 'config_database'
|
26
|
+
config_hash
|
27
|
+
}
|
28
|
+
let(:config) { Duple::Configuration.new(db_config_hash, {}) }
|
29
|
+
subject(:db_config) { config.db_config('development') }
|
30
|
+
|
31
|
+
it 'loads the options from the config' do
|
32
|
+
db_config[:username].should == 'config_username'
|
33
|
+
db_config[:password].should == 'config_password'
|
34
|
+
db_config[:host].should == 'config_host'
|
35
|
+
db_config[:port].should == '6022'
|
36
|
+
db_config[:database].should == 'config_database'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'fails if the database name is missing' do
|
41
|
+
config_hash['environments']['development'].delete('database')
|
42
|
+
config = Duple::Configuration.new(config_hash, {})
|
43
|
+
|
44
|
+
expect {
|
45
|
+
config.db_config('development')
|
46
|
+
}.to raise_error(
|
47
|
+
ArgumentError,
|
48
|
+
'Invalid config: "database" is required for a local environment.'
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
5
53
|
describe '#excluded_tables' do
|
6
54
|
let(:config_hash) { YAML.load(File.read('spec/config/groups.yml'))}
|
7
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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-10-
|
12
|
+
date: 2012-10-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- .gitignore
|
120
120
|
- .rspec
|
121
121
|
- .simplecov
|
122
|
+
- CHANGES.md
|
122
123
|
- Gemfile
|
123
124
|
- LICENSE.txt
|
124
125
|
- README.md
|