orats 0.7.3 → 0.8.0

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