orats 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a26044924f29339758058ce1fd44c070b101b3b1
4
- data.tar.gz: d900ea0bea9f77b6ed79548f1454795ce11f1d1d
3
+ metadata.gz: ed3528a226c156ebd2bb1155fc50f3a5074f78cb
4
+ data.tar.gz: 972dd00fe19344f92c8079837f841db6226b9425
5
5
  SHA512:
6
- metadata.gz: 39b50b3fce6c70c9a660032088a79b61a76ffb8ebb9c05b217f310626063b44469029c9a9ebbde2d414590a49c70e1928800291f0c05e2a2b737b0c804fddb9a
7
- data.tar.gz: 2ec9125e2e64d80cb301ecc0d97c75b2113b0811bf597ae6bc94206f4418ac4d026781d2f6741622ee9419381d949fb3d66d6216d742ca649e6111e264c9b7d9
6
+ metadata.gz: 1ca57f387e3d371752ae69c303c14044491e8abfd8fd8ac093b3c860ae5c307c85576638ffdf11e4f82b320c8d9e405c4324645ad8335a28829960fd96ba77c5
7
+ data.tar.gz: 20d28d78394998d2d0f4ead1969aa0f959c279753f1bffd836d783b3f79503b938092543393f32b56b4c5c12dbaa27cd0fab885b2ffc513c2bad54820397a753
data/.gitignore CHANGED
@@ -4,4 +4,5 @@
4
4
  .*.sw*
5
5
  *~
6
6
  .idea/
7
- .gem
7
+ .gem
8
+ Gemfile.lock
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orats (0.3.0)
5
- thor (~> 0)
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 (~> 0)
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
- It is important that you change all of these values to match your setup. The only non-obvious one might be the SSH key. You
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
- You should also edit the details in the `metadata.rb` file.
283
+ Nice, then you should know what to do from this point. Setup your encrypted data bag and bootstrap the node.
285
284
 
286
- ### Encrypted values
285
+ #### Do you need a full blown walk through?
287
286
 
288
- Chef has this notion of encrypted data bags. They are used to protect sensitive information like passwords or secret tokens.
289
- You can check out the `data_bags/<app_name>_secrets/production.json` file to know which fields you need to fill out later.
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
@@ -14,4 +14,4 @@ if File.exist?(git_path)
14
14
  end
15
15
 
16
16
  require 'orats/cli'
17
- Orats::Orats.start(ARGV)
17
+ Orats::CLI.start(ARGV)
data/lib/orats/cli.rb CHANGED
@@ -1,23 +1,17 @@
1
1
  require 'thor'
2
- require 'orats/shell'
3
- require 'orats/server'
2
+ require 'orats/command'
4
3
 
5
4
  module Orats
6
- class Orats < Thor
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 <<-LONGDESC
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
- if options[:auth]
60
- rails_template 'auth', '--skip ' do
61
- run_rake 'db:migrate db:seed'
62
- end
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 <<-LONGDESC
44
+ long_desc <<-D
75
45
  `orats cook myapp` will create a stand alone cookbook.
76
- LONGDESC
46
+ D
77
47
  def cook(app_name)
78
- @options = options
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: '-S'
51
+ option :skip_data, type: :boolean, default: false, aliases: '-D'
85
52
  desc 'nuke APP_PATH [options]', ''
86
- long_desc <<-LONGDESC
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
- LONGDESC
59
+ D
93
60
  def nuke(app_name)
94
- @active_path = app_name
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
- nuke_directory
119
- end
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 Server
6
- def foreman_start
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[1mStarting server with the following commands:\e[0m", :cyan
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 nuke_redis
44
- log_message 'root', 'Removing redis keys'
45
-
46
- run "redis-cli KEYS '#{active_project}:*' | xargs --delim='\n' redis-cli DEL"
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 nuke_directory
50
- log_message 'root', 'Deleting directory'
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
- run "rm -rf #{@active_path}"
48
+ gemfile_paths.map { |gemfile| File.dirname(gemfile) }
53
49
  end
54
50
 
55
- def exit_if_exists
56
- log_message 'shell', 'Checking if a file or directory already exists'
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
- exit 1
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
- dependency_error 'Cannot access knife',
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
- dependency_error 'Cannot access berkshelf',
80
- 'Are you sure you have berkshelf installed correctly?',
81
- 'You can install it by running `gem install berkshelf`' if has_berks.empty?
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
- !has_knife.empty? && !has_berks.empty?
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 exit_if_cannot_rails
87
- log_message 'shell', 'Checking for rails'
77
+ def can_cook?
78
+ log_message 'shell', 'Checking for the cookbook system dependencies'
88
79
 
89
- has_rails = run('which rails', capture: true)
80
+ has_knife = run('which knife', capture: true)
81
+ has_berks = run('which berks', capture: true)
90
82
 
91
- dependency_error 'Cannot access rails',
92
- 'Are you sure you have rails setup correctly?',
93
- 'You can install it by running `gem install rails`' if has_rails.empty?
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
- exit 1 if has_rails.empty?
96
- end
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
- def dependency_error(message, question, answer)
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 = '', &block)
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
@@ -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 = { url: "redis://#{ENV['app_name_CACHE_HOST']}:#{ENV['app_name_CACHE_PORT']}/#{ENV['app_name_CACHE_DATABASE']}", namespace: "ns_app::sidekiq_#{Rails.env}" }
337
+ config.redis = sidekiq_config
333
338
  end
334
339
 
335
340
  Sidekiq.configure_client do |config|
336
- config.redis = { url: "redis://#{ENV['app_name_CACHE_HOST']}:#{ENV['app_name_CACHE_PORT']}/#{ENV['app_name_CACHE_DATABASE']}", namespace: "ns_app::sidekiq_#{Rails.env}" }
341
+ config.redis = sidekiq_config
337
342
  end
338
343
  CODE
339
344
 
@@ -424,11 +424,13 @@ node.override[:firewall][:rules] = [
424
424
  include_recipe 'ufw'
425
425
 
426
426
  # swapfile
427
+
427
428
  swap_file '/mnt/swap' do
428
429
  size node[:app_name][:base][:swap_size]
429
430
  end
430
431
 
431
432
  # htop
433
+
432
434
  package 'htop'
433
435
  CODE
434
436
  end
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '4.0.2'
3
+ gem 'rails', '4.0.3'
4
4
  gem 'turbolinks', '~> 1.3.1'
5
5
  gem 'jquery-rails', '~> 3.0.4'
6
6
  gem 'jquery-turbolinks', '~> 2.0.1'
data/lib/orats/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Orats
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
data/orats.gemspec CHANGED
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 1.5'
24
24
  spec.add_development_dependency 'rake', '~> 0'
25
+ spec.add_development_dependency 'minitest', '~> 4.7'
25
26
  end
@@ -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
@@ -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.1
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-12 00:00:00.000000000 Z
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/server.rb
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