potassium 6.1.0 → 6.5.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +103 -38
- data/.circleci/setup-rubygems.sh +3 -0
- data/.gitignore +2 -1
- data/.node-version +1 -1
- data/.rubocop.yml +530 -0
- data/CHANGELOG.md +50 -1
- data/README.md +11 -3
- data/lib/potassium/assets/.circleci/config.yml.erb +107 -40
- data/lib/potassium/assets/.pryrc +0 -6
- data/lib/potassium/assets/.rubocop.yml +13 -0
- data/lib/potassium/assets/README.yml +45 -8
- data/lib/potassium/assets/active_admin/policies/admin_user_policy.rb +2 -0
- data/lib/potassium/assets/active_admin/policies/comment_policy.rb +2 -0
- data/lib/potassium/assets/active_admin/policies/default_policy.rb +49 -0
- data/lib/potassium/assets/active_admin/policies/page_policy.rb +2 -0
- data/lib/potassium/assets/app/javascript/app.spec.js +1 -1
- data/lib/potassium/assets/app/views/shared/_gtm_body.html.erb +4 -0
- data/lib/potassium/assets/app/views/shared/_gtm_head.html.erb +7 -0
- data/lib/potassium/assets/testing/.rspec +1 -0
- data/lib/potassium/assets/testing/devise_config.rb +6 -0
- data/lib/potassium/assets/testing/factory_bot_config.rb +3 -0
- data/lib/potassium/assets/testing/faker_config.rb +1 -0
- data/lib/potassium/assets/testing/power_types_config.rb +1 -0
- data/lib/potassium/assets/testing/rails_helper.rb +130 -49
- data/lib/potassium/assets/testing/shoulda_matchers_config.rb +8 -0
- data/lib/potassium/assets/testing/simplecov_config.rb +64 -0
- data/lib/potassium/assets/testing/system_tests_config.rb +6 -0
- data/lib/potassium/cli_options.rb +19 -3
- data/lib/potassium/helpers/template-helpers.rb +4 -0
- data/lib/potassium/recipes/admin.rb +27 -17
- data/lib/potassium/recipes/api.rb +2 -0
- data/lib/potassium/recipes/background_processor.rb +43 -32
- data/lib/potassium/recipes/ci.rb +9 -39
- data/lib/potassium/recipes/coverage.rb +35 -0
- data/lib/potassium/recipes/file_storage.rb +1 -1
- data/lib/potassium/recipes/front_end.rb +26 -13
- data/lib/potassium/recipes/google_tag_manager.rb +94 -0
- data/lib/potassium/recipes/heroku.rb +43 -31
- data/lib/potassium/recipes/mailer.rb +18 -5
- data/lib/potassium/recipes/monitoring.rb +5 -0
- data/lib/potassium/recipes/pundit.rb +29 -10
- data/lib/potassium/recipes/rails.rb +0 -4
- data/lib/potassium/recipes/schedule.rb +16 -1
- data/lib/potassium/recipes/spring.rb +9 -0
- data/lib/potassium/recipes/style.rb +2 -2
- data/lib/potassium/recipes/testing.rb +75 -18
- data/lib/potassium/templates/application.rb +7 -2
- data/lib/potassium/version.rb +7 -4
- data/potassium.gemspec +3 -1
- data/spec/features/background_processor_spec.rb +7 -5
- data/spec/features/ci_spec.rb +7 -4
- data/spec/features/coverage_spec.rb +26 -0
- data/spec/features/front_end_spec.rb +18 -1
- data/spec/features/google_tag_manager_spec.rb +36 -0
- data/spec/features/heroku_spec.rb +0 -4
- data/spec/features/mailer_spec.rb +16 -0
- data/spec/features/node_spec.rb +1 -1
- data/spec/features/pundit_spec.rb +34 -0
- data/spec/features/schedule_spec.rb +11 -4
- data/spec/features/testing_spec.rb +56 -0
- data/spec/support/potassium_test_helpers.rb +2 -3
- data/tmp/.keep +0 -0
- metadata +64 -15
- data/lib/potassium/assets/Dockerfile.ci +0 -6
- data/lib/potassium/assets/active_admin/admin_user_policy.rb +0 -2
- data/lib/potassium/assets/active_admin/comment_policy.rb +0 -2
- data/lib/potassium/assets/active_admin/pundit_page_policy.rb +0 -5
- data/lib/potassium/assets/bin/cibuild.erb +0 -117
- data/lib/potassium/assets/docker-compose.ci.yml +0 -12
- data/lib/potassium/assets/sidekiq_scheduler.yml +0 -9
@@ -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
|
@@ -97,10 +97,10 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
97
97
|
default_test_value: false
|
98
98
|
},
|
99
99
|
{
|
100
|
-
type: :
|
100
|
+
type: :switch,
|
101
101
|
name: "background_processor",
|
102
|
-
desc: "
|
103
|
-
default_test_value:
|
102
|
+
desc: "Whether to use Sidekiq for background processing or not",
|
103
|
+
default_test_value: false
|
104
104
|
},
|
105
105
|
{
|
106
106
|
type: :switch,
|
@@ -177,6 +177,14 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
177
177
|
desc: "Decides which front-end framework to use. Available: Vue, Angular 2, None",
|
178
178
|
default_test_value: "None"
|
179
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
|
+
},
|
180
188
|
{
|
181
189
|
type: :switch,
|
182
190
|
name: "test",
|
@@ -184,6 +192,14 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
184
192
|
negatable: true,
|
185
193
|
default_value: false,
|
186
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
|
187
203
|
}
|
188
204
|
]
|
189
205
|
|
@@ -7,6 +7,10 @@ module TemplateHelpers
|
|
7
7
|
"#{Potassium::NODE_VERSION}.x"
|
8
8
|
end
|
9
9
|
|
10
|
+
def ruby_version
|
11
|
+
Semantic::Version.new(Potassium::RUBY_VERSION).instance_eval { "#{major}.#{minor}" }
|
12
|
+
end
|
13
|
+
|
10
14
|
def load_recipe(recipe_name)
|
11
15
|
@recipes ||= {}
|
12
16
|
@recipes[recipe_name] ||= get_recipe_class(recipe_name.to_sym).new(self)
|
@@ -32,12 +32,11 @@ class Recipes::Admin < Rails::AppBuilder
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def add_active_admin
|
35
|
-
gather_gem 'activeadmin', '~> 2.
|
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"
|
41
40
|
line = "ActiveAdmin.setup do |config|"
|
42
41
|
initializer = "config/initializers/active_admin.rb"
|
43
42
|
gsub_file initializer, /(#{Regexp.escape(line)})/mi do |_match|
|
@@ -50,26 +49,37 @@ class Recipes::Admin < Rails::AppBuilder
|
|
50
49
|
end\n
|
51
50
|
ActiveAdmin.setup do |config|
|
52
51
|
config.view_factory.footer = CustomFooter
|
52
|
+
meta_tags_options = { viewport: 'width=device-width, initial-scale=1' }
|
53
|
+
config.meta_tags = meta_tags_options
|
54
|
+
config.meta_tags_for_logged_out_pages = meta_tags_options
|
53
55
|
HERE
|
54
56
|
end
|
55
57
|
|
56
|
-
|
57
|
-
style = "app/assets/stylesheets/active_admin.css.scss"
|
58
|
-
style = File.exist?(style) ? style : "app/assets/stylesheets/active_admin.scss"
|
58
|
+
generate "activeadmin_addons:install"
|
59
59
|
|
60
|
-
|
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;
|
60
|
+
run "bin/yarn add arctic_admin @fortawesome/fontawesome-free"
|
67
61
|
|
68
|
-
|
69
|
-
HERE
|
70
|
-
end
|
62
|
+
aa_style = "app/javascript/stylesheets/active_admin.scss"
|
71
63
|
|
72
|
-
|
64
|
+
gsub_file(
|
65
|
+
aa_style,
|
66
|
+
"@import \"~@activeadmin/activeadmin/src/scss/mixins\";\n" +
|
67
|
+
"@import \"~@activeadmin/activeadmin/src/scss/base\";",
|
68
|
+
"@import '~arctic_admin/src/scss/main'; \n"
|
69
|
+
)
|
70
|
+
|
71
|
+
aa_js = "app/javascript/packs/active_admin.js"
|
72
|
+
js_line = "import \"@activeadmin/activeadmin\";\n"
|
73
|
+
|
74
|
+
gsub_file(
|
75
|
+
aa_js,
|
76
|
+
js_line,
|
77
|
+
<<~HERE
|
78
|
+
#{js_line}
|
79
|
+
import '@fortawesome/fontawesome-free/css/all.css';
|
80
|
+
import 'arctic_admin';
|
81
|
+
HERE
|
82
|
+
)
|
73
83
|
end
|
74
84
|
end
|
75
85
|
end
|
@@ -38,6 +38,8 @@ class Recipes::Api < Rails::AppBuilder
|
|
38
38
|
end
|
39
39
|
|
40
40
|
add_readme_section :internal_dependencies, :power_api
|
41
|
+
rubocop_example = "RSpec:\n Language:\n Includes:\n Examples:\n - run_test!"
|
42
|
+
append_to_file('.rubocop.yml', rubocop_example)
|
41
43
|
|
42
44
|
after(:gem_install) do
|
43
45
|
generate "power_api:install"
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class Recipes::BackgroundProcessor < Rails::AppBuilder
|
2
2
|
def ask
|
3
|
-
response = if
|
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
|
@@ -30,6 +30,42 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
|
|
30
30
|
gem_exists?(/sidekiq/)
|
31
31
|
end
|
32
32
|
|
33
|
+
def add_sidekiq
|
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
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def edit_procfile(cmd)
|
49
|
+
heroku = load_recipe(:heroku)
|
50
|
+
if selected?(:heroku) || heroku.installed?
|
51
|
+
gsub_file('Procfile', /^.*$/m) { |match| "#{match}worker: #{cmd}" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_adapters(name)
|
56
|
+
application("config.active_job.queue_adapter = :#{name}")
|
57
|
+
application "config.active_job.queue_adapter = :async", env: "development"
|
58
|
+
application "config.active_job.queue_adapter = :test", env: "test"
|
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
|
+
|
33
69
|
private
|
34
70
|
|
35
71
|
def add_docker_compose_redis_config
|
@@ -59,33 +95,8 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
|
|
59
95
|
)
|
60
96
|
end
|
61
97
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
add_readme_section :internal_dependencies, :sidekiq
|
66
|
-
edit_procfile("bundle exec sidekiq")
|
67
|
-
append_to_file(".env.development", "DB_POOL=25\n")
|
68
|
-
template("../assets/sidekiq.rb.erb", "config/initializers/sidekiq.rb", force: true)
|
69
|
-
copy_file("../assets/sidekiq.yml", "config/sidekiq.yml", force: true)
|
70
|
-
copy_file("../assets/redis.yml", "config/redis.yml", force: true)
|
71
|
-
|
72
|
-
insert_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n" do
|
73
|
-
<<-HERE.gsub(/^ {6}/, '')
|
74
|
-
mount Sidekiq::Web => '/queue'
|
75
|
-
HERE
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def edit_procfile(cmd)
|
80
|
-
heroku = load_recipe(:heroku)
|
81
|
-
if selected?(:heroku) || heroku.installed?
|
82
|
-
gsub_file('Procfile', /^.*$/m) { |match| "#{match}worker: #{cmd}" }
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def add_adapters(name)
|
87
|
-
application("config.active_job.queue_adapter = :#{name}")
|
88
|
-
application "config.active_job.queue_adapter = :async", env: "development"
|
89
|
-
application "config.active_job.queue_adapter = :test", env: "test"
|
98
|
+
def enabled_mailer?
|
99
|
+
mailer_answer = get(:email_service)
|
100
|
+
mailer_answer && ![:none, :None].include?(mailer_answer.to_sym)
|
90
101
|
end
|
91
102
|
end
|
data/lib/potassium/recipes/ci.rb
CHANGED
@@ -1,50 +1,20 @@
|
|
1
1
|
class Recipes::Ci < Rails::AppBuilder
|
2
2
|
def create
|
3
|
-
copy_file '../assets/Dockerfile.ci', 'Dockerfile.ci'
|
4
3
|
template '../assets/.circleci/config.yml.erb', '.circleci/config.yml'
|
5
4
|
|
6
|
-
template '../assets/bin/cibuild.erb', 'bin/cibuild'
|
7
|
-
run "chmod a+x bin/cibuild"
|
8
|
-
|
9
|
-
copy_file '../assets/docker-compose.ci.yml', 'docker-compose.ci.yml'
|
10
|
-
|
11
5
|
gather_gems(:test) do
|
12
|
-
gather_gem 'rspec_junit_formatter', '0.
|
13
|
-
end
|
14
|
-
|
15
|
-
compose = DockerHelpers.new('docker-compose.ci.yml')
|
16
|
-
|
17
|
-
if selected?(:database, :mysql)
|
18
|
-
srv =
|
19
|
-
<<~YAML
|
20
|
-
image: mysql:#{Potassium::MYSQL_VERSION}
|
21
|
-
environment:
|
22
|
-
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
|
23
|
-
YAML
|
24
|
-
compose.add_service("mysql", srv)
|
25
|
-
compose.add_link('test', 'mysql')
|
26
|
-
compose.add_env('test', 'MYSQL_HOST', 'mysql')
|
27
|
-
compose.add_env('test', 'MYSQL_PORT', '3306')
|
28
|
-
|
29
|
-
elsif selected?(:database, :postgresql)
|
30
|
-
srv =
|
31
|
-
<<~YAML
|
32
|
-
image: "postgres:#{Potassium::POSTGRES_VERSION}"
|
33
|
-
environment:
|
34
|
-
POSTGRES_USER: postgres
|
35
|
-
POSTGRES_PASSWORD: ''
|
36
|
-
YAML
|
37
|
-
compose.add_service("postgresql", srv)
|
38
|
-
compose.add_link('test', 'postgresql')
|
39
|
-
compose.add_env('test', 'DB_USER', 'postgres')
|
40
|
-
compose.add_env('test', 'DB_HOST', 'postgresql')
|
41
|
-
compose.add_env('test', 'DB_PORT', '5432')
|
6
|
+
gather_gem 'rspec_junit_formatter', '~> 0.4'
|
42
7
|
end
|
43
8
|
|
44
|
-
compose.add_volume('test_data')
|
45
|
-
|
46
9
|
add_readme_header :ci
|
47
|
-
|
48
10
|
application 'config.assets.js_compressor = :uglifier', env: 'test'
|
49
11
|
end
|
12
|
+
|
13
|
+
def install
|
14
|
+
create
|
15
|
+
end
|
16
|
+
|
17
|
+
def installed?
|
18
|
+
file_exist?('.circleci/config.yml')
|
19
|
+
end
|
50
20
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Recipes::Coverage < Rails::AppBuilder
|
2
|
+
def create
|
3
|
+
load_gems
|
4
|
+
configure_rails_helper
|
5
|
+
append_to_file('.gitignore', "/coverage/*\n")
|
6
|
+
end
|
7
|
+
|
8
|
+
def installed?
|
9
|
+
gem_exists?(/simplecov/)
|
10
|
+
end
|
11
|
+
|
12
|
+
def install
|
13
|
+
create
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def load_gems
|
19
|
+
gather_gems(:test) do
|
20
|
+
gather_gem 'simplecov'
|
21
|
+
gather_gem 'simplecov_linter_formatter', '~> 0.2'
|
22
|
+
gather_gem 'simplecov_text_formatter'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def configure_rails_helper
|
27
|
+
copy_file '../assets/testing/simplecov_config.rb', 'spec/simplecov_config.rb'
|
28
|
+
|
29
|
+
after(:gem_install) do
|
30
|
+
gsub_file 'spec/rails_helper.rb', "ENV['RACK_ENV'] ||= 'test'" do |match|
|
31
|
+
"#{match}\nrequire 'simplecov_config'"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -39,7 +39,7 @@ class Recipes::FileStorage < Rails::AppBuilder
|
|
39
39
|
|
40
40
|
def add_shrine
|
41
41
|
gather_gem('shrine', '~> 3.0')
|
42
|
-
gather_gem('marcel', '~> 0
|
42
|
+
gather_gem('marcel', '~> 1.0')
|
43
43
|
copy_file('../assets/config/shrine.rb', 'config/initializers/shrine.rb', force: true)
|
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')
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class Recipes::FrontEnd < Rails::AppBuilder
|
2
|
+
VUE_LOADER_VERSION = Potassium::VUE_LOADER_VERSION
|
3
|
+
|
2
4
|
def ask
|
3
5
|
frameworks = {
|
4
6
|
vue: "Vue",
|
@@ -15,21 +17,13 @@ class Recipes::FrontEnd < Rails::AppBuilder
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def create
|
18
|
-
return if [:none, :None].include? get(:front_end).to_sym
|
19
|
-
|
20
20
|
recipe = self
|
21
21
|
after(:gem_install) do
|
22
22
|
value = get(:front_end)
|
23
23
|
run "rails webpacker:install"
|
24
|
-
run "rails webpacker:install:#{value}"
|
25
|
-
|
26
|
-
if value == :vue
|
27
|
-
recipe.setup_vue_with_compiler_build
|
28
|
-
recipe.setup_jest
|
29
|
-
if get(:api) == :graphql
|
30
|
-
recipe.setup_apollo
|
31
|
-
end
|
32
|
-
end
|
24
|
+
run "rails webpacker:install:#{value}" unless [:none, :None].include? value.to_sym
|
25
|
+
|
26
|
+
recipe.setup_vue if value == :vue
|
33
27
|
recipe.add_responsive_meta_tag
|
34
28
|
recipe.setup_tailwind
|
35
29
|
add_readme_header :webpack
|
@@ -69,7 +63,8 @@ class Recipes::FrontEnd < Rails::AppBuilder
|
|
69
63
|
end
|
70
64
|
|
71
65
|
def setup_tailwind
|
72
|
-
run
|
66
|
+
run "bin/yarn add tailwindcss@#{Potassium::TAILWINDCSS}"
|
67
|
+
specify_autoprefixer_postcss_compatibility_versions
|
73
68
|
setup_client_css
|
74
69
|
remove_server_css_requires
|
75
70
|
setup_tailwind_requirements
|
@@ -107,6 +102,19 @@ class Recipes::FrontEnd < Rails::AppBuilder
|
|
107
102
|
)
|
108
103
|
end
|
109
104
|
|
105
|
+
def foce_vue_loader_version
|
106
|
+
run "bin/yarn add vue-loader@#{VUE_LOADER_VERSION}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def setup_vue
|
110
|
+
foce_vue_loader_version
|
111
|
+
setup_vue_with_compiler_build
|
112
|
+
setup_jest
|
113
|
+
if get(:api) == :graphql
|
114
|
+
setup_apollo
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
110
118
|
private
|
111
119
|
|
112
120
|
def frameworks(framework)
|
@@ -147,6 +155,10 @@ class Recipes::FrontEnd < Rails::AppBuilder
|
|
147
155
|
JS
|
148
156
|
end
|
149
157
|
|
158
|
+
def specify_autoprefixer_postcss_compatibility_versions
|
159
|
+
run 'bin/yarn -D add postcss@^7 autoprefixer@^9'
|
160
|
+
end
|
161
|
+
|
150
162
|
def setup_client_css
|
151
163
|
application_css = 'app/javascript/css/application.css'
|
152
164
|
create_file application_css, "", force: true
|
@@ -264,7 +276,8 @@ class Recipes::FrontEnd < Rails::AppBuilder
|
|
264
276
|
},
|
265
277
|
"snapshotSerializers": [
|
266
278
|
"<rootDir>/node_modules/jest-serializer-vue"
|
267
|
-
]
|
279
|
+
],
|
280
|
+
"testEnvironment": "jsdom"
|
268
281
|
}
|
269
282
|
}
|
270
283
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class Recipes::GoogleTagManager < Rails::AppBuilder
|
2
|
+
def ask
|
3
|
+
use_google_tag_manager = answer(:google_tag_manager) do
|
4
|
+
Ask.confirm 'Do you want to use Google Tag Manager?'
|
5
|
+
end
|
6
|
+
|
7
|
+
set(:google_tag_manager, use_google_tag_manager)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
install if selected?(:google_tag_manager)
|
12
|
+
end
|
13
|
+
|
14
|
+
def install
|
15
|
+
add_google_tag_manager
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_google_tag_manager
|
19
|
+
copy_tag_manager_files
|
20
|
+
append_to_file '.env.development', "GTM_CONTAINER_ID=\n"
|
21
|
+
include_tag_manager
|
22
|
+
add_content_security_policy
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_content_security_policy
|
26
|
+
inject_into_file(
|
27
|
+
'config/initializers/content_security_policy.rb',
|
28
|
+
content_security_policy_code
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def copy_tag_manager_files
|
33
|
+
copy_file(
|
34
|
+
'../assets/app/views/shared/_gtm_head.html.erb',
|
35
|
+
'app/views/shared/_gtm_head.html.erb',
|
36
|
+
force: true
|
37
|
+
)
|
38
|
+
|
39
|
+
copy_file(
|
40
|
+
'../assets/app/views/shared/_gtm_body.html.erb',
|
41
|
+
'app/views/shared/_gtm_body.html.erb',
|
42
|
+
force: true
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def include_tag_manager
|
47
|
+
inject_into_file(
|
48
|
+
'app/views/layouts/application.html.erb',
|
49
|
+
render_string('shared/gtm_head'),
|
50
|
+
before: '</head>'
|
51
|
+
)
|
52
|
+
|
53
|
+
inject_into_file(
|
54
|
+
'app/views/layouts/application.html.erb',
|
55
|
+
render_string('shared/gtm_body'),
|
56
|
+
after: '<body>'
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def render_string(file_path)
|
63
|
+
" <%if Rails.env.production? %>
|
64
|
+
<%= render \"#{file_path}\" %>
|
65
|
+
<% end %>\n "
|
66
|
+
end
|
67
|
+
|
68
|
+
def content_security_policy_code
|
69
|
+
<<~HERE
|
70
|
+
Rails.application.config.content_security_policy do |policy|
|
71
|
+
policy.connect_src(
|
72
|
+
:self,
|
73
|
+
:https,
|
74
|
+
'http://localhost:3035',
|
75
|
+
'ws://localhost:3035',
|
76
|
+
'https://www.google-analytics.com'
|
77
|
+
)
|
78
|
+
# google tag manager requires to enable unsafe inline and vue unsave eval:
|
79
|
+
# https://developers.google.com/tag-manager/web/csp
|
80
|
+
# https://vuejs.org/v2/guide/installation.html#CSP-environments
|
81
|
+
policy.script_src(
|
82
|
+
:self,
|
83
|
+
:https,
|
84
|
+
:unsafe_inline,
|
85
|
+
:unsafe_eval,
|
86
|
+
'https://www.googletagmanager.com',
|
87
|
+
'https://www.google-analytics.com',
|
88
|
+
'https://ssl.google-analytics.com'
|
89
|
+
)
|
90
|
+
policy.img_src :self, :https, 'https://www.googletagmanager.com', 'https://www.google-analytics.com'
|
91
|
+
end
|
92
|
+
HERE
|
93
|
+
end
|
94
|
+
end
|