duple 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|