potassium 5.2.1 → 6.2.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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +84 -0
  3. data/.gitignore +2 -1
  4. data/.node-version +1 -0
  5. data/.rubocop.yml +530 -0
  6. data/.ruby-version +1 -1
  7. data/CHANGELOG.md +91 -0
  8. data/README.md +41 -47
  9. data/docs/DSL.md +5 -5
  10. data/lib/potassium/assets/.buildpacks +0 -1
  11. data/lib/potassium/assets/.circleci/config.yml.erb +102 -0
  12. data/lib/potassium/assets/.eslintrc.json +352 -0
  13. data/lib/potassium/assets/.github/pull_request_template.md +9 -0
  14. data/lib/potassium/assets/.pryrc +1 -1
  15. data/lib/potassium/assets/.rubocop.yml +528 -0
  16. data/lib/potassium/assets/.stylelintrc.json +46 -0
  17. data/lib/potassium/assets/Dockerfile.ci +1 -1
  18. data/lib/potassium/assets/Makefile.erb +21 -32
  19. data/lib/potassium/assets/Procfile +1 -0
  20. data/lib/potassium/assets/README.yml +58 -11
  21. data/lib/potassium/assets/active_admin/admin-component.vue +35 -0
  22. data/lib/potassium/assets/active_admin/admin_application.js +14 -0
  23. data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +10 -0
  24. data/lib/potassium/assets/app/graphql/graphql_controller.rb +55 -0
  25. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +23 -0
  26. data/lib/potassium/assets/app/graphql/queries/base_query.rb +4 -0
  27. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +4 -0
  28. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +4 -0
  29. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +5 -0
  30. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +5 -0
  31. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +7 -0
  32. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +5 -0
  33. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +4 -0
  34. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +4 -0
  35. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +10 -0
  36. data/lib/potassium/assets/app/graphql/types/query_type.rb +13 -0
  37. data/lib/potassium/assets/app/javascript/app.spec.js +14 -0
  38. data/lib/potassium/assets/app/uploaders/base_uploader.rb +11 -0
  39. data/lib/potassium/assets/app/uploaders/image_uploader.rb +5 -0
  40. data/lib/potassium/assets/app/views/shared/_gtm_body.html.erb +4 -0
  41. data/lib/potassium/assets/app/views/shared/_gtm_head.html.erb +7 -0
  42. data/lib/potassium/assets/bin/cibuild.erb +24 -7
  43. data/lib/potassium/assets/bin/release +9 -0
  44. data/lib/potassium/assets/bin/setup.erb +1 -1
  45. data/lib/potassium/assets/config/database_mysql.yml.erb +2 -2
  46. data/lib/potassium/assets/config/database_postgresql.yml.erb +2 -2
  47. data/lib/potassium/assets/config/graphql_playground.rb +20 -0
  48. data/lib/potassium/assets/config/puma.rb +1 -1
  49. data/lib/potassium/assets/config/shrine.rb +36 -0
  50. data/lib/potassium/assets/docker-compose.ci.yml +2 -1
  51. data/lib/potassium/assets/lib/tasks/auto_annotate_models.rake +34 -33
  52. data/lib/potassium/assets/package.json +4 -1
  53. data/lib/potassium/assets/redis.yml +1 -2
  54. data/lib/potassium/assets/testing/rails_helper.rb +4 -2
  55. data/lib/potassium/cli/commands/create.rb +12 -19
  56. data/lib/potassium/cli_options.rb +77 -26
  57. data/lib/potassium/helpers/gem-helpers.rb +1 -1
  58. data/lib/potassium/helpers/template-helpers.rb +4 -0
  59. data/lib/potassium/newest_version_ensurer.rb +19 -36
  60. data/lib/potassium/node_version_ensurer.rb +30 -0
  61. data/lib/potassium/recipes/admin.rb +3 -3
  62. data/lib/potassium/recipes/annotate.rb +1 -1
  63. data/lib/potassium/recipes/api.rb +93 -21
  64. data/lib/potassium/recipes/background_processor.rb +66 -19
  65. data/lib/potassium/recipes/ci.rb +6 -4
  66. data/lib/potassium/recipes/data_migrate.rb +44 -0
  67. data/lib/potassium/recipes/database.rb +4 -0
  68. data/lib/potassium/recipes/database_container.rb +7 -5
  69. data/lib/potassium/recipes/draper.rb +1 -10
  70. data/lib/potassium/recipes/file_storage.rb +66 -0
  71. data/lib/potassium/recipes/front_end.rb +219 -9
  72. data/lib/potassium/recipes/github.rb +93 -15
  73. data/lib/potassium/recipes/google_tag_manager.rb +90 -0
  74. data/lib/potassium/recipes/heroku.rb +44 -30
  75. data/lib/potassium/recipes/mailer.rb +27 -4
  76. data/lib/potassium/recipes/node.rb +21 -0
  77. data/lib/potassium/recipes/rack_cors.rb +18 -15
  78. data/lib/potassium/recipes/schedule.rb +17 -2
  79. data/lib/potassium/recipes/style.rb +21 -3
  80. data/lib/potassium/recipes/vue_admin.rb +124 -0
  81. data/lib/potassium/templates/application.rb +9 -7
  82. data/lib/potassium/version.rb +6 -4
  83. data/potassium.gemspec +11 -6
  84. data/spec/features/api_spec.rb +25 -0
  85. data/spec/features/background_processor_spec.rb +19 -6
  86. data/spec/features/data_migrate_spec.rb +14 -0
  87. data/spec/features/database_container_spec.rb +2 -5
  88. data/spec/features/draper_spec.rb +1 -6
  89. data/spec/features/file_storage_spec.rb +75 -0
  90. data/spec/features/front_end_spec.rb +88 -0
  91. data/spec/features/github_spec.rb +53 -8
  92. data/spec/features/google_tag_manager_spec.rb +59 -0
  93. data/spec/features/graphql_spec.rb +71 -0
  94. data/spec/features/heroku_spec.rb +8 -5
  95. data/spec/features/mailer_spec.rb +58 -0
  96. data/spec/features/new_project_spec.rb +6 -14
  97. data/spec/features/node_spec.rb +28 -0
  98. data/spec/features/power_types_spec.rb +5 -16
  99. data/spec/features/schedule_spec.rb +11 -4
  100. data/spec/features/vue_admin_spec.rb +47 -0
  101. data/spec/spec_helper.rb +5 -0
  102. data/spec/support/fake_octokit.rb +31 -0
  103. data/spec/support/potassium_test_helpers.rb +26 -9
  104. data/tmp/.keep +0 -0
  105. metadata +157 -48
  106. data/circle.yml +0 -12
  107. data/lib/potassium/assets/.circleci/config.yml +0 -20
  108. data/lib/potassium/assets/active_admin/active_admin.js.coffee +0 -4
  109. data/lib/potassium/assets/active_admin/init_activeadmin_angular.rb +0 -8
  110. data/lib/potassium/assets/api/api_error_concern.rb +0 -32
  111. data/lib/potassium/assets/api/base_controller.rb +0 -9
  112. data/lib/potassium/assets/api/draper_responder.rb +0 -62
  113. data/lib/potassium/assets/api/responder.rb +0 -41
  114. data/lib/potassium/assets/aws.rb +0 -1
  115. data/lib/potassium/assets/sidekiq_scheduler.yml +0 -9
  116. data/lib/potassium/assets/testing/paperclip.rb +0 -59
  117. data/lib/potassium/recipes/active_storage.rb +0 -40
  118. data/lib/potassium/recipes/angular_admin.rb +0 -56
  119. data/lib/potassium/recipes/aws_sdk.rb +0 -7
  120. data/lib/potassium/recipes/paperclip.rb +0 -47
  121. data/spec/features/active_storage_spec.rb +0 -30
  122. data/spec/features/front_end.rb +0 -30
@@ -1,5 +1,21 @@
1
1
  module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
2
2
  CREATE_OPTIONS = [
3
+ {
4
+ type: :switch,
5
+ name: 'version-check',
6
+ desc: 'Performs a version check before running.',
7
+ negatable: true,
8
+ default_value: true,
9
+ default_test_value: true
10
+ },
11
+ {
12
+ type: :switch,
13
+ name: 'node-version-check',
14
+ desc: 'Performs a node version check before running.',
15
+ negatable: true,
16
+ default_value: true,
17
+ default_test_value: true
18
+ },
3
19
  {
4
20
  type: :flag,
5
21
  name: [:db, :database],
@@ -16,7 +32,7 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
16
32
  type: :flag,
17
33
  name: [:email_service, :email],
18
34
  desc: "Decides which email adapter to use. Available: aws_ses, sendgrid, none",
19
- default_test_value: "aws_ses"
35
+ default_test_value: "None"
20
36
  },
21
37
  {
22
38
  type: :switch,
@@ -44,8 +60,8 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
44
60
  },
45
61
  {
46
62
  type: :switch,
47
- name: "angular-admin",
48
- desc: "Whether to use Angular within ActiveAdmin or not",
63
+ name: :vue_admin,
64
+ desc: "Whether to use Vue within ActiveAdmin or not",
49
65
  negatable: true,
50
66
  default_value: "none",
51
67
  default_test_value: false
@@ -59,28 +75,18 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
59
75
  default_test_value: false
60
76
  },
61
77
  {
62
- type: :switch,
78
+ type: :flag,
63
79
  name: "api",
64
- desc: "Whether to apply the API mode or not",
65
- negatable: true,
80
+ desc: "Which API interface to use",
66
81
  default_value: "none",
67
- default_test_value: false
68
- },
69
- {
70
- type: :switch,
71
- name: "paperclip",
72
- desc: "Whether to include Paperclip as dependency",
73
- negatable: true,
74
- default_value: "none",
75
- default_test_value: false
82
+ default_test_value: "None"
76
83
  },
77
84
  {
78
- type: :switch,
79
- name: "active_storage",
80
- desc: "Whether to include Active Storage as dependency",
81
- negatable: true,
85
+ type: :flag,
86
+ name: "storage",
87
+ desc: "Decides which file storage to use. Available: active_storage, shrine, none",
82
88
  default_value: "none",
83
- default_test_value: false
89
+ default_test_value: "None"
84
90
  },
85
91
  {
86
92
  type: :switch,
@@ -91,10 +97,10 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
91
97
  default_test_value: false
92
98
  },
93
99
  {
94
- type: :flag,
100
+ type: :switch,
95
101
  name: "background_processor",
96
- desc: "Decides which background processor to use. Available: sidekiq, delayed_job, none",
97
- default_test_value: "sidekiq"
102
+ desc: "Whether to use Sidekiq for background processing or not",
103
+ default_test_value: false
98
104
  },
99
105
  {
100
106
  type: :switch,
@@ -114,12 +120,41 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
114
120
  },
115
121
  {
116
122
  type: :switch,
117
- name: "github-private",
118
- desc: "Whether to the github repository is private",
123
+ name: "github_private",
124
+ desc: "Whether the github repository is private or not",
119
125
  negatable: true,
120
- default_value: false,
126
+ default_value: "none",
121
127
  default_test_value: false
122
128
  },
129
+ {
130
+ type: :switch,
131
+ name: "github_has_org",
132
+ desc: "Whether the github repository should belong to an organization",
133
+ negatable: true,
134
+ default_value: "none",
135
+ default_test_value: false
136
+ },
137
+ {
138
+ type: :flag,
139
+ name: "github_org",
140
+ desc: "The github organization where the repository will be created",
141
+ default_value: "none",
142
+ default_test_value: "none"
143
+ },
144
+ {
145
+ type: :flag,
146
+ name: "github_name",
147
+ desc: "The github repository name",
148
+ default_value: "none",
149
+ default_test_value: "none"
150
+ },
151
+ {
152
+ type: :flag,
153
+ name: "github_access_token",
154
+ desc: "Github personal access token used to auth to Github API",
155
+ default_value: "none",
156
+ default_test_value: "none"
157
+ },
123
158
  {
124
159
  type: :switch,
125
160
  name: "schedule",
@@ -141,6 +176,22 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
141
176
  name: :front_end,
142
177
  desc: "Decides which front-end framework to use. Available: Vue, Angular 2, None",
143
178
  default_test_value: "None"
179
+ },
180
+ {
181
+ type: :switch,
182
+ name: 'google_tag_manager',
183
+ desc: 'Whether to use google tag manager',
184
+ negatable: true,
185
+ default_value: 'none',
186
+ default_test_value: false
187
+ },
188
+ {
189
+ type: :switch,
190
+ name: "test",
191
+ desc: "Whether or not it is a test project creation",
192
+ negatable: true,
193
+ default_value: false,
194
+ default_test_value: true
144
195
  }
145
196
  ]
146
197
 
@@ -69,7 +69,7 @@ module GemHelpers
69
69
  def add_original_rails_gems
70
70
  gemfile_entries.each do |entry|
71
71
  unless entry.commented_out
72
- gather_gem(entry.name, entry.version)
72
+ gather_gem(entry.name, version: entry[:version])
73
73
  end
74
74
  end
75
75
  end
@@ -3,6 +3,10 @@ module TemplateHelpers
3
3
  @app_name || app_name_from_file
4
4
  end
5
5
 
6
+ def node_version
7
+ "#{Potassium::NODE_VERSION}.x"
8
+ end
9
+
6
10
  def load_recipe(recipe_name)
7
11
  @recipes ||= {}
8
12
  @recipes[recipe_name] ||= get_recipe_class(recipe_name.to_sym).new(self)
@@ -1,51 +1,34 @@
1
- require "term/ansicolor"
2
- require "gems"
3
- require "semantic"
4
- require "potassium/text_spinner"
1
+ require 'gems'
2
+ require 'semantic'
3
+ require 'potassium/text_spinner'
4
+
5
+ class VersionError < StandardError
6
+ end
5
7
 
6
8
  module Potassium
7
9
  class NewestVersionEnsurer
8
- include Term::ANSIColor
9
-
10
- def initialize(current_version = Potassium::VERSION)
11
- self.current_version = Semantic::Version.new(current_version)
10
+ def initialize
11
+ self.installed_version = Semantic::Version.new(Potassium::VERSION)
12
12
  self.text_spinner = Potassium::TextSpinner.new
13
13
  end
14
14
 
15
- def ensure(&success_block)
16
- spin_text("Checking your Potassium installation") { latest_version }
15
+ def ensure!
16
+ spin_text('Checking your Potassium installation') { published_version }
17
17
 
18
- self.latest_version = Semantic::Version.new(
19
- Gems.versions("potassium").first["number"]
20
- )
21
-
22
- if latest_version <= current_version
23
- up_to_date
24
- success_block.call
25
- else
26
- please_update
27
- end
18
+ self.published_version = Semantic::Version.new(Gems.versions('potassium').first['number'])
19
+ raise VersionError.new(update_message) if published_version > installed_version
28
20
  end
29
21
 
30
22
  private
31
23
 
32
- attr_accessor :latest_version, :current_version, :text_spinner
33
-
34
- def up_to_date
35
- puts green("\nYour Potassium installation is up to date.")
36
- end
24
+ attr_accessor :published_version, :installed_version, :text_spinner
37
25
 
38
- def please_update
39
- puts red("\nYour Potassium installation is not up to date.")
40
- puts red("Found: #{current_version}")
41
- puts red("Expected: #{latest_version}\n")
42
- print white("Please run: ")
43
- print green("gem update potassium ")
44
- print white("to upgrade your potassium installation.\n\n")
45
- print white("If you really need to run this outdated version of potassium anyway, ")
46
- print white("re-run this command with the ")
47
- print black("--no-version-check")
48
- puts white(" flag.")
26
+ def update_message
27
+ <<~HERE
28
+ Your potassium installation is not up to date.
29
+ The last available version is #{published_version} while the running version is #{installed_version}.
30
+ If you really need to run this outdated version of potassium, re-run this command with the `--no-version-check` flag.
31
+ HERE
49
32
  end
50
33
 
51
34
  def spin_text(message, &block)
@@ -0,0 +1,30 @@
1
+ module Potassium
2
+ class NodeVersionEnsurer
3
+ def ensure!
4
+ raise VersionError.new(install_message) if installed_node_version.nil?
5
+ raise VersionError.new(update_message) if Potassium::NODE_VERSION != installed_node_version
6
+ end
7
+
8
+ private
9
+
10
+ def installed_node_version
11
+ node_version = `node -v 2>&1`
12
+ return node_version.delete('^[0-9\.]').split('.').first if $?.success?
13
+ end
14
+
15
+ def install_message
16
+ <<~HERE
17
+ Node doesn't appear to be installed.
18
+ Please make sure you have node #{Potassium::NODE_VERSION} installed.
19
+ HERE
20
+ end
21
+
22
+ def update_message
23
+ <<~HERE
24
+ An unsupported version of node was found.
25
+ Please make sure you have node #{Potassium::NODE_VERSION} installed. Newer versions may work but potassium only supports that one.
26
+ If you really need to run potassium with a different version of node, re-run this command with the `--no-node-version-check` flag.
27
+ HERE
28
+ end
29
+ end
30
+ end
@@ -32,10 +32,10 @@ class Recipes::Admin < Rails::AppBuilder
32
32
  private
33
33
 
34
34
  def add_active_admin
35
- gather_gem 'activeadmin', '~> 1.3.0'
35
+ gather_gem 'activeadmin', '~> 2.6'
36
36
  gather_gem 'activeadmin_addons'
37
- gather_gem 'active_skin'
38
-
37
+ gather_gem 'active_skin', github: 'SoftwareBrothers/active_skin'
38
+ add_readme_section :internal_dependencies, :active_admin
39
39
  after(:gem_install, wrap_in_action: :admin_install) do
40
40
  generate "active_admin:install"
41
41
  line = "ActiveAdmin.setup do |config|"
@@ -1,7 +1,7 @@
1
1
  class Recipes::Annotate < Rails::AppBuilder
2
2
  def create
3
3
  gather_gems(:development) do
4
- gather_gem('annotate')
4
+ gather_gem('annotate', '~> 3.0')
5
5
  end
6
6
 
7
7
  template '../assets/lib/tasks/auto_annotate_models.rake',
@@ -1,43 +1,115 @@
1
1
  class Recipes::Api < Rails::AppBuilder
2
2
  def ask
3
- api_support = answer(:api) { Ask.confirm("Do you want to enable API support?") }
4
- set(:api_support, api_support)
3
+ api_interfaces = {
4
+ rest: "REST (with Power API)",
5
+ graphql: "GraphQL (beta)",
6
+ none: "None, thanks"
7
+ }
8
+ api_interface = answer(:api) do
9
+ api_interfaces.keys[Ask.list("Which API interface are you using?", api_interfaces.values)]
10
+ end
11
+ set :api, api_interface.to_sym
5
12
  end
6
13
 
7
14
  def create
8
- add_api if get(:api_support)
15
+ if get(:api) == :graphql
16
+ add_graphql
17
+ elsif get(:api) == :rest
18
+ add_power_api
19
+ end
9
20
  end
10
21
 
11
22
  def install
12
- add_api
23
+ ask
24
+ create
13
25
  end
14
26
 
15
27
  def installed?
16
- gem_exists?(/versionist/)
28
+ gem_exists?(/power_api/) || gem_exists?(/graphql/)
17
29
  end
18
30
 
19
31
  private
20
32
 
21
- def add_api
22
- gather_gem 'versionist'
23
- gather_gem 'responders'
24
- gather_gem 'active_model_serializers', '~> 0.9.3'
25
- gather_gem 'simple_token_authentication', '~> 1.0'
33
+ def add_power_api
34
+ gather_gem 'power_api'
35
+
36
+ gather_gems(:development, :test) do
37
+ gather_gem 'rswag-specs'
38
+ end
39
+
40
+ add_readme_section :internal_dependencies, :power_api
41
+
42
+ after(:gem_install) do
43
+ generate "power_api:install"
44
+ end
45
+ end
46
+
47
+ def add_graphql
48
+ gather_gem 'graphql'
49
+ if get(:authentication)
50
+ gather_gem 'jwt'
51
+ end
52
+ gather_gems(:development, :test) do
53
+ gather_gem 'graphql_playground-rails'
54
+ end
26
55
 
27
56
  after(:gem_install) do
28
- line = "Rails.application.routes.draw do\n"
29
- insert_into_file "config/routes.rb", after: line do
30
- <<-HERE.gsub(/^ {8}/, '')
31
- scope path: '/api' do
32
- api_version(module: "Api::V1", path: { value: "v1" }, defaults: { format: 'json' }) do
33
- end
34
- end
35
- HERE
57
+ generate "graphql:install --skip_graphiql"
58
+ playground_route = <<~HEREDOC
59
+ \n
60
+ if Rails.env.development?
61
+ mount GraphqlPlayground::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"
62
+ end
63
+ HEREDOC
64
+ inject_into_file(
65
+ 'config/routes.rb',
66
+ playground_route,
67
+ after: 'post "/graphql", to: "graphql#execute"'
68
+ )
69
+ copy_file(
70
+ "../assets/config/graphql_playground.rb",
71
+ "config/initializers/graphql_playground.rb"
72
+ )
73
+ remove_dir 'app/graphql/types'
74
+ directory '../assets/app/graphql/types', 'app/graphql/types'
75
+ gsub_file 'app/graphql/mutations/base_mutation.rb', 'Types::Base', 'Types::Base::Base'
76
+ directory '../assets/app/graphql/queries', 'app/graphql/queries'
77
+ gsub_file 'app/graphql/mutations/base_mutation.rb', 'RelayClassic', ''
78
+ gsub_file(
79
+ 'app/graphql/mutations/base_mutation.rb',
80
+ " input_object_class Types::Base::BaseInputObject\n", ''
81
+ )
82
+
83
+ if get(:authentication)
84
+ copy_file(
85
+ '../assets/app/graphql/graphql_controller.rb',
86
+ 'app/controllers/graphql_controller.rb',
87
+ force: true
88
+ )
89
+ gsub_file(
90
+ 'app/controllers/graphql_controller.rb',
91
+ 'GqlSampleSchema',
92
+ "#{get(:titleized_app_name).delete(' ')}Schema"
93
+ )
94
+ copy_file(
95
+ '../assets/app/graphql/mutations/login_mutation.rb',
96
+ 'app/graphql/mutations/login_mutation.rb'
97
+ )
98
+ inject_into_file(
99
+ 'app/graphql/types/mutation_type.rb',
100
+ "\n field :login, mutation: Mutations::LoginMutation",
101
+ after: 'class MutationType < Types::Base::BaseObject'
102
+ )
103
+ append_to_file(".env.development", "HMAC_SECRET=\n")
36
104
  end
37
105
 
38
- copy_file '../assets/api/base_controller.rb', 'app/controllers/api/v1/base_controller.rb'
39
- copy_file '../assets/api/api_error_concern.rb', 'app/controllers/concerns/api_error_concern.rb'
40
- copy_file '../assets/api/responder.rb', 'app/responders/api_responder.rb'
106
+ inject_into_file(
107
+ 'app/controllers/graphql_controller.rb',
108
+ "\n\n skip_before_action :verify_authenticity_token",
109
+ after: '# protect_from_forgery with: :null_session'
110
+ )
111
+
112
+ add_readme_section :internal_dependencies, :graphql
41
113
  end
42
114
  end
43
115
  end
@@ -1,18 +1,22 @@
1
1
  class Recipes::BackgroundProcessor < Rails::AppBuilder
2
2
  def ask
3
- response = if selected?(:email_service, :none)
3
+ response = if enabled_mailer?
4
+ info "Note: Emails should be sent on background jobs. We'll install sidekiq"
5
+ true
6
+ else
4
7
  answer(:background_processor) do
5
8
  Ask.confirm("Do you want to use Sidekiq for background job processing?")
6
9
  end
7
- else
8
- info "Note: Emails should be sent on background jobs. We'll install sidekiq"
9
- true
10
10
  end
11
11
  set(:background_processor, response)
12
12
  end
13
13
 
14
14
  def create
15
- add_sidekiq if get(:background_processor)
15
+ if get(:background_processor)
16
+ add_sidekiq
17
+ add_docker_compose_redis_config
18
+ set_redis_dot_env
19
+ end
16
20
  end
17
21
 
18
22
  def install
@@ -27,24 +31,25 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
27
31
  end
28
32
 
29
33
  def add_sidekiq
30
- gather_gem("sidekiq")
31
- add_adapters("sidekiq")
32
- add_readme_section :internal_dependencies, :sidekiq
33
- edit_procfile("bundle exec sidekiq")
34
- append_to_file(".env.development", "DB_POOL=25\n")
35
- template("../assets/sidekiq.rb.erb", "config/initializers/sidekiq.rb", force: true)
36
- copy_file("../assets/sidekiq.yml", "config/sidekiq.yml", force: true)
37
- copy_file("../assets/redis.yml", "config/redis.yml", force: true)
38
-
39
- insert_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n" do
40
- <<-HERE.gsub(/^ {6}/, '')
41
- mount Sidekiq::Web => '/queue'
42
- HERE
34
+ recipe = self
35
+ run_action(:install_sidekiq) do
36
+ gather_gem("sidekiq")
37
+ recipe.add_adapters("sidekiq")
38
+ add_readme_section :internal_dependencies, :sidekiq
39
+ recipe.edit_procfile("bundle exec sidekiq")
40
+ append_to_file(".env.development", "DB_POOL=25\n")
41
+ template("../assets/sidekiq.rb.erb", "config/initializers/sidekiq.rb", force: true)
42
+ copy_file("../assets/sidekiq.yml", "config/sidekiq.yml", force: true)
43
+ copy_file("../assets/redis.yml", "config/redis.yml", force: true)
44
+ recipe.mount_sidekiq_routes
43
45
  end
44
46
  end
45
47
 
46
48
  def edit_procfile(cmd)
47
- gsub_file("Procfile", /^.*$/m) { |match| "#{match}worker: #{cmd}" } if selected?(:heroku)
49
+ heroku = load_recipe(:heroku)
50
+ if selected?(:heroku) || heroku.installed?
51
+ gsub_file('Procfile', /^.*$/m) { |match| "#{match}worker: #{cmd}" }
52
+ end
48
53
  end
49
54
 
50
55
  def add_adapters(name)
@@ -52,4 +57,46 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
52
57
  application "config.active_job.queue_adapter = :async", env: "development"
53
58
  application "config.active_job.queue_adapter = :test", env: "test"
54
59
  end
60
+
61
+ def mount_sidekiq_routes
62
+ insert_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n" do
63
+ <<-HERE.gsub(/^ {6}/, '')
64
+ mount Sidekiq::Web => '/queue'
65
+ HERE
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def add_docker_compose_redis_config
72
+ compose = DockerHelpers.new('docker-compose.yml')
73
+
74
+ service_definition =
75
+ <<~YAML
76
+ image: redis
77
+ ports:
78
+ - 6379
79
+ volumes:
80
+ - redis_data:/data
81
+ YAML
82
+
83
+ compose.add_service('redis', service_definition)
84
+ compose.add_volume('redis_data')
85
+ end
86
+
87
+ def set_redis_dot_env
88
+ append_to_file(
89
+ '.env.development',
90
+ <<~TEXT
91
+ REDIS_HOST=127.0.0.1
92
+ REDIS_PORT=$(make services-port SERVICE=redis PORT=6379)
93
+ REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT}/1
94
+ TEXT
95
+ )
96
+ end
97
+
98
+ def enabled_mailer?
99
+ mailer_answer = get(:email_service)
100
+ mailer_answer && ![:none, :None].include?(mailer_answer.to_sym)
101
+ end
55
102
  end