potassium 5.2.2 → 6.3.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 -28
- data/.circleci/setup-rubygems.sh +3 -0
- data/.gitignore +2 -1
- data/.node-version +1 -0
- data/.rubocop.yml +530 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +92 -1
- data/README.md +51 -45
- data/docs/DSL.md +5 -5
- data/lib/potassium/assets/.circleci/config.yml.erb +151 -0
- data/lib/potassium/assets/.eslintrc.json +352 -0
- data/lib/potassium/assets/.github/pull_request_template.md +9 -0
- data/lib/potassium/assets/.rubocop.yml +528 -0
- data/lib/potassium/assets/.stylelintrc.json +46 -0
- data/lib/potassium/assets/Makefile.erb +21 -32
- data/lib/potassium/assets/README.yml +59 -15
- data/lib/potassium/assets/active_admin/admin-component.vue +35 -0
- data/lib/potassium/assets/active_admin/admin_application.js +14 -0
- data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +10 -0
- data/lib/potassium/assets/app/graphql/graphql_controller.rb +55 -0
- data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +23 -0
- data/lib/potassium/assets/app/graphql/queries/base_query.rb +4 -0
- data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +4 -0
- data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +4 -0
- data/lib/potassium/assets/app/graphql/types/base/base_field.rb +5 -0
- data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +5 -0
- data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +7 -0
- data/lib/potassium/assets/app/graphql/types/base/base_object.rb +5 -0
- data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +4 -0
- data/lib/potassium/assets/app/graphql/types/base/base_union.rb +4 -0
- data/lib/potassium/assets/app/graphql/types/mutation_type.rb +10 -0
- data/lib/potassium/assets/app/graphql/types/query_type.rb +13 -0
- data/lib/potassium/assets/app/javascript/app.spec.js +14 -0
- data/lib/potassium/assets/app/uploaders/base_uploader.rb +11 -0
- data/lib/potassium/assets/app/uploaders/image_uploader.rb +5 -0
- 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/bin/release +1 -1
- data/lib/potassium/assets/bin/setup.erb +1 -1
- data/lib/potassium/assets/config/database_mysql.yml.erb +2 -2
- data/lib/potassium/assets/config/database_postgresql.yml.erb +2 -2
- data/lib/potassium/assets/config/graphql_playground.rb +20 -0
- data/lib/potassium/assets/config/puma.rb +1 -1
- data/lib/potassium/assets/config/shrine.rb +36 -0
- data/lib/potassium/assets/lib/tasks/auto_annotate_models.rake +2 -1
- data/lib/potassium/assets/package.json +4 -1
- data/lib/potassium/assets/redis.yml +1 -2
- data/lib/potassium/assets/testing/rails_helper.rb +2 -0
- data/lib/potassium/cli/commands/create.rb +12 -19
- data/lib/potassium/cli_options.rb +77 -26
- data/lib/potassium/helpers/gem-helpers.rb +1 -1
- data/lib/potassium/helpers/template-helpers.rb +8 -0
- data/lib/potassium/newest_version_ensurer.rb +19 -36
- data/lib/potassium/node_version_ensurer.rb +30 -0
- data/lib/potassium/recipes/admin.rb +3 -3
- data/lib/potassium/recipes/annotate.rb +1 -1
- data/lib/potassium/recipes/api.rb +93 -21
- data/lib/potassium/recipes/background_processor.rb +66 -19
- data/lib/potassium/recipes/ci.rb +10 -38
- data/lib/potassium/recipes/data_migrate.rb +44 -0
- data/lib/potassium/recipes/database.rb +4 -0
- data/lib/potassium/recipes/database_container.rb +7 -5
- data/lib/potassium/recipes/draper.rb +1 -10
- data/lib/potassium/recipes/file_storage.rb +66 -0
- data/lib/potassium/recipes/front_end.rb +225 -9
- data/lib/potassium/recipes/github.rb +93 -15
- data/lib/potassium/recipes/google_tag_manager.rb +90 -0
- data/lib/potassium/recipes/heroku.rb +42 -29
- data/lib/potassium/recipes/mailer.rb +18 -2
- data/lib/potassium/recipes/monitoring.rb +5 -0
- data/lib/potassium/recipes/node.rb +21 -0
- data/lib/potassium/recipes/rack_cors.rb +18 -15
- data/lib/potassium/recipes/schedule.rb +17 -2
- data/lib/potassium/recipes/style.rb +21 -3
- data/lib/potassium/recipes/vue_admin.rb +124 -0
- data/lib/potassium/templates/application.rb +10 -7
- data/lib/potassium/version.rb +7 -4
- data/potassium.gemspec +11 -6
- data/spec/features/api_spec.rb +25 -0
- data/spec/features/background_processor_spec.rb +19 -6
- data/spec/features/ci_spec.rb +7 -4
- data/spec/features/data_migrate_spec.rb +14 -0
- data/spec/features/database_container_spec.rb +1 -5
- data/spec/features/draper_spec.rb +1 -6
- data/spec/features/file_storage_spec.rb +75 -0
- data/spec/features/front_end_spec.rb +102 -0
- data/spec/features/github_spec.rb +53 -8
- data/spec/features/google_tag_manager_spec.rb +59 -0
- data/spec/features/graphql_spec.rb +71 -0
- data/spec/features/heroku_spec.rb +1 -1
- data/spec/features/mailer_spec.rb +16 -0
- data/spec/features/new_project_spec.rb +6 -14
- data/spec/features/node_spec.rb +28 -0
- data/spec/features/power_types_spec.rb +5 -16
- data/spec/features/schedule_spec.rb +11 -4
- data/spec/features/vue_admin_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/fake_octokit.rb +31 -0
- data/spec/support/potassium_test_helpers.rb +26 -9
- data/tmp/.keep +0 -0
- metadata +152 -46
- data/lib/potassium/assets/.circleci/config.yml +0 -20
- data/lib/potassium/assets/Dockerfile.ci +0 -6
- data/lib/potassium/assets/active_admin/active_admin.js.coffee +0 -4
- data/lib/potassium/assets/active_admin/init_activeadmin_angular.rb +0 -8
- data/lib/potassium/assets/api/api_error_concern.rb +0 -32
- data/lib/potassium/assets/api/base_controller.rb +0 -9
- data/lib/potassium/assets/api/draper_responder.rb +0 -62
- data/lib/potassium/assets/api/responder.rb +0 -41
- data/lib/potassium/assets/aws.rb +0 -1
- data/lib/potassium/assets/bin/cibuild.erb +0 -100
- data/lib/potassium/assets/docker-compose.ci.yml +0 -11
- data/lib/potassium/assets/sidekiq_scheduler.yml +0 -9
- data/lib/potassium/assets/testing/paperclip.rb +0 -59
- data/lib/potassium/recipes/active_storage.rb +0 -40
- data/lib/potassium/recipes/angular_admin.rb +0 -56
- data/lib/potassium/recipes/aws_sdk.rb +0 -7
- data/lib/potassium/recipes/paperclip.rb +0 -47
- data/spec/features/active_storage_spec.rb +0 -30
- data/spec/features/front_end.rb +0 -30
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
if Rails.env.development?
|
|
72
|
+
policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035'
|
|
73
|
+
policy.script_src :self, :https, :unsafe_eval
|
|
74
|
+
else
|
|
75
|
+
policy.script_src :self, :https
|
|
76
|
+
# google tag manager requires to enable unsafe inline:
|
|
77
|
+
# https://developers.google.com/tag-manager/web/csp
|
|
78
|
+
policy.connect_src :self, :https, 'https://www.google-analytics.com'
|
|
79
|
+
policy.script_src :self,
|
|
80
|
+
:https,
|
|
81
|
+
:unsafe_inline,
|
|
82
|
+
'https://www.googletagmanager.com',
|
|
83
|
+
'https://www.google-analytics.com',
|
|
84
|
+
'https://ssl.google-analytics.com'
|
|
85
|
+
policy.img_src :self, :https, 'https://www.googletagmanager.com', 'https://www.google-analytics.com'
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
HERE
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
class Recipes::Heroku < Rails::AppBuilder
|
|
2
2
|
NAME_PREFIX = 'pl'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def initialize(args)
|
|
7
|
-
super(args)
|
|
8
|
-
set(:heroku_app_name_staging, app_name_for('staging'))
|
|
9
|
-
set(:heroku_app_name_production, app_name_for('production'))
|
|
10
|
-
end
|
|
3
|
+
ENVIRONMENTS = ['staging', 'production']
|
|
4
|
+
HEROKU_NAMES_MAX_CHARS = 30
|
|
11
5
|
|
|
12
6
|
def ask
|
|
13
7
|
heroku = answer(:heroku) do
|
|
@@ -16,6 +10,8 @@ class Recipes::Heroku < Rails::AppBuilder
|
|
|
16
10
|
|
|
17
11
|
if heroku
|
|
18
12
|
set(:heroku, heroku)
|
|
13
|
+
|
|
14
|
+
ENVIRONMENTS.each { |environment| set_app_name_for(environment) }
|
|
19
15
|
end
|
|
20
16
|
end
|
|
21
17
|
|
|
@@ -47,31 +43,34 @@ class Recipes::Heroku < Rails::AppBuilder
|
|
|
47
43
|
template "../assets/bin/setup_heroku.erb", "bin/setup_heroku", force: true
|
|
48
44
|
run "chmod a+x bin/setup_heroku"
|
|
49
45
|
|
|
50
|
-
|
|
51
|
-
%w(staging production).each do |environment|
|
|
52
|
-
create_app_on_heroku(environment)
|
|
53
|
-
end
|
|
54
|
-
puts "Remember to connect the github repository to the new pipeline"
|
|
55
|
-
open_pipeline_command = "\e[33mheroku pipelines:open #{heroku_pipeline_name}\e[0m"
|
|
56
|
-
puts "run #{open_pipeline_command} to open the dashboard"
|
|
57
|
-
else
|
|
58
|
-
puts "You are not logged in into heroku"
|
|
59
|
-
login_command = "\e[33mheroku login\e[0m"
|
|
60
|
-
puts "Run #{login_command} and enter your credentials"
|
|
61
|
-
puts "You can install the heroku recipe again create the app in heroku"
|
|
62
|
-
install_command = "\e[33mpostassium install heroku --force\e[0m"
|
|
63
|
-
puts "Just run #{install_command}"
|
|
64
|
-
end
|
|
46
|
+
logged_in? ? create_apps : puts_not_logged_in_msg
|
|
65
47
|
|
|
66
48
|
add_readme_header :deployment
|
|
67
49
|
end
|
|
68
50
|
|
|
51
|
+
def create_apps
|
|
52
|
+
ENVIRONMENTS.each { |environment| create_app_on_heroku(environment) }
|
|
53
|
+
puts "Remember to connect the github repository to the new pipeline"
|
|
54
|
+
open_pipeline_command = "\e[33mheroku pipelines:open #{heroku_pipeline_name}\e[0m"
|
|
55
|
+
puts "run #{open_pipeline_command} to open the dashboard"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def puts_not_logged_in_msg
|
|
59
|
+
puts "You are not logged in into heroku"
|
|
60
|
+
login_command = "\e[33mheroku login\e[0m"
|
|
61
|
+
puts "Run #{login_command} and enter your credentials"
|
|
62
|
+
puts "You can install the heroku recipe again to create the app in heroku"
|
|
63
|
+
install_command = "\e[33mpostassium install heroku --force\e[0m"
|
|
64
|
+
puts "Just run #{install_command}"
|
|
65
|
+
end
|
|
66
|
+
|
|
69
67
|
def heroku_pipeline_name
|
|
70
|
-
app_name.dasherize
|
|
68
|
+
@heroku_pipeline_name ||= valid_heroku_name(app_name.dasherize, 'pipeline', false)
|
|
71
69
|
end
|
|
72
70
|
|
|
73
|
-
def
|
|
74
|
-
"#{NAME_PREFIX}-#{app_name.dasherize}-#{environment}"
|
|
71
|
+
def set_app_name_for(environment)
|
|
72
|
+
default_name = "#{NAME_PREFIX}-#{app_name.dasherize}-#{environment}"
|
|
73
|
+
set("heroku_app_name_#{environment}".to_sym, valid_heroku_name(default_name, environment))
|
|
75
74
|
end
|
|
76
75
|
|
|
77
76
|
def logged_in?
|
|
@@ -84,7 +83,7 @@ class Recipes::Heroku < Rails::AppBuilder
|
|
|
84
83
|
|
|
85
84
|
def create_app_on_heroku(environment)
|
|
86
85
|
rack_env = "RACK_ENV=production"
|
|
87
|
-
staged_app_name =
|
|
86
|
+
staged_app_name = get("heroku_app_name_#{environment}".to_sym)
|
|
88
87
|
|
|
89
88
|
run_toolbelt_command "create #{staged_app_name} --remote #{environment}"
|
|
90
89
|
run_toolbelt_command "labs:enable runtime-dyno-metadata", staged_app_name
|
|
@@ -99,14 +98,14 @@ class Recipes::Heroku < Rails::AppBuilder
|
|
|
99
98
|
def set_rails_secrets(environment)
|
|
100
99
|
run_toolbelt_command(
|
|
101
100
|
"config:add SECRET_KEY_BASE=#{generate_secret}",
|
|
102
|
-
|
|
101
|
+
get("heroku_app_name_#{environment}".to_sym)
|
|
103
102
|
)
|
|
104
103
|
end
|
|
105
104
|
|
|
106
105
|
def set_app_multi_buildpack(environment)
|
|
107
106
|
run_toolbelt_command(
|
|
108
107
|
"buildpacks:set https://github.com/heroku/heroku-buildpack-multi.git",
|
|
109
|
-
|
|
108
|
+
get("heroku_app_name_#{environment}".to_sym)
|
|
110
109
|
)
|
|
111
110
|
end
|
|
112
111
|
|
|
@@ -133,4 +132,18 @@ class Recipes::Heroku < Rails::AppBuilder
|
|
|
133
132
|
`heroku #{command} --app #{app_env_name}`
|
|
134
133
|
end
|
|
135
134
|
end
|
|
135
|
+
|
|
136
|
+
def valid_heroku_name(name, element, force_suffix = true)
|
|
137
|
+
suffix = "-#{element}"
|
|
138
|
+
while name.length > HEROKU_NAMES_MAX_CHARS
|
|
139
|
+
puts "Heroku names must be shorter than #{HEROKU_NAMES_MAX_CHARS} chars."
|
|
140
|
+
if force_suffix
|
|
141
|
+
puts "Potassium uses the heroku-stage gem, because of that '#{suffix}' will be "\
|
|
142
|
+
"added to your app name. The suffix, #{suffix}, counts towards the app name length."
|
|
143
|
+
end
|
|
144
|
+
name = Ask.input("Please enter a valid name for #{element}:")
|
|
145
|
+
name += suffix if force_suffix && !name.end_with?(suffix)
|
|
146
|
+
end
|
|
147
|
+
name
|
|
148
|
+
end
|
|
136
149
|
end
|
|
@@ -24,8 +24,7 @@ class Recipes::Mailer < Rails::AppBuilder
|
|
|
24
24
|
dependencies(email_service)
|
|
25
25
|
config(email_service)
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
background_processor.add_sidekiq unless background_processor.installed?
|
|
27
|
+
ensure_sidekiq_install_and_add_mailers_queue
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def install
|
|
@@ -33,6 +32,10 @@ class Recipes::Mailer < Rails::AppBuilder
|
|
|
33
32
|
create
|
|
34
33
|
end
|
|
35
34
|
|
|
35
|
+
def add_mailer_queue
|
|
36
|
+
insert_into_file "config/sidekiq.yml", " - mailers", after: "- default\n"
|
|
37
|
+
end
|
|
38
|
+
|
|
36
39
|
private
|
|
37
40
|
|
|
38
41
|
def email_services(service_name)
|
|
@@ -99,4 +102,17 @@ class Recipes::Mailer < Rails::AppBuilder
|
|
|
99
102
|
gather_gems(:development) { gather_gem("letter_opener") }
|
|
100
103
|
application "config.action_mailer.delivery_method = :letter_opener", env: "development"
|
|
101
104
|
end
|
|
105
|
+
|
|
106
|
+
def ensure_sidekiq_install_and_add_mailers_queue
|
|
107
|
+
background_processor_recipe = load_recipe(:background_processor)
|
|
108
|
+
background_processor_answer = get(:background_processor)
|
|
109
|
+
|
|
110
|
+
if background_processor_recipe.installed?
|
|
111
|
+
add_mailer_queue
|
|
112
|
+
else
|
|
113
|
+
recipe = self
|
|
114
|
+
after(:install_sidekiq) { recipe.add_mailer_queue }
|
|
115
|
+
background_processor_recipe.add_sidekiq unless background_processor_answer
|
|
116
|
+
end
|
|
117
|
+
end
|
|
102
118
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'semantic'
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
class Recipes::Node < Rails::AppBuilder
|
|
6
|
+
def create
|
|
7
|
+
info "Using node version LTS #{version}"
|
|
8
|
+
create_file '.node-version', version, force: true
|
|
9
|
+
json_file = File.read(Pathname.new("package.json"))
|
|
10
|
+
js_package = JSON.parse(json_file)
|
|
11
|
+
js_package["engines"] = { "node" => "#{version}.x" }
|
|
12
|
+
json_string = JSON.pretty_generate(js_package)
|
|
13
|
+
create_file 'package.json', json_string, force: true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def version
|
|
19
|
+
Potassium::NODE_VERSION
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -4,23 +4,26 @@ class Recipes::RackCors < Rails::AppBuilder
|
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
def create
|
|
7
|
-
gather_gem('rack-cors', '~>
|
|
7
|
+
gather_gem('rack-cors', '~> 1.1')
|
|
8
|
+
recipe = self
|
|
8
9
|
after(:gem_install) do
|
|
9
|
-
rack_cors_config
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
allow do
|
|
13
|
-
origins '*'
|
|
14
|
-
resource '*',
|
|
15
|
-
headers: :any,
|
|
16
|
-
expose: ['X-Page', 'X-PageTotal'],
|
|
17
|
-
methods: [:get, :post, :delete, :put, :options]
|
|
18
|
-
end
|
|
19
|
-
end
|
|
10
|
+
application recipe.rack_cors_config
|
|
11
|
+
end
|
|
12
|
+
end
|
|
20
13
|
|
|
21
|
-
|
|
14
|
+
def rack_cors_config
|
|
15
|
+
<<~RUBY
|
|
16
|
+
config.middleware.insert_before 0, Rack::Cors do
|
|
17
|
+
allow do
|
|
18
|
+
origins '*'
|
|
19
|
+
resource '/public/*', headers: :any, methods: :get
|
|
20
|
+
resource '/api/*',
|
|
21
|
+
headers: :any,
|
|
22
|
+
expose: ['X-Page', 'X-PageTotal'],
|
|
23
|
+
methods: [:get, :post, :patch, :put, :delete, :options]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
end
|
|
27
|
+
RUBY
|
|
25
28
|
end
|
|
26
29
|
end
|
|
@@ -8,10 +8,10 @@ class Recipes::Schedule < Rails::AppBuilder
|
|
|
8
8
|
|
|
9
9
|
def create
|
|
10
10
|
if selected?(:schedule)
|
|
11
|
-
gather_gem 'sidekiq-scheduler'
|
|
11
|
+
gather_gem 'sidekiq-scheduler', '>= 3.0.1'
|
|
12
12
|
add_readme_section :internal_dependencies, :sidekiq_scheduler
|
|
13
|
+
append_schedule_section_to_yml
|
|
13
14
|
end
|
|
14
|
-
template '../assets/sidekiq_scheduler.yml', 'config/sidekiq.yml', force: true
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def install
|
|
@@ -22,4 +22,19 @@ class Recipes::Schedule < Rails::AppBuilder
|
|
|
22
22
|
def installed?
|
|
23
23
|
gem_exists?(/sidekiq-scheduler/) && file_exist?('config/sidekiq.yml')
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def append_schedule_section_to_yml
|
|
29
|
+
append_to_file(
|
|
30
|
+
'config/sidekiq.yml',
|
|
31
|
+
<<-HERE.gsub(/^ {8}/, '')
|
|
32
|
+
# :schedule:
|
|
33
|
+
# an_scheduled_task:
|
|
34
|
+
# cron: '0 * * * * *' # Runs once per minute
|
|
35
|
+
# class: ExampleJob
|
|
36
|
+
# args: ['a', 'b']
|
|
37
|
+
HERE
|
|
38
|
+
)
|
|
39
|
+
end
|
|
25
40
|
end
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
class Recipes::Style < Rails::AppBuilder
|
|
2
2
|
def create
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
append_to_file ".gitignore", ".sscs-lint.yml\n"
|
|
3
|
+
add_linters
|
|
4
|
+
add_config_files
|
|
6
5
|
add_readme_header :style_guide
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
def install
|
|
10
9
|
create
|
|
11
10
|
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def add_linters
|
|
15
|
+
gather_gems(:development, :test) do
|
|
16
|
+
gather_gem 'rubocop', Potassium::RUBOCOP_VERSION
|
|
17
|
+
gather_gem 'rubocop-performance'
|
|
18
|
+
gather_gem 'rubocop-rails'
|
|
19
|
+
gather_gem 'rubocop-rspec', Potassium::RUBOCOP_RSPEC_VERSION
|
|
20
|
+
end
|
|
21
|
+
run 'bin/yarn add --dev stylelint eslint eslint-plugin-import'
|
|
22
|
+
run 'bin/yarn add --dev eslint-plugin-vue' if selected?(:front_end, :vue)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_config_files
|
|
26
|
+
copy_file '../assets/.rubocop.yml', '.rubocop.yml'
|
|
27
|
+
copy_file '../assets/.eslintrc.json', '.eslintrc.json'
|
|
28
|
+
copy_file '../assets/.stylelintrc.json', '.stylelintrc.json'
|
|
29
|
+
end
|
|
12
30
|
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
class Recipes::VueAdmin < Rails::AppBuilder
|
|
2
|
+
def ask
|
|
3
|
+
if selected?(:admin_mode)
|
|
4
|
+
vue_admin = answer(:vue_admin) do
|
|
5
|
+
Ask.confirm "Do you want Vue support for ActiveAdmin?"
|
|
6
|
+
end
|
|
7
|
+
set(:vue_admin, vue_admin)
|
|
8
|
+
set(:front_end, :vue) if vue_admin
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create
|
|
13
|
+
recipe = self
|
|
14
|
+
if selected?(:vue_admin)
|
|
15
|
+
after(:admin_install) do
|
|
16
|
+
recipe.add_vue_admin
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def install
|
|
22
|
+
active_admin = load_recipe(:admin)
|
|
23
|
+
if active_admin.installed?
|
|
24
|
+
add_vue_admin
|
|
25
|
+
info "VueAdmin installed"
|
|
26
|
+
else
|
|
27
|
+
info "VueAdmin can't be installed because Active Admin isn't installed."
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def installed?
|
|
32
|
+
dir_exist?("app/assets/javascripts/admin")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_vue_admin
|
|
36
|
+
add_vue_component_library
|
|
37
|
+
add_component_integration
|
|
38
|
+
copy_file '../assets/active_admin/init_activeadmin_vue.rb',
|
|
39
|
+
'config/initializers/init_activeadmin_vue.rb'
|
|
40
|
+
copy_file '../assets/active_admin/admin_application.js',
|
|
41
|
+
'app/javascript/packs/admin_application.js',
|
|
42
|
+
force: true
|
|
43
|
+
empty_directory 'app/javascript/components'
|
|
44
|
+
copy_file '../assets/active_admin/admin-component.vue',
|
|
45
|
+
'app/javascript/components/admin-component.vue',
|
|
46
|
+
force: true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def add_component_integration
|
|
50
|
+
line = "class CustomFooter < ActiveAdmin::Component"
|
|
51
|
+
initializer = "config/initializers/active_admin.rb"
|
|
52
|
+
gsub_file initializer, /(#{Regexp.escape(line)})/mi do |_match|
|
|
53
|
+
<<~HERE
|
|
54
|
+
require "vue_component.rb"
|
|
55
|
+
AUTO_BUILD_ELEMENTS=[:admin_component, :template, :slot]
|
|
56
|
+
component_creator(AUTO_BUILD_ELEMENTS)
|
|
57
|
+
|
|
58
|
+
#{line}
|
|
59
|
+
HERE
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def add_vue_component_library
|
|
64
|
+
lib_component_path = "lib/vue_component.rb"
|
|
65
|
+
class_definitions =
|
|
66
|
+
<<~HERE
|
|
67
|
+
#{vue_component}
|
|
68
|
+
#{component_builder}
|
|
69
|
+
HERE
|
|
70
|
+
File.open(lib_component_path, "w") { |file| file.write(class_definitions) }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def vue_component
|
|
74
|
+
<<~HERE
|
|
75
|
+
class VueComponent < Arbre::Component
|
|
76
|
+
builder_method :root
|
|
77
|
+
def tag_name
|
|
78
|
+
:root
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def initialize(*)
|
|
82
|
+
super
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build(attributes = {})
|
|
86
|
+
super(process_attributes(attributes))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def process_attributes(attributes)
|
|
90
|
+
vue_attributes = {}
|
|
91
|
+
attributes.each do |key, value|
|
|
92
|
+
dasherized_key = key.to_s.dasherize
|
|
93
|
+
if value.is_a?(String)
|
|
94
|
+
vue_attributes[dasherized_key] = value
|
|
95
|
+
elsif !dasherized_key.index(':').nil? && dasherized_key.index(':').zero?
|
|
96
|
+
vue_attributes[dasherized_key] = value.to_json
|
|
97
|
+
else
|
|
98
|
+
vue_attributes[":" + dasherized_key] = value.to_json
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
vue_attributes
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
HERE
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def component_builder
|
|
108
|
+
<<~HERE
|
|
109
|
+
def component_creator(auto_build_elements)
|
|
110
|
+
auto_build_elements.each do |element|
|
|
111
|
+
as_string=element.to_s
|
|
112
|
+
camelized_element = as_string.camelize
|
|
113
|
+
Object.const_set(camelized_element,Class.new(VueComponent))
|
|
114
|
+
Object.const_get(camelized_element).class_eval do
|
|
115
|
+
builder_method as_string.to_sym
|
|
116
|
+
def tag_name
|
|
117
|
+
self.class.to_s.underscore
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
HERE
|
|
123
|
+
end
|
|
124
|
+
end
|