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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +103 -28
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.gitignore +2 -1
  5. data/.node-version +1 -0
  6. data/.rubocop.yml +530 -0
  7. data/.ruby-version +1 -1
  8. data/CHANGELOG.md +92 -1
  9. data/README.md +51 -45
  10. data/docs/DSL.md +5 -5
  11. data/lib/potassium/assets/.circleci/config.yml.erb +151 -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/.rubocop.yml +528 -0
  15. data/lib/potassium/assets/.stylelintrc.json +46 -0
  16. data/lib/potassium/assets/Makefile.erb +21 -32
  17. data/lib/potassium/assets/README.yml +59 -15
  18. data/lib/potassium/assets/active_admin/admin-component.vue +35 -0
  19. data/lib/potassium/assets/active_admin/admin_application.js +14 -0
  20. data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +10 -0
  21. data/lib/potassium/assets/app/graphql/graphql_controller.rb +55 -0
  22. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +23 -0
  23. data/lib/potassium/assets/app/graphql/queries/base_query.rb +4 -0
  24. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +4 -0
  25. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +4 -0
  26. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +5 -0
  27. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +5 -0
  28. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +7 -0
  29. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +5 -0
  30. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +4 -0
  31. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +4 -0
  32. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +10 -0
  33. data/lib/potassium/assets/app/graphql/types/query_type.rb +13 -0
  34. data/lib/potassium/assets/app/javascript/app.spec.js +14 -0
  35. data/lib/potassium/assets/app/uploaders/base_uploader.rb +11 -0
  36. data/lib/potassium/assets/app/uploaders/image_uploader.rb +5 -0
  37. data/lib/potassium/assets/app/views/shared/_gtm_body.html.erb +4 -0
  38. data/lib/potassium/assets/app/views/shared/_gtm_head.html.erb +7 -0
  39. data/lib/potassium/assets/bin/release +1 -1
  40. data/lib/potassium/assets/bin/setup.erb +1 -1
  41. data/lib/potassium/assets/config/database_mysql.yml.erb +2 -2
  42. data/lib/potassium/assets/config/database_postgresql.yml.erb +2 -2
  43. data/lib/potassium/assets/config/graphql_playground.rb +20 -0
  44. data/lib/potassium/assets/config/puma.rb +1 -1
  45. data/lib/potassium/assets/config/shrine.rb +36 -0
  46. data/lib/potassium/assets/lib/tasks/auto_annotate_models.rake +2 -1
  47. data/lib/potassium/assets/package.json +4 -1
  48. data/lib/potassium/assets/redis.yml +1 -2
  49. data/lib/potassium/assets/testing/rails_helper.rb +2 -0
  50. data/lib/potassium/cli/commands/create.rb +12 -19
  51. data/lib/potassium/cli_options.rb +77 -26
  52. data/lib/potassium/helpers/gem-helpers.rb +1 -1
  53. data/lib/potassium/helpers/template-helpers.rb +8 -0
  54. data/lib/potassium/newest_version_ensurer.rb +19 -36
  55. data/lib/potassium/node_version_ensurer.rb +30 -0
  56. data/lib/potassium/recipes/admin.rb +3 -3
  57. data/lib/potassium/recipes/annotate.rb +1 -1
  58. data/lib/potassium/recipes/api.rb +93 -21
  59. data/lib/potassium/recipes/background_processor.rb +66 -19
  60. data/lib/potassium/recipes/ci.rb +10 -38
  61. data/lib/potassium/recipes/data_migrate.rb +44 -0
  62. data/lib/potassium/recipes/database.rb +4 -0
  63. data/lib/potassium/recipes/database_container.rb +7 -5
  64. data/lib/potassium/recipes/draper.rb +1 -10
  65. data/lib/potassium/recipes/file_storage.rb +66 -0
  66. data/lib/potassium/recipes/front_end.rb +225 -9
  67. data/lib/potassium/recipes/github.rb +93 -15
  68. data/lib/potassium/recipes/google_tag_manager.rb +90 -0
  69. data/lib/potassium/recipes/heroku.rb +42 -29
  70. data/lib/potassium/recipes/mailer.rb +18 -2
  71. data/lib/potassium/recipes/monitoring.rb +5 -0
  72. data/lib/potassium/recipes/node.rb +21 -0
  73. data/lib/potassium/recipes/rack_cors.rb +18 -15
  74. data/lib/potassium/recipes/schedule.rb +17 -2
  75. data/lib/potassium/recipes/style.rb +21 -3
  76. data/lib/potassium/recipes/vue_admin.rb +124 -0
  77. data/lib/potassium/templates/application.rb +10 -7
  78. data/lib/potassium/version.rb +7 -4
  79. data/potassium.gemspec +11 -6
  80. data/spec/features/api_spec.rb +25 -0
  81. data/spec/features/background_processor_spec.rb +19 -6
  82. data/spec/features/ci_spec.rb +7 -4
  83. data/spec/features/data_migrate_spec.rb +14 -0
  84. data/spec/features/database_container_spec.rb +1 -5
  85. data/spec/features/draper_spec.rb +1 -6
  86. data/spec/features/file_storage_spec.rb +75 -0
  87. data/spec/features/front_end_spec.rb +102 -0
  88. data/spec/features/github_spec.rb +53 -8
  89. data/spec/features/google_tag_manager_spec.rb +59 -0
  90. data/spec/features/graphql_spec.rb +71 -0
  91. data/spec/features/heroku_spec.rb +1 -1
  92. data/spec/features/mailer_spec.rb +16 -0
  93. data/spec/features/new_project_spec.rb +6 -14
  94. data/spec/features/node_spec.rb +28 -0
  95. data/spec/features/power_types_spec.rb +5 -16
  96. data/spec/features/schedule_spec.rb +11 -4
  97. data/spec/features/vue_admin_spec.rb +47 -0
  98. data/spec/spec_helper.rb +5 -0
  99. data/spec/support/fake_octokit.rb +31 -0
  100. data/spec/support/potassium_test_helpers.rb +26 -9
  101. data/tmp/.keep +0 -0
  102. metadata +152 -46
  103. data/lib/potassium/assets/.circleci/config.yml +0 -20
  104. data/lib/potassium/assets/Dockerfile.ci +0 -6
  105. data/lib/potassium/assets/active_admin/active_admin.js.coffee +0 -4
  106. data/lib/potassium/assets/active_admin/init_activeadmin_angular.rb +0 -8
  107. data/lib/potassium/assets/api/api_error_concern.rb +0 -32
  108. data/lib/potassium/assets/api/base_controller.rb +0 -9
  109. data/lib/potassium/assets/api/draper_responder.rb +0 -62
  110. data/lib/potassium/assets/api/responder.rb +0 -41
  111. data/lib/potassium/assets/aws.rb +0 -1
  112. data/lib/potassium/assets/bin/cibuild.erb +0 -100
  113. data/lib/potassium/assets/docker-compose.ci.yml +0 -11
  114. data/lib/potassium/assets/sidekiq_scheduler.yml +0 -9
  115. data/lib/potassium/assets/testing/paperclip.rb +0 -59
  116. data/lib/potassium/recipes/active_storage.rb +0 -40
  117. data/lib/potassium/recipes/angular_admin.rb +0 -56
  118. data/lib/potassium/recipes/aws_sdk.rb +0 -7
  119. data/lib/potassium/recipes/paperclip.rb +0 -47
  120. data/spec/features/active_storage_spec.rb +0 -30
  121. data/spec/features/front_end.rb +0 -30
@@ -1,20 +0,0 @@
1
- version: 2
2
- jobs:
3
- build:
4
- working_directory: ~/app
5
-
6
- docker:
7
- - image: platanus/compose:1.22.0
8
-
9
- steps:
10
- - checkout
11
- - setup_remote_docker
12
-
13
- - run: docker info
14
- - run: docker-compose -f docker-compose.ci.yml pull
15
- - run: docker-compose -f docker-compose.ci.yml build test
16
- - run: bin/cibuild services
17
- - run: bin/cibuild deps
18
-
19
- - run: bin/cibuild db
20
- - run: bin/cibuild tests
@@ -1,6 +0,0 @@
1
- FROM platanus/ruby:2.5
2
-
3
- RUN mkdir /app
4
- WORKDIR /app
5
-
6
- ADD . /app
@@ -1,4 +0,0 @@
1
- #= require active_admin/base
2
- #= require angular
3
- #= require admin_app
4
- #= require_tree ./admin
@@ -1,8 +0,0 @@
1
- class ActiveAdmin::Views::Pages::Base
2
- alias_method :old_add_classes_to_body, :add_classes_to_body
3
-
4
- def add_classes_to_body
5
- old_add_classes_to_body
6
- @body.set_attribute "ng-app", "ActiveAdmin"
7
- end
8
- end
@@ -1,32 +0,0 @@
1
- module ApiErrorConcern
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- rescue_from "Exception" do |exception|
6
- logger.error exception.message
7
- logger.error exception.backtrace.join("\n")
8
- respond_api_error(:internal_server_error, message: "server_error",
9
- type: exception.class.to_s,
10
- detail: exception.message)
11
- end
12
-
13
- rescue_from "ActiveRecord::RecordNotFound" do |exception|
14
- respond_api_error(:not_found, message: "record_not_found",
15
- detail: exception.message)
16
- end
17
-
18
- rescue_from "ActiveModel::ForbiddenAttributesError" do |exception|
19
- respond_api_error(:bad_request, message: "protected_attributes",
20
- detail: exception.message)
21
- end
22
-
23
- rescue_from "ActiveRecord::RecordInvalid" do |exception|
24
- respond_api_error(:bad_request, message: "invalid_attributes",
25
- errors: exception.record.errors)
26
- end
27
- end
28
-
29
- def respond_api_error(status, error = {})
30
- render json: error, status: status
31
- end
32
- end
@@ -1,9 +0,0 @@
1
- class Api::V1::BaseController < ApplicationController
2
- if Rails.env.production?
3
- include ApiErrorConcern
4
- end
5
-
6
- self.responder = ApiResponder
7
-
8
- respond_to :json
9
- end
@@ -1,62 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_options = infer_serializer(serializer_class).merge(options)
21
- serializer_class.new(decorated_resource, serializer_options)
22
- else
23
- decorated_resource
24
- end
25
- end
26
-
27
- def status_code
28
- return :created if post?
29
- :ok
30
- end
31
-
32
- def display_errors
33
- controller.render(
34
- status: :unprocessable_entity,
35
- json: { msg: "invalid_attributes", errors: format_errors }
36
- )
37
- end
38
-
39
- def format_errors
40
- resource.errors.as_json
41
- end
42
-
43
- def infer_serializer(serializer_class)
44
- if serializer_class == ActiveModel::ArraySerializer
45
- s = options.delete(:each_serializer) || "#{resource.klass}Serializer".constantize
46
- { each_serializer: s }
47
- else
48
- s = options.delete(:serializer) || "#{resource.class}Serializer".constantize
49
- { serializer: s }
50
- end
51
- end
52
-
53
- def decorated_resource
54
- if resource.respond_to?(:decorate)
55
- resource.decorate
56
- else
57
- resource
58
- end
59
- rescue Draper::UninferrableDecoratorError
60
- resource
61
- end
62
- end
@@ -1,41 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_class.new(resource, options)
21
- else
22
- resource
23
- end
24
- end
25
-
26
- def status_code
27
- return :created if post?
28
- :ok
29
- end
30
-
31
- def display_errors
32
- controller.render(
33
- status: :unprocessable_entity,
34
- json: { msg: "invalid_attributes", errors: format_errors }
35
- )
36
- end
37
-
38
- def format_errors
39
- resource.errors.as_json
40
- end
41
- end
@@ -1 +0,0 @@
1
- Aws::VERSION = Gem.loaded_specs["aws-sdk"].version
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env bash
2
- trap "exit" SIGINT SIGTERM
3
-
4
- command -v docker >/dev/null 2>&1 && docker info >/dev/null || {
5
- printf >&2 "\e[31mI require docker but it's not installed. Aborting.\e[0m\n"; exit 1;
6
- }
7
-
8
- DOCKER_COMPOSE_ARGS="-f docker-compose.ci.yml"
9
-
10
- # Build Image
11
- build(){
12
- docker-compose $DOCKER_COMPOSE_ARGS build test
13
- }
14
-
15
- # Wait services to be ready
16
- wait_services(){
17
- function test_service {
18
- docker-compose $DOCKER_COMPOSE_ARGS run test sh -c "nc -z $1 $2"
19
- }
20
-
21
- count=0
22
- # Chain tests together by using &&
23
- until (
24
- <% if(selected?(:database, :mysql) || selected?(:database, :postgresql))-%>
25
- test_service '$DB_HOST' '$DB_PORT' && \
26
- <% end-%>
27
- echo "Services ready"
28
- )
29
- do
30
- ((count++))
31
- if [ $count -gt 50 ]
32
- then
33
- echo "Services didn't become ready in time"
34
- exit 1
35
- else
36
- echo "Waiting for services to become ready..."
37
- fi
38
- sleep 0.5
39
- done
40
- }
41
-
42
- # Prepare dependencies
43
- dependencies(){
44
- docker-compose $DOCKER_COMPOSE_ARGS run test bundle install
45
- }
46
-
47
- assets() {
48
- docker-compose $DOCKER_COMPOSE_ARGS run test /bin/bash -c "bin/setup && bundle exec rake assets:precompile"
49
- }
50
-
51
- # Prepare database
52
- database(){
53
- docker-compose $DOCKER_COMPOSE_ARGS run test bundle exec rake db:create db:schema:load
54
- }
55
-
56
- # Run the specs
57
- tests(){
58
- [ -n "$CI" ] && {
59
- RSPEC_JUNIT_ARGS="-r rspec_junit_formatter --format RspecJunitFormatter -o $HOME/.rspec_reports/junit.xml"
60
- RSPEC_FORMAT_ARGS="--format progress --no-color"
61
- }
62
- docker-compose $DOCKER_COMPOSE_ARGS run test bundle exec rspec spec $RSPEC_FORMAT_ARGS $RSPEC_JUNIT_ARGS
63
- }
64
-
65
- # Run the complete ci build
66
- no_ci(){
67
- build
68
- wait_services
69
- dependencies
70
- assets
71
- database
72
- tests
73
- }
74
-
75
- case "$1" in
76
- "")
77
- no_ci
78
- ;;
79
- "services")
80
- wait_services
81
- ;;
82
- "deps"|"dependencies")
83
- dependencies
84
- ;;
85
- "assets")
86
- assets
87
- ;;
88
- "db"|"database")
89
- database
90
- ;;
91
- "specs"|"tests")
92
- tests
93
- ;;
94
- "build")
95
- build
96
- ;;
97
- *)
98
- echo "Usage: cibuild [services|deps|assets|db|specs|build]"
99
- ;;
100
- esac
@@ -1,11 +0,0 @@
1
- version: '3.4'
2
-
3
- services:
4
- test:
5
- build:
6
- context: "."
7
- dockerfile: Dockerfile.ci
8
- volumes:
9
- - "./vendor/bundle:/usr/local/bundle"
10
- environment:
11
- RACK_ENV: test
@@ -1,9 +0,0 @@
1
- production:
2
- :concurrency: 5
3
- :queues:
4
- - default
5
- :schedule:
6
- # an_scheduled_task:
7
- # cron: '0 * * * * *' # Runs once per minute
8
- # class: ExampleJob
9
- # args: ['a', 'b']
@@ -1,59 +0,0 @@
1
- require "paperclip/matchers"
2
-
3
- include ActionDispatch::TestProcess
4
-
5
- test_files_path = ":rails_root/test_files/:class/:attachment/:id_partition/:filename"
6
- Paperclip::Attachment.default_options[:path] = test_files_path
7
-
8
- RSpec.configure do |config|
9
- config.fixture_path = "#{::Rails.root}/spec/assets"
10
-
11
- config.include Paperclip::Shoulda::Matchers
12
-
13
- config.after(:suite) do
14
- FileUtils.rm_rf("#{Rails.root}/test_files")
15
- FileUtils.rm_rf("#{Rails.root}/public/uploads")
16
- end
17
- end
18
-
19
- def fixture_asset(file_name, mime)
20
- file_path = Rails.root.to_s + "/spec/assets/" + file_name
21
- fixture_file_upload(file_path, mime)
22
- rescue
23
- fixture_file_upload(file_name, mime)
24
- end
25
-
26
- # GENERAL CONFIG
27
- # On test environment, paperclip attachments will be generated under /test_files directory.
28
- # After running all the specs, the test_files folder will be deleted.
29
- #
30
- # SHOULDA MATCHERS
31
- # Including Paperclip::Shoulda::Matchers will allow you to use special matchers
32
- # to work with paperclip. For example:
33
- #
34
- # describe User do
35
- # it { should have_attached_file(:avatar) }
36
- # it { should validate_attachment_presence(:avatar) }
37
- # it { should validate_attachment_content_type(:avatar).
38
- # allowing('image/png', 'image/gif').
39
- # rejecting('text/plain', 'text/xml') }
40
- # it { should validate_attachment_size(:avatar).
41
- # less_than(2.megabytes) }
42
- # end
43
- #
44
- # ASSETS
45
- # Your attachments go into /spec/assets directory. You can access them...
46
- #
47
- # From your factories:
48
- #
49
- # FactoryBot.define do
50
- # factory :ticket do
51
- # attachment { fixture_asset("platanus.png", "image/png") }
52
- # end
53
- # end
54
- #
55
- # From your specs:
56
- #
57
- # it "gets file name" do
58
- # expect(fixture_asset("platanus.png", "image/png").original_filename).to eq("platanus.png")
59
- # end
@@ -1,40 +0,0 @@
1
- class Recipes::ActiveStorage < Rails::AppBuilder
2
- def ask
3
- active_storage = answer(:active_storage) do
4
- Ask.confirm("Do you want to use ActiveStorage for uploads?")
5
- end
6
-
7
- set(:active_storage, active_storage)
8
- end
9
-
10
- def create
11
- return unless selected?(:active_storage)
12
- add_active_storage
13
- end
14
-
15
- def install
16
- add_active_storage
17
- end
18
-
19
- def installed?
20
- file_exist?('config/storage.yml')
21
- end
22
-
23
- private
24
-
25
- def add_active_storage
26
- after(:gem_install) { run("bundle exec rails active_storage:install") }
27
-
28
- add_readme_section :internal_dependencies, :storage
29
-
30
- copy_file("../assets/config/storage.yml", "config/storage.yml", force: true)
31
-
32
- append_to_file '.env.development', "AWS_REGION=\n"
33
- append_to_file '.env.development', "S3_BUCKET=\n"
34
-
35
- raise_delivery_errors_regexp = /config.active_storage.service = :local\n/
36
- gsub_file 'config/environments/production.rb', raise_delivery_errors_regexp do
37
- "config.active_storage.service = :amazon"
38
- end
39
- end
40
- end
@@ -1,56 +0,0 @@
1
- class Recipes::AngularAdmin < Rails::AppBuilder
2
- def ask
3
- if selected?(:admin_mode)
4
- angular_admin = answer(:"angular-admin") do
5
- Ask.confirm "Do you want Angular support for ActiveAdmin?"
6
- end
7
- set(:angular_admin, angular_admin)
8
- end
9
- end
10
-
11
- def create
12
- recipe = self
13
- if selected?(:angular_admin)
14
- after(:admin_install) do
15
- recipe.add_angular_admin
16
- end
17
- end
18
- end
19
-
20
- def install
21
- active_admin = load_recipe(:admin)
22
- if active_admin.installed?
23
- add_angular_admin
24
- else
25
- info "ActiveAdmin can't be installed because Active Admin isn't installed."
26
- end
27
- end
28
-
29
- def installed?
30
- dir_exist?("app/assets/javascripts/admin")
31
- end
32
-
33
- def add_angular_admin
34
- copy_file '../assets/active_admin/init_activeadmin_angular.rb',
35
- 'config/initializers/init_activeadmin_angular.rb'
36
-
37
- create_file 'app/assets/javascripts/admin_app.js', "angular.module('ActiveAdmin', []);"
38
-
39
- copy_file '../assets/active_admin/active_admin.js.coffee',
40
- 'app/assets/javascripts/active_admin.js.coffee',
41
- force: true
42
-
43
- empty_directory 'app/assets/javascripts/admin'
44
- empty_directory 'app/assets/javascripts/admin/controllers'
45
- empty_directory 'app/assets/javascripts/admin/services'
46
- empty_directory 'app/assets/javascripts/admin/directives'
47
-
48
- create_file 'app/assets/javascripts/admin/controllers/.keep'
49
- create_file 'app/assets/javascripts/admin/services/.keep'
50
- create_file 'app/assets/javascripts/admin/directives/.keep'
51
-
52
- inside('.') do
53
- run('bin/yarn add angular --save')
54
- end
55
- end
56
- end