potassium 6.0.0 → 6.1.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/CHANGELOG.md +19 -0
- data/README.md +41 -45
- data/lib/potassium/assets/.eslintrc.json +13 -4
- data/lib/potassium/assets/.github/pull_request_template.md +9 -0
- data/lib/potassium/assets/README.yml +6 -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/uploaders/base_uploader.rb +1 -3
- 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 +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 +11 -19
- data/lib/potassium/cli_options.rb +59 -7
- data/lib/potassium/newest_version_ensurer.rb +19 -36
- data/lib/potassium/node_version_ensurer.rb +30 -0
- data/lib/potassium/recipes/api.rb +91 -27
- data/lib/potassium/recipes/background_processor.rb +34 -1
- data/lib/potassium/recipes/database.rb +4 -0
- data/lib/potassium/recipes/draper.rb +0 -9
- data/lib/potassium/recipes/file_storage.rb +1 -0
- data/lib/potassium/recipes/front_end.rb +62 -0
- data/lib/potassium/recipes/github.rb +93 -15
- data/lib/potassium/version.rb +1 -1
- data/potassium.gemspec +2 -1
- data/spec/features/api_spec.rb +25 -0
- data/spec/features/background_processor_spec.rb +12 -1
- data/spec/features/draper_spec.rb +1 -6
- data/spec/features/file_storage_spec.rb +5 -0
- data/spec/features/front_end_spec.rb +14 -0
- data/spec/features/github_spec.rb +53 -8
- data/spec/features/graphql_spec.rb +71 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/fake_octokit.rb +31 -0
- metadata +40 -8
- data/lib/potassium/assets/api/api_error_concern.rb +0 -32
- data/lib/potassium/assets/api/base_controller.rb +0 -7
- data/lib/potassium/assets/api/draper_responder.rb +0 -62
- data/lib/potassium/assets/api/responder.rb +0 -41
@@ -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
|
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+
|
@@ -24,7 +24,10 @@ elsif Rails.env.production?
|
|
24
24
|
else
|
25
25
|
require 'shrine/storage/memory'
|
26
26
|
|
27
|
-
Shrine.storages
|
27
|
+
Shrine.storages = {
|
28
|
+
cache: Shrine::Storage::Memory.new,
|
29
|
+
store: Shrine::Storage::Memory.new
|
30
|
+
}
|
28
31
|
end
|
29
32
|
|
30
33
|
Shrine.plugin :activerecord
|
@@ -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,37 +3,29 @@ require 'potassium/cli_options'
|
|
3
3
|
module Potassium::CLI
|
4
4
|
extend Potassium::CliOptions
|
5
5
|
|
6
|
-
desc
|
6
|
+
desc 'Create a new Potassium Rails project.'
|
7
7
|
arg 'app_path'
|
8
8
|
command :create do |c|
|
9
|
-
c.default_desc
|
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
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
28
25
|
ARGV.push('--skip-webpack-install', '--skip-bundle')
|
29
26
|
template.start
|
30
|
-
|
31
|
-
|
32
|
-
if options["version-check"]
|
33
|
-
ensurer = Potassium::NewestVersionEnsurer.new
|
34
|
-
ensurer.ensure(&begin_creation)
|
35
|
-
else
|
36
|
-
begin_creation.call
|
27
|
+
rescue VersionError => e
|
28
|
+
print "\nError: #{e.message}" # rubocop:disable Rails/Output
|
37
29
|
end
|
38
30
|
end
|
39
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],
|
@@ -59,12 +75,11 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
59
75
|
default_test_value: false
|
60
76
|
},
|
61
77
|
{
|
62
|
-
type: :
|
78
|
+
type: :flag,
|
63
79
|
name: "api",
|
64
|
-
desc: "
|
65
|
-
negatable: true,
|
80
|
+
desc: "Which API interface to use",
|
66
81
|
default_value: "none",
|
67
|
-
default_test_value:
|
82
|
+
default_test_value: "None"
|
68
83
|
},
|
69
84
|
{
|
70
85
|
type: :flag,
|
@@ -105,12 +120,41 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
105
120
|
},
|
106
121
|
{
|
107
122
|
type: :switch,
|
108
|
-
name: "
|
109
|
-
desc: "Whether
|
123
|
+
name: "github_private",
|
124
|
+
desc: "Whether the github repository is private or not",
|
110
125
|
negatable: true,
|
111
|
-
default_value:
|
126
|
+
default_value: "none",
|
127
|
+
default_test_value: false
|
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",
|
112
135
|
default_test_value: false
|
113
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
|
+
},
|
114
158
|
{
|
115
159
|
type: :switch,
|
116
160
|
name: "schedule",
|
@@ -132,6 +176,14 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
|
|
132
176
|
name: :front_end,
|
133
177
|
desc: "Decides which front-end framework to use. Available: Vue, Angular 2, None",
|
134
178
|
default_test_value: "None"
|
179
|
+
},
|
180
|
+
{
|
181
|
+
type: :switch,
|
182
|
+
name: "test",
|
183
|
+
desc: "Whether or not it is a test project creation",
|
184
|
+
negatable: true,
|
185
|
+
default_value: false,
|
186
|
+
default_test_value: true
|
135
187
|
}
|
136
188
|
]
|
137
189
|
|
@@ -1,51 +1,34 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
1
|
+
require 'gems'
|
2
|
+
require 'semantic'
|
3
|
+
require 'potassium/text_spinner'
|
4
|
+
|
5
|
+
class VersionError < StandardError
|
6
|
+
end
|
5
7
|
|
6
8
|
module Potassium
|
7
9
|
class NewestVersionEnsurer
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(current_version = Potassium::VERSION)
|
11
|
-
self.current_version = Semantic::Version.new(current_version)
|
10
|
+
def initialize
|
11
|
+
self.installed_version = Semantic::Version.new(Potassium::VERSION)
|
12
12
|
self.text_spinner = Potassium::TextSpinner.new
|
13
13
|
end
|
14
14
|
|
15
|
-
def ensure
|
16
|
-
spin_text(
|
15
|
+
def ensure!
|
16
|
+
spin_text('Checking your Potassium installation') { published_version }
|
17
17
|
|
18
|
-
self.
|
19
|
-
|
20
|
-
)
|
21
|
-
|
22
|
-
if latest_version <= current_version
|
23
|
-
up_to_date
|
24
|
-
success_block.call
|
25
|
-
else
|
26
|
-
please_update
|
27
|
-
end
|
18
|
+
self.published_version = Semantic::Version.new(Gems.versions('potassium').first['number'])
|
19
|
+
raise VersionError.new(update_message) if published_version > installed_version
|
28
20
|
end
|
29
21
|
|
30
22
|
private
|
31
23
|
|
32
|
-
attr_accessor :
|
33
|
-
|
34
|
-
def up_to_date
|
35
|
-
puts green("\nYour Potassium installation is up to date.")
|
36
|
-
end
|
24
|
+
attr_accessor :published_version, :installed_version, :text_spinner
|
37
25
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
print white("to upgrade your potassium installation.\n\n")
|
45
|
-
print white("If you really need to run this outdated version of potassium anyway, ")
|
46
|
-
print white("re-run this command with the ")
|
47
|
-
print black("--no-version-check")
|
48
|
-
puts white(" flag.")
|
26
|
+
def update_message
|
27
|
+
<<~HERE
|
28
|
+
Your potassium installation is not up to date.
|
29
|
+
The last available version is #{published_version} while the running version is #{installed_version}.
|
30
|
+
If you really need to run this outdated version of potassium, re-run this command with the `--no-version-check` flag.
|
31
|
+
HERE
|
49
32
|
end
|
50
33
|
|
51
34
|
def spin_text(message, &block)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Potassium
|
2
|
+
class NodeVersionEnsurer
|
3
|
+
def ensure!
|
4
|
+
raise VersionError.new(install_message) if installed_node_version.nil?
|
5
|
+
raise VersionError.new(update_message) if Potassium::NODE_VERSION != installed_node_version
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def installed_node_version
|
11
|
+
node_version = `node -v 2>&1`
|
12
|
+
return node_version.delete('^[0-9\.]').split('.').first if $?.success?
|
13
|
+
end
|
14
|
+
|
15
|
+
def install_message
|
16
|
+
<<~HERE
|
17
|
+
Node doesn't appear to be installed.
|
18
|
+
Please make sure you have node #{Potassium::NODE_VERSION} installed.
|
19
|
+
HERE
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_message
|
23
|
+
<<~HERE
|
24
|
+
An unsupported version of node was found.
|
25
|
+
Please make sure you have node #{Potassium::NODE_VERSION} installed. Newer versions may work but potassium only supports that one.
|
26
|
+
If you really need to run potassium with a different version of node, re-run this command with the `--no-node-version-check` flag.
|
27
|
+
HERE
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,51 +1,115 @@
|
|
1
1
|
class Recipes::Api < Rails::AppBuilder
|
2
2
|
def ask
|
3
|
-
|
4
|
-
|
3
|
+
api_interfaces = {
|
4
|
+
rest: "REST (with Power API)",
|
5
|
+
graphql: "GraphQL (beta)",
|
6
|
+
none: "None, thanks"
|
7
|
+
}
|
8
|
+
api_interface = answer(:api) do
|
9
|
+
api_interfaces.keys[Ask.list("Which API interface are you using?", api_interfaces.values)]
|
10
|
+
end
|
11
|
+
set :api, api_interface.to_sym
|
5
12
|
end
|
6
13
|
|
7
14
|
def create
|
8
|
-
|
15
|
+
if get(:api) == :graphql
|
16
|
+
add_graphql
|
17
|
+
elsif get(:api) == :rest
|
18
|
+
add_power_api
|
19
|
+
end
|
9
20
|
end
|
10
21
|
|
11
22
|
def install
|
12
|
-
|
23
|
+
ask
|
24
|
+
create
|
13
25
|
end
|
14
26
|
|
15
27
|
def installed?
|
16
|
-
gem_exists?(/
|
28
|
+
gem_exists?(/power_api/) || gem_exists?(/graphql/)
|
17
29
|
end
|
18
30
|
|
19
31
|
private
|
20
32
|
|
21
|
-
def
|
22
|
-
gather_gem '
|
23
|
-
|
24
|
-
|
25
|
-
|
33
|
+
def add_power_api
|
34
|
+
gather_gem 'power_api'
|
35
|
+
|
36
|
+
gather_gems(:development, :test) do
|
37
|
+
gather_gem 'rswag-specs'
|
38
|
+
end
|
39
|
+
|
40
|
+
add_readme_section :internal_dependencies, :power_api
|
26
41
|
|
27
42
|
after(:gem_install) do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
scope path: '/api' do
|
32
|
-
api_version(module: "Api::V1", path: { value: "v1" }, defaults: { format: 'json' }) do
|
33
|
-
end
|
34
|
-
end
|
35
|
-
HERE
|
36
|
-
end
|
43
|
+
generate "power_api:install"
|
44
|
+
end
|
45
|
+
end
|
37
46
|
|
38
|
-
|
47
|
+
def add_graphql
|
48
|
+
gather_gem 'graphql'
|
49
|
+
if get(:authentication)
|
50
|
+
gather_gem 'jwt'
|
51
|
+
end
|
52
|
+
gather_gems(:development, :test) do
|
53
|
+
gather_gem 'graphql_playground-rails'
|
54
|
+
end
|
39
55
|
|
40
|
-
|
41
|
-
|
42
|
-
|
56
|
+
after(:gem_install) do
|
57
|
+
generate "graphql:install --skip_graphiql"
|
58
|
+
playground_route = <<~HEREDOC
|
59
|
+
\n
|
60
|
+
if Rails.env.development?
|
61
|
+
mount GraphqlPlayground::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"
|
62
|
+
end
|
63
|
+
HEREDOC
|
64
|
+
inject_into_file(
|
65
|
+
'config/routes.rb',
|
66
|
+
playground_route,
|
67
|
+
after: 'post "/graphql", to: "graphql#execute"'
|
68
|
+
)
|
69
|
+
copy_file(
|
70
|
+
"../assets/config/graphql_playground.rb",
|
71
|
+
"config/initializers/graphql_playground.rb"
|
72
|
+
)
|
73
|
+
remove_dir 'app/graphql/types'
|
74
|
+
directory '../assets/app/graphql/types', 'app/graphql/types'
|
75
|
+
gsub_file 'app/graphql/mutations/base_mutation.rb', 'Types::Base', 'Types::Base::Base'
|
76
|
+
directory '../assets/app/graphql/queries', 'app/graphql/queries'
|
77
|
+
gsub_file 'app/graphql/mutations/base_mutation.rb', 'RelayClassic', ''
|
78
|
+
gsub_file(
|
79
|
+
'app/graphql/mutations/base_mutation.rb',
|
80
|
+
" input_object_class Types::Base::BaseInputObject\n", ''
|
81
|
+
)
|
43
82
|
|
44
|
-
if
|
45
|
-
|
46
|
-
|
47
|
-
|
83
|
+
if get(:authentication)
|
84
|
+
copy_file(
|
85
|
+
'../assets/app/graphql/graphql_controller.rb',
|
86
|
+
'app/controllers/graphql_controller.rb',
|
87
|
+
force: true
|
88
|
+
)
|
89
|
+
gsub_file(
|
90
|
+
'app/controllers/graphql_controller.rb',
|
91
|
+
'GqlSampleSchema',
|
92
|
+
"#{get(:titleized_app_name).delete(' ')}Schema"
|
93
|
+
)
|
94
|
+
copy_file(
|
95
|
+
'../assets/app/graphql/mutations/login_mutation.rb',
|
96
|
+
'app/graphql/mutations/login_mutation.rb'
|
97
|
+
)
|
98
|
+
inject_into_file(
|
99
|
+
'app/graphql/types/mutation_type.rb',
|
100
|
+
"\n field :login, mutation: Mutations::LoginMutation",
|
101
|
+
after: 'class MutationType < Types::Base::BaseObject'
|
102
|
+
)
|
103
|
+
append_to_file(".env.development", "HMAC_SECRET=\n")
|
48
104
|
end
|
105
|
+
|
106
|
+
inject_into_file(
|
107
|
+
'app/controllers/graphql_controller.rb',
|
108
|
+
"\n\n skip_before_action :verify_authenticity_token",
|
109
|
+
after: '# protect_from_forgery with: :null_session'
|
110
|
+
)
|
111
|
+
|
112
|
+
add_readme_section :internal_dependencies, :graphql
|
49
113
|
end
|
50
114
|
end
|
51
115
|
end
|
@@ -12,7 +12,11 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def create
|
15
|
-
|
15
|
+
if get(:background_processor)
|
16
|
+
add_sidekiq
|
17
|
+
add_docker_compose_redis_config
|
18
|
+
set_redis_dot_env
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def install
|
@@ -26,6 +30,35 @@ class Recipes::BackgroundProcessor < Rails::AppBuilder
|
|
26
30
|
gem_exists?(/sidekiq/)
|
27
31
|
end
|
28
32
|
|
33
|
+
private
|
34
|
+
|
35
|
+
def add_docker_compose_redis_config
|
36
|
+
compose = DockerHelpers.new('docker-compose.yml')
|
37
|
+
|
38
|
+
service_definition =
|
39
|
+
<<~YAML
|
40
|
+
image: redis
|
41
|
+
ports:
|
42
|
+
- 6379
|
43
|
+
volumes:
|
44
|
+
- redis_data:/data
|
45
|
+
YAML
|
46
|
+
|
47
|
+
compose.add_service('redis', service_definition)
|
48
|
+
compose.add_volume('redis_data')
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_redis_dot_env
|
52
|
+
append_to_file(
|
53
|
+
'.env.development',
|
54
|
+
<<~TEXT
|
55
|
+
REDIS_HOST=127.0.0.1
|
56
|
+
REDIS_PORT=$(make services-port SERVICE=redis PORT=6379)
|
57
|
+
REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT}/1
|
58
|
+
TEXT
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
29
62
|
def add_sidekiq
|
30
63
|
gather_gem("sidekiq")
|
31
64
|
add_adapters("sidekiq")
|