orats 0.3.1 → 0.3.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/Gemfile.lock +5 -3
- data/README.md +8 -43
- data/bin/orats +1 -1
- data/lib/orats/cli.rb +23 -84
- data/lib/orats/command.rb +93 -0
- data/lib/orats/{server.rb → foreman.rb} +7 -4
- data/lib/orats/shell.rb +95 -55
- data/lib/orats/templates/base.rb +7 -2
- data/lib/orats/templates/cook.rb +2 -0
- data/lib/orats/templates/includes/Gemfile +1 -1
- data/lib/orats/version.rb +1 -1
- data/orats.gemspec +1 -0
- data/test/integration/cli_test.rb +133 -0
- data/test/test_helper.rb +34 -0
- metadata +23 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed3528a226c156ebd2bb1155fc50f3a5074f78cb
|
4
|
+
data.tar.gz: 972dd00fe19344f92c8079837f841db6226b9425
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ca57f387e3d371752ae69c303c14044491e8abfd8fd8ac093b3c860ae5c307c85576638ffdf11e4f82b320c8d9e405c4324645ad8335a28829960fd96ba77c5
|
7
|
+
data.tar.gz: 20d28d78394998d2d0f4ead1969aa0f959c279753f1bffd836d783b3f79503b938092543393f32b56b4c5c12dbaa27cd0fab885b2ffc513c2bad54820397a753
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
orats (0.3.
|
5
|
-
thor
|
4
|
+
orats (0.3.1)
|
5
|
+
thor
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
+
minitest (4.7.5)
|
10
11
|
rake (0.9.6)
|
11
12
|
thor (0.18.1)
|
12
13
|
|
@@ -15,5 +16,6 @@ PLATFORMS
|
|
15
16
|
|
16
17
|
DEPENDENCIES
|
17
18
|
bundler (~> 1.5)
|
19
|
+
minitest (~> 4.7.0)
|
18
20
|
orats!
|
19
|
-
rake
|
21
|
+
rake
|
data/README.md
CHANGED
@@ -78,6 +78,7 @@ running `orats <command name> help` from your terminal. You can also type `orats
|
|
78
78
|
- Project features:
|
79
79
|
- Optionally takes: `--skip-cook [false]`
|
80
80
|
- Optionally takes: `--skip-extras [false]`
|
81
|
+
- Optionally takes: `--skip-foreman-start [false]`
|
81
82
|
|
82
83
|
- Create a stand alone chef cookbook
|
83
84
|
- `orats cook <APP_PATH>`
|
@@ -277,45 +278,15 @@ at least it generates a directory structure capable of sustaining multiple cookb
|
|
277
278
|
You can quickly tweak a bunch of values by investigating the `attributes/default.rb` file. The values here are used in each
|
278
279
|
recipe. They are also namespaced to match the recipe file that uses them.
|
279
280
|
|
280
|
-
|
281
|
-
should use the key inside of your `.ssh/id_rsa.pub` file. It is the key that ends with your work station's username@hostname. Make
|
282
|
-
sure you do not include the trailing line break too.
|
281
|
+
#### Are you experienced with chef?
|
283
282
|
|
284
|
-
|
283
|
+
Nice, then you should know what to do from this point. Setup your encrypted data bag and bootstrap the node.
|
285
284
|
|
286
|
-
|
285
|
+
#### Do you need a full blown walk through?
|
287
286
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
Please keep in mind that you should never input your real passwords/etc. in this file, it is only here to remind you which
|
292
|
-
settings are in your bag. This file is checked into version control. We will cover setting up the data bag with your real
|
293
|
-
information in [chef walk through on the wiki](https://github.com/nickjj/orats/wiki/Chef-walk-through).
|
294
|
-
|
295
|
-
### Workflow for customizing the cookbook
|
296
|
-
|
297
|
-
This cookbook is designed to be a generic base to get you started. It is highly encouraged to change the cookbook to suite your
|
298
|
-
exact needs. A typical workflow for making changes to the cookbook is this:
|
299
|
-
|
300
|
-
- Edit any files that you want to change.
|
301
|
-
- Bump the version in the `metadata.rb` file. *Never forget to do this step!*
|
302
|
-
- Run `berks upload` which sends the cookbooks up to your hosted chef server.
|
303
|
-
|
304
|
-
If you need to add new cookbooks then add them to `metadata.rb` and run `berks install`. If you need to pull in a cookbook
|
305
|
-
from a git repo or your local file system then put them in your `Berksfile` and also place them in `metadata.rb`. Check the
|
306
|
-
berkshelf documentation for more details.
|
307
|
-
|
308
|
-
#### Applying the cookbook changes on your server
|
309
|
-
|
310
|
-
This step is highly dependent but you have a few options. The first option is to ssh into your node and run `sudo chef-client`.
|
311
|
-
Replace ssh with capistrano if you want but the idea is the same. You would be manually invoking the `chef-client` command
|
312
|
-
which tells your node to contact the hosted chef server and pull in the changes.
|
313
|
-
|
314
|
-
The second option would be to setup a cronjob to run `chef-client` automatically at whatever interval you want. By default
|
315
|
-
I did not include this because by default chef does not do this.
|
316
|
-
|
317
|
-
Chef is idempotent so it will not re-run tasks that result in nothing changing so feel free to make changes whenever you
|
318
|
-
see fit.
|
287
|
+
If you have very little chef experience and want to go through the steps of creating a new orats project with a cookbook,
|
288
|
+
pushing it to a free managed chef server solution and bootstrapping a node then check out the
|
289
|
+
[chef walk through on the wiki](https://github.com/nickjj/orats/wiki/Chef-walk-through).
|
319
290
|
|
320
291
|
### The server is up but how do I deploy my application?
|
321
292
|
|
@@ -325,10 +296,4 @@ them over to capistrano 3 scripts so they can be included as an orats template b
|
|
325
296
|
|
326
297
|
I'm calling out to the community for help. Can a chef expert please leverage the `deploy` or `application` resources
|
327
298
|
and provide us with a well documented solution to deploy a rails application with chef? Complete with runit scripts for
|
328
|
-
ensuring puma and sidekiq are always running of course.
|
329
|
-
|
330
|
-
### Walk through
|
331
|
-
|
332
|
-
If you have very little chef experience and want to go through the steps of creating a new orats project with a cookbook,
|
333
|
-
pushing it to a free managed chef server solution and bootstrapping a server on a local virtual machine then check out the
|
334
|
-
[chef walk through on the wiki](https://github.com/nickjj/orats/wiki/Chef-walk-through).
|
299
|
+
ensuring puma and sidekiq are always running of course.
|
data/bin/orats
CHANGED
data/lib/orats/cli.rb
CHANGED
@@ -1,23 +1,17 @@
|
|
1
1
|
require 'thor'
|
2
|
-
require 'orats/
|
3
|
-
require 'orats/server'
|
2
|
+
require 'orats/command'
|
4
3
|
|
5
4
|
module Orats
|
6
|
-
class
|
7
|
-
include Thor::Actions
|
8
|
-
include Shell
|
9
|
-
include Server
|
10
|
-
|
11
|
-
attr_accessor :active_path, :active_project
|
12
|
-
|
5
|
+
class CLI < Thor
|
13
6
|
option :pg_location, default: 'localhost'
|
14
7
|
option :pg_username, default: 'postgres'
|
15
8
|
option :pg_password, required: true
|
16
9
|
option :auth, type: :boolean, default: false, aliases: '-a'
|
17
10
|
option :skip_cook, type: :boolean, default: false, aliases: '-C'
|
18
11
|
option :skip_extras, type: :boolean, default: false, aliases: '-E'
|
12
|
+
option :skip_foreman_start, type: :boolean, default: false, aliases: '-F'
|
19
13
|
desc 'new APP_PATH [options]', ''
|
20
|
-
long_desc <<-
|
14
|
+
long_desc <<-D
|
21
15
|
`orats new myapp --pg-password supersecret` will create a new orats project and it will also create a chef cookbook to go with it by default.
|
22
16
|
|
23
17
|
You must supply at least this flag:
|
@@ -39,99 +33,44 @@ module Orats
|
|
39
33
|
`--skip-cook` skip creating the cookbook [false]
|
40
34
|
|
41
35
|
`--skip-extras` skip creating the services directory and cookbook [false]
|
42
|
-
LONGDESC
|
43
|
-
def new(app_name)
|
44
|
-
@options = options
|
45
|
-
@active_path = app_name
|
46
|
-
|
47
|
-
@active_path = services_path(app_name)
|
48
|
-
rails_template 'base' do
|
49
|
-
gsub_postgres_info
|
50
|
-
|
51
|
-
bundle_install
|
52
|
-
git_commit 'Change the postgres information'
|
53
|
-
git_commit 'Add gem lock file'
|
54
|
-
|
55
|
-
run_rake 'db:create:all db:migrate db:test:prepare'
|
56
|
-
git_commit 'Add the database schema file'
|
57
|
-
end
|
58
36
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
unless options[:skip_cook] || options[:skip_extras]
|
66
|
-
cook_app cookbooks_path(app_name)
|
67
|
-
end
|
68
|
-
|
69
|
-
@active_path = services_path(app_name)
|
70
|
-
foreman_start unless invoked?
|
37
|
+
`--skip-foreman-start` skip automatically running puma and sidekiq [false]
|
38
|
+
D
|
39
|
+
def new(app_name)
|
40
|
+
Command.new(app_name, options).new
|
71
41
|
end
|
72
42
|
|
73
43
|
desc 'cook APP_PATH', ''
|
74
|
-
long_desc <<-
|
44
|
+
long_desc <<-D
|
75
45
|
`orats cook myapp` will create a stand alone cookbook.
|
76
|
-
|
46
|
+
D
|
77
47
|
def cook(app_name)
|
78
|
-
|
79
|
-
@active_path = app_name
|
80
|
-
|
81
|
-
cook_app app_name
|
48
|
+
Command.new(app_name).cook
|
82
49
|
end
|
83
50
|
|
84
|
-
option :skip_data, type: :boolean, default: false, aliases: '-
|
51
|
+
option :skip_data, type: :boolean, default: false, aliases: '-D'
|
85
52
|
desc 'nuke APP_PATH [options]', ''
|
86
|
-
long_desc <<-
|
53
|
+
long_desc <<-D
|
87
54
|
`orats nuke myapp` will delete the directory and optionally all data associated to it.
|
88
55
|
|
89
56
|
Options:
|
90
57
|
|
91
58
|
`--skip-data` will skip deleting app specific postgres databases and redis namespaces [false]
|
92
|
-
|
59
|
+
D
|
93
60
|
def nuke(app_name)
|
94
|
-
|
95
|
-
|
96
|
-
puts
|
97
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete this directory:\e[0m", :red
|
98
|
-
say_status 'path', "#{File.expand_path(@active_path)}", :yellow
|
99
|
-
|
100
|
-
unless options[:skip_data]
|
101
|
-
puts
|
102
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete these postgres databases:\e[0m", :red
|
103
|
-
say_status 'databases', "#{active_project} and #{active_project}_test", :yellow
|
104
|
-
puts
|
105
|
-
say_status 'nuke', "\e[1mYou are about to permanently delete this redis namespace:\e[0m", :red
|
106
|
-
say_status 'namespace', active_project, :yellow
|
107
|
-
end
|
108
|
-
puts
|
109
|
-
|
110
|
-
confirmed_to_delete = yes?('Are you sure? (y/N)', :cyan)
|
111
|
-
|
112
|
-
if confirmed_to_delete
|
113
|
-
unless options[:skip_data]
|
114
|
-
run_rake 'db:drop:all'
|
115
|
-
nuke_redis
|
116
|
-
end
|
61
|
+
Command.new(app_name, options).nuke
|
62
|
+
end
|
117
63
|
|
118
|
-
|
119
|
-
|
64
|
+
desc 'version', ''
|
65
|
+
long_desc <<-LONGDESC
|
66
|
+
`orats version` will print the current version.
|
67
|
+
LONGDESC
|
68
|
+
def version
|
69
|
+
Command.new.version
|
120
70
|
end
|
71
|
+
map %w(-v --version) => :version
|
121
72
|
|
122
73
|
private
|
123
|
-
def active_project
|
124
|
-
@active_path.split('/').last
|
125
|
-
end
|
126
|
-
|
127
|
-
def services_path(app_name)
|
128
|
-
options[:skip_extras] ? app_name : "#{app_name}/services/#{active_project}"
|
129
|
-
end
|
130
|
-
|
131
|
-
def cookbooks_path(app_name)
|
132
|
-
"#{app_name}/cookbooks/#{active_project}"
|
133
|
-
end
|
134
|
-
|
135
74
|
def invoked?
|
136
75
|
caller_locations(0).any? { |backtrace| backtrace.label == 'invoke' }
|
137
76
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'orats/version'
|
2
|
+
require 'orats/shell'
|
3
|
+
require 'orats/foreman'
|
4
|
+
|
5
|
+
module Orats
|
6
|
+
class Command
|
7
|
+
include Thor::Base
|
8
|
+
include Thor::Shell
|
9
|
+
include Thor::Actions
|
10
|
+
#source_root Dir.pwd
|
11
|
+
|
12
|
+
include Shell
|
13
|
+
include Foreman
|
14
|
+
|
15
|
+
attr_accessor :active_path
|
16
|
+
|
17
|
+
def initialize(app_name = '', options = {})
|
18
|
+
@app_name = app_name
|
19
|
+
@options = options
|
20
|
+
|
21
|
+
# required to mix in thor actions without having a base thor class
|
22
|
+
#@destination_stack = [self.class.source_root]
|
23
|
+
self.destination_root = Dir.pwd
|
24
|
+
@behavior = :invoke
|
25
|
+
end
|
26
|
+
|
27
|
+
def new
|
28
|
+
@active_path = @app_name
|
29
|
+
@active_path = services_path(@app_name)
|
30
|
+
|
31
|
+
rails_template 'base' do
|
32
|
+
gsub_postgres_info
|
33
|
+
git_commit 'Change the postgres information'
|
34
|
+
|
35
|
+
bundle_install
|
36
|
+
git_commit 'Add gem lock file'
|
37
|
+
|
38
|
+
run_rake 'db:create:all db:migrate db:test:prepare'
|
39
|
+
git_commit 'Add the database schema file'
|
40
|
+
end
|
41
|
+
|
42
|
+
if @options[:auth]
|
43
|
+
rails_template 'auth', '--skip ' do
|
44
|
+
run_rake 'db:migrate db:seed'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
unless @options[:skip_cook] || @options[:skip_extras]
|
49
|
+
cook_app cookbooks_path(@app_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
@active_path = services_path(@app_name)
|
53
|
+
foreman_init
|
54
|
+
end
|
55
|
+
|
56
|
+
def cook
|
57
|
+
cook_app @app_name
|
58
|
+
end
|
59
|
+
|
60
|
+
def nuke
|
61
|
+
@active_path = @app_name
|
62
|
+
|
63
|
+
nuke_warning
|
64
|
+
|
65
|
+
nuke_data_details_warning unless @options[:skip_data]
|
66
|
+
|
67
|
+
confirmed_to_delete = yes?('Are you sure? (y/N)', :cyan)
|
68
|
+
|
69
|
+
if confirmed_to_delete
|
70
|
+
nuke_data unless @options[:skip_data]
|
71
|
+
|
72
|
+
nuke_directory
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def version
|
77
|
+
puts "Orats version #{VERSION}"
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def active_project
|
82
|
+
project_from_path(@active_path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def services_path(app_name)
|
86
|
+
@options[:skip_extras] ? app_name : "#{app_name}/services/#{active_project}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def cookbooks_path(app_name)
|
90
|
+
"#{app_name}/cookbooks/#{active_project}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -2,15 +2,18 @@ require 'socket'
|
|
2
2
|
require 'timeout'
|
3
3
|
|
4
4
|
module Orats
|
5
|
-
module
|
6
|
-
def
|
5
|
+
module Foreman
|
6
|
+
def foreman_init
|
7
|
+
|
8
|
+
@options[:skip_foreman_start] ? message = 'Start your' : message = 'Starting'
|
9
|
+
|
7
10
|
puts '', '='*80
|
8
|
-
say_status 'action', "\e[
|
11
|
+
say_status 'action', "\e[1m#{message} server with the following commands:\e[0m", :cyan
|
9
12
|
say_status 'command', "cd #{@active_path}", :magenta
|
10
13
|
say_status 'command', 'bundle exec foreman start', :magenta
|
11
14
|
puts '='*80, ''
|
12
15
|
|
13
|
-
attempt_to_start
|
16
|
+
attempt_to_start unless @options[:skip_foreman_start]
|
14
17
|
end
|
15
18
|
|
16
19
|
private
|
data/lib/orats/shell.rb
CHANGED
@@ -4,12 +4,6 @@ module Orats
|
|
4
4
|
run "cd #{path} && #{command} && cd -"
|
5
5
|
end
|
6
6
|
|
7
|
-
def cd_inside(path, &block)
|
8
|
-
run "cd #{path}"
|
9
|
-
yield
|
10
|
-
run 'cd -'
|
11
|
-
end
|
12
|
-
|
13
7
|
def log_message(type, message)
|
14
8
|
puts
|
15
9
|
say_status type, "#{message}...", :yellow
|
@@ -40,75 +34,68 @@ module Orats
|
|
40
34
|
run_from @active_path, 'bundle install'
|
41
35
|
end
|
42
36
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
def nuke_warning
|
38
|
+
puts
|
39
|
+
say_status 'nuke', "\e[1mYou are about to permanently delete this directory:\e[0m", :red
|
40
|
+
say_status 'path', "#{File.expand_path(@app_name)}", :yellow
|
41
|
+
puts
|
47
42
|
end
|
48
43
|
|
49
|
-
def
|
50
|
-
|
44
|
+
def rails_directories
|
45
|
+
rails_gemfiles = run("find #{@active_path} -type f -name Gemfile | xargs grep -lE \"gem 'rails'|gem \\\"rails\\\"\"", capture: true)
|
46
|
+
gemfile_paths = rails_gemfiles.split("\n")
|
51
47
|
|
52
|
-
|
48
|
+
gemfile_paths.map { |gemfile| File.dirname(gemfile) }
|
53
49
|
end
|
54
50
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
if Dir.exist?(@active_path) || File.exist?(@active_path)
|
59
|
-
puts
|
60
|
-
say_status 'aborting', "\e[1mA file or directory already exists at this location:\e[0m", :red
|
61
|
-
say_status 'location', @active_path, :yellow
|
62
|
-
puts '-'*80
|
63
|
-
puts
|
51
|
+
def nuke_data_details_warning
|
52
|
+
rails_projects = []
|
64
53
|
|
65
|
-
|
54
|
+
rails_directories.each do |rails_dir|
|
55
|
+
rails_projects << project_from_path(rails_dir)
|
66
56
|
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def can_cook?
|
70
|
-
log_message 'shell', 'Checking for the cookbook system dependencies'
|
71
|
-
|
72
|
-
has_knife = run('which knife', capture: true)
|
73
|
-
has_berks = run('which berks', capture: true)
|
74
57
|
|
75
|
-
|
76
|
-
'Are you sure you have chef setup correctly?',
|
77
|
-
'http://www.getchef.com/chef/install/`' if has_knife.empty?
|
58
|
+
project_names = rails_projects.join(', ')
|
78
59
|
|
79
|
-
|
80
|
-
|
81
|
-
|
60
|
+
puts
|
61
|
+
say_status 'nuke', "\e[1mYou are about to permanently delete all postgres databases for:\e[0m", :red
|
62
|
+
say_status 'databases', project_names, :yellow
|
63
|
+
puts
|
64
|
+
say_status 'nuke', "\e[1mYou are about to permanently delete all redis namespaces for:\e[0m", :red
|
65
|
+
say_status 'namespace', project_names, :yellow
|
66
|
+
puts
|
67
|
+
end
|
82
68
|
|
83
|
-
|
69
|
+
def nuke_data
|
70
|
+
rails_directories.each do |directory|
|
71
|
+
log_message 'root', 'Removing postgres databases'
|
72
|
+
run_from directory, 'bundle exec rake db:drop:all'
|
73
|
+
nuke_redis project_from_path(directory)
|
74
|
+
end
|
84
75
|
end
|
85
76
|
|
86
|
-
def
|
87
|
-
log_message 'shell', 'Checking for
|
77
|
+
def can_cook?
|
78
|
+
log_message 'shell', 'Checking for the cookbook system dependencies'
|
88
79
|
|
89
|
-
|
80
|
+
has_knife = run('which knife', capture: true)
|
81
|
+
has_berks = run('which berks', capture: true)
|
90
82
|
|
91
|
-
|
92
|
-
|
93
|
-
|
83
|
+
dependency_error 'Cannot access knife',
|
84
|
+
'Are you sure you have chef setup correctly?',
|
85
|
+
'http://www.getchef.com/chef/install/`' if has_knife.empty?
|
94
86
|
|
95
|
-
|
96
|
-
|
87
|
+
dependency_error 'Cannot access berkshelf',
|
88
|
+
'Are you sure you have berkshelf installed correctly?',
|
89
|
+
'You can install it by running `gem install berkshelf`' if has_berks.empty?
|
97
90
|
|
98
|
-
|
99
|
-
puts
|
100
|
-
say_status 'error', "\e[1m#{message}\e[0m", :red
|
101
|
-
say_status 'question', question, :yellow
|
102
|
-
say_status 'answer', answer, :cyan
|
103
|
-
puts '-'*80
|
104
|
-
puts
|
91
|
+
!has_knife.empty? && !has_berks.empty?
|
105
92
|
end
|
106
93
|
|
107
|
-
def rails_template(command, flags = ''
|
94
|
+
def rails_template(command, flags = '')
|
108
95
|
exit_if_cannot_rails
|
109
|
-
exit_if_exists unless flags.index(/--skip
|
96
|
+
exit_if_exists unless flags.index(/--skip/)
|
110
97
|
|
111
|
-
run "rails new #{@active_path} #{flags}--skip-bundle --template #{File.expand_path File.dirname(__FILE__)}/templates/#{command}.rb"
|
98
|
+
run "rails new #{@active_path} #{flags} --skip-bundle --template #{File.expand_path File.dirname(__FILE__)}/templates/#{command}.rb"
|
112
99
|
yield if block_given?
|
113
100
|
end
|
114
101
|
|
@@ -118,5 +105,58 @@ module Orats
|
|
118
105
|
@active_path = app_path
|
119
106
|
rails_template 'cook'
|
120
107
|
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def nuke_redis(namespace)
|
112
|
+
log_message 'root', 'Removing redis keys'
|
113
|
+
|
114
|
+
run "redis-cli KEYS '#{namespace}:*' | xargs --delim='\n' redis-cli DEL"
|
115
|
+
end
|
116
|
+
|
117
|
+
def nuke_directory
|
118
|
+
log_message 'root', 'Deleting directory'
|
119
|
+
|
120
|
+
run "rm -rf #{@active_path}"
|
121
|
+
end
|
122
|
+
|
123
|
+
def dependency_error(message, question, answer)
|
124
|
+
puts
|
125
|
+
say_status 'error', "\e[1m#{message}\e[0m", :red
|
126
|
+
say_status 'question', question, :yellow
|
127
|
+
say_status 'answer', answer, :cyan
|
128
|
+
puts '-'*80
|
129
|
+
puts
|
130
|
+
end
|
131
|
+
|
132
|
+
def exit_if_cannot_rails
|
133
|
+
log_message 'shell', 'Checking for rails'
|
134
|
+
|
135
|
+
has_rails = run('which rails', capture: true)
|
136
|
+
|
137
|
+
dependency_error 'Cannot access rails',
|
138
|
+
'Are you sure you have rails setup correctly?',
|
139
|
+
'You can install it by running `gem install rails`' if has_rails.empty?
|
140
|
+
|
141
|
+
exit 1 if has_rails.empty?
|
142
|
+
end
|
143
|
+
|
144
|
+
def exit_if_exists
|
145
|
+
log_message 'shell', 'Checking if a file or directory already exists'
|
146
|
+
|
147
|
+
if Dir.exist?(@active_path) || File.exist?(@active_path)
|
148
|
+
puts
|
149
|
+
say_status 'aborting', "\e[1mA file or directory already exists at this location:\e[0m", :red
|
150
|
+
say_status 'location', @active_path, :yellow
|
151
|
+
puts '-'*80
|
152
|
+
puts
|
153
|
+
|
154
|
+
exit 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def project_from_path(path)
|
159
|
+
path.split('/').last
|
160
|
+
end
|
121
161
|
end
|
122
162
|
end
|
data/lib/orats/templates/base.rb
CHANGED
@@ -328,12 +328,17 @@ say_status 'config', 'Modifying the initializer files...', :yellow
|
|
328
328
|
puts '-'*80, ''; sleep 0.25
|
329
329
|
|
330
330
|
file 'config/initializers/sidekiq.rb', <<-'CODE'
|
331
|
+
sidekiq_config = {
|
332
|
+
url: "redis://#{ENV['app_name_CACHE_HOST']}:#{ENV['app_name_CACHE_PORT']}/#{ENV['app_name_CACHE_DATABASE']}",
|
333
|
+
namespace: "ns_app::sidekiq_#{Rails.env}"
|
334
|
+
}
|
335
|
+
|
331
336
|
Sidekiq.configure_server do |config|
|
332
|
-
config.redis =
|
337
|
+
config.redis = sidekiq_config
|
333
338
|
end
|
334
339
|
|
335
340
|
Sidekiq.configure_client do |config|
|
336
|
-
config.redis =
|
341
|
+
config.redis = sidekiq_config
|
337
342
|
end
|
338
343
|
CODE
|
339
344
|
|
data/lib/orats/templates/cook.rb
CHANGED
data/lib/orats/version.rb
CHANGED
data/orats.gemspec
CHANGED
@@ -0,0 +1,133 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestCLI < Minitest::Unit::TestCase
|
4
|
+
include Orats::Test
|
5
|
+
|
6
|
+
def test_new_app
|
7
|
+
app_name = generate_app_name
|
8
|
+
|
9
|
+
out, err = capture_subprocess_io do
|
10
|
+
orats "new #{app_name}", flags: ORATS_FLAGS
|
11
|
+
end
|
12
|
+
|
13
|
+
assert_match /success/, out
|
14
|
+
|
15
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}/cookbooks/#{app_name}"
|
16
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}/services/#{app_name}"
|
17
|
+
|
18
|
+
assert_nuked app_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_new_app_with_auth
|
22
|
+
app_name = generate_app_name
|
23
|
+
gemfile_path = "#{TEST_PATH}/#{app_name}/services/#{app_name}/Gemfile"
|
24
|
+
|
25
|
+
out, err = capture_subprocess_io do
|
26
|
+
orats "new #{app_name}", flags: "--auth #{ORATS_FLAGS}"
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_match /success/, out
|
30
|
+
|
31
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}/cookbooks/#{app_name}"
|
32
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}/services/#{app_name}"
|
33
|
+
|
34
|
+
assert_in_file gemfile_path, /devise/
|
35
|
+
assert_in_file gemfile_path, /devise-async/
|
36
|
+
assert_in_file gemfile_path, /pundit/
|
37
|
+
|
38
|
+
assert_nuked app_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_new_app_without_cookbook
|
42
|
+
app_name = generate_app_name
|
43
|
+
|
44
|
+
out, err = capture_subprocess_io do
|
45
|
+
orats "new #{app_name}", flags: "--skip-cook #{ORATS_FLAGS}"
|
46
|
+
end
|
47
|
+
|
48
|
+
refute_path_exists "#{TEST_PATH}/#{app_name}/cookbooks/#{app_name}"
|
49
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}/services/#{app_name}"
|
50
|
+
|
51
|
+
assert_nuked app_name
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_new_app_without_extras
|
55
|
+
app_name = generate_app_name
|
56
|
+
|
57
|
+
out, err = capture_subprocess_io do
|
58
|
+
orats "new #{app_name}", flags: "--skip-extras #{ORATS_FLAGS}"
|
59
|
+
end
|
60
|
+
|
61
|
+
refute_path_exists "#{TEST_PATH}/#{app_name}/cookbooks/#{app_name}"
|
62
|
+
refute_path_exists "#{TEST_PATH}/#{app_name}/services/#{app_name}"
|
63
|
+
assert_path_exists "#{TEST_PATH}/#{app_name}"
|
64
|
+
|
65
|
+
assert_nuked app_name
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_cook
|
69
|
+
app_name = generate_app_name
|
70
|
+
|
71
|
+
out, err = capture_subprocess_io do
|
72
|
+
orats "cook #{app_name}"
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_match /success/, out
|
76
|
+
assert_nuked app_name, flags: '-D'
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_version
|
80
|
+
out, err = capture_subprocess_io do
|
81
|
+
orats 'version'
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_match /Orats/, out
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def assert_nuked(app_name, options = {})
|
90
|
+
out, err = capture_subprocess_io do
|
91
|
+
orats "nuke #{app_name}", flags: options[:flags], answer: 'y'
|
92
|
+
end
|
93
|
+
|
94
|
+
assert_match /#{app_name}/, out
|
95
|
+
system 'rm -rf /tmp/orats'
|
96
|
+
end
|
97
|
+
|
98
|
+
def assert_server_started
|
99
|
+
assert port_taken?
|
100
|
+
end
|
101
|
+
|
102
|
+
def assert_path_exists(file_or_dir)
|
103
|
+
assert File.exists?(file_or_dir), "Expected path '#{file_or_dir}' to exist"
|
104
|
+
end
|
105
|
+
|
106
|
+
def refute_path_exists(file_or_dir)
|
107
|
+
refute File.exists?(file_or_dir), "Expected path '#{file_or_dir}' to exist"
|
108
|
+
end
|
109
|
+
|
110
|
+
def assert_in_file(file_path, regex)
|
111
|
+
out, err = capture_subprocess_io do
|
112
|
+
system "cat #{file_path}"
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_match regex, out
|
116
|
+
end
|
117
|
+
|
118
|
+
def ensure_port_is_free
|
119
|
+
skip 'Port 3000 is already in use, aborting test' if port_taken?
|
120
|
+
end
|
121
|
+
|
122
|
+
def kill_server(stdout_text)
|
123
|
+
pid_lines = stdout_text.scan(/started with pid \d+/)
|
124
|
+
|
125
|
+
puma = pid_lines[0].split(' ').last
|
126
|
+
sidekiq = pid_lines[1].split(' ').last
|
127
|
+
|
128
|
+
puts "puma pid #{puma}"
|
129
|
+
puts "sidekiq pid #{sidekiq}"
|
130
|
+
|
131
|
+
system "kill -9 #{puma} && kill -9 #{sidekiq}"
|
132
|
+
end
|
133
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'securerandom'
|
3
|
+
require_relative '../lib/orats/foreman'
|
4
|
+
|
5
|
+
module Orats
|
6
|
+
module Test
|
7
|
+
include Foreman
|
8
|
+
|
9
|
+
BINARY_PATH = File.absolute_path('../../bin/orats',__FILE__)
|
10
|
+
TEST_PATH = '/tmp/orats/test'
|
11
|
+
ORATS_FLAGS = '--pg-password pleasedonthackme --skip-foreman-start'
|
12
|
+
|
13
|
+
def orats(command, options = {})
|
14
|
+
cmd, app_name = command.split(' ')
|
15
|
+
prepend_command = ''
|
16
|
+
|
17
|
+
command = "#{cmd} #{TEST_PATH}/#{app_name}" if command.include?(' ')
|
18
|
+
|
19
|
+
if options.has_key?(:answer)
|
20
|
+
options[:answer] == 'y' || options[:answer] == 'yes' ? insert_answer = 'yes' : insert_answer = 'echo'
|
21
|
+
|
22
|
+
prepend_command = "#{insert_answer} | "
|
23
|
+
end
|
24
|
+
|
25
|
+
system "#{prepend_command} #{BINARY_PATH} #{command} #{options[:flags]}"
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def generate_app_name
|
31
|
+
"a_#{SecureRandom.hex(8)}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Janetakis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.7'
|
55
69
|
description: A collection of rails application templates using modern versions of
|
56
70
|
Ruby on Rails. Launch new applications and the infrastructure to run them in seconds.
|
57
71
|
email:
|
@@ -70,7 +84,8 @@ files:
|
|
70
84
|
- bin/orats
|
71
85
|
- lib/orats.rb
|
72
86
|
- lib/orats/cli.rb
|
73
|
-
- lib/orats/
|
87
|
+
- lib/orats/command.rb
|
88
|
+
- lib/orats/foreman.rb
|
74
89
|
- lib/orats/shell.rb
|
75
90
|
- lib/orats/templates/auth.rb
|
76
91
|
- lib/orats/templates/base.rb
|
@@ -78,6 +93,8 @@ files:
|
|
78
93
|
- lib/orats/templates/includes/Gemfile
|
79
94
|
- lib/orats/version.rb
|
80
95
|
- orats.gemspec
|
96
|
+
- test/integration/cli_test.rb
|
97
|
+
- test/test_helper.rb
|
81
98
|
homepage: https://github.com/nickjj/orats
|
82
99
|
licenses:
|
83
100
|
- MIT
|
@@ -102,4 +119,6 @@ rubygems_version: 2.2.0
|
|
102
119
|
signing_key:
|
103
120
|
specification_version: 4
|
104
121
|
summary: Opinionated rails application templates.
|
105
|
-
test_files:
|
122
|
+
test_files:
|
123
|
+
- test/integration/cli_test.rb
|
124
|
+
- test/test_helper.rb
|