roro 0.3.4 → 0.3.9

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -2
  3. data/Guardfile +3 -6
  4. data/lib/roro.rb +1 -1
  5. data/lib/roro/cli.rb +75 -6
  6. data/lib/roro/cli/base/base.rb +2 -1
  7. data/lib/roro/cli/base/base_files.rb +4 -18
  8. data/lib/roro/cli/base/check_dependencies.rb +98 -0
  9. data/lib/roro/cli/base/insert_gems.rb +15 -7
  10. data/lib/roro/cli/base/insertions.rb +3 -1
  11. data/lib/roro/cli/base/utilities.rb +22 -0
  12. data/lib/roro/cli/cli.rb +99 -0
  13. data/lib/roro/cli/configuration.rb +69 -0
  14. data/lib/roro/cli/expose.rb +8 -7
  15. data/lib/roro/cli/generate/config.rb +13 -0
  16. data/lib/roro/cli/generate/config/rails.rb +17 -0
  17. data/lib/roro/cli/generate/generate.rb +1 -0
  18. data/lib/roro/cli/generate/generate_keys.rb +47 -0
  19. data/lib/roro/cli/greenfield.rb +22 -91
  20. data/lib/roro/cli/obfuscate.rb +10 -11
  21. data/lib/roro/cli/rollon.rb +74 -18
  22. data/lib/roro/cli/rollon/stories.rb +2 -0
  23. data/{.keep → lib/roro/cli/rollon/stories/database.rb} +0 -0
  24. data/lib/roro/cli/rollon/stories/rails.rb +1 -0
  25. data/lib/roro/cli/{templates/base/roro → rollon/stories/rails}/.keep +0 -0
  26. data/lib/roro/cli/rollon/stories/rails/database.rb +33 -0
  27. data/lib/roro/cli/rollon/stories/rails/database/with_mysql.rb +22 -0
  28. data/lib/roro/cli/rollon/stories/rails/database/with_postgresql.rb +21 -0
  29. data/lib/roro/cli/rollon/stories/ruby_gem.rb +77 -0
  30. data/lib/roro/cli/rollon/stories/ruby_gem/with_ci_cd.rb +81 -0
  31. data/lib/roro/cli/rollon/stories/stories.rb +3 -0
  32. data/lib/roro/cli/roro_configurator.yml +157 -0
  33. data/lib/roro/cli/ruby_gem.rb +60 -47
  34. data/lib/roro/cli/templates/base/.dockerignore +48 -10
  35. data/lib/roro/cli/templates/base/.roro_config.yml +15 -0
  36. data/lib/roro/cli/templates/base/Dockerfile.tt +82 -0
  37. data/lib/roro/cli/templates/base/config/database.mysql.yml +19 -0
  38. data/lib/roro/cli/templates/base/config/{database.yml → database.pg.yml} +0 -0
  39. data/lib/roro/cli/templates/greenfield/Dockerfile.tt +29 -7
  40. data/lib/roro/cli/templates/{base/livereload → livereload}/hosts.example +0 -0
  41. data/lib/roro/cli/templates/{base/roro/containers → roro}/.keep +0 -0
  42. data/lib/roro/cli/templates/{dockerize/docker-compose.yml → roro/docker-compose.yml.tt} +18 -18
  43. data/lib/roro/cli/templates/{base/roro/containers/app → roro/roro}/.keep +0 -0
  44. data/lib/roro/cli/templates/{base/roro/containers/frontend → roro/roro/containers}/.keep +0 -0
  45. data/lib/roro/cli/templates/{dockerize/.env → roro/roro/containers/app}/.keep +0 -0
  46. data/lib/roro/cli/templates/{dockerize/.env/development → roro/roro/containers/frontend}/.keep +0 -0
  47. data/lib/roro/cli/templates/{quickstart/entrypoint.sh → roro/roro/docker-entrypoint.sh.tt} +1 -1
  48. data/lib/roro/cli/templates/ruby_gem/.circleci/config.yml +17 -0
  49. data/lib/roro/cli/templates/ruby_gem/docker-compose.yml +6 -4
  50. data/lib/roro/cli/templates/ruby_gem/roro/ci.env.tt +1 -0
  51. data/lib/roro/cli/templates/{dockerize → ruby_gem/roro/containers}/.keep +0 -0
  52. data/lib/roro/cli/templates/ruby_gem/roro/containers/ruby_image/Dockerfile.tt +16 -0
  53. data/lib/roro/cli/templates/ruby_gem/{docker/env_files → roro/keys}/.keep +0 -0
  54. data/lib/roro/cli/templates/{ruby_gem/docker/keys → stories}/.keep +0 -0
  55. data/lib/roro/cli/templates/stories/with_mysql/_service.yml +10 -0
  56. data/lib/roro/cli/templates/stories/with_postgresql/.keep +0 -0
  57. data/lib/roro/cli/templates/stories/with_postgresql/_service.yml +7 -0
  58. data/lib/roro/version.rb +1 -1
  59. data/roro.gemspec +5 -4
  60. data/sandbox/.keep +0 -0
  61. data/vendor/cache/concurrent-ruby-1.1.7.gem +0 -0
  62. data/vendor/cache/gem-release-2.1.1.gem +0 -0
  63. data/vendor/cache/mocha-1.11.2.gem +0 -0
  64. metadata +86 -55
  65. data/lib/roro/cli/base/configuration.rb +0 -63
  66. data/lib/roro/cli/generate_keys.rb +0 -79
  67. data/lib/roro/cli/rollon/as_dockerize.rb +0 -28
  68. data/lib/roro/cli/rollon/as_quickstart.rb +0 -17
  69. data/lib/roro/cli/rollon/as_roro.rb +0 -30
  70. data/lib/roro/cli/rollon/use_cases.rb +0 -3
  71. data/lib/roro/cli/templates/base/circleci/config.yml.tt +0 -70
  72. data/lib/roro/cli/templates/base/docker-compose.yml.tt +0 -53
  73. data/lib/roro/cli/templates/base/roro/containers/app/Dockerfile.tt +0 -32
  74. data/lib/roro/cli/templates/base/roro/containers/app/development.env.tt +0 -1
  75. data/lib/roro/cli/templates/base/roro/containers/app/docker-entrypoint.sh +0 -8
  76. data/lib/roro/cli/templates/base/roro/containers/app/test.env.tt +0 -1
  77. data/lib/roro/cli/templates/base/roro/containers/database/development.env.tt +0 -4
  78. data/lib/roro/cli/templates/base/roro/containers/database/test.env.tt +0 -4
  79. data/lib/roro/cli/templates/dockerize/.env/development/database +0 -3
  80. data/lib/roro/cli/templates/dockerize/.env/development/web +0 -1
  81. data/lib/roro/cli/templates/dockerize/Dockerfile.tt +0 -23
  82. data/lib/roro/cli/templates/dockerize/docker-entrypoint.sh +0 -9
  83. data/lib/roro/cli/templates/greenfield/Gemfile +0 -2
  84. data/lib/roro/cli/templates/greenfield/config/database.yml.example +0 -16
  85. data/lib/roro/cli/templates/greenfield/docker-compose.yml +0 -17
  86. data/lib/roro/cli/templates/greenfield/docker-entrypoint.sh +0 -8
  87. data/lib/roro/cli/templates/quickstart/Dockerfile.tt +0 -20
  88. data/lib/roro/cli/templates/quickstart/database.yml +0 -85
  89. data/lib/roro/cli/templates/quickstart/docker-compose.yml +0 -17
  90. data/lib/roro/cli/templates/ruby_gem/.gitignore +0 -8
  91. data/lib/roro/cli/templates/ruby_gem/config.yml +0 -122
  92. data/lib/roro/cli/templates/ruby_gem/docker/containers/app/Dockerfile.tt +0 -10
  93. data/vendor/cache/concurrent-ruby-1.1.6.gem +0 -0
@@ -0,0 +1,69 @@
1
+ require 'yaml'
2
+ module Roro
3
+ class Configuration < Thor
4
+
5
+ attr_reader :master, :app, :choices, :thor_actions
6
+
7
+ def initialize(options={})
8
+ @options = options || {}
9
+ @master = YAML.load_file(File.dirname(__FILE__) + '/roro_configurator.yml')
10
+ @master['services']['server_app']['vendors']['rails']['version'] = `ruby -v`.scan(/\d.\d/).first
11
+ @choices = @master['services']['server_app']['vendors']['rails']['choices']
12
+ @app = {}
13
+ @thor_actions = {}
14
+ configure
15
+ end
16
+
17
+ no_commands do
18
+
19
+ def configure
20
+ set_from_defaults
21
+ case
22
+ when @options['interactive'] && File.exist?('.roro_config.yml')
23
+ set_from_roro_config
24
+ set_from_interactive
25
+ when File.exist?('.roro_config.yml')
26
+ set_from_roro_config
27
+ when @options['interactive']
28
+ set_from_interactive
29
+ end
30
+ end
31
+
32
+ def set_from_defaults
33
+ svcs = @master['services']
34
+ rails = svcs['server_app']['vendors']['rails']
35
+ @app = {
36
+ 'main_app_name' => Dir.pwd.split('/').last,
37
+ 'database_host' => rails['env_vars']['DATABASE_HOST'],
38
+ 'ruby_version' => rails['version'],
39
+ 'frontend_service' => svcs['frontend']['name'],
40
+ 'webserver_service' => svcs['webserver']['default'],
41
+ 'database_service' => svcs['database']['name'],
42
+ 'database_vendor' => svcs['database']['vendor'],
43
+ }
44
+ @choices.each { |key, value| @thor_actions[key] = value["default"] }
45
+ end
46
+
47
+ def set_from_roro_config
48
+ yaml = YAML.load_file(Dir.pwd + '/.roro_config.yml')
49
+ yaml.each { |key, value| @app[key] = value }
50
+ if yaml['thor_actions']
51
+ yaml['thor_actions'].each do |key, value|
52
+ @thor_actions[key] = value
53
+ end
54
+ end
55
+ end
56
+
57
+ def set_from_interactive
58
+ @choices.each do |key, v|
59
+ prompt = ["\n\n" + v['question']]
60
+ v['choices'].each { |k,v| prompt << "(#{k}) #{v.to_s}" }
61
+ answer = ask((prompt.join("\n\n") + "\n\n"),
62
+ default: v['default'],
63
+ limited_to: v['choices'].keys)
64
+ @thor_actions[key] = answer
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,13 +1,14 @@
1
1
  module Roro
2
2
  class CLI < Thor
3
+
4
+ no_commands do
3
5
 
4
- desc "expose", "Expose encrypted files"
5
-
6
- def expose(*args)
7
- environments = args.first ? [args.first] : gather_environments
8
- environments.each do |environment|
9
- HandsomeFencer::Crypto.expose(environment, 'docker')
6
+ def expose(*args)
7
+ environments = args.first ? [args.first] : gather_environments
8
+ environments.each do |environment|
9
+ HandsomeFencer::Crypto.expose(environment, 'roro')
10
+ end
10
11
  end
11
12
  end
12
13
  end
13
- end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Roro
2
+ class CLI < Thor
3
+ include Thor::Actions
4
+
5
+ # desc "generate::config::roro", "Generate a config file at .roro_config.yml"
6
+ # map "generate::config::roro" => "generate_roro_config"
7
+
8
+
9
+ # def generate_roro_config
10
+ # create_file ".roro_config.yml", @config.app.to_yaml
11
+ # end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # module Roro
2
+ # class CLI < Thor
3
+ # include Thor::Actions
4
+
5
+ # desc "generate::config::rails", "Generates a config file to use roro with
6
+ # a rails app at .roro.yml"
7
+ # map "generate::config::rails" => "generate_config_rails"
8
+
9
+ # def generate_config_rails
10
+ # master_config = YAML.load_file(ENV['PWD'] + "/lib/roro/cli/roro_configurator.yml")
11
+ # template 'base/.roro_config.yml', '.roro_config.yml'
12
+ # end
13
+
14
+ # no_commands do
15
+ # end
16
+ # end
17
+ # end
@@ -0,0 +1 @@
1
+ require_relative 'config/rails'
@@ -0,0 +1,47 @@
1
+ module Roro
2
+
3
+ class CLI < Thor
4
+
5
+ no_commands do
6
+
7
+ def generate_key_or_keys(*args)
8
+ environments = args.first ? [args.first] : gather_environments
9
+ environments.each do |environment|
10
+
11
+ confirm_files_decrypted?(environment)
12
+ create_file "roro/keys/#{environment}.key", encoded_key
13
+ end
14
+ end
15
+
16
+ def encoded_key
17
+ @cipher = OpenSSL::Cipher.new 'AES-128-CBC'
18
+ @salt = '8 octets'
19
+ @new_key = @cipher.random_key
20
+ Base64.encode64(@new_key)
21
+ end
22
+
23
+ def gather_environments
24
+ environments = []
25
+ ['.env', '.env.enc'].each do |extension|
26
+ HandsomeFencer::Crypto.source_files('roro', extension).each do |env_file|
27
+ environments << env_file.split('/').last.split(extension).last
28
+ end
29
+ end
30
+ environments.uniq
31
+ end
32
+
33
+ def confirm_files_decrypted?(environment)
34
+ orphan_encrypted = []
35
+ HandsomeFencer::Crypto.source_files('.', '.env.enc').each do |file|
36
+ unless File.exist? file.split('.enc').first
37
+ orphan_encrypted << file
38
+ end
39
+ end
40
+ if !orphan_encrypted.empty?
41
+ raise Roro::Error.new("You have an encrypted files (.env.enc) #{orphan_encrypted} that do not have corresponding decrypted files (.env). Please decrypt or remove these encrypted files before generating a new key for #{environment}.")
42
+ end
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,100 +1,31 @@
1
- require 'os'
2
-
3
1
  module Roro
4
2
 
5
3
  class CLI < Thor
6
-
7
- include Thor::Actions
8
-
9
- desc "greenfield", "Greenfield a brand new rails app using Docker's instructions"
10
-
11
- method_option :env_vars, type: :hash, default: {}, desc: "Pass a list of environment variables like so: env:var", banner: "key1:value1 key2:value2"
12
- method_option :interactive, desc: "Set up your environment variables as you go."
13
- method_option :force, desc: "force over-write of existing files"
14
-
15
-
16
- def greenfield
17
- get_configuration_variables
18
- @env_hash[:use_force] = { force: true }
19
- template 'greenfield/Dockerfile.tt', 'Dockerfile', @env_hash
20
- system "DOCKER_BUILDKIT=1 docker build --file Dockerfile --output . ."
21
- rollon_as_dockerized
22
- end
23
-
4
+
24
5
  no_commands do
25
-
26
- def copy_greenfield_files
27
- template 'greenfield/Dockerfile.tt', 'Dockerfile', @env_hash
28
- template 'greenfield/docker-compose.yml', 'docker-compose.yml'
29
- copy_file 'greenfield/Gemfile', 'Gemfile'
30
- copy_file 'greenfield/Gemfile.lock', 'Gemfile.lock'
31
- end
32
-
33
- def as_system(command)
34
- command = OS.linux? ? "sudo #{command}" : command
35
- system command
36
- end
37
-
38
- def chown_if_required()
39
- warning = "It looks like you're running Docker on some flavor of Linux, in which case the files created by your containers are owned by the root user of the container, and not by the user of the host machine. Please change their ownership by supplying your password at the prompt.",
40
- action = "system 'sudo chown -R $USER .'"
41
- msg = []
42
- msg << ""
43
- msg << delineator
44
- msg << warning
45
- msg << ""
46
- msg.join("\n\n")
47
- puts msg
48
- eval(action)
49
- end
50
-
51
- def delineator
52
- ("-" * 80)
53
- end
54
-
55
- def confirm_dependency(options)
56
- msg = []
57
- msg << ""
58
- msg << delineator
59
- msg << "It looks like #{options[:warning]}. The following bash command returns false:"
60
- msg << "\t$ #{options[:system_query]}"
61
- msg << "Please try these instructions:"
62
- msg << ("\t" + options[:suggestion])
63
- msg << delineator
64
- conditional = options[:conditional] ? eval(options[:conditional]) : system(options[:system_query])
65
- if conditional == false
66
- raise(Roro::Error.new(msg.join("\n\n")))
67
- end
6
+
7
+ def greenfield
8
+ confirm_directory_empty
9
+ confirm_dependencies
10
+ remove_roro_artifacts
11
+ configure_for_greenfielding
12
+ copy_greenfield_files
13
+ run_greenfield_commands
68
14
  end
69
-
70
- def confirm_dependencies
71
- dependencies = [
72
- {
73
- system_query: "ls -A",
74
- warning: "this is not an empty directory. Roro will not greenfield a new Rails app unless either a) the current directory is empty or b) you run greenfield with the --force flag",
75
- suggestion: "$ roro greenfield --force",
76
- conditional: "Dir.glob('*').empty?"
77
- }, {
78
-
79
- system_query: "which docker",
80
- warning: "Docker isn't installed",
81
- suggestion: "https://docs.docker.com/install/"
82
- }, {
83
- system_query: "which docker-compose",
84
- warning: "Docker Compose isn't installed",
85
- suggestion: "https://docs.docker.com/compose/install/"
86
-
87
- }, {
88
- system_query: "docker info",
89
- warning: "the Docker daemon isn't running",
90
- suggestion: "https://docs.docker.com/config/daemon/#start-the-daemon-manually"
91
- }
92
- ]
93
-
94
- dependencies.each do |dependency|
95
- confirm_dependency(dependency)
96
- end
15
+
16
+ def configure_for_greenfielding
17
+ @config ||= Roro::Configuration.new(options)
18
+ end
19
+
20
+ def run_greenfield_commands
21
+ system "DOCKER_BUILDKIT=1 docker build --file Dockerfile --output . ."
22
+ rollon
97
23
  end
24
+
25
+ def copy_greenfield_files
26
+ template 'greenfield/Dockerfile.tt', 'Dockerfile', @config.app
27
+ template 'roro/docker-compose.yml.tt', 'docker-compose.yml', @config.app
28
+ end
98
29
  end
99
30
  end
100
31
  end
@@ -3,17 +3,16 @@ require 'handsome_fencer/crypto'
3
3
  module Roro
4
4
 
5
5
  class CLI < Thor
6
-
7
- include Thor::Actions
8
- include HandsomeFencer::Crypto
9
-
10
- desc "obfuscate", "obfuscates any files matching the pattern ./docker/**/*.env"
11
-
12
- def obfuscate(*args)
13
- default_environments = %w[circleci development staging production]
14
- environments = args.first ? [args.first] : default_environments
15
- environments.each do |environment|
16
- HandsomeFencer::Crypto.obfuscate(environment, 'docker')
6
+
7
+ no_commands do
8
+ include Thor::Actions
9
+ include HandsomeFencer::Crypto
10
+
11
+ def obfuscate(*args)
12
+ environments = args.first ? [args.first] : gather_environments
13
+ environments.each do |environment|
14
+ HandsomeFencer::Crypto.obfuscate(environment, 'roro')
15
+ end
17
16
  end
18
17
  end
19
18
  end
@@ -1,28 +1,84 @@
1
- require_relative 'rollon/use_cases'
1
+ require 'roro/cli/rollon/stories'
2
2
 
3
3
  module Roro
4
4
 
5
5
  class CLI < Thor
6
6
 
7
- desc "rollon", "Generates files and makes changes to your rails app necessary
8
- to run it using Docker containers."
9
- method_option :interactive, desc: "Set up your environment variables as you go."
7
+ desc "rollon", "Generates files for and makes changes to your app
8
+ so it can run using Docker containers."
9
+ method_option :interactive, desc: "Set up your environment variables as
10
+ you go."
10
11
 
11
12
  def rollon
12
- # if Dir['./*'].empty?
13
- # raise Roro::Error.new("Oops -- Roro can't roll itself onto a Rails app if it
14
- # doesn't exist. Please either change into a directory with a Rails app or
15
- # generate a new one using '$ roro greenfield'.")
16
- # end
17
- get_configuration_variables
18
- # case ask("Configure using the Quickstart, Curated, or HandsomeFencer way?\n\n(1) Quikstart\n\n(2) Curated\n\n(3) HandsomeFencer\n\n", { default: '2', limited_to: %w(1 2 3) })
19
- # when '1'
20
- # rollon_as_quickstart
21
- # when '2'
22
- # rollon_as_dockerized
23
- # when '3'
24
- # end
25
- rollon_as_dockerized
13
+ confirm_directory_not_empty
14
+ confirm_dependencies
15
+ remove_roro_artifacts
16
+
17
+ configure_for_rollon
18
+
19
+ copy_roro_files
20
+ generate_config
21
+ startup_commands
22
+ end
23
+
24
+ no_commands do
25
+
26
+ def configure_for_rollon
27
+ @config ||= Roro::Configuration.new(options)
28
+ end
29
+
30
+ def yaml_from_template(file)
31
+ File.read(File.dirname(__FILE__) + "/templates/#{file}")
32
+ end
33
+
34
+ def copy_roro_files
35
+ configure_database
36
+ directory 'roro', './', @config.app
37
+ template 'base/Dockerfile.tt', 'roro/containers/app/Dockerfile', @config.app
38
+ take_thor_actions
39
+ end
40
+
41
+ def take_thor_actions
42
+ @config.thor_actions.each {|k, v| eval(k) if v.eql?('y') }
43
+ end
44
+
45
+ def startup_commands
46
+ system 'docker-compose build'
47
+ system 'docker-compose run web bundle'
48
+ system 'docker-compose run web bin/rails webpacker:install'
49
+ system 'docker-compose run web bin/rails yarn:install'
50
+ system 'docker-compose run web bin/rails db:create'
51
+ system 'docker-compose run web bin/rails db:migrate'
52
+ system 'docker-compose up'
53
+ end
54
+
55
+ def confirm_directory_empty
56
+ confirm = confirm_dependency({
57
+ system_query: "ls -A",
58
+ warning: "this is not an empty directory. Roro will not greenfield a new Rails app unless either a) the current directory is empty or b) you run greenfield with the --force flag",
59
+ suggestion: "$ roro greenfield --force",
60
+ conditional: "Dir.glob('*').empty?" })
61
+ confirm || true
62
+ end
63
+
64
+
65
+ def confirm_dependency(options)
66
+ msg = []
67
+ msg << ""
68
+ msg << delineator
69
+ msg << "It looks like #{options[:warning]}. The following bash command returns false:"
70
+ msg << "\t$ #{options[:system_query]}"
71
+ msg << "Please try these instructions:"
72
+ msg << ("\t" + options[:suggestion])
73
+ msg << delineator
74
+ conditional = options[:conditional] ? eval(options[:conditional]) : system(options[:system_query])
75
+ if conditional == false
76
+ raise(Roro::Error.new(msg.join("\n\n")))
77
+ else
78
+ true
79
+ end
80
+ end
81
+
26
82
  end
27
83
  end
28
84
  end
@@ -0,0 +1,2 @@
1
+ require 'roro/cli/rollon/stories/ruby_gem'
2
+ require 'roro/cli/rollon/stories/rails'
@@ -0,0 +1 @@
1
+ require 'roro/cli/rollon/stories/rails/database'
@@ -0,0 +1,33 @@
1
+ require 'roro/cli/rollon/stories/rails/database/with_mysql'
2
+ require 'roro/cli/rollon/stories/rails/database/with_postgresql'
3
+ module Roro
4
+
5
+ class CLI < Thor
6
+
7
+ no_commands do
8
+
9
+ def configure_database
10
+ database = @config.thor_actions['configure_database']
11
+ vendor = @config.master['services']['database']['vendors']
12
+ case database
13
+ when 'p'
14
+ @config.app['database_vendor'] = 'postgresql'
15
+ @config.app['postgresql_env_vars'] = vendor['postgresql']['env_vars']
16
+ configure_for_pg
17
+ when 'm'
18
+ @config.app['database_vendor'] = 'mysql'
19
+ @config.app['mysql_env_vars'] = vendor['mysql']['env_vars']
20
+ configure_for_mysql
21
+ end
22
+
23
+ %w(development production test staging ci).each do |environment|
24
+ template(
25
+ 'base/.env/web.env.tt',
26
+ "roro/containers/app/#{environment}.env", @config.app
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+