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
@@ -0,0 +1,14 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import App from 'app';
3
+
4
+ describe('App', () => {
5
+ test('is a Vue instance', () => {
6
+ const wrapper = shallowMount(App);
7
+ expect(wrapper.isVueInstance()).toBeTruthy();
8
+ });
9
+
10
+ it('displays message on load', () => {
11
+ const wrapper = shallowMount(App);
12
+ expect(wrapper.find('p').text()).toEqual('Hello Vue!');
13
+ });
14
+ });
@@ -0,0 +1,11 @@
1
+ class BaseUploader < Shrine
2
+ plugin :validation_helpers
3
+
4
+ Attacher.validate do
5
+ validate_mime_type store.allowed_types
6
+ end
7
+
8
+ def allowed_types
9
+ raise NotImplementedError
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class ImageUploader < BaseUploader
2
+ def allowed_types
3
+ @allowed_types ||= %w[image/jpeg image/jpg image/png image/svg+xml image/gif].freeze
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ <!-- Google Tag Manager (noscript) -->
2
+ <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%= ENV['GTM_CONTAINER_ID'] %>"
3
+ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
4
+ <!-- End Google Tag Manager (noscript) -->
@@ -0,0 +1,7 @@
1
+ <!-- Google Tag Manager -->
2
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
3
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
4
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
5
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
6
+ })(window,document,'script','dataLayer','<%=ENV['GTM_CONTAINER_ID']%>');</script>
7
+ <!-- End Google Tag Manager -->
@@ -4,6 +4,6 @@ set -e
4
4
 
5
5
  echo 'Release Phase...'
6
6
 
7
- bundle exec rails db:migrate
7
+ bundle exec rails db:migrate:with_data
8
8
 
9
9
  echo 'Release Phase: OK'
@@ -14,7 +14,7 @@ bundle check || bundle install
14
14
  bin/yarn install
15
15
 
16
16
  # Set up required services
17
- make services-up
17
+ docker-compose up -d
18
18
 
19
19
  # Set up database
20
20
  bin/rails db:setup
@@ -1,6 +1,6 @@
1
1
  development: &default
2
2
  adapter: mysql2
3
- database: <%= get(:underscorized_app_name) %>_development
3
+ database: <%= get(:dasherized_app_name) %>_development
4
4
  encoding: utf8
5
5
  host: <%%= ENV["DB_HOST"] || "127.0.0.1" %>
6
6
  port: <%%= ENV["DB_PORT"] || 3306 %>
@@ -12,7 +12,7 @@ development: &default
12
12
 
13
13
  test:
14
14
  <<: *default
15
- database: <%= get(:underscorized_app_name) %>_test
15
+ database: <%= get(:dasherized_app_name) %>_test
16
16
 
17
17
  production: &deploy
18
18
  encoding: utf8
@@ -1,6 +1,6 @@
1
1
  development: &default
2
2
  adapter: postgresql
3
- database: <%= get(:underscorized_app_name) %>_development
3
+ database: <%= get(:dasherized_app_name) %>_development
4
4
  encoding: utf8
5
5
  host: <%%= ENV["DB_HOST"] || "127.0.0.1" %>
6
6
  port: <%%= ENV["DB_PORT"] || 5432 %>
@@ -12,7 +12,7 @@ development: &default
12
12
 
13
13
  test:
14
14
  <<: *default
15
- database: <%= get(:underscorized_app_name) %>_test
15
+ database: <%= get(:dasherized_app_name) %>_test
16
16
 
17
17
  production: &deploy
18
18
  encoding: utf8
@@ -0,0 +1,20 @@
1
+ # config/initializers/graphql_playground.rb
2
+ # All config options have a default that should work out of the box
3
+ if Rails.env.development?
4
+ GraphqlPlayground::Rails.configure do |config|
5
+ # config.headers = {
6
+ # 'X-Auth-Header' => ->(view_context) { "123" }
7
+ # }
8
+ # config.title = "Playground"
9
+ # config.csrf = true
10
+ # config.playground_version = "latest"
11
+ # # Ideally the assets would be added to your projects `vendor/assets` directories
12
+ # config.favicon = "/assets/playground.ico"
13
+ # config.playground_js_url = "/assets/playground.js"
14
+ # config.playground_css_url = "/assets/playground.css"
15
+ # # see: https://github.com/prisma-labs/graphql-playground#settings
16
+ config.settings = {
17
+ "schema.polling.enable": false
18
+ }
19
+ end
20
+ end
@@ -24,7 +24,7 @@ rack_env = ENV.fetch("RACK_ENV", "development")
24
24
  environment rack_env
25
25
 
26
26
  # Set 1 day timeout for workers while developing
27
- worker_timeout 1.day.seconds.to_i if rack_env == "development"
27
+ worker_timeout 24 * 60 * 60 if rack_env == "development"
28
28
 
29
29
  on_worker_boot do
30
30
  # Worker specific setup for Rails 4.1+
@@ -0,0 +1,36 @@
1
+ require 'shrine'
2
+
3
+ if Rails.env.development?
4
+ require 'shrine/storage/file_system'
5
+
6
+ Shrine.storages = {
7
+ cache: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
8
+ store: Shrine::Storage::FileSystem.new('public', prefix: 'uploads')
9
+ }
10
+ elsif Rails.env.production?
11
+ require 'shrine/storage/s3'
12
+
13
+ s3_options = {
14
+ bucket: ENV.fetch('S3_BUCKET'),
15
+ region: ENV.fetch('AWS_REGION'),
16
+ access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
17
+ secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')
18
+ }
19
+
20
+ Shrine.storages = {
21
+ cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
22
+ store: Shrine::Storage::S3.new(**s3_options)
23
+ }
24
+ else
25
+ require 'shrine/storage/memory'
26
+
27
+ Shrine.storages = {
28
+ cache: Shrine::Storage::Memory.new,
29
+ store: Shrine::Storage::Memory.new
30
+ }
31
+ end
32
+
33
+ Shrine.plugin :activerecord
34
+ Shrine.plugin :cached_attachment_data
35
+ Shrine.plugin :restore_cached_data
36
+ Shrine.plugin :determine_mime_type, analyzer: :marcel
@@ -36,7 +36,8 @@ if Rails.env.development?
36
36
  'force' => 'false',
37
37
  'trace' => 'false',
38
38
  'wrapper_open' => nil,
39
- 'wrapper_close' => nil
39
+ 'wrapper_close' => nil,
40
+ 'models' => true
40
41
  )
41
42
  end
42
43
 
@@ -1,3 +1,6 @@
1
1
  {
2
- "name": "<%= @app_name.camelcase %>"
2
+ "name": "<%= @app_name.camelcase %>",
3
+ "engines": {
4
+ "node": "<%= get(:node_version) %>"
5
+ }
3
6
  }
@@ -1,6 +1,5 @@
1
1
  development: &default
2
- host: <%= ENV["BOXEN_REDIS_HOST"] || ENV["REDIS_HOST"] || "127.0.0.1" %>
3
- port: <%= ENV["BOXEN_REDIS_PORT"] || ENV["REDIS_PORT"] || 6379 %>
2
+ url: <%= ENV.fetch("REDIS_URL") %>
4
3
 
5
4
  test:
6
5
  <<: *default
@@ -26,6 +26,8 @@ Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
26
26
  # If you are not using ActiveRecord, you can remove this line.
27
27
  ActiveRecord::Migration.maintain_test_schema!
28
28
 
29
+ PowerTypes::Observable.observable_disabled = true
30
+
29
31
  RSpec.configure do |config|
30
32
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
31
33
  # examples within a transaction, remove the following line or assign false
@@ -3,36 +3,29 @@ require 'potassium/cli_options'
3
3
  module Potassium::CLI
4
4
  extend Potassium::CliOptions
5
5
 
6
- desc "Create a new Potassium Rails project."
6
+ desc 'Create a new Potassium Rails project.'
7
7
  arg 'app_path'
8
8
  command :create do |c|
9
- c.default_desc "Create a new project."
10
- c.switch "version-check",
11
- default_value: true,
12
- desc: "Performs a version check before running.",
13
- negatable: true
14
-
9
+ c.default_desc 'Create a new project.'
15
10
  create_options.each { |opts| c.send(opts.delete(:type), opts.delete(:name), opts) }
16
11
 
17
12
  c.action do |_global_options, options, _args|
18
- require "potassium/newest_version_ensurer"
19
-
20
- begin_creation = -> do
21
- require "potassium/generators/application"
22
- require "potassium/template_finder"
13
+ require 'potassium/newest_version_ensurer'
14
+ require 'potassium/node_version_ensurer'
15
+ require 'potassium/generators/application'
16
+ require 'potassium/template_finder'
23
17
 
18
+ begin
19
+ Potassium::NewestVersionEnsurer.new.ensure! if options['version-check']
20
+ Potassium::NodeVersionEnsurer.new.ensure! if options['node-version-check']
24
21
  template_finder = Potassium::TemplateFinder.new
25
22
  template = template_finder.default_template
26
23
  template.cli_options = options
27
24
  template.source_paths << Rails::Generators::AppGenerator.source_root
25
+ ARGV.push('--skip-webpack-install', '--skip-bundle')
28
26
  template.start
29
- end
30
-
31
- if options["version-check"]
32
- ensurer = Potassium::NewestVersionEnsurer.new
33
- ensurer.ensure(&begin_creation)
34
- else
35
- begin_creation.call
27
+ rescue VersionError => e
28
+ print "\nError: #{e.message}" # rubocop:disable Rails/Output
36
29
  end
37
30
  end
38
31
  end
@@ -1,5 +1,21 @@
1
1
  module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
2
2
  CREATE_OPTIONS = [
3
+ {
4
+ type: :switch,
5
+ name: 'version-check',
6
+ desc: 'Performs a version check before running.',
7
+ negatable: true,
8
+ default_value: true,
9
+ default_test_value: true
10
+ },
11
+ {
12
+ type: :switch,
13
+ name: 'node-version-check',
14
+ desc: 'Performs a node version check before running.',
15
+ negatable: true,
16
+ default_value: true,
17
+ default_test_value: true
18
+ },
3
19
  {
4
20
  type: :flag,
5
21
  name: [:db, :database],
@@ -16,7 +32,7 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
16
32
  type: :flag,
17
33
  name: [:email_service, :email],
18
34
  desc: "Decides which email adapter to use. Available: aws_ses, sendgrid, none",
19
- default_test_value: "aws_ses"
35
+ default_test_value: "None"
20
36
  },
21
37
  {
22
38
  type: :switch,
@@ -44,8 +60,8 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
44
60
  },
45
61
  {
46
62
  type: :switch,
47
- name: "angular-admin",
48
- desc: "Whether to use Angular within ActiveAdmin or not",
63
+ name: :vue_admin,
64
+ desc: "Whether to use Vue within ActiveAdmin or not",
49
65
  negatable: true,
50
66
  default_value: "none",
51
67
  default_test_value: false
@@ -59,28 +75,18 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
59
75
  default_test_value: false
60
76
  },
61
77
  {
62
- type: :switch,
78
+ type: :flag,
63
79
  name: "api",
64
- desc: "Whether to apply the API mode or not",
65
- negatable: true,
80
+ desc: "Which API interface to use",
66
81
  default_value: "none",
67
- default_test_value: false
68
- },
69
- {
70
- type: :switch,
71
- name: "paperclip",
72
- desc: "Whether to include Paperclip as dependency",
73
- negatable: true,
74
- default_value: "none",
75
- default_test_value: false
82
+ default_test_value: "None"
76
83
  },
77
84
  {
78
- type: :switch,
79
- name: "active_storage",
80
- desc: "Whether to include Active Storage as dependency",
81
- negatable: true,
85
+ type: :flag,
86
+ name: "storage",
87
+ desc: "Decides which file storage to use. Available: active_storage, shrine, none",
82
88
  default_value: "none",
83
- default_test_value: false
89
+ default_test_value: "None"
84
90
  },
85
91
  {
86
92
  type: :switch,
@@ -91,10 +97,10 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
91
97
  default_test_value: false
92
98
  },
93
99
  {
94
- type: :flag,
100
+ type: :switch,
95
101
  name: "background_processor",
96
- desc: "Decides which background processor to use. Available: sidekiq, delayed_job, none",
97
- default_test_value: "sidekiq"
102
+ desc: "Whether to use Sidekiq for background processing or not",
103
+ default_test_value: false
98
104
  },
99
105
  {
100
106
  type: :switch,
@@ -114,12 +120,41 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
114
120
  },
115
121
  {
116
122
  type: :switch,
117
- name: "github-private",
118
- desc: "Whether to the github repository is private",
123
+ name: "github_private",
124
+ desc: "Whether the github repository is private or not",
119
125
  negatable: true,
120
- default_value: false,
126
+ default_value: "none",
121
127
  default_test_value: false
122
128
  },
129
+ {
130
+ type: :switch,
131
+ name: "github_has_org",
132
+ desc: "Whether the github repository should belong to an organization",
133
+ negatable: true,
134
+ default_value: "none",
135
+ default_test_value: false
136
+ },
137
+ {
138
+ type: :flag,
139
+ name: "github_org",
140
+ desc: "The github organization where the repository will be created",
141
+ default_value: "none",
142
+ default_test_value: "none"
143
+ },
144
+ {
145
+ type: :flag,
146
+ name: "github_name",
147
+ desc: "The github repository name",
148
+ default_value: "none",
149
+ default_test_value: "none"
150
+ },
151
+ {
152
+ type: :flag,
153
+ name: "github_access_token",
154
+ desc: "Github personal access token used to auth to Github API",
155
+ default_value: "none",
156
+ default_test_value: "none"
157
+ },
123
158
  {
124
159
  type: :switch,
125
160
  name: "schedule",
@@ -141,6 +176,22 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
141
176
  name: :front_end,
142
177
  desc: "Decides which front-end framework to use. Available: Vue, Angular 2, None",
143
178
  default_test_value: "None"
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
+ },
188
+ {
189
+ type: :switch,
190
+ name: "test",
191
+ desc: "Whether or not it is a test project creation",
192
+ negatable: true,
193
+ default_value: false,
194
+ default_test_value: true
144
195
  }
145
196
  ]
146
197
 
@@ -69,7 +69,7 @@ module GemHelpers
69
69
  def add_original_rails_gems
70
70
  gemfile_entries.each do |entry|
71
71
  unless entry.commented_out
72
- gather_gem(entry.name, entry.version)
72
+ gather_gem(entry.name, version: entry[:version])
73
73
  end
74
74
  end
75
75
  end
@@ -3,6 +3,14 @@ module TemplateHelpers
3
3
  @app_name || app_name_from_file
4
4
  end
5
5
 
6
+ def node_version
7
+ "#{Potassium::NODE_VERSION}.x"
8
+ end
9
+
10
+ def ruby_version
11
+ Semantic::Version.new(Potassium::RUBY_VERSION).instance_eval { "#{major}.#{minor}" }
12
+ end
13
+
6
14
  def load_recipe(recipe_name)
7
15
  @recipes ||= {}
8
16
  @recipes[recipe_name] ||= get_recipe_class(recipe_name.to_sym).new(self)