stack_car 0.6.1 → 0.12.0

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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +64 -1
  3. data/lib/stack_car.rb +1 -0
  4. data/lib/stack_car/cli.rb +136 -38
  5. data/lib/stack_car/dot_rc.rb +25 -0
  6. data/lib/stack_car/version.rb +1 -1
  7. data/stack_car.gemspec +1 -0
  8. data/templates/.dockerignore.erb +2 -2
  9. data/templates/.env.development.erb +2 -0
  10. data/templates/.env.erb +15 -16
  11. data/templates/.gitlab-ci.yml.erb +94 -62
  12. data/templates/Dockerfile.base.erb +28 -19
  13. data/templates/Dockerfile.erb +26 -7
  14. data/templates/chart-fcrepo/fcrepo-deploy.yaml +63 -0
  15. data/templates/chart-fcrepo/fcrepo-env-cm.yaml +8 -0
  16. data/templates/chart-fcrepo/fcrepo-env-secret.yaml.tt +10 -0
  17. data/templates/chart-fcrepo/fcrepo-pvc.yaml +20 -0
  18. data/templates/chart-fcrepo/fcrepo-svc.yaml +19 -0
  19. data/templates/chart-sidekiq/sidekiq-deploy.yaml +80 -0
  20. data/templates/chart/.gitignore +3 -0
  21. data/templates/chart/.helmignore +23 -0
  22. data/templates/chart/Chart.yaml.tt +29 -0
  23. data/templates/chart/README.md +223 -0
  24. data/templates/chart/bin/check_sidekiq.rb +0 -0
  25. data/templates/chart/bin/decrypt +17 -0
  26. data/templates/chart/bin/deploy +14 -0
  27. data/templates/chart/bin/encrypt +15 -0
  28. data/templates/chart/bin/remove +15 -0
  29. data/templates/chart/sample-values.yaml.tt +138 -0
  30. data/templates/chart/templates/_helpers.tpl.tt +85 -0
  31. data/templates/chart/templates/rails-env-cm.yaml.tt +47 -0
  32. data/templates/chart/templates/rails-env-secret.yaml +10 -0
  33. data/templates/chart/templates/rails-pvc-shared.yml +20 -0
  34. data/templates/chart/templates/setup-job.yaml +73 -0
  35. data/templates/chart/templates/web-deploy.yaml +67 -0
  36. data/templates/chart/templates/web-ing-wildcard.yaml +20 -0
  37. data/templates/chart/templates/web-ing.yaml +20 -0
  38. data/templates/chart/templates/web-svc.yaml +20 -0
  39. data/templates/database.yml.erb +10 -10
  40. data/templates/docker-compose.yml.erb +53 -12
  41. data/templates/env.conf.erb +11 -9
  42. data/templates/nginx.sh.erb +17 -0
  43. metadata +47 -10
  44. data/templates/docker-compose.ci.yml.erb +0 -87
  45. data/templates/docker-compose.production.yml.erb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c211b3d1c2030db2a5e70cb4bf82e735d161ff30
4
- data.tar.gz: 2d66451f16f94290bdc5cc85af8ed13893f1acde
2
+ SHA256:
3
+ metadata.gz: 0e8df8e8dbd70e738de0a61cd09489c72e4cd822326b237269d21ebe4dacd258
4
+ data.tar.gz: 11214bdf66ad316ad4feec518f0ef0e39f9e146aea500c3b7e187a67ecaa33fe
5
5
  SHA512:
6
- metadata.gz: 7e7deb0336394994473ee04230589480b72fb43983cf6bba5bf741475deb8f7c574b0584feba769b28fff08cd3d356095357013541cc37977f300b38aef5b2da
7
- data.tar.gz: 21a74ff7c055eab71c3a4c43f260830756b2adfe72f23ff3d335788384d3575587b59fb72e490ddfe4c1f1cef5a448062f3a5aea4bb321d98fbd653e55b12eea
6
+ metadata.gz: 65b81508cd79dd4fdff903820133034b4dc894eeaff69a3033e2439b9cae81f5b34e48055a83485e56f3236ea7111cc9dc24d3c8a3a8cdb8341a5b64490e070a
7
+ data.tar.gz: 60223a2ce56c3173e4c62b8d08e05e1d8c6c5fcd2c64027864cef6aa76857c88e3b9a9ae2d6c88cd4a229f2c858f1f1359959b849faffe129119258500b97b2c
data/README.md CHANGED
@@ -33,7 +33,70 @@ Commands:
33
33
 
34
34
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
35
35
 
36
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
36
+ **To install this gem onto your local machine**
37
+ - Run `bundle exec rake install`
38
+
39
+ ### Workflow
40
+
41
+ **Create a dummy rails app**
42
+
43
+ Developing stack_car often requires a rails application for you to run updated commands and templates against. Generate one for this purpose:
44
+ - `rails new <dummy-app-name>`
45
+
46
+ **Make and test your changes**
47
+ - In stack_car, make your command / template changes
48
+ - Run `rake install` to update your local gem
49
+ - In your dummy application, test the updated command
50
+ - Commit your changes
51
+
52
+ ### Releasing a new version
53
+ - Update the version number in `version.rb`
54
+ - Run `bundle exec rake release`
55
+ - This will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
56
+
57
+ ## Generating a Helm Chart
58
+
59
+ stack_car's **dockerize** command can be used in conjunction with available flags to generate a **Helm chart** template for your application. You will need to create the *values* files with necessary configuration values from the *sample-values* provided by stack_car, but the command will effectively give you the baseline Notch8 template (scripts, template files, template helpers, sample values file) for a **Helm base Kubernetes deploy**
60
+
61
+ The following examples are to be run in the repo of the application you are creating the chart for.
62
+
63
+ **To generate a Helm chart template**
64
+
65
+ - `sc dockerize --helm`
66
+ - This command without additional flags will only generate Rails web related template files
67
+
68
+ In broad strokes adding additional flags signals stack_car to generate template files for other services. Note that any configuration that would normally be applied for these services in a non Helm context (without the `--helm` flag) still apply.
69
+
70
+ **For example**:
71
+ - `sc dockerize --helm --fcrepo --solr`
72
+ - This command will add templates for the **fcrepo** service and add a **solr chart dependency** in the `Chart.yaml` (You can think of `Chart.yaml` like the **Gemfile** or **package.json** of a Helm chart)
73
+
74
+ **Creating values files**
75
+
76
+ Values files allows you to configure your helm deploy from number of web instances to hostname for your ingress to environment variables required by your application.
77
+
78
+ When starting from a new helm chart, you'll want to copy the sample values file to one named after the environment you're creating a deployment for.
79
+
80
+ For example:
81
+ `cp sample-values.yaml staging-values.yaml`
82
+
83
+ *Note: You will do this once for every environment you'd like to deploy*
84
+
85
+ **Handling values files**
86
+
87
+ Since values files are likely to contain sensitive information like API keys, they should never be committed to your repository. The scripts that stack_car includes in your chart simplifies encrypting and decrypting values for version control.
88
+
89
+ Example workflow (given values file is already created):
90
+ - Edit values file
91
+ - `chart/bin/encrypt staging <keybase-team-name>`
92
+ - This command will create `staging-values.yaml.enc`
93
+ - `git add staging-values.yaml.enc`
94
+ - Commit and push
95
+
96
+ When pulling down a repo or branch, you will need to start by decrypting.
97
+
98
+ Example:
99
+ - `chart/bin/decrypt staging`
37
100
 
38
101
  ## Contributing
39
102
 
data/lib/stack_car.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "stack_car/version"
2
2
  require "stack_car/cli"
3
+ require "stack_car/dot_rc"
3
4
 
4
5
  module StackCar
5
6
  # Your code goes here...
data/lib/stack_car/cli.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'thor'
2
2
  require 'erb'
3
3
  require 'dotenv/load'
4
-
4
+ require 'json'
5
+ require 'byebug'
5
6
  module StackCar
6
7
  class HammerOfTheGods < Thor
7
8
  include Thor::Actions
@@ -19,111 +20,135 @@ module StackCar
19
20
  method_option :logs, default: true, type: :boolean
20
21
  desc "up", "starts docker-compose with rebuild and orphan removal, defaults to web"
21
22
  def up
23
+ setup
24
+ ensure_development_env
22
25
  args = ['--remove-orphans']
23
26
  args << '--build' if options[:build]
24
27
  if options[:build]
25
- run("docker-compose pull #{options[:service]}")
28
+ run("#{dotenv} docker-compose pull #{options[:service]}")
26
29
  end
27
30
 
28
- run("docker-compose up #{args.join(' ')} #{options[:service]}")
31
+ run_with_exit("#{dotenv} docker-compose up #{args.join(' ')} #{options[:service]}")
29
32
  end
30
33
 
31
34
  method_option :service, default: '', type: :string, aliases: '-s'
32
35
  desc "stop", "stops the specified running service, defaults to all"
33
36
  def stop
34
- run("docker-compose stop #{options[:service]}")
35
- run("rm -rf tmp/pids/*")
37
+ setup
38
+ ensure_development_env
39
+ run("#{dotenv} docker-compose stop #{options[:service]}")
40
+ run_with_exit("rm -rf tmp/pids/*")
36
41
  end
37
42
  map down: :stop
38
43
 
39
44
  method_option :service, default: 'web', type: :string, aliases: '-s'
40
45
  desc "build", "builds specified service, defaults to web"
41
46
  def build
42
- run("docker-compose build #{options[:service]}")
47
+ setup
48
+ ensure_development_env
49
+ run_with_exit("#{dotenv} docker-compose build #{options[:service]}")
43
50
  end
44
51
 
45
52
  method_option :service, default: 'web', type: :string, aliases: '-s'
46
53
  desc "push ARGS", "wraps docker-compose push web unless --service is used to specify"
47
54
  def push(*args)
48
- run("docker-compose push #{options[:service]} #{args.join(' ')}")
55
+ setup
56
+ run_with_exit("#{dotenv} docker-compose push #{options[:service]} #{args.join(' ')}")
49
57
  end
50
58
 
51
59
  method_option :service, default: 'web', type: :string, aliases: '-s'
52
60
  desc "pull ARGS", "wraps docker-compose pull web unless --service is used to specify"
53
61
  def pull(*args)
54
- run("docker-compose pull #{options[:service]} #{args.join(' ')}")
62
+ setup
63
+ run_with_exit("#{dotenv} docker-compose pull #{options[:service]} #{args.join(' ')}")
55
64
  end
56
65
 
57
66
  method_option :service, default: '', type: :string, aliases: '-s'
58
67
  desc "ps ARGS", "wraps docker-compose pull web unless --service is used to specify"
59
68
  def ps(*args)
60
- run("docker-compose ps #{options[:service]} #{args.join(' ')}")
69
+ setup
70
+ run_with_exit("#{dotenv} docker-compose ps #{options[:service]} #{args.join(' ')}")
61
71
  end
62
72
  map status: :ps
63
73
 
64
74
  method_option :service, default: 'web', type: :string, aliases: '-s'
65
75
  desc "bundle ARGS", "wraps docker-compose run web unless --service is used to specify"
66
76
  def bundle(*args)
67
- run("docker-compose exec #{options[:service]} bundle")
77
+ setup
78
+ run_with_exit("#{dotenv} docker-compose exec #{options[:service]} bundle")
68
79
  end
69
80
 
70
81
  method_option :service, default: 'web', type: :string, aliases: '-s'
71
82
  desc "walk ARGS", "wraps docker-compose run web unless --service is used to specify"
72
83
  def walk(*args)
73
- run("docker-compose run #{options[:service]} #{args.join(' ')}")
84
+ setup
85
+ run_with_exit("#{dotenv} docker-compose run #{options[:service]} #{args.join(' ')}")
74
86
  end
75
87
 
76
88
  method_option :service, default: 'web', type: :string, aliases: '-s'
77
89
  desc "exec ARGS", "wraps docker-compose exec web unless --service is used to specify"
78
90
  def exec(*args)
79
- run("docker-compose exec #{options[:service]} #{args.join(' ')}")
91
+ setup
92
+ run_with_exit("#{dotenv} docker-compose exec #{options[:service]} #{args.join(' ')}")
80
93
  end
81
94
  map ex: :exec
82
95
 
96
+ method_option :service, default: 'web', type: :string, aliases: '-s'
97
+ desc 'sh ARGS', "launch a shell using docker-compose exec, sets tty properly"
98
+ def sh(*args)
99
+ setup
100
+ run_with_exit("#{dotenv} docker-compose exec -e COLUMNS=\"\`tput cols\`\" -e LINES=\"\`tput lines\`\" #{options[:service]} bash #{args.join(' ')}")
101
+ end
102
+
83
103
  method_option :service, default: 'web', type: :string, aliases: '-s'
84
104
  desc "bundle_exec ARGS", "wraps docker-compose exec web bundle exec unless --service is used to specify"
85
105
  def bundle_exec(*args)
86
- run("docker-compose exec #{options[:service]} bundle exec #{args.join(' ')}")
106
+ setup
107
+ run_with_exit("#{dotenv} docker-compose exec #{options[:service]} bundle exec #{args.join(' ')}")
87
108
  end
88
109
  map be: :bundle_exec
89
110
 
90
111
  method_option :service, default: 'web', type: :string, aliases: '-s'
91
112
  desc "console ARGS", "shortcut to start rails console"
92
113
  def console(*args)
93
- run("docker-compose exec #{options[:service]} bundle exec rails console #{args.join(' ')}")
114
+ setup
115
+ run_with_exit("#{dotenv} docker-compose exec #{options[:service]} bundle exec rails console #{args.join(' ')}")
94
116
  end
95
117
  map rc: :console
96
118
 
97
119
  desc "release ENVIRONTMENT", "tag and push and image to the registry"
98
120
  def release(environment)
121
+ setup
99
122
  timestamp = Time.now.strftime("%Y%m%d%I%M%S")
100
- sha = `git rev-parse HEAD`[0..7]
123
+ sha = `git rev-parse HEAD`[0..8]
101
124
  registry = "#{ENV['REGISTRY_HOST']}#{ENV['REGISTRY_URI']}"
102
125
  tag = ENV["TAG"] || 'latest'
103
126
  unless File.exists?("#{ENV['HOME']}/.docker/config.json") && File.readlines("#{ENV['HOME']}/.docker/config.json").grep(/#{ENV['REGISTRY_HOST']}/).size > 0
104
- run("docker login #{ENV['REGISTRY_HOST']}")
127
+ run_with_exit("#{dotenv(environment)} docker login #{ENV['REGISTRY_HOST']}")
105
128
  end
106
- run("docker tag #{registry}:#{tag} #{registry}:#{environment}-#{timestamp}")
107
- run("docker push #{registry}:#{environment}-#{timestamp}")
108
- run("docker tag #{registry}:#{tag} #{registry}:#{sha}")
109
- run("docker push #{registry}:#{sha}")
110
- run("docker tag #{registry}:#{tag} #{registry}:#{environment}-latest")
111
- run("docker push #{registry}:#{environment}-latest")
112
- run("docker tag #{registry}:#{tag} #{registry}:latest")
113
- run("docker push #{registry}:latest")
129
+ run_with_exit("#{dotenv(environment)} docker tag #{registry}:#{tag} #{registry}:#{environment}-#{timestamp}")
130
+ run_with_exit("#{dotenv(environment)} docker push #{registry}:#{environment}-#{timestamp}")
131
+ run_with_exit("#{dotenv(environment)} docker tag #{registry}:#{tag} #{registry}:#{sha}")
132
+ run_with_exit("#{dotenv(environment)} docker push #{registry}:#{sha}")
133
+ run_with_exit("#{dotenv(environment)} docker tag #{registry}:#{tag} #{registry}:#{environment}-latest")
134
+ run_with_exit("#{dotenv(environment)} docker push #{registry}:#{environment}-latest")
135
+ run_with_exit("#{dotenv(environment)} docker tag #{registry}:#{tag} #{registry}:latest")
136
+ run_with_exit("#{dotenv(environment)} docker push #{registry}:latest")
114
137
  end
115
138
 
116
139
  desc "provision ENVIRONMENT", "configure the servers for docker and then deploy an image"
117
140
  def provision(environment)
141
+ setup
118
142
  # TODO make dotenv load a specific environment?
119
- run("dotenv ansible-playbook -i ops/hosts -l #{environment}:localhost ops/provision.yml")
143
+ run_with_exit("DEPLOY_ENV=#{environment} #{dotenv(environment)} ansible-playbook -i ops/hosts -l #{environment}:localhost ops/provision.yml")
120
144
  end
121
145
 
122
146
  desc "ssh ENVIRONMENT", "log in to a running instance - requires PRODUCTION_SSH to be set"
123
147
  def ssh(environment)
148
+ setup
124
149
  target = ENV["#{environment.upcase}_SSH"]
125
150
  if target
126
- run(target)
151
+ run_with_exit(target)
127
152
  else
128
153
  say "Please set #{environment.upcase}_SSH"
129
154
  end
@@ -131,22 +156,27 @@ module StackCar
131
156
 
132
157
  desc "deploy ENVIRONMENT", "deploy an image from the registry"
133
158
  def deploy(environment)
134
- run("dotenv ansible-playbook -i ops/hosts -l #{environment}:localhost ops/deploy.yml")
159
+ setup
160
+ run_with_exit("DEPLOY_HOOK=$DEPLOY_HOOK_#{environment.upcase} #{dotenv(environment)} ansible-playbook -i ops/hosts -l #{environment}:localhost ops/deploy.yml")
135
161
  end
136
162
 
137
- method_option :elasticsearch, default: false, type: :boolean, aliases: '-e'
138
- method_option :solr, default: false, type: :boolean, aliases: '-s'
139
- method_option :postgres, default: false, type: :boolean, aliases: '-p'
140
- method_option :mysql, default: false, type: :boolean, aliases: '-m'
141
- method_option :redis, default: false, type: :boolean, aliases: '-r'
142
163
  method_option :delayed_job, default: false, type: :boolean, aliases: '-j'
143
- method_option :fcrepo, default: false, type: :boolean, aliases: '-f'
144
164
  method_option :deploy, default: false, type: :boolean, aliases: '-d'
165
+ method_option :elasticsearch, default: false, type: :boolean, aliases: '-e'
166
+ method_option :fcrepo, default: false, type: :boolean, aliases: '-f'
167
+ method_option :helm, default: false, type: :boolean, aliases: '-h'
168
+ method_option :git, default: true, type: :boolean, aliases: '-g'
145
169
  method_option :heroku, default: false, type: :boolean, aliases: '-h'
170
+ method_option :hyku, default: false, type: :boolean, aliases: '-u'
171
+ method_option :imagemagick, default: false, type: :boolean, aliases: '-i'
172
+ method_option :memcached, default: false, type: :boolean, aliases: '-mc'
173
+ method_option :mongodb, default: false, type: :boolean, aliases: '-mg'
174
+ method_option :mysql, default: false, type: :boolean, aliases: '-m'
175
+ method_option :postgres, default: false, type: :boolean, aliases: '-p'
146
176
  method_option :rancher, default: false, type: :boolean, aliases: '-dr'
177
+ method_option :redis, default: false, type: :boolean, aliases: '-r'
147
178
  method_option :sidekiq, default: false, type: :boolean, aliases: '-sq' # TODO
148
- method_option :mongodb, default: false, type: :boolean, aliases: '-mg'
149
- method_option :memcached, default: false, type: :boolean, aliases: '-mc'
179
+ method_option :solr, default: false, type: :boolean, aliases: '-s'
150
180
  method_option :yarn, default: false, type: :boolean, aliases: '-y'
151
181
  desc 'dockerize DIR', 'Will copy the docker tempates in to your project, see options for supported dependencies'
152
182
  long_desc <<-DOCKERIZE
@@ -157,9 +187,14 @@ module StackCar
157
187
  DOCKERIZE
158
188
  def dockerize(dir=".")
159
189
  Dir.chdir(dir)
190
+ self.destination_root = dir
191
+ setup
192
+ # Commandline overrides config files
193
+ # options = file_config.merge(options)
160
194
  @project_name = File.basename(File.expand_path(dir))
161
195
  apt_packages << "libpq-dev postgresql-client" if options[:postgres]
162
196
  apt_packages << "mysql-client" if options[:mysql]
197
+ apt_packages << "imagemagick" if options[:imagemagick]
163
198
  pre_apt << "echo 'Downloading Packages'"
164
199
  post_apt << "echo 'Packages Downloaded'"
165
200
 
@@ -179,7 +214,7 @@ module StackCar
179
214
  post_apt << "cd /opt && unzip fits-1.0.5.zip && chmod +X fits-1.0.5/fits.sh"
180
215
  end
181
216
 
182
- ['.dockerignore', 'Dockerfile', 'Dockerfile.base', 'docker-compose.yml', 'docker-compose.ci.yml', 'docker-compose.production.yml', '.gitlab-ci.yml', '.env'].each do |template_file|
217
+ ['.dockerignore', 'Dockerfile', 'Dockerfile.base', 'docker-compose.yml', '.gitlab-ci.yml', '.env'].each do |template_file|
183
218
  puts template_file
184
219
  template("#{template_file}.erb", template_file)
185
220
  end
@@ -196,14 +231,33 @@ module StackCar
196
231
  File.read("#{self.class.source_root}/README.md")
197
232
  end
198
233
  end
199
- append_to_file("Gemfile", "gem 'activerecord-nulldb-adapter'")
234
+
235
+ if File.exist?('Gemfile')
236
+ append_to_file('Gemfile', "gem 'activerecord-nulldb-adapter'")
237
+ else
238
+ append_to_file('../Gemfile', "gem 'activerecord-nulldb-adapter'", { verbose: false })
239
+ # TODO: remove '../' from message after other status messages are prepended with 'stack_car/'
240
+ append_to_file("../Gemfile", "gem 'pronto', groups: [:development, :test]")
241
+ append_to_file("../Gemfile", "gem 'pronto-rubocop', groups: [:development, :test]")
242
+ say_status(:append, '../Gemfile')
243
+ end
244
+
200
245
  if options[:deploy] || options[:rancher]
201
246
  directory('ops')
202
247
  ['hosts', 'deploy.yml', 'provision.yml'].each do |template_file|
203
248
  template("#{template_file}.erb", "ops/#{template_file}")
204
249
  end
250
+
205
251
  say 'Please update ops/hosts with the correct server addresses'
206
- else
252
+ elsif options[:helm]
253
+ directory('chart')
254
+ if options[:fcrepo]
255
+ directory('chart-fcrepo', 'chart/templates')
256
+ end
257
+ if options[:sidekiq]
258
+ directory('chart-sidekiq', 'chart/templates')
259
+ end
260
+ else
207
261
  empty_directory('ops')
208
262
  end
209
263
 
@@ -251,5 +305,49 @@ module StackCar
251
305
  post_apt.join(" && \\\n")
252
306
  end
253
307
 
308
+ def run_with_exit(*args)
309
+ result = run(*args)
310
+ if !result
311
+ exit(1)
312
+ end
313
+ end
314
+
315
+ def file_config
316
+ path = find_config(Dir.pwd)
317
+ if path
318
+ JSON.parse(File.read(path))
319
+ else
320
+ {}
321
+ end
322
+ end
323
+
324
+ def find_config(dir)
325
+ path = File.join(dir, '.stackcar_rc')
326
+ if File.exists?(path)
327
+ return path
328
+ elsif dir == "/"
329
+ return nil
330
+ else
331
+ return find_config(File.dirname(dir))
332
+ end
333
+ end
334
+
335
+ def ensure_development_env
336
+ if !File.exists?('.env.development')
337
+ template(".env.development.erb", ".env.development")
338
+ end
339
+ end
340
+
341
+ def dotenv(environment='development')
342
+ "dotenv -f .env.#{environment},.env"
343
+ end
344
+
345
+ def setup
346
+ if File.exists?('stack_car')
347
+ Dir.chdir('stack_car')
348
+ self.destination_root += "/stack_car"
349
+ end
350
+ DotRc.new
351
+ end
254
352
  end
255
353
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require 'pathname'
3
+ module StackCar
4
+ class DotRc
5
+ include Thor::Shell
6
+
7
+ def initialize
8
+ @file = find_file
9
+ say_status :load, 'not found', :red && return unless @file
10
+ say_status :load, @file
11
+ load(@file)
12
+ end
13
+
14
+ def find_file
15
+ path = nil
16
+ Pathname(Dir.pwd).ascend do |p|
17
+ if File.directory?(p) && File.exist?(File.join(p, '.stack_car_rc'))
18
+ path = File.join(p, '.stack_car_rc')
19
+ break
20
+ end
21
+ end
22
+ path
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module StackCar
2
- VERSION = "0.6.1"
2
+ VERSION = "0.12.0"
3
3
  end
data/stack_car.gemspec CHANGED
@@ -26,5 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "yard-thor"
27
27
  spec.add_development_dependency "pry"
28
28
  spec.add_runtime_dependency "dotenv", "~> 2.2"
29
+ spec.add_runtime_dependency "json", "~> 2.3"
29
30
  spec.add_runtime_dependency "thor", "~> 0.19"
30
31
  end