shopify-cli 1.0.4 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +1 -1
- data/.travis.yml +3 -2
- data/CHANGELOG.md +21 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -13
- data/bin/load_shopify.rb +3 -1
- data/bin/shopify +2 -0
- data/docs/Gemfile.lock +23 -13
- data/docs/getting-started/index.md +3 -2
- data/docs/getting-started/install/index.md +55 -9
- data/docs/getting-started/uninstall/index.md +1 -1
- data/docs/getting-started/upgrade/index.md +8 -4
- data/ext/shopify-cli/extconf.rb +40 -20
- data/lib/project_types/extension/cli.rb +1 -0
- data/lib/project_types/extension/features/argo_config.rb +60 -0
- data/lib/project_types/extension/messages/messages.rb +3 -0
- data/lib/project_types/extension/models/type.rb +1 -0
- data/lib/project_types/extension/models/types/checkout_post_purchase.rb +5 -2
- data/lib/project_types/extension/tasks/create_extension.rb +1 -1
- data/lib/project_types/extension/tasks/get_app.rb +1 -1
- data/lib/project_types/extension/tasks/update_draft.rb +1 -1
- data/lib/project_types/node/commands/create.rb +4 -4
- data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
- data/lib/project_types/node/commands/generate/billing.rb +7 -5
- data/lib/project_types/node/commands/generate/page.rb +9 -5
- data/lib/project_types/node/commands/generate/webhook.rb +5 -1
- data/lib/project_types/node/commands/serve.rb +5 -5
- data/lib/project_types/node/messages/messages.rb +5 -1
- data/lib/project_types/rails/commands/create.rb +56 -5
- data/lib/project_types/rails/commands/generate.rb +1 -0
- data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
- data/lib/project_types/rails/commands/serve.rb +11 -7
- data/lib/project_types/rails/gem.rb +61 -6
- data/lib/project_types/rails/messages/messages.rb +32 -12
- data/lib/project_types/script/commands/create.rb +1 -5
- data/lib/project_types/script/commands/disable.rb +1 -2
- data/lib/project_types/script/commands/enable.rb +5 -5
- data/lib/project_types/script/commands/push.rb +1 -6
- data/lib/project_types/script/config/extension_points.yml +4 -4
- data/lib/project_types/script/errors.rb +8 -0
- data/lib/project_types/script/forms/create.rb +1 -1
- data/lib/project_types/script/layers/domain/errors.rb +2 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +36 -1
- data/lib/project_types/script/layers/infrastructure/errors.rb +8 -0
- data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
- data/lib/project_types/script/messages/messages.rb +22 -48
- data/lib/project_types/script/ui/error_handler.rb +12 -0
- data/lib/rubygems_plugin.rb +18 -10
- data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
- data/lib/shopify-cli/command.rb +12 -6
- data/lib/shopify-cli/commands/connect.rb +7 -75
- data/lib/shopify-cli/commands/create.rb +1 -1
- data/lib/shopify-cli/commands/system.rb +21 -12
- data/lib/shopify-cli/context.rb +68 -0
- data/lib/shopify-cli/core/entry_point.rb +4 -1
- data/lib/shopify-cli/core/executor.rb +3 -5
- data/lib/shopify-cli/core/monorail.rb +1 -1
- data/lib/shopify-cli/db.rb +1 -1
- data/lib/shopify-cli/git.rb +1 -1
- data/lib/shopify-cli/heroku.rb +21 -5
- data/lib/shopify-cli/js_deps.rb +2 -2
- data/lib/shopify-cli/js_system.rb +2 -2
- data/lib/shopify-cli/messages/messages.rb +35 -25
- data/lib/shopify-cli/process_supervision.rb +60 -21
- data/lib/shopify-cli/project.rb +17 -9
- data/lib/shopify-cli/project_type.rb +3 -2
- data/lib/shopify-cli/sub_command.rb +1 -0
- data/lib/shopify-cli/task.rb +2 -2
- data/lib/shopify-cli/tasks.rb +11 -4
- data/lib/shopify-cli/tasks/ensure_env.rb +74 -17
- data/lib/shopify-cli/tunnel.rb +22 -7
- data/lib/shopify-cli/version.rb +1 -1
- data/lib/shopify_cli.rb +35 -9
- data/shopify-cli.gemspec +4 -1
- data/vendor/deps/cli-kit/REVISION +1 -1
- data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
- data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
- data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
- data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
- data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
- data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
- data/vendor/deps/cli-ui/REVISION +1 -1
- data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
- data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
- data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
- data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
- data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
- data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
- data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
- data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
- data/vendor/gen/lib/gen.rb +39 -0
- data/vendor/gen/lib/gen/commands.rb +18 -0
- data/vendor/gen/lib/gen/commands/help.rb +20 -0
- data/vendor/gen/lib/gen/commands/new.rb +21 -0
- data/vendor/gen/lib/gen/entry_point.rb +10 -0
- data/vendor/gen/lib/gen/generator.rb +165 -0
- data/vendor/gen/template/.gitignore +2 -0
- data/vendor/gen/template/Gemfile +10 -0
- data/vendor/gen/template/README.md +1 -0
- data/vendor/gen/template/bin/testunit +23 -0
- data/vendor/gen/template/bin/update-deps +97 -0
- data/vendor/gen/template/dev-gems.yml +3 -0
- data/vendor/gen/template/dev-vendor.yml +4 -0
- data/vendor/gen/template/exe/__app__-gems +17 -0
- data/vendor/gen/template/exe/__app__-vendor +18 -0
- data/vendor/gen/template/lib/__app__.rb +33 -0
- data/vendor/gen/template/lib/__app__/commands.rb +18 -0
- data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
- data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
- data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
- data/vendor/gen/template/test/example_test.rb +17 -0
- data/vendor/gen/template/test/test_helper.rb +22 -0
- metadata +26 -4
- data/Vagrantfile +0 -17
- data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -53,6 +53,7 @@ module Extension
|
|
53
53
|
autoload :ArgoSetupStep, Project.project_filepath('features/argo_setup_step')
|
54
54
|
autoload :ArgoSetupSteps, Project.project_filepath('features/argo_setup_steps')
|
55
55
|
autoload :ArgoDependencies, Project.project_filepath('features/argo_dependencies')
|
56
|
+
autoload :ArgoConfig, Project.project_filepath('features/argo_config')
|
56
57
|
end
|
57
58
|
|
58
59
|
module Models
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Extension
|
4
|
+
module Features
|
5
|
+
class ArgoConfig
|
6
|
+
CONFIG_FILE_NAME = 'extension.config.yml'
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def parse_yaml(context, permitted_keys = [])
|
10
|
+
file_name = File.join(context.root, CONFIG_FILE_NAME)
|
11
|
+
|
12
|
+
return {} unless File.size?(file_name)
|
13
|
+
|
14
|
+
require 'yaml' # takes 20ms, so deferred as late as possible.
|
15
|
+
begin
|
16
|
+
config = YAML.load_file(file_name)
|
17
|
+
|
18
|
+
# `YAML.load_file` returns nil if the file is not empty
|
19
|
+
# but does not contain any parsable yml data, e.g. only comments
|
20
|
+
# We consider this valid
|
21
|
+
return {} if config.nil?
|
22
|
+
|
23
|
+
unless config.is_a?(Hash)
|
24
|
+
raise ShopifyCli::Abort, ShopifyCli::Context.message('core.yaml.error.not_hash', CONFIG_FILE_NAME)
|
25
|
+
end
|
26
|
+
|
27
|
+
config.transform_keys!(&:to_sym)
|
28
|
+
assert_valid_config(config, permitted_keys) unless permitted_keys.empty?
|
29
|
+
|
30
|
+
config
|
31
|
+
rescue Psych::SyntaxError => e
|
32
|
+
raise(
|
33
|
+
ShopifyCli::Abort,
|
34
|
+
ShopifyCli::Context.message('core.yaml.error.invalid', CONFIG_FILE_NAME, e.message)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def assert_valid_config(config, permitted_keys)
|
42
|
+
unpermitted_keys = config.keys.select do |k|
|
43
|
+
!permitted_keys.include?(k)
|
44
|
+
end
|
45
|
+
|
46
|
+
unless unpermitted_keys.empty?
|
47
|
+
raise(
|
48
|
+
ShopifyCli::Abort,
|
49
|
+
ShopifyCli::Context.message(
|
50
|
+
'features.argo.config.unpermitted_keys',
|
51
|
+
CONFIG_FILE_NAME,
|
52
|
+
unpermitted_keys.map { |k| "\n- #{k}" }.join
|
53
|
+
)
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -6,13 +6,16 @@ module Extension
|
|
6
6
|
module Types
|
7
7
|
class CheckoutPostPurchase < Models::Type
|
8
8
|
IDENTIFIER = 'CHECKOUT_POST_PURCHASE'
|
9
|
-
|
9
|
+
PERMITTED_CONFIG_KEYS = [:metafields]
|
10
10
|
def create(directory_name, context)
|
11
11
|
Features::Argo.checkout.create(directory_name, IDENTIFIER, context)
|
12
12
|
end
|
13
13
|
|
14
14
|
def config(context)
|
15
|
-
|
15
|
+
{
|
16
|
+
**Features::ArgoConfig.parse_yaml(context, PERMITTED_CONFIG_KEYS),
|
17
|
+
**Features::Argo.checkout.config(context),
|
18
|
+
}
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
@@ -20,7 +20,7 @@ module Extension
|
|
20
20
|
extension_context: extension_context,
|
21
21
|
}
|
22
22
|
|
23
|
-
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, input).dig(*RESPONSE_FIELD)
|
23
|
+
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, **input).dig(*RESPONSE_FIELD)
|
24
24
|
context.abort(context.message('tasks.errors.parse_error')) if response.nil?
|
25
25
|
|
26
26
|
abort_if_user_errors(context, response)
|
@@ -12,7 +12,7 @@ module Extension
|
|
12
12
|
def call(context:, api_key:)
|
13
13
|
input = { api_key: api_key }
|
14
14
|
|
15
|
-
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, input).dig(*RESPONSE_FIELD)
|
15
|
+
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, **input).dig(*RESPONSE_FIELD)
|
16
16
|
context.abort(context.message('tasks.errors.parse_error')) if response.nil?
|
17
17
|
|
18
18
|
Converters::AppConverter.from_hash(response.dig(APP_FIELD))
|
@@ -18,7 +18,7 @@ module Extension
|
|
18
18
|
config: JSON.generate(config),
|
19
19
|
extension_context: extension_context,
|
20
20
|
}
|
21
|
-
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, input).dig(*RESPONSE_FIELD)
|
21
|
+
response = ShopifyCli::PartnersAPI.query(context, GRAPHQL_FILE, **input).dig(*RESPONSE_FIELD)
|
22
22
|
context.abort(context.message('tasks.errors.parse_error')) if response.nil?
|
23
23
|
|
24
24
|
abort_if_user_errors(context, response)
|
@@ -54,8 +54,8 @@ module Node
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def check_node
|
57
|
-
|
58
|
-
@ctx.abort(@ctx.message('node.create.error.node_required'))
|
57
|
+
cmd_path = @ctx.which('node')
|
58
|
+
@ctx.abort(@ctx.message('node.create.error.node_required')) if cmd_path.nil?
|
59
59
|
|
60
60
|
version, stat = @ctx.capture2e('node', '-v')
|
61
61
|
@ctx.abort(@ctx.message('node.create.error.node_version_failure')) unless stat.success?
|
@@ -64,8 +64,8 @@ module Node
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def check_npm
|
67
|
-
|
68
|
-
@ctx.abort(@ctx.message('node.create.error.npm_required'))
|
67
|
+
cmd_path = @ctx.which('npm')
|
68
|
+
@ctx.abort(@ctx.message('node.create.error.npm_required')) if cmd_path.nil?
|
69
69
|
|
70
70
|
version, stat = @ctx.capture2e('npm', '-v')
|
71
71
|
@ctx.abort(@ctx.message('node.create.error.npm_version_failure')) unless stat.success?
|
@@ -19,10 +19,15 @@ module Node
|
|
19
19
|
end
|
20
20
|
spin_group.wait
|
21
21
|
|
22
|
-
|
22
|
+
install_message = @ctx.message(
|
23
|
+
@ctx.windows? ? 'node.deploy.heroku.installing_windows' : 'node.deploy.heroku.installing'
|
24
|
+
)
|
25
|
+
spin_group.add(install_message) do |spinner|
|
23
26
|
heroku_service.install
|
24
27
|
spinner.update_title(@ctx.message('node.deploy.heroku.installed'))
|
25
28
|
end
|
29
|
+
spin_group.wait
|
30
|
+
|
26
31
|
spin_group.add(@ctx.message('node.deploy.heroku.git.checking')) do |spinner|
|
27
32
|
ShopifyCli::Git.init(@ctx)
|
28
33
|
spinner.update_title(@ctx.message('node.deploy.heroku.git.initialized'))
|
@@ -5,8 +5,8 @@ module Node
|
|
5
5
|
class Generate
|
6
6
|
class Billing < ShopifyCli::SubCommand
|
7
7
|
BILLING_TYPES = {
|
8
|
-
'recurring-billing' => './node_modules/.bin/generate-node-app recurring-billing',
|
9
|
-
'one-time-billing' => './node_modules/.bin/generate-node-app one-time-billing',
|
8
|
+
'recurring-billing' => ['./node_modules/.bin/generate-node-app', 'recurring-billing'],
|
9
|
+
'one-time-billing' => ['./node_modules/.bin/generate-node-app', 'one-time-billing'],
|
10
10
|
}
|
11
11
|
def call(args, _name)
|
12
12
|
selected_type = BILLING_TYPES[args[1]]
|
@@ -18,11 +18,13 @@ module Node
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
billing_type_name = BILLING_TYPES.key(selected_type)
|
21
|
+
selected_type[0] = File.join(ShopifyCli::Project.current.directory, selected_type[0])
|
22
|
+
selected_type[0] = "\"#{selected_type[0]}\""
|
23
|
+
selected_type = selected_type.join(' ')
|
24
|
+
|
21
25
|
spin_group = CLI::UI::SpinGroup.new
|
22
26
|
spin_group.add(@ctx.message('node.generate.billing.generating', billing_type_name)) do |spinner|
|
23
|
-
Node::Commands::Generate.run_generate(
|
24
|
-
selected_type, billing_type_name, @ctx
|
25
|
-
)
|
27
|
+
Node::Commands::Generate.run_generate(selected_type, billing_type_name, @ctx)
|
26
28
|
spinner.update_title(@ctx.message('node.generate.billing.generated', billing_type_name))
|
27
29
|
end
|
28
30
|
spin_group.wait
|
@@ -5,10 +5,10 @@ module Node
|
|
5
5
|
class Generate
|
6
6
|
class Page < ShopifyCli::SubCommand
|
7
7
|
PAGE_TYPES = {
|
8
|
-
'empty-state' => './node_modules/.bin/generate-node-app empty-state-page',
|
9
|
-
'two-column' => './node_modules/.bin/generate-node-app two-column-page',
|
10
|
-
'annotated' => './node_modules/.bin/generate-node-app settings-page',
|
11
|
-
'list' => './node_modules/.bin/generate-node-app list-page',
|
8
|
+
'empty-state' => ['./node_modules/.bin/generate-node-app', 'empty-state-page'],
|
9
|
+
'two-column' => ['./node_modules/.bin/generate-node-app', 'two-column-page'],
|
10
|
+
'annotated' => ['./node_modules/.bin/generate-node-app', 'settings-page'],
|
11
|
+
'list' => ['./node_modules/.bin/generate-node-app', 'list-page'],
|
12
12
|
}
|
13
13
|
|
14
14
|
options do |parser, flags|
|
@@ -37,9 +37,13 @@ module Node
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
+
page_type_name = PAGE_TYPES.key(selected_type)
|
41
|
+
selected_type[0] = File.join(ShopifyCli::Project.current.directory, selected_type[0])
|
42
|
+
selected_type[0] = "\"#{selected_type[0]}\""
|
43
|
+
selected_type = selected_type.join(' ')
|
40
44
|
|
41
45
|
spin_group = CLI::UI::SpinGroup.new
|
42
|
-
spin_group.add(@ctx.message('node.generate.page.generating',
|
46
|
+
spin_group.add(@ctx.message('node.generate.page.generating', page_type_name)) do |spinner|
|
43
47
|
Node::Commands::Generate.run_generate("#{selected_type} #{name}", name, @ctx)
|
44
48
|
spinner.update_title(@ctx.message('node.generate.page.generated', name, name))
|
45
49
|
end
|
@@ -15,9 +15,13 @@ module Node
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
generate_path = File.join(ShopifyCli::Project.current.directory, "node_modules/.bin/generate-node-app")
|
20
|
+
generate_path = "\"#{generate_path}\""
|
21
|
+
|
18
22
|
spin_group = CLI::UI::SpinGroup.new
|
19
23
|
spin_group.add(@ctx.message('node.generate.webhook.generating', selected_type)) do |spinner|
|
20
|
-
Node::Commands::Generate.run_generate("
|
24
|
+
Node::Commands::Generate.run_generate("#{generate_path} webhook #{selected_type}",
|
21
25
|
selected_type, @ctx)
|
22
26
|
spinner.update_title(@ctx.message('node.generate.webhook.generated', selected_type))
|
23
27
|
end
|
@@ -20,12 +20,12 @@ module Node
|
|
20
20
|
url: url,
|
21
21
|
callback_url: "/auth/callback",
|
22
22
|
)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
23
|
+
|
24
|
+
if project.env.shop
|
25
|
+
project_url = "#{project.env.host}/auth?shop=#{project.env.shop}"
|
26
|
+
@ctx.puts("\n" + @ctx.message('node.serve.open_info', project_url) + "\n")
|
28
27
|
end
|
28
|
+
|
29
29
|
CLI::UI::Frame.open(@ctx.message('node.serve.running_server')) do
|
30
30
|
env = project.env.to_h
|
31
31
|
env['PORT'] = ShopifyCli::Tunnel::PORT.to_s
|
@@ -54,6 +54,7 @@ module Node
|
|
54
54
|
downloading: "Downloading Heroku CLI…",
|
55
55
|
downloaded: "Downloaded Heroku CLI",
|
56
56
|
installing: "Installing Heroku CLI…",
|
57
|
+
installing_windows: "Running Heroku CLI install wizard…",
|
57
58
|
installed: "Installed Heroku CLI",
|
58
59
|
authenticating: "Authenticating with Heroku…",
|
59
60
|
authenticated: "{{v}} Authenticated with Heroku",
|
@@ -201,7 +202,10 @@ module Node
|
|
201
202
|
host_must_be_https: "HOST must be a HTTPS url.",
|
202
203
|
},
|
203
204
|
|
204
|
-
open_info:
|
205
|
+
open_info: <<~MESSAGE,
|
206
|
+
{{*}} To install and start using your app, open this URL in your browser:
|
207
|
+
{{green:%s}}
|
208
|
+
MESSAGE
|
205
209
|
running_server: "Running server...",
|
206
210
|
},
|
207
211
|
|
@@ -30,6 +30,9 @@ module Rails
|
|
30
30
|
@ctx.abort(@ctx.message('rails.create.error.invalid_ruby_version')) unless
|
31
31
|
Ruby.version(@ctx).satisfies?('~>2.5')
|
32
32
|
|
33
|
+
check_node
|
34
|
+
check_yarn
|
35
|
+
|
33
36
|
build(form.name, form.db)
|
34
37
|
set_custom_ua
|
35
38
|
ShopifyCli::Project.write(
|
@@ -65,12 +68,54 @@ module Rails
|
|
65
68
|
|
66
69
|
private
|
67
70
|
|
71
|
+
def check_node
|
72
|
+
cmd_path = @ctx.which('node')
|
73
|
+
if cmd_path.nil?
|
74
|
+
@ctx.abort(@ctx.message('rails.create.error.node_required')) unless @ctx.windows?
|
75
|
+
@ctx.puts("{{x}} {{red:" + @ctx.message('rails.create.error.node_required') + "}}")
|
76
|
+
@ctx.puts(@ctx.message('rails.create.info.open_new_shell', 'node'))
|
77
|
+
raise ShopifyCli::AbortSilent
|
78
|
+
end
|
79
|
+
|
80
|
+
version, stat = @ctx.capture2e('node', '-v')
|
81
|
+
unless stat.success?
|
82
|
+
@ctx.abort(@ctx.message('rails.create.error.node_version_failure')) unless @ctx.windows?
|
83
|
+
# execution stops above if not Windows
|
84
|
+
@ctx.puts("{{x}} {{red:" + @ctx.message('rails.create.error.node_version_failure') + "}}")
|
85
|
+
@ctx.puts(@ctx.message('rails.create.info.open_new_shell', 'node'))
|
86
|
+
raise ShopifyCli::AbortSilent
|
87
|
+
end
|
88
|
+
|
89
|
+
@ctx.done(@ctx.message('rails.create.node_version', version))
|
90
|
+
end
|
91
|
+
|
92
|
+
def check_yarn
|
93
|
+
cmd_path = @ctx.which('yarn')
|
94
|
+
if cmd_path.nil?
|
95
|
+
@ctx.abort(@ctx.message('rails.create.error.yarn_required')) unless @ctx.windows?
|
96
|
+
@ctx.puts("{{x}} {{red:" + @ctx.message('rails.create.error.yarn_required') + "}}")
|
97
|
+
@ctx.puts(@ctx.message('rails.create.info.open_new_shell', 'yarn'))
|
98
|
+
raise ShopifyCli::AbortSilent
|
99
|
+
end
|
100
|
+
|
101
|
+
version, stat = @ctx.capture2e('yarn', '-v')
|
102
|
+
unless stat.success?
|
103
|
+
@ctx.abort(@ctx.message('rails.create.error.yarn_version_failure')) unless @ctx.windows?
|
104
|
+
@ctx.puts("{{x}} {{red:" + @ctx.message('rails.create.error.yarn_version_failure') + "}}")
|
105
|
+
@ctx.puts(@ctx.message('rails.create.info.open_new_shell', 'yarn'))
|
106
|
+
raise ShopifyCli::AbortSilent
|
107
|
+
end
|
108
|
+
|
109
|
+
@ctx.done(@ctx.message('rails.create.yarn_version', version))
|
110
|
+
end
|
111
|
+
|
68
112
|
def build(name, db)
|
69
|
-
install_gem('rails')
|
70
|
-
|
71
|
-
install_gem('bundler', '~>1.0')
|
113
|
+
@ctx.abort(@ctx.message('rails.create.error.install_failure', 'rails')) unless install_gem('rails')
|
114
|
+
@ctx.abort(@ctx.message('rails.create.error.install_failure', 'bundler ~>2.0')) unless
|
72
115
|
install_gem('bundler', '~>2.0')
|
73
|
-
|
116
|
+
|
117
|
+
full_path = File.join(@ctx.root, name)
|
118
|
+
@ctx.abort(@ctx.message('rails.create.error.dir_exists', name)) if Dir.exist?(full_path)
|
74
119
|
|
75
120
|
CLI::UI::Frame.open(@ctx.message('rails.create.generating_app', name)) do
|
76
121
|
new_command = %w(rails new)
|
@@ -82,7 +127,7 @@ module Rails
|
|
82
127
|
syscall(new_command)
|
83
128
|
end
|
84
129
|
|
85
|
-
@ctx.root =
|
130
|
+
@ctx.root = full_path
|
86
131
|
|
87
132
|
File.open(File.join(@ctx.root, '.gitignore'), 'a') { |f| f.write('.env') }
|
88
133
|
|
@@ -106,6 +151,12 @@ module Rails
|
|
106
151
|
syscall(%w(rails db:create))
|
107
152
|
syscall(%w(rails db:migrate RAILS_ENV=development))
|
108
153
|
end
|
154
|
+
|
155
|
+
unless File.exist?(File.join(@ctx.root, 'config/webpacker.yml'))
|
156
|
+
CLI::UI::Frame.open(@ctx.message('rails.create.running_webpacker_install')) do
|
157
|
+
syscall(%w(rails webpacker:install))
|
158
|
+
end
|
159
|
+
end
|
109
160
|
end
|
110
161
|
|
111
162
|
def set_custom_ua
|
@@ -29,9 +29,10 @@ module Rails
|
|
29
29
|
|
30
30
|
def generate_command(selected_type)
|
31
31
|
parts = selected_type.downcase.split("_")
|
32
|
-
|
32
|
+
host = ShopifyCli::Project.current.env.host
|
33
33
|
selected_type = parts[0..-2].join("_") + "/" + parts[-1]
|
34
|
-
|
34
|
+
command = @ctx.windows? ? "ruby bin\\rails" : "bin/rails"
|
35
|
+
"#{command} g shopify_app:add_webhook -t #{selected_type} -a #{host}/webhooks/#{selected_type.downcase}"
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
@@ -20,18 +20,22 @@ module Rails
|
|
20
20
|
url: url,
|
21
21
|
callback_url: "/auth/shopify/callback",
|
22
22
|
)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
23
|
+
|
24
|
+
if project.env.shop
|
25
|
+
project_url = "#{project.env.host}/login?shop=#{project.env.shop}"
|
26
|
+
@ctx.puts("\n" + @ctx.message('rails.serve.open_info', project_url) + "\n")
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
CLI::UI::Frame.open(@ctx.message('rails.serve.running_server')) do
|
31
30
|
env = ShopifyCli::Project.current.env.to_h
|
32
31
|
env.delete('HOST')
|
33
32
|
env['PORT'] = ShopifyCli::Tunnel::PORT.to_s
|
34
|
-
|
33
|
+
env['GEM_PATH'] = Gem.gem_path(@ctx)
|
34
|
+
if @ctx.windows?
|
35
|
+
@ctx.system("ruby bin\\rails server", env: env)
|
36
|
+
else
|
37
|
+
@ctx.system('bin/rails server', env: env)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
@@ -15,30 +15,65 @@ module Rails
|
|
15
15
|
version = args.shift
|
16
16
|
gem = new(ctx: ctx, name: name, version: version)
|
17
17
|
ctx.debug(ctx.message('rails.gem.installed_debug', name, gem.installed?))
|
18
|
-
gem.
|
18
|
+
gem.installed? ? true : gem.install!
|
19
19
|
end
|
20
20
|
|
21
21
|
def binary_path_for(ctx, binary)
|
22
|
-
File.join(gem_home(ctx), 'bin', binary)
|
22
|
+
path_to_binary = File.join(gem_home(ctx), 'bin', binary)
|
23
|
+
File.exist?(path_to_binary) ? path_to_binary : binary
|
23
24
|
end
|
24
25
|
|
25
26
|
def gem_home(ctx)
|
26
27
|
ctx.getenv('GEM_HOME') || apply_gem_home(ctx)
|
27
28
|
end
|
28
29
|
|
30
|
+
def gem_path(ctx)
|
31
|
+
ctx.getenv('GEM_PATH') || apply_gem_path(ctx)
|
32
|
+
end
|
33
|
+
|
29
34
|
private
|
30
35
|
|
31
36
|
def apply_gem_home(ctx)
|
32
|
-
path =
|
37
|
+
path = ''
|
38
|
+
# extract GEM_HOME from `gem environment home` command
|
39
|
+
out, stat = ctx.capture2e('gem', 'environment', 'home')
|
40
|
+
path = out&.empty? ? '' : out.strip if stat.success?
|
41
|
+
# fallback if return from `gem environment home` is empty (somewhat unlikely)
|
42
|
+
path = fallback_gem_home_path(ctx) if path.empty?
|
43
|
+
# fallback if path isn't writable (if using a system installed ruby)
|
44
|
+
path = fallback_gem_home_path(ctx) unless File.writable?(path)
|
33
45
|
ctx.mkdir_p(path) unless Dir.exist?(path)
|
46
|
+
ctx.debug(ctx.message('rails.gem.setting_gem_home', path))
|
34
47
|
ctx.setenv('GEM_HOME', path)
|
35
48
|
end
|
49
|
+
|
50
|
+
def apply_gem_path(ctx)
|
51
|
+
path = ''
|
52
|
+
out, stat = ctx.capture2e('gem', 'environment', 'path')
|
53
|
+
path = out&.empty? ? '' : out.strip if stat.success?
|
54
|
+
# usually GEM_PATH already contains GEM_HOME
|
55
|
+
# if gem_home() falls back to our fallback path, we need to add it
|
56
|
+
path = gem_home(ctx) + File::PATH_SEPARATOR + path unless path.include?(gem_home(ctx))
|
57
|
+
ctx.debug(ctx.message('rails.gem.setting_gem_path', path))
|
58
|
+
ctx.setenv('GEM_PATH', path)
|
59
|
+
end
|
60
|
+
|
61
|
+
def fallback_gem_home_path(ctx)
|
62
|
+
File.join(ctx.getenv('HOME'), '.gem', 'ruby', RUBY_VERSION)
|
63
|
+
end
|
36
64
|
end
|
37
65
|
|
38
66
|
def installed?
|
39
|
-
|
40
|
-
|
67
|
+
found = false
|
68
|
+
paths = self.class.gem_path(ctx).split(File::PATH_SEPARATOR)
|
69
|
+
paths.each do |path|
|
70
|
+
ctx.debug(ctx.message('rails.gem.checking_installation_path', "#{path}/gems/", name))
|
71
|
+
found = !!Dir.glob("#{path}/gems/#{name}-*").detect do |f|
|
72
|
+
gem_satisfies_version?(f)
|
73
|
+
end
|
74
|
+
break if found
|
41
75
|
end
|
76
|
+
found
|
42
77
|
end
|
43
78
|
|
44
79
|
def install!
|
@@ -46,11 +81,31 @@ module Rails
|
|
46
81
|
spin.add(ctx.message('rails.gem.installing', name)) do |spinner|
|
47
82
|
args = %w(gem install)
|
48
83
|
args.push(name)
|
49
|
-
|
84
|
+
unless version.nil?
|
85
|
+
if ctx.windows? && version.include?('~')
|
86
|
+
args.push('-v', "\"#{version}\"")
|
87
|
+
else
|
88
|
+
args.push('-v', version)
|
89
|
+
end
|
90
|
+
end
|
50
91
|
ctx.system(*args)
|
51
92
|
spinner.update_title(ctx.message('rails.gem.installed', name))
|
52
93
|
end
|
53
94
|
spin.wait
|
54
95
|
end
|
96
|
+
|
97
|
+
def gem_satisfies_version?(path)
|
98
|
+
if version
|
99
|
+
# there was a specific version given during new(), so
|
100
|
+
# check version of gem found to determine match
|
101
|
+
require 'semantic/semantic'
|
102
|
+
found_version, _ = path.match(%r{/#{Regexp.quote(name)}-([\d\.]+)})&.captures
|
103
|
+
found_version.nil? ? false : Semantic::Version.new(found_version).satisfies?(version)
|
104
|
+
else
|
105
|
+
# otherwise ignore the actual version number,
|
106
|
+
# just check there's an initial digit
|
107
|
+
%r{/#{Regexp.quote(name)}-\d}.match?(path)
|
108
|
+
end
|
109
|
+
end
|
55
110
|
end
|
56
111
|
end
|