potassium 6.3.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.node-version +1 -1
  4. data/CHANGELOG.md +45 -0
  5. data/README.md +30 -3
  6. data/docs/CONTRIBUTING.md +2 -2
  7. data/lib/potassium/assets/.circleci/config.yml.erb +40 -12
  8. data/lib/potassium/assets/.eslintrc.json +15 -9
  9. data/lib/potassium/assets/.pryrc +0 -6
  10. data/lib/potassium/assets/.rubocop.yml +1 -0
  11. data/lib/potassium/assets/Aptfile +5 -0
  12. data/lib/potassium/assets/README.yml +74 -7
  13. data/lib/potassium/assets/active_admin/admin-component.vue +22 -30
  14. data/lib/potassium/assets/active_admin/policies/admin_user_policy.rb +2 -0
  15. data/lib/potassium/assets/active_admin/policies/comment_policy.rb +2 -0
  16. data/lib/potassium/assets/active_admin/policies/default_policy.rb +49 -0
  17. data/lib/potassium/assets/active_admin/policies/page_policy.rb +2 -0
  18. data/lib/potassium/assets/app/javascript/{app.spec.js → components/app.spec.ts} +2 -2
  19. data/lib/potassium/assets/app/javascript/components/app.vue +9 -0
  20. data/lib/potassium/assets/app/javascript/types/vue.d.ts +5 -0
  21. data/lib/potassium/assets/app/jobs/shrine_promote_job.rb +14 -0
  22. data/lib/potassium/assets/app/mailers/application_mailer.rb +1 -1
  23. data/lib/potassium/assets/app/mailers/example_mailer.rb +6 -0
  24. data/lib/potassium/assets/app/serializers/base_serializer.rb +3 -0
  25. data/lib/potassium/assets/app/serializers/concerns/image_handling_attributes.rb +20 -0
  26. data/lib/potassium/assets/app/uploaders/cover_image_uploader.rb +52 -0
  27. data/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml +7 -0
  28. data/lib/potassium/assets/app/views/layouts/default_mail.html.mjml +49 -0
  29. data/lib/potassium/assets/config/initializers/shrine/plugins/image_handling_utilities.rb +143 -0
  30. data/lib/potassium/assets/config/mailer.rb.erb +0 -2
  31. data/lib/potassium/assets/config/shrine.rb +15 -0
  32. data/lib/potassium/assets/config/webpack/rules/css.js +5 -0
  33. data/lib/potassium/assets/config/webpack/rules/index.js +11 -0
  34. data/lib/potassium/assets/config/webpack/rules/jquery.js +11 -0
  35. data/lib/potassium/assets/config/webpack/rules/typescript.js +32 -0
  36. data/lib/potassium/assets/config/webpack/rules/vue.js +19 -0
  37. data/lib/potassium/assets/config/webpack/webpack.config.js +4 -0
  38. data/lib/potassium/assets/public/mails/platanus-logo.png +0 -0
  39. data/lib/potassium/assets/testing/.rspec +1 -0
  40. data/lib/potassium/assets/testing/devise_config.rb +6 -0
  41. data/lib/potassium/assets/testing/factory_bot_config.rb +3 -0
  42. data/lib/potassium/assets/testing/faker_config.rb +1 -0
  43. data/lib/potassium/assets/testing/power_types_config.rb +1 -0
  44. data/lib/potassium/assets/testing/rails_helper.rb +130 -49
  45. data/lib/potassium/assets/testing/shoulda_matchers_config.rb +8 -0
  46. data/lib/potassium/assets/testing/simplecov_config.rb +64 -0
  47. data/lib/potassium/assets/testing/system_tests_config.rb +6 -0
  48. data/lib/potassium/assets/tsconfig.json +31 -0
  49. data/lib/potassium/cli/commands/create.rb +3 -1
  50. data/lib/potassium/cli_options.rb +23 -3
  51. data/lib/potassium/platanus_config.rb +20 -0
  52. data/lib/potassium/recipes/admin.rb +37 -16
  53. data/lib/potassium/recipes/api.rb +8 -85
  54. data/lib/potassium/recipes/coverage.rb +66 -0
  55. data/lib/potassium/recipes/file_storage.rb +50 -0
  56. data/lib/potassium/recipes/front_end.rb +87 -108
  57. data/lib/potassium/recipes/google_tag_manager.rb +20 -16
  58. data/lib/potassium/recipes/heroku.rb +1 -2
  59. data/lib/potassium/recipes/mailer.rb +22 -10
  60. data/lib/potassium/recipes/mjml.rb +31 -0
  61. data/lib/potassium/recipes/node.rb +11 -13
  62. data/lib/potassium/recipes/pundit.rb +29 -10
  63. data/lib/potassium/recipes/rails.rb +0 -4
  64. data/lib/potassium/recipes/spring.rb +9 -0
  65. data/lib/potassium/recipes/style.rb +9 -2
  66. data/lib/potassium/recipes/testing.rb +75 -18
  67. data/lib/potassium/recipes/vue_admin.rb +38 -8
  68. data/lib/potassium/templates/application.rb +5 -2
  69. data/lib/potassium/version.rb +10 -4
  70. data/spec/features/api_spec.rb +6 -1
  71. data/spec/features/ci_spec.rb +1 -1
  72. data/spec/features/coverage_spec.rb +43 -0
  73. data/spec/features/file_storage_spec.rb +102 -26
  74. data/spec/features/front_end_spec.rb +16 -47
  75. data/spec/features/google_tag_manager_spec.rb +1 -24
  76. data/spec/features/heroku_spec.rb +0 -4
  77. data/spec/features/mailer_spec.rb +79 -33
  78. data/spec/features/mjml_spec.rb +53 -0
  79. data/spec/features/node_spec.rb +1 -1
  80. data/spec/features/pundit_spec.rb +34 -0
  81. data/spec/features/testing_spec.rb +56 -0
  82. data/spec/features/vue_admin_spec.rb +0 -10
  83. data/spec/support/potassium_test_helpers.rb +2 -2
  84. data/spec/support/shared_examples.rb +5 -0
  85. metadata +50 -27
  86. data/lib/potassium/assets/active_admin/admin_application.js +0 -14
  87. data/lib/potassium/assets/active_admin/admin_user_policy.rb +0 -2
  88. data/lib/potassium/assets/active_admin/comment_policy.rb +0 -2
  89. data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +0 -10
  90. data/lib/potassium/assets/active_admin/pundit_page_policy.rb +0 -5
  91. data/lib/potassium/assets/app/graphql/graphql_controller.rb +0 -55
  92. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +0 -23
  93. data/lib/potassium/assets/app/graphql/queries/base_query.rb +0 -4
  94. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +0 -4
  95. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +0 -4
  96. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +0 -5
  97. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +0 -5
  98. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +0 -7
  99. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +0 -5
  100. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +0 -4
  101. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +0 -4
  102. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +0 -10
  103. data/lib/potassium/assets/app/graphql/types/query_type.rb +0 -13
  104. data/lib/potassium/assets/config/graphql_playground.rb +0 -20
  105. data/spec/features/graphql_spec.rb +0 -71
@@ -0,0 +1,64 @@
1
+ require 'simplecov'
2
+ require 'simplecov_text_formatter'
3
+ require 'simplecov_linter_formatter'
4
+
5
+ SimpleCovLinterFormatter.setup do |config|
6
+ config.scope = ENV.fetch(
7
+ "SIMPLE_COV_LINTER_SCOPE", :own_changes
8
+ )
9
+ config.json_filename = ENV.fetch(
10
+ "SIMPLE_COV_LINTER_JSON_FILENAME", ".resultset.json"
11
+ )
12
+ config.summary_enabled = ENV.fetch(
13
+ "SIMPLE_COV_LINTER_SUMMARY_ENABLED", true
14
+ )
15
+ config.summary_enabled_bg = ENV.fetch(
16
+ "SIMPLE_COV_LINTER_SUMMARY_BG_ENABLED", true
17
+ )
18
+ config.summary_covered_bg_color = ENV.fetch(
19
+ "SIMPLE_COV_LINTER_SUMMARY_COVERED_BG_COLOR", :darkgreen
20
+ )
21
+ config.summary_not_covered_bg_color = ENV.fetch(
22
+ "SIMPLE_COV_LINTER_SUMMARY_NOT_COVERED_BG_COLOR", :firebrick
23
+ )
24
+ config.summary_text_color = ENV.fetch(
25
+ "SIMPLE_COV_LINTER_SUMMARY_TEXT_COLOR", :white
26
+ )
27
+ config.summary_files_sorting = ENV.fetch(
28
+ "SIMPLE_COV_LINTER_SUMMARY_FILES_SORTING", :coverage
29
+ )
30
+ end
31
+
32
+ SimpleCov.start 'rails' do
33
+ add_group 'Commands', 'app/commands'
34
+ add_group 'Services', 'app/services'
35
+ add_group 'Observers', 'app/observers'
36
+ add_group 'Policies', 'app/policies'
37
+ add_group 'Utils', 'app/utils'
38
+ add_group 'Extensions', 'app/extensions'
39
+
40
+ add_filter %r{app/controllers/([a-z]|_)*_controller.rb}
41
+ add_filter 'app/admin'
42
+ add_filter 'app/channels'
43
+ add_filter 'app/uploaders'
44
+ add_filter 'app/serializers'
45
+ add_filter 'app/clients'
46
+ add_filter 'app/helpers'
47
+ add_filter 'app/decorators'
48
+ add_filter 'app/responders'
49
+ add_filter 'lib/fake_data_loader.rb'
50
+ add_filter 'lib/vue_component.rb'
51
+
52
+ if ENV["CIRCLECI"]
53
+ formatter(SimpleCov::Formatter::TextFormatter)
54
+ else
55
+ formatter(
56
+ SimpleCov::Formatter::MultiFormatter.new(
57
+ [
58
+ SimpleCov::Formatter::LinterFormatter,
59
+ SimpleCov::Formatter::HTMLFormatter
60
+ ]
61
+ )
62
+ )
63
+ end
64
+ end
@@ -0,0 +1,6 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each, type: :system) do |example|
3
+ driver = example.metadata[:no_js] ? :rack_test : :selenium_chrome_headless
4
+ driven_by(driver)
5
+ end
6
+ end
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "ESNext",
4
+ "moduleResolution": "Node",
5
+ "resolveJsonModule": true,
6
+ "useDefineForClassFields": true,
7
+ "jsx": "preserve",
8
+ "noImplicitThis": true,
9
+ "strict": true,
10
+ "isolatedModules": true,
11
+ "preserveValueImports": true,
12
+ "importsNotUsedAsValues": "error",
13
+ "target": "esnext",
14
+ "allowJs": true,
15
+
16
+ // Recommended
17
+ "esModuleInterop": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ // See <https://github.com/vuejs/vue-cli/pull/5688>
20
+ "skipLibCheck": true,
21
+ "baseUrl": "app/javascript/",
22
+ "types": ["@types/jest", "@types/node"],
23
+ },
24
+ "include": [
25
+ "app/javascript/**/*.ts",
26
+ "app/javascript/**/*.vue"
27
+ ],
28
+ "exclude": [
29
+ "node_modules"
30
+ ]
31
+ }
@@ -12,17 +12,19 @@ module Potassium::CLI
12
12
  c.action do |_global_options, options, _args|
13
13
  require 'potassium/newest_version_ensurer'
14
14
  require 'potassium/node_version_ensurer'
15
+ require 'potassium/platanus_config'
15
16
  require 'potassium/generators/application'
16
17
  require 'potassium/template_finder'
17
18
 
18
19
  begin
19
20
  Potassium::NewestVersionEnsurer.new.ensure! if options['version-check']
20
21
  Potassium::NodeVersionEnsurer.new.ensure! if options['node-version-check']
22
+ options = Potassium::PlatanusConfig.new(options).generate! if options['platanus-config']
21
23
  template_finder = Potassium::TemplateFinder.new
22
24
  template = template_finder.default_template
23
25
  template.cli_options = options
24
26
  template.source_paths << Rails::Generators::AppGenerator.source_root
25
- ARGV.push('--skip-webpack-install', '--skip-bundle')
27
+ ARGV.push('--skip-javascript', '--skip-bundle')
26
28
  template.start
27
29
  rescue VersionError => e
28
30
  print "\nError: #{e.message}" # rubocop:disable Rails/Output
@@ -75,11 +75,11 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
75
75
  default_test_value: false
76
76
  },
77
77
  {
78
- type: :flag,
78
+ type: :switch,
79
79
  name: "api",
80
- desc: "Which API interface to use",
80
+ desc: "Whether to include power_api for API support or not",
81
81
  default_value: "none",
82
- default_test_value: "None"
82
+ default_test_value: false
83
83
  },
84
84
  {
85
85
  type: :flag,
@@ -192,6 +192,22 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
192
192
  negatable: true,
193
193
  default_value: false,
194
194
  default_test_value: true
195
+ },
196
+ {
197
+ type: :switch,
198
+ name: "spring",
199
+ desc: "Whether to use Spring",
200
+ negatable: true,
201
+ default_value: true,
202
+ default_test_value: false
203
+ },
204
+ {
205
+ type: :switch,
206
+ name: 'platanus-config',
207
+ desc: 'Wheter to use the Platanus configuration.',
208
+ negatable: true,
209
+ default_value: false,
210
+ default_test_value: false
195
211
  }
196
212
  ]
197
213
 
@@ -211,4 +227,8 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
211
227
  memo
212
228
  end
213
229
  end
230
+
231
+ def self.option_names
232
+ CREATE_OPTIONS.map { |option| option[:name] }.flatten.map(&:to_sym)
233
+ end
214
234
  end
@@ -0,0 +1,20 @@
1
+ module Potassium
2
+ class PlatanusConfig
3
+ def initialize(options)
4
+ @options = options
5
+ @option_key_names = Potassium::CliOptions.option_names
6
+ end
7
+
8
+ def generate!
9
+ default_options = {
10
+ 'db': 'postgresql', 'locale': 'es-CL', 'email_service': 'sendgrid', 'devise': true,
11
+ 'devise-user-model': true, 'admin': true, 'vue_admin': true, 'pundit': true,
12
+ 'api': true, 'storage': 'shrine', 'heroku': true, 'background_processor': true,
13
+ 'draper': true, 'schedule': true, 'sentry': true, 'front_end': 'vue',
14
+ 'google_tag_manager': true, 'test': true, 'spring': true
15
+ }
16
+ default_options = default_options.filter { |key, _| @option_key_names.include?(key) }
17
+ @options.merge(default_options, default_options.stringify_keys)
18
+ end
19
+ end
20
+ end
@@ -32,12 +32,12 @@ class Recipes::Admin < Rails::AppBuilder
32
32
  private
33
33
 
34
34
  def add_active_admin
35
- gather_gem 'activeadmin', '~> 2.6'
35
+ gather_gem 'activeadmin', '~> 2.9'
36
36
  gather_gem 'activeadmin_addons'
37
- gather_gem 'active_skin', github: 'SoftwareBrothers/active_skin'
38
37
  add_readme_section :internal_dependencies, :active_admin
39
38
  after(:gem_install, wrap_in_action: :admin_install) do
40
- generate "active_admin:install"
39
+ generate "active_admin:install --use_webpacker"
40
+ run 'bin/yarn add @activeadmin/activeadmin'
41
41
  line = "ActiveAdmin.setup do |config|"
42
42
  initializer = "config/initializers/active_admin.rb"
43
43
  gsub_file initializer, /(#{Regexp.escape(line)})/mi do |_match|
@@ -50,26 +50,47 @@ class Recipes::Admin < Rails::AppBuilder
50
50
  end\n
51
51
  ActiveAdmin.setup do |config|
52
52
  config.view_factory.footer = CustomFooter
53
+ meta_tags_options = { viewport: 'width=device-width, initial-scale=1' }
54
+ config.meta_tags = meta_tags_options
55
+ config.meta_tags_for_logged_out_pages = meta_tags_options
53
56
  HERE
54
57
  end
55
58
 
56
- line = "@import \"active_admin/base\";"
57
- style = "app/assets/stylesheets/active_admin.css.scss"
58
- style = File.exist?(style) ? style : "app/assets/stylesheets/active_admin.scss"
59
+ generate "activeadmin_addons:install"
59
60
 
60
- gsub_file style, /(#{Regexp.escape(line)})/mi do |_match|
61
- <<~HERE
62
- #{line}
63
- $skinActiveColor: #001CEE;
64
- $skinHeaderBck: #002744;
65
- $panelHeaderBck: #002744;
66
- //$skinLogo: $skinHeaderBck image-url("logo_admin.png") no-repeat center center;
61
+ run "bin/yarn add arctic_admin @fortawesome/fontawesome-free"
62
+
63
+ aa_style = "app/javascript/stylesheets/active_admin.scss"
64
+
65
+ gsub_file(
66
+ aa_style,
67
+ "@import \"~@activeadmin/activeadmin/src/scss/mixins\";\n" +
68
+ "@import \"~@activeadmin/activeadmin/src/scss/base\";",
69
+ "@import '~arctic_admin/src/scss/main'; \n"
70
+ )
71
+
72
+ aa_js = "app/javascript/packs/active_admin.js"
73
+ js_line = "import \"@activeadmin/activeadmin\";\n"
67
74
 
68
- @import "active_skin";
75
+ gsub_file(
76
+ aa_js,
77
+ js_line,
78
+ <<~HERE
79
+ #{js_line}
80
+ import '@fortawesome/fontawesome-free/css/all.css';
81
+ import 'arctic_admin';
69
82
  HERE
70
- end
83
+ )
71
84
 
72
- generate "activeadmin_addons:install"
85
+ run "mv app/javascript/packs/active_admin.js app/javascript/active_admin.js"
86
+ gsub_file(
87
+ "app/javascript/active_admin.js",
88
+ 'import "../stylesheets/active_admin";',
89
+ 'import "./stylesheets/active_admin.scss";'
90
+ )
91
+
92
+ run 'rm -rf config/webpack/plugins'
93
+ run 'rm -rf app/javascript/packs/active_admin'
73
94
  end
74
95
  end
75
96
  end
@@ -1,22 +1,11 @@
1
1
  class Recipes::Api < Rails::AppBuilder
2
2
  def ask
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
3
+ api_support = answer(:api) { Ask.confirm("Do you want to enable API support?") }
4
+ set :api, api_support
12
5
  end
13
6
 
14
7
  def create
15
- if get(:api) == :graphql
16
- add_graphql
17
- elsif get(:api) == :rest
18
- add_power_api
19
- end
8
+ add_power_api if get(:api)
20
9
  end
21
10
 
22
11
  def install
@@ -25,91 +14,25 @@ class Recipes::Api < Rails::AppBuilder
25
14
  end
26
15
 
27
16
  def installed?
28
- gem_exists?(/power_api/) || gem_exists?(/graphql/)
17
+ gem_exists?(/power_api/)
29
18
  end
30
19
 
31
20
  private
32
21
 
33
22
  def add_power_api
34
- gather_gem 'power_api'
23
+ gather_gem 'power_api', '~> 2.0'
35
24
 
36
25
  gather_gems(:development, :test) do
37
26
  gather_gem 'rswag-specs'
38
27
  end
39
28
 
40
29
  add_readme_section :internal_dependencies, :power_api
30
+ rubocop_example = "RSpec:\n Language:\n Includes:\n Examples:\n - run_test!"
31
+ append_to_file('.rubocop.yml', rubocop_example)
41
32
 
42
33
  after(:gem_install) do
43
34
  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
55
-
56
- after(:gem_install) do
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")
104
- end
105
-
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
35
+ generate "power_api:internal_api_config"
113
36
  end
114
37
  end
115
38
  end
@@ -0,0 +1,66 @@
1
+ class Recipes::Coverage < Rails::AppBuilder
2
+ def create
3
+ load_gems
4
+ configure_rails_helper
5
+ append_to_file('.gitignore', "/coverage/*\n")
6
+ recipe = self
7
+ after(:setup_jest) do
8
+ recipe.configure_jest_coverage
9
+ recipe.setup_jest_text_formatter
10
+ end
11
+ end
12
+
13
+ def installed?
14
+ gem_exists?(/simplecov/)
15
+ end
16
+
17
+ def install
18
+ create
19
+ end
20
+
21
+ def configure_jest_coverage
22
+ json_file = File.read(Pathname.new("package.json"))
23
+ js_package = JSON.parse(json_file)
24
+ js_package = add_coverage_config(js_package)
25
+ json_string = JSON.pretty_generate(js_package)
26
+ create_file 'package.json', json_string, force: true
27
+ end
28
+
29
+ def setup_jest_text_formatter
30
+ run "bin/yarn add jest-text-formatter@1.0.2 --dev"
31
+ end
32
+
33
+ private
34
+
35
+ def load_gems
36
+ gather_gems(:test) do
37
+ gather_gem 'simplecov'
38
+ gather_gem 'simplecov_linter_formatter', '~> 0.2'
39
+ gather_gem 'simplecov_text_formatter'
40
+ end
41
+ end
42
+
43
+ def configure_rails_helper
44
+ copy_file '../assets/testing/simplecov_config.rb', 'spec/simplecov_config.rb'
45
+
46
+ after(:gem_install) do
47
+ gsub_file 'spec/rails_helper.rb', "ENV['RACK_ENV'] ||= 'test'" do |match|
48
+ "#{match}\nrequire 'simplecov_config'"
49
+ end
50
+ end
51
+ end
52
+
53
+ def add_coverage_config(js_package)
54
+ js_package['scripts']['test:changes'] = 'jest --changedSince=master'
55
+ js_package['jest'] = js_package['jest'].merge(coverage_defaults)
56
+ js_package
57
+ end
58
+
59
+ def coverage_defaults
60
+ {
61
+ collectCoverage: true,
62
+ collectCoverageFrom: ['**/*.{js,ts,vue}', '!**/node_modules/**'],
63
+ coverageReporters: ['text']
64
+ }
65
+ end
66
+ end
@@ -44,6 +44,56 @@ class Recipes::FileStorage < Rails::AppBuilder
44
44
  copy_file('../assets/app/uploaders/image_uploader.rb', 'app/uploaders/image_uploader.rb')
45
45
  copy_file('../assets/app/uploaders/base_uploader.rb', 'app/uploaders/base_uploader.rb')
46
46
  append_to_file('.gitignore', "/public/uploads\n")
47
+ add_image_handling_and_cover_image_uploader
48
+ end
49
+
50
+ def add_image_handling_and_cover_image_uploader
51
+ gather_gem('image_processing', '~> 1.8')
52
+ gather_gem('blurhash', '~> 0.1')
53
+ gather_gem('ruby-vips', '~> 2.1')
54
+ append_to_file('.env.development', "SHRINE_SECRET_KEY=#{SecureRandom.hex}\n")
55
+ copy_file('../assets/app/jobs/shrine_promote_job.rb', 'app/jobs/shrine_promote_job.rb')
56
+ add_image_handling_plugin
57
+ add_cover_image_uploader
58
+ add_image_handling_serializer_concern if get(:api)
59
+ add_image_handling_heroku_setup if get(:heroku)
60
+ end
61
+
62
+ def add_cover_image_uploader
63
+ copy_file(
64
+ '../assets/app/uploaders/cover_image_uploader.rb', 'app/uploaders/cover_image_uploader.rb'
65
+ )
66
+ insert_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n" do
67
+ <<~HERE.indent(2)
68
+ mount CoverImageUploader.derivation_endpoint => "/derivations/cover_image"
69
+ HERE
70
+ end
71
+ end
72
+
73
+ def add_image_handling_plugin
74
+ copy_file(
75
+ '../assets/config/initializers/shrine/plugins/image_handling_utilities.rb',
76
+ 'config/initializers/shrine/plugins/image_handling_utilities.rb'
77
+ )
78
+ end
79
+
80
+ def add_image_handling_serializer_concern
81
+ copy_file(
82
+ '../assets/app/serializers/concerns/image_handling_attributes.rb',
83
+ 'app/serializers/concerns/image_handling_attributes.rb'
84
+ )
85
+ copy_file('../assets/app/serializers/base_serializer.rb', 'app/serializers/base_serializer.rb')
86
+ end
87
+
88
+ def add_image_handling_heroku_setup
89
+ append_to_file(
90
+ '.buildpacks',
91
+ <<~HERE
92
+ https://github.com/heroku/heroku-buildpack-apt
93
+ https://github.com/brandoncc/heroku-buildpack-vips
94
+ HERE
95
+ )
96
+ copy_file('../assets/Aptfile', 'Aptfile')
47
97
  end
48
98
 
49
99
  def common_setup