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
data/circle.yml DELETED
@@ -1,12 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.5.1
4
- services:
5
- - docker
6
- post:
7
- - "echo 'export rvm_install_on_use_flag=0' >> /home/ubuntu/.rvmrc"
8
-
9
- dependencies:
10
- override:
11
- - bundle install
12
- - gem install hound-cli
@@ -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,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,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
@@ -1,7 +0,0 @@
1
- class Recipes::AwsSdk < Rails::AppBuilder
2
- def create
3
- gather_gem('aws-sdk', '~> 3')
4
-
5
- template("../assets/aws.rb", "config/initializers/aws.rb", force: true)
6
- end
7
- end
@@ -1,47 +0,0 @@
1
- class Recipes::Paperclip < Rails::AppBuilder
2
- def ask
3
- paperclip = answer(:paperclip) { Ask.confirm("Do you want to use Paperclip for uploads?") }
4
- set(:paperclip, paperclip)
5
- end
6
-
7
- def create
8
- return unless selected?(:paperclip)
9
- add_paperclip
10
- config_rspec
11
- end
12
-
13
- def install
14
- add_paperclip
15
- config_rspec if gem_exists?(/rspec-rails/)
16
- end
17
-
18
- def installed?
19
- gem_exists?(/paperclip/)
20
- end
21
-
22
- private
23
-
24
- def add_paperclip
25
- gather_gem 'paperclip', '~> 5.0'
26
- paperclip_config =
27
- <<~RUBY
28
- config.paperclip_defaults = {
29
- storage: :s3,
30
- s3_protocol: 'https',
31
- s3_region: ENV.fetch('AWS_REGION', 'us-east-1'),
32
- s3_credentials: {
33
- bucket: ENV['S3_BUCKET']
34
- }
35
- }
36
- RUBY
37
- application paperclip_config, env: 'production'
38
- append_to_file '.env.development', "S3_BUCKET=\n"
39
- append_to_file '.gitignore', "/public/system/*\n"
40
- add_readme_section :internal_dependencies, :paperclip
41
- end
42
-
43
- def config_rspec
44
- copy_file '../assets/testing/platanus.png', 'spec/assets/platanus.png'
45
- copy_file '../assets/testing/paperclip.rb', 'spec/support/paperclip.rb'
46
- end
47
- end
@@ -1,30 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe "Active Storage" do
4
- before :all do
5
- drop_dummy_database
6
- remove_project_directory
7
- create_dummy_project("active_storage" => true)
8
- end
9
-
10
- it "customizes config file" do
11
- content = IO.read("#{project_path}/config/storage.yml")
12
- expect(content).to include("bucket: <%= ENV['S3_BUCKET'] %>")
13
- end
14
-
15
- it "adds brief to README file" do
16
- content = IO.read("#{project_path}/README.md")
17
- expect(content).to include("Active Storage")
18
- end
19
-
20
- it "uses amazon on production env" do
21
- content = IO.read("#{project_path}/config/environments/production.rb")
22
- expect(content).to include("config.active_storage.service = :amazon")
23
- end
24
-
25
- it "adds amazon ENV vars" do
26
- content = IO.read("#{project_path}/.env.development")
27
- expect(content).to include("AWS_REGION=")
28
- expect(content).to include("S3_BUCKET=")
29
- end
30
- end