shopify-cli 1.0.3 → 1.1.2

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +20 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +13 -13
  7. data/bin/load_shopify.rb +3 -1
  8. data/bin/shopify +2 -0
  9. data/docs/Gemfile.lock +23 -13
  10. data/docs/getting-started/index.md +3 -2
  11. data/docs/getting-started/install/index.md +55 -9
  12. data/docs/getting-started/uninstall/index.md +1 -1
  13. data/docs/getting-started/upgrade/index.md +8 -4
  14. data/ext/shopify-cli/extconf.rb +40 -20
  15. data/lib/project_types/extension/models/type.rb +1 -0
  16. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  17. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  18. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  19. data/lib/project_types/node/commands/create.rb +4 -4
  20. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  21. data/lib/project_types/node/commands/generate/billing.rb +7 -5
  22. data/lib/project_types/node/commands/generate/page.rb +9 -5
  23. data/lib/project_types/node/commands/generate/webhook.rb +5 -1
  24. data/lib/project_types/node/commands/serve.rb +5 -5
  25. data/lib/project_types/node/messages/messages.rb +5 -1
  26. data/lib/project_types/rails/commands/create.rb +56 -5
  27. data/lib/project_types/rails/commands/generate.rb +1 -0
  28. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  29. data/lib/project_types/rails/commands/serve.rb +11 -7
  30. data/lib/project_types/rails/gem.rb +61 -6
  31. data/lib/project_types/rails/messages/messages.rb +32 -12
  32. data/lib/project_types/script/commands/create.rb +1 -5
  33. data/lib/project_types/script/commands/disable.rb +1 -2
  34. data/lib/project_types/script/commands/enable.rb +5 -5
  35. data/lib/project_types/script/commands/push.rb +1 -6
  36. data/lib/project_types/script/config/extension_points.yml +4 -4
  37. data/lib/project_types/script/errors.rb +8 -0
  38. data/lib/project_types/script/forms/create.rb +1 -1
  39. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  40. data/lib/project_types/script/layers/infrastructure/errors.rb +1 -0
  41. data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
  42. data/lib/project_types/script/messages/messages.rb +19 -48
  43. data/lib/project_types/script/ui/error_handler.rb +4 -0
  44. data/lib/rubygems_plugin.rb +18 -10
  45. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  46. data/lib/shopify-cli/command.rb +12 -6
  47. data/lib/shopify-cli/commands/connect.rb +7 -75
  48. data/lib/shopify-cli/commands/create.rb +1 -1
  49. data/lib/shopify-cli/commands/system.rb +21 -12
  50. data/lib/shopify-cli/context.rb +68 -0
  51. data/lib/shopify-cli/core/entry_point.rb +4 -1
  52. data/lib/shopify-cli/core/executor.rb +3 -5
  53. data/lib/shopify-cli/core/monorail.rb +1 -1
  54. data/lib/shopify-cli/db.rb +1 -1
  55. data/lib/shopify-cli/git.rb +1 -1
  56. data/lib/shopify-cli/heroku.rb +21 -5
  57. data/lib/shopify-cli/js_deps.rb +2 -2
  58. data/lib/shopify-cli/js_system.rb +2 -2
  59. data/lib/shopify-cli/messages/messages.rb +27 -20
  60. data/lib/shopify-cli/process_supervision.rb +60 -21
  61. data/lib/shopify-cli/project.rb +14 -6
  62. data/lib/shopify-cli/project_type.rb +3 -2
  63. data/lib/shopify-cli/sub_command.rb +1 -0
  64. data/lib/shopify-cli/task.rb +2 -2
  65. data/lib/shopify-cli/tasks.rb +11 -4
  66. data/lib/shopify-cli/tasks/ensure_env.rb +74 -17
  67. data/lib/shopify-cli/tunnel.rb +22 -7
  68. data/lib/shopify-cli/version.rb +1 -1
  69. data/lib/shopify_cli.rb +35 -9
  70. data/shopify-cli.gemspec +4 -1
  71. data/vendor/deps/cli-kit/REVISION +1 -1
  72. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  73. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  74. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  75. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  76. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  77. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  78. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  79. data/vendor/deps/cli-ui/REVISION +1 -1
  80. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  81. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  82. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  83. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  84. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  85. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  86. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  87. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  88. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  89. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  90. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  91. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  92. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  93. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  94. data/vendor/gen/lib/gen.rb +39 -0
  95. data/vendor/gen/lib/gen/commands.rb +18 -0
  96. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  97. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  98. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  99. data/vendor/gen/lib/gen/generator.rb +165 -0
  100. data/vendor/gen/template/.gitignore +2 -0
  101. data/vendor/gen/template/Gemfile +10 -0
  102. data/vendor/gen/template/README.md +1 -0
  103. data/vendor/gen/template/bin/testunit +23 -0
  104. data/vendor/gen/template/bin/update-deps +97 -0
  105. data/vendor/gen/template/dev-gems.yml +3 -0
  106. data/vendor/gen/template/dev-vendor.yml +4 -0
  107. data/vendor/gen/template/exe/__app__-gems +17 -0
  108. data/vendor/gen/template/exe/__app__-vendor +18 -0
  109. data/vendor/gen/template/lib/__app__.rb +33 -0
  110. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  111. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  112. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  113. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  114. data/vendor/gen/template/test/example_test.rb +17 -0
  115. data/vendor/gen/template/test/test_helper.rb +22 -0
  116. metadata +25 -4
  117. data/Vagrantfile +0 -17
  118. data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -16,23 +16,7 @@ module ShopifyCli
16
16
  already_connected_warning: "{{yellow:! This app appears to be already connected}}",
17
17
  connected: "{{v}} Project now connected to {{green:%s}}",
18
18
  project_type_select: "What type of project would you like to connect?",
19
- organization_select: "To which partner organization does this project belong?",
20
- app_select: "To which app does this project belong?",
21
- no_development_stores: <<~MESSAGE,
22
- No development stores available.
23
- Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
24
- MESSAGE
25
- development_store_select: "Which development store would you like to use?",
26
19
  cli_yml_saved: ".shopify-cli.yml saved to project root",
27
-
28
- no_apps: 'You have no apps to connect to, creating a new app.',
29
- app_name: "App name",
30
- app_type: {
31
- select: "What type of app are you building?",
32
- select_public: "Public: An app built for a wide merchant audience.",
33
- select_custom: "Custom: An app custom built for a single client.",
34
- selected: "App type {{green:%s}}",
35
- },
36
20
  },
37
21
 
38
22
  context: {
@@ -254,9 +238,21 @@ module ShopifyCli
254
238
 
255
239
  tasks: {
256
240
  ensure_env: {
257
- api_key_question: "What is your Shopify API key?",
258
- api_secret_key_question: "What is your Shopify API secret key?",
259
- development_store_question: "What is your development store URL? (Example: my-dev-store.myshopify.com)",
241
+ organization_select: "To which partner organization does this project belong?",
242
+ no_development_stores: <<~MESSAGE,
243
+ No development stores available.
244
+ Visit {{underline:https://partners.shopify.com/%d/stores}} to create one
245
+ MESSAGE
246
+ development_store_select: "Which development store would you like to use?",
247
+ app_select: "To which app does this project belong?",
248
+ no_apps: 'You have no apps to connect to, creating a new app.',
249
+ app_name: "App name",
250
+ app_type: {
251
+ select: "What type of app are you building?",
252
+ select_public: "Public: An app built for a wide merchant audience.",
253
+ select_custom: "Custom: An app custom built for a single client.",
254
+ selected: "App type {{green:%s}}",
255
+ },
260
256
  },
261
257
  ensure_dev_store: {
262
258
  could_not_verify_store: "Couldn't verify your store %s",
@@ -293,6 +289,8 @@ module ShopifyCli
293
289
  error: {
294
290
  stop: "ngrok tunnel could not be stopped. Try running {{command:killall -9 ngrok}}",
295
291
  url_fetch_failure: "Unable to fetch external url",
292
+ prereq_command_required: "%1$s is required for installing ngrok. Please install %1$s using the appropriate"\
293
+ " package manager for your system.",
296
294
  },
297
295
 
298
296
  not_running: "{{green:x}} ngrok tunnel not running",
@@ -306,6 +304,7 @@ module ShopifyCli
306
304
  stopped: "{{green:x}} ngrok tunnel stopped",
307
305
  timed_out: "{{x}} ngrok tunnel has timed out, restarting ...",
308
306
  will_timeout: "{{*}} This tunnel will timeout in {{red:%s}}",
307
+ prereq_command_location: "%s @ %s",
309
308
  },
310
309
 
311
310
  version: {
@@ -318,7 +317,7 @@ module ShopifyCli
318
317
  warning: {
319
318
  development_version: <<~DEVELOPMENT,
320
319
  {{*}} {{yellow:You are running a development version of the CLI at:}}
321
- {{yellow:%s}}
320
+ {{yellow:%s}}
322
321
 
323
322
  DEVELOPMENT
324
323
 
@@ -329,6 +328,14 @@ module ShopifyCli
329
328
  {{underline:https://shopify.github.io/shopify-app-cli/migrate/}}
330
329
 
331
330
  MESSAGE
331
+
332
+ new_version: <<~MESSAGE,
333
+ {{*}} {{yellow:A new version of the Shopify App CLI is available! You have version %s and the latest version is %s.
334
+
335
+ To upgrade, follow the instructions for the package manager you’re using:
336
+ {{underline:https://shopify.github.io/shopify-app-cli/getting-started/upgrade/}}}}
337
+
338
+ MESSAGE
332
339
  },
333
340
  },
334
341
  }.freeze
@@ -5,13 +5,10 @@ module ShopifyCli
5
5
  # ProcessSupervision wraps a running process spawned by `exec` and keeps track
6
6
  # if its `pid` and keeps a log file for it as well
7
7
  class ProcessSupervision
8
- # is the directory where the pid and logfile are kept
9
- RUN_DIR = File.join(ShopifyCli::CACHE_DIR, 'sv')
10
-
11
8
  # a string or a symbol to identify this process by
12
9
  attr_reader :identifier
13
10
  # process ID for the running process
14
- attr_reader :pid
11
+ attr_accessor :pid
15
12
  # starttime of the process
16
13
  attr_reader :time
17
14
  # filepath to the pidfile for this process
@@ -20,6 +17,11 @@ module ShopifyCli
20
17
  attr_reader :log_path
21
18
 
22
19
  class << self
20
+ def run_dir
21
+ # is the directory where the pid and logfile are kept
22
+ File.join(ShopifyCli.cache_dir, 'sv')
23
+ end
24
+
23
25
  ##
24
26
  # Will find and create a new instance of ProcessSupervision for a running process
25
27
  # if it is currently running. It will return nil if the process is not running.
@@ -34,7 +36,7 @@ module ShopifyCli
34
36
  # will be nil if the process is not running.
35
37
  #
36
38
  def for_ident(identifier)
37
- pid, time = File.read(File.join(RUN_DIR, "#{identifier}.pid")).split(':')
39
+ pid, time = File.read(File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")).split(':')
38
40
  new(identifier, pid: Integer(pid), time: time)
39
41
  rescue Errno::ENOENT
40
42
  nil
@@ -56,15 +58,37 @@ module ShopifyCli
56
58
  #
57
59
  def start(identifier, args)
58
60
  return for_ident(identifier) if running?(identifier)
59
- fork do
60
- pid_file = new(identifier, pid: Process.pid)
61
+
62
+ # Windows doesn't support forking process without extra gems, so we resort to spawning a new child process -
63
+ # that means that it dies along with the original process if it is interrupted. On UNIX, we fork the process so
64
+ # that it doesn't have to be restarted on every run.
65
+ if Context.new.windows?
66
+ pid_file = new(identifier)
67
+
68
+ # Make sure the file exists and is empty, otherwise Windows fails
69
+ File.open(pid_file.log_path, 'w') {}
70
+ pid = Process.spawn(
71
+ *args,
72
+ out: pid_file.log_path,
73
+ err: pid_file.log_path,
74
+ in: Context.new.windows? ? "nul" : "/dev/null",
75
+ )
76
+ pid_file.pid = pid
61
77
  pid_file.write
62
- STDOUT.reopen(pid_file.log_path, "w")
63
- STDERR.reopen(pid_file.log_path, "w")
64
- STDIN.reopen("/dev/null", "r")
65
- Process.setsid
66
- exec(*args)
78
+
79
+ Process.detach(pid)
80
+ else
81
+ fork do
82
+ pid_file = new(identifier, pid: Process.pid)
83
+ pid_file.write
84
+ STDOUT.reopen(pid_file.log_path, "w")
85
+ STDERR.reopen(pid_file.log_path, "w")
86
+ STDIN.reopen("/dev/null", "r")
87
+ Process.setsid
88
+ exec(*args)
89
+ end
67
90
  end
91
+
68
92
  sleep(0.1)
69
93
  for_ident(identifier)
70
94
  end
@@ -104,24 +128,29 @@ module ShopifyCli
104
128
  end
105
129
  end
106
130
 
107
- def initialize(identifier, pid:, time: Time.now.strftime('%s')) # :nodoc:
131
+ def initialize(identifier, pid: nil, time: Time.now.strftime('%s')) # :nodoc:
108
132
  @identifier = identifier
109
133
  @pid = pid
110
134
  @time = time
111
- @pid_path = File.join(RUN_DIR, "#{identifier}.pid")
112
- @log_path = File.join(RUN_DIR, "#{identifier}.log")
135
+ FileUtils.mkdir_p(ShopifyCli::ProcessSupervision.run_dir)
136
+ @pid_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.pid")
137
+ @log_path = File.join(ShopifyCli::ProcessSupervision.run_dir, "#{identifier}.log")
113
138
  end
114
139
 
115
140
  ##
116
141
  # will attempt to shutdown a running process
117
142
  #
143
+ # #### Parameters
144
+ #
145
+ # * `ctx` - the context of this command
146
+ #
118
147
  # #### Returns
119
148
  #
120
149
  # * `stopped` - [true, false]
121
150
  #
122
151
  def stop
123
- unlink
124
152
  kill_proc
153
+ unlink
125
154
  true
126
155
  rescue
127
156
  false
@@ -157,7 +186,11 @@ module ShopifyCli
157
186
  end
158
187
 
159
188
  def kill_proc
160
- kill(-pid) # process group
189
+ if Context.new.windows?
190
+ kill(pid)
191
+ else
192
+ kill(-pid) # process group
193
+ end
161
194
  rescue Errno::ESRCH
162
195
  begin
163
196
  kill(pid)
@@ -167,12 +200,18 @@ module ShopifyCli
167
200
  end
168
201
 
169
202
  def kill(id)
170
- Process.kill('TERM', id)
171
- 50.times do
172
- sleep 0.1
173
- break unless stat(id)
203
+ ctx = Context.new
204
+
205
+ # Windows does not handle SIGTERM, go straight to SIGKILL
206
+ unless ctx.windows?
207
+ Process.kill('TERM', id)
208
+ 50.times do
209
+ sleep 0.1
210
+ break unless stat(id)
211
+ end
174
212
  end
175
213
  Process.kill('KILL', id) if stat(id)
214
+ sleep(0.1) if ctx.windows? # Give Windows a second to actually close the process
176
215
  end
177
216
 
178
217
  def stat(id)
@@ -15,6 +15,10 @@ module ShopifyCli
15
15
  # will get an instance of the project that the user is currently operating
16
16
  # on. This is used for access to project resources.
17
17
  #
18
+ # #### Parameters
19
+ #
20
+ # * `force_reload` - whether to force a reload of the project files
21
+ #
18
22
  # #### Returns
19
23
  #
20
24
  # * `project` - a Project instance if the user is currently in the project.
@@ -29,8 +33,8 @@ module ShopifyCli
29
33
  #
30
34
  # project = ShopifyCli::Project.current
31
35
  #
32
- def current
33
- at(Dir.pwd)
36
+ def current(force_reload: false)
37
+ at(Dir.pwd, force_reload: force_reload)
34
38
  end
35
39
 
36
40
  ##
@@ -93,13 +97,17 @@ module ShopifyCli
93
97
 
94
98
  private
95
99
 
96
- def directory(dir)
100
+ def directory(dir, force_reload: false)
101
+ @dir = nil if force_reload
102
+
97
103
  @dir ||= Hash.new { |h, k| h[k] = __directory(k) }
98
104
  @dir[dir]
99
105
  end
100
106
 
101
- def at(dir)
102
- proj_dir = directory(dir)
107
+ def at(dir, force_reload: false)
108
+ @at = nil if force_reload
109
+
110
+ proj_dir = directory(dir, force_reload: force_reload)
103
111
  unless proj_dir
104
112
  raise(ShopifyCli::Abort, Context.message('core.project.error.not_in_project'))
105
113
  end
@@ -109,7 +117,7 @@ module ShopifyCli
109
117
 
110
118
  def __directory(curr)
111
119
  loop do
112
- return nil if curr == '/'
120
+ return nil if curr == '/' || /^[A-Z]:\/$/.match?(curr)
113
121
  file = File.join(curr, '.shopify-cli.yml')
114
122
  return curr if File.exist?(file)
115
123
  curr = File.dirname(curr)
@@ -14,6 +14,7 @@ module ShopifyCli
14
14
  alias_method :all_loaded, :repository
15
15
 
16
16
  def inherited(klass)
17
+ super
17
18
  repository << klass
18
19
  klass.project_type = @current_type
19
20
  klass.project_load_shallow = @shallow_load
@@ -32,7 +33,7 @@ module ShopifyCli
32
33
 
33
34
  def load_all
34
35
  Dir.glob(File.join(ShopifyCli::ROOT, 'lib', 'project_types', '*', 'cli.rb')).map do |filepath|
35
- load_type(filepath.split(File::Separator)[-2], true)
36
+ load_type(filepath.split(File::Separator)[-2].to_sym, true)
36
37
  end
37
38
  end
38
39
 
@@ -64,7 +65,7 @@ module ShopifyCli
64
65
 
65
66
  def register_task(task, name)
66
67
  return if project_load_shallow
67
- Task::Registry.add(const_get(task), name)
68
+ ShopifyCli::Task.register(task, name)
68
69
  end
69
70
 
70
71
  def register_messages(messages)
@@ -8,6 +8,7 @@ module ShopifyCli
8
8
  cmd = new(@ctx)
9
9
  args = cmd.options.parse(@_options, args[1..-1] || [])
10
10
  return call_help(parent_command, command_name) if cmd.options.help
11
+ run_prerequisites
11
12
  cmd.call(args, command_name)
12
13
  end
13
14
  end
@@ -2,9 +2,9 @@ require 'shopify_cli'
2
2
 
3
3
  module ShopifyCli
4
4
  class Task
5
- def self.call(*args)
5
+ def self.call(*args, **kwargs)
6
6
  task = new
7
- task.call(*args)
7
+ task.call(*args, **kwargs)
8
8
  end
9
9
  end
10
10
  end
@@ -12,15 +12,22 @@ module ShopifyCli
12
12
  end
13
13
 
14
14
  def [](name)
15
- @tasks[name]
15
+ class_or_proc = @tasks[name]
16
+ if class_or_proc.is_a?(Class)
17
+ class_or_proc
18
+ elsif class_or_proc.respond_to?(:call)
19
+ class_or_proc.call
20
+ else
21
+ class_or_proc
22
+ end
16
23
  end
17
24
  end
18
25
 
19
26
  Registry = TaskRegistry.new
20
27
 
21
- def self.register(task, name, path)
22
- autoload(task, path)
23
- Registry.add(const_get(task), name)
28
+ def self.register(task, name, path = nil)
29
+ autoload(task, path) if path
30
+ Registry.add(-> () { const_get(task) }, name)
24
31
  end
25
32
 
26
33
  register :CreateApiClient, :create_api_client, 'shopify-cli/tasks/create_api_client'
@@ -3,27 +3,84 @@ require 'shopify_cli'
3
3
  module ShopifyCli
4
4
  module Tasks
5
5
  class EnsureEnv < ShopifyCli::Task
6
- def call(ctx)
6
+ def call(ctx, regenerate: false, required: [:api_key, :secret])
7
7
  @ctx = ctx
8
- Resources::EnvFile.read(ctx.root)
9
- rescue Errno::ENOENT
10
- ask
8
+ env_data =
9
+ begin
10
+ Resources::EnvFile.parse_external_env
11
+ rescue Errno::ENOENT
12
+ {}
13
+ end
14
+
15
+ return {} if !regenerate && required.all? { |property| env_data[property] }
16
+
17
+ org = fetch_org
18
+ write_env(env_data, org)
19
+ org
20
+ end
21
+
22
+ private
23
+
24
+ def fetch_org
25
+ orgs = PartnersAPI::Organizations.fetch_with_app(@ctx)
26
+ org_id = if orgs.count == 1
27
+ orgs.first["id"]
28
+ else
29
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.organization_select')) do |handler|
30
+ orgs.each do |org|
31
+ handler.option(
32
+ @ctx.message('core.partners_api.org_name_and_id', org['businessName'], org['id'])
33
+ ) { org["id"] }
34
+ end
35
+ end
36
+ end
37
+ orgs.find { |o| o["id"] == org_id }
11
38
  end
12
39
 
13
- def ask
14
- api_key = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_key_question'))
15
- api_secret = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.api_secret_key_question'))
16
- shop = CLI::UI.ask(@ctx.message('core.tasks.ensure_env.development_store_question'))
17
- shop.gsub!(/https?\:\/\//, '')
18
-
19
- env = Resources::EnvFile.new(
20
- api_key: api_key,
21
- secret: api_secret,
22
- shop: shop,
23
- host: ShopifyCli::Tunnel.start(@ctx),
24
- scopes: 'write_products,write_customers,write_draft_orders',
40
+ def get_app(org_id, apps)
41
+ if apps.count == 1
42
+ apps.first
43
+ elsif apps.count == 0
44
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_apps'))
45
+ title = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_name'))
46
+ type = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_type.select')) do |handler|
47
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_public')) { 'public' }
48
+ handler.option(@ctx.message('core.tasks.ensure_env.app_type.select_custom')) { 'custom' }
49
+ end
50
+ ShopifyCli::Tasks::CreateApiClient.call(@ctx, org_id: org_id, title: title, type: type)
51
+ else
52
+ CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.app_select')) do |handler|
53
+ apps.each { |app| handler.option(app["title"]) { app } }
54
+ end
55
+ end
56
+ end
57
+
58
+ def get_shop(shops, id)
59
+ if shops.count == 1
60
+ shop = shops.first["shopDomain"]
61
+ elsif shops.count == 0
62
+ @ctx.puts(@ctx.message('core.tasks.ensure_env.no_development_stores', id))
63
+ else
64
+ shop = CLI::UI::Prompt.ask(@ctx.message('core.tasks.ensure_env.development_store_select')) do |handler|
65
+ shops.each { |s| handler.option(s["shopName"]) { s["shopDomain"] } }
66
+ end
67
+ end
68
+ shop
69
+ end
70
+
71
+ def write_env(env_data, org)
72
+ id = org['id']
73
+ app = get_app(id, org['apps'])
74
+
75
+ env_data[:shop] = get_shop(org['stores'], id)
76
+ env_data[:api_key] = app["apiKey"]
77
+ env_data[:secret] = app["apiSecretKeys"].first["secret"]
78
+ env_data[:scopes] = 'write_products,write_customers,write_draft_orders' if env_data[:scopes].nil?
79
+ env_data[:extra] = {} if env_data[:extra].nil?
80
+
81
+ Resources::EnvFile.new(
82
+ env_data
25
83
  ).write(@ctx)
26
- env
27
84
  end
28
85
  end
29
86
  end