orats 0.7.3 → 0.8.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile +1 -1
  4. data/{LICENSE.txt → LICENSE} +21 -21
  5. data/README.md +51 -346
  6. data/Rakefile +1 -1
  7. data/bin/orats +5 -2
  8. data/lib/orats/argv_adjust.rb +61 -0
  9. data/lib/orats/cli.rb +53 -141
  10. data/lib/orats/cli_help/new +27 -0
  11. data/lib/orats/cli_help/nuke +19 -0
  12. data/lib/orats/commands/new/exec.rb +59 -0
  13. data/lib/orats/commands/new/rails.rb +197 -0
  14. data/lib/orats/commands/new/server.rb +67 -0
  15. data/lib/orats/commands/nuke.rb +66 -44
  16. data/lib/orats/common.rb +76 -0
  17. data/lib/orats/postgres.rb +90 -0
  18. data/lib/orats/process.rb +35 -0
  19. data/lib/orats/redis.rb +25 -0
  20. data/lib/orats/shell.rb +12 -0
  21. data/lib/orats/templates/auth.rb +96 -82
  22. data/lib/orats/templates/base.rb +115 -110
  23. data/lib/orats/templates/includes/new/rails/.env +28 -28
  24. data/lib/orats/templates/includes/new/rails/Gemfile +4 -4
  25. data/lib/orats/templates/includes/new/rails/config/{whenever.rb → schedule.rb} +0 -0
  26. data/lib/orats/ui.rb +33 -0
  27. data/lib/orats/version.rb +3 -2
  28. data/lib/orats.rb +2 -1
  29. data/orats.gemspec +7 -5
  30. data/test/integration/cli_test.rb +28 -177
  31. data/test/test_helper.rb +24 -9
  32. metadata +17 -29
  33. data/lib/orats/commands/common.rb +0 -146
  34. data/lib/orats/commands/diff/compare.rb +0 -106
  35. data/lib/orats/commands/diff/exec.rb +0 -60
  36. data/lib/orats/commands/diff/parse.rb +0 -66
  37. data/lib/orats/commands/inventory.rb +0 -100
  38. data/lib/orats/commands/playbook.rb +0 -60
  39. data/lib/orats/commands/project/exec.rb +0 -74
  40. data/lib/orats/commands/project/rails.rb +0 -162
  41. data/lib/orats/commands/project/server.rb +0 -57
  42. data/lib/orats/commands/role.rb +0 -70
  43. data/lib/orats/commands/ui.rb +0 -47
  44. data/lib/orats/templates/includes/inventory/group_vars/all.yml +0 -202
  45. data/lib/orats/templates/includes/inventory/hosts +0 -8
  46. data/lib/orats/templates/includes/playbook/Galaxyfile +0 -15
  47. data/lib/orats/templates/includes/playbook/common.yml +0 -23
  48. data/lib/orats/templates/includes/playbook/site.yml +0 -36
  49. data/lib/orats/templates/includes/role/.travis.yml +0 -19
  50. data/lib/orats/templates/includes/role/README.md +0 -62
  51. data/lib/orats/templates/includes/role/meta/main.yml +0 -123
  52. data/lib/orats/templates/includes/role/tests/inventory +0 -1
  53. data/lib/orats/templates/includes/role/tests/main.yml +0 -7
  54. data/lib/orats/templates/playbook.rb +0 -119
  55. data/lib/orats/templates/role.rb +0 -144
@@ -1,47 +1,55 @@
1
- require 'orats/commands/common'
1
+ require 'orats/common'
2
2
 
3
3
  module Orats
4
4
  module Commands
5
+ # delete a path and its data
5
6
  class Nuke < Common
6
7
  def initialize(target_path = '', options = {})
7
8
  super
8
9
  end
9
10
 
10
11
  def init
11
- log_nuke_info
12
- log_nuke_details unless @options[:skip_data]
12
+ exit_if_invalid_system
13
13
 
14
- confirmed_to_delete = yes?('Are you sure? (y/N)', :cyan); puts
15
-
16
- if confirmed_to_delete
17
- nuke_data unless @options[:skip_data]
18
- nuke_directory
19
- end
14
+ nuke_report
15
+ nuke_details
16
+ nuke_data unless @options[:skip_data]
17
+ nuke_path
20
18
  end
21
19
 
22
20
  private
23
21
 
24
- def log_nuke_info
25
- log_error 'nuke', 'You are about to permanently delete this directory',
26
- 'path', File.expand_path(@target_path)
22
+ def exit_if_path_missing
23
+ task 'Check if path is missing'
24
+
25
+ return if Dir.exist?(@target_path) || File.exist?(@target_path)
26
+
27
+ error 'Path was not found', @target_path
28
+ exit 1
27
29
  end
28
30
 
29
- def log_nuke_details
30
- rails_projects = []
31
+ def nuke_report
32
+ puts
33
+ log 'warning', 'You are about to permanently delete this path',
34
+ :yellow, true
35
+ log 'nuke path', File.expand_path(@target_path), :white
36
+ puts
37
+ end
31
38
 
32
- valid_rails_directories.each { |rails_dir| rails_projects << File.basename(rails_dir) }
33
- project_names = rails_projects.join(', ')
39
+ def nuke_details
40
+ rails_apps = []
34
41
 
35
- log_error 'nuke', 'You are about to permanently delete all postgres databases for',
36
- 'databases', project_names, true
42
+ valid_rails_apps.each do
43
+ |rails_dir| rails_apps << File.basename(rails_dir)
44
+ end
37
45
 
38
- log_error 'nuke', 'You are about to permanently delete all redis namespaces for',
39
- 'namespaces', project_names
46
+ nuke_items(rails_apps) unless @options[:skip_data]
40
47
  end
41
48
 
42
- def valid_rails_directories
49
+ def valid_rails_apps
43
50
  rails_gemfiles =
44
- run("find #{@active_path} -type f -name Gemfile | xargs grep -lE \"gem 'rails'|gem \\\"rails\\\"\"",
51
+ run("find #{@target_path} -type f -name Gemfile | " + \
52
+ "xargs grep -lE \"gem 'rails'|gem \\\"rails\\\"\"",
45
53
  capture: true)
46
54
 
47
55
  gemfile_paths = rails_gemfiles.split("\n")
@@ -49,38 +57,52 @@ module Orats
49
57
  gemfile_paths.map { |gemfile| File.dirname(gemfile) }
50
58
  end
51
59
 
52
- def nuke_data
53
- valid_rails_directories.each do |directory|
54
- log_task 'Remove postgres databases'
55
- run_from directory, 'bundle exec rake db:drop:all'
56
-
57
- nuke_redis File.basename(directory)
60
+ def nuke_items(apps)
61
+ if apps.empty?
62
+ results 'No apps were found in this path',
63
+ 'skipping', File.expand_path(@target_path)
64
+ nuke_path
65
+ exit
66
+ else
67
+ nuke_app_details(apps.join(', '))
58
68
  end
59
69
  end
60
70
 
61
- def nuke_redis(namespace)
62
- log_task 'Remove redis keys'
71
+ def nuke_app_details(app_names)
72
+ puts
73
+ log 'nuke', 'You are about to permanently delete all postgres' + \
74
+ ' databases for', :red, true
75
+ log 'databases', app_names, :yellow
76
+ puts
77
+ log 'nuke', 'You are about to permanently delete all redis' + \
78
+ ' namespaces for', :red, true
79
+ log 'namespaces', app_names, :yellow
80
+ puts
81
+
82
+ exit unless yes?('Are you sure? (y/N)', :cyan)
83
+ end
63
84
 
64
- while not_able_to_nuke_redis?(@options[:redis_password], namespace)
65
- log_status_top 'error', "The redis password you supplied was incorrect\n", :red
66
- new_password = ask('Enter the correct password or CTRL+C to quit:', :cyan)
67
- puts
85
+ def nuke_data
86
+ valid_rails_apps.each do |app|
87
+ task 'Delete postgres database'
88
+ drop_database app
68
89
 
69
- break unless not_able_to_nuke_redis?(new_password, namespace)
90
+ task 'Delete redis keys'
91
+ drop_namespace File.basename(app)
70
92
  end
71
93
  end
72
94
 
73
- def not_able_to_nuke_redis?(password, namespace)
74
- password.empty? ? redis_password = '' : redis_password = "-a #{password}"
75
- redis_out = run("redis-cli #{redis_password} KEYS '#{namespace}:*' | xargs --delim='\n' redis-cli #{redis_password} DEL", capture: true)
95
+ def nuke_path
96
+ exit_if_path_missing
76
97
 
77
- redis_out.include?('NOAUTH Authentication required')
78
- end
98
+ task 'Delete path'
99
+
100
+ return if @options[:skip_data]
79
101
 
80
- def nuke_directory
81
- log_task 'Delete directory'
82
- run "rm -rf #{@active_path}"
102
+ puts
103
+ exit unless yes?('Are you sure? (y/N)', :cyan)
104
+ run "rm -rf #{@target_path}"
83
105
  end
84
106
  end
85
107
  end
86
- end
108
+ end
@@ -0,0 +1,76 @@
1
+ require 'orats/postgres'
2
+ require 'orats/process'
3
+ require 'orats/redis'
4
+ require 'orats/shell'
5
+ require 'orats/ui'
6
+
7
+ module Orats
8
+ # common class that other CLI driven classes subclass
9
+ class Common
10
+ include Thor::Base
11
+ include Thor::Shell
12
+ include Thor::Actions
13
+ include Shell
14
+ include UI
15
+ include Process
16
+ include Postgres
17
+ include Redis
18
+
19
+ def initialize(target_path = '', options = {})
20
+ @target_path = target_path
21
+ @options = options
22
+
23
+ self.destination_root = Dir.pwd
24
+ @behavior = :invoke
25
+ end
26
+
27
+ def base_path
28
+ File.join(File.expand_path(File.dirname(__FILE__)))
29
+ end
30
+
31
+ def url_to_string(url)
32
+ open(url).read
33
+ rescue *[OpenURI::HTTPError, SocketError] => ex
34
+ error 'Unable to access URL', ex
35
+ exit 1
36
+ end
37
+
38
+ def file_to_string(path)
39
+ if File.exist?(path) && File.file?(path)
40
+ IO.read path
41
+ else
42
+ error 'Path not found', path
43
+ exit 1
44
+ end
45
+ end
46
+
47
+ def exit_if_path_exists(extend_path = '')
48
+ task 'Check if path exists'
49
+
50
+ extended_path = @target_path.dup
51
+
52
+ unless extend_path.empty?
53
+ extended_path = File.join(extended_path, extend_path)
54
+ end
55
+
56
+ return unless Dir.exist?(extended_path) || File.exist?(extended_path)
57
+
58
+ error 'Path already exists', extended_path
59
+ exit 1
60
+ end
61
+
62
+ def exit_if_invalid_system
63
+ exit_if_process :not_found, 'rails', 'git', 'psql', 'redis-cli'
64
+ exit_if_process :not_running, 'postgres', 'redis'
65
+
66
+ exit_if_postgres_unreachable
67
+ exit_if_redis_unreachable
68
+ end
69
+
70
+ def run_rake(command)
71
+ task 'Run rake command'
72
+
73
+ run_from @target_path, "bundle exec rake #{command}"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,90 @@
1
+ module Orats
2
+ # manage the postgres process
3
+ module Postgres
4
+ def postgres_bin(bin_name = 'psql')
5
+ exec = "#{bin_name} -h #{@options[:pg_location]} -U " + \
6
+ "#{@options[:pg_username]}"
7
+
8
+ return exec if @options[:pg_password].empty?
9
+ exec.prepend("PGPASSWORD=#{@options[:pg_password]} ")
10
+ end
11
+
12
+ def create_database
13
+ if local_postgres?
14
+ run_rake 'db:create:all'
15
+ else
16
+ manually_create_postgres_db
17
+ end
18
+ end
19
+
20
+ def drop_database(name)
21
+ if local_postgres?
22
+ run_rake 'db:drop:all'
23
+ else
24
+ manually_delete_postgres_db File.basename(name)
25
+ end
26
+ end
27
+
28
+ def exit_if_postgres_unreachable
29
+ task 'Check if you can connect to postgres'
30
+
31
+ return if run("#{postgres_bin} -c 'select 1'")
32
+
33
+ error 'Cannot connect to postgres', 'attempt to SELECT 1'
34
+ exit 1
35
+ end
36
+
37
+ def exit_if_database_exists
38
+ task 'Check if the postgres database exists'
39
+
40
+ # detect if the database already exists
41
+ database = File.basename(@target_path)
42
+ return if run("#{postgres_bin} -d #{database} -l | " + \
43
+ "grep #{database} | wc -l", capture: true).chomp == '0'
44
+
45
+ error "'#{database}' database already exists",
46
+ 'attempt to check database existence'
47
+ puts
48
+
49
+ exit 1 unless yes?('Would you like to continue anyways? (y/N)',
50
+ :cyan)
51
+ end
52
+
53
+ private
54
+
55
+ def local_postgres?
56
+ @options[:pg_location] == 'localhost' ||
57
+ @options[:pg_location] == '127.0.0.1'
58
+ end
59
+
60
+ def manually_create_postgres_db
61
+ database = File.basename(@target_path)
62
+ test_database = "#{database}_test"
63
+
64
+ createdb(database)
65
+ createdb(test_database)
66
+ end
67
+
68
+ def createdb(database)
69
+ return if run("#{postgres_bin('createdb')} #{database}")
70
+
71
+ log 'Skipped creating postgres database',
72
+ "#{database} already exists", :yellow
73
+ end
74
+
75
+ def manually_delete_postgres_db(name)
76
+ database = File.basename(name)
77
+ test_database = "#{database}_test"
78
+
79
+ dropdb(database)
80
+ dropdb(test_database)
81
+ end
82
+
83
+ def dropdb(database)
84
+ return if run("#{postgres_bin('dropdb')} #{database}")
85
+
86
+ log 'Skipped dropping postgres database',
87
+ "#{database} does not exists", :yellow
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,35 @@
1
+ module Orats
2
+ # manage detecting processes
3
+ module Process
4
+ def exit_if_process(detect_method, *processes)
5
+ result = process_detect(detect_method)
6
+
7
+ processes.each do |process|
8
+ task "Check if #{process} is available"
9
+
10
+ exit 1 if process_unusable?("#{result} #{process}", process)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def process_detect(method)
17
+ if method == :not_found
18
+ 'which'
19
+ elsif method == :not_running
20
+ 'ps cax | grep'
21
+ end
22
+ end
23
+
24
+ def process_unusable?(command, process)
25
+ out = run(command, capture: true)
26
+
27
+ if out.empty?
28
+ error "Cannot detect #{process}",
29
+ 'trying to do `which` on it'
30
+ end
31
+
32
+ out.empty?
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ module Orats
2
+ # manage the redis process
3
+ module Redis
4
+ def redis_bin(bin_name = 'redis-cli')
5
+ exec = "#{bin_name} -h #{@options[:redis_location]}"
6
+
7
+ return exec if @options[:redis_password].empty?
8
+ exec << " -a #{@options[:redis_password]}"
9
+ end
10
+
11
+ def drop_namespace(namespace)
12
+ run "#{redis_bin} KEYS '#{namespace}:*'| " + \
13
+ "xargs --delim='\n' #{redis_bin} DEL"
14
+ end
15
+
16
+ def exit_if_redis_unreachable
17
+ task 'Check if you can ping redis'
18
+
19
+ return if run("#{redis_bin} ping")
20
+
21
+ error 'Cannot ping redis', 'attempt to PING'
22
+ exit 1
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ module Orats
2
+ # execute various shell commands
3
+ module Shell
4
+ def run_from(path, command)
5
+ run "cd #{path} && #{command} && cd -"
6
+ end
7
+
8
+ def commit(message)
9
+ run_from @target_path, "git add -A && git commit -m '#{message}'"
10
+ end
11
+ end
12
+ end