shopify-cli 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +20 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +13 -13
  6. data/docs/Gemfile.lock +23 -13
  7. data/docs/getting-started/install/index.md +37 -1
  8. data/docs/getting-started/migrate/index.md +34 -1
  9. data/lib/project_types/extension/cli.rb +1 -1
  10. data/lib/project_types/extension/commands/build.rb +1 -1
  11. data/lib/project_types/extension/models/type.rb +1 -0
  12. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  13. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  14. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  15. data/lib/project_types/node/forms/create.rb +3 -54
  16. data/lib/project_types/node/messages/messages.rb +3 -14
  17. data/lib/project_types/rails/cli.rb +0 -1
  18. data/lib/project_types/rails/forms/create.rb +3 -52
  19. data/lib/project_types/rails/messages/messages.rb +2 -13
  20. data/lib/project_types/script/cli.rb +2 -3
  21. data/lib/project_types/script/commands/create.rb +5 -9
  22. data/lib/project_types/script/commands/disable.rb +4 -15
  23. data/lib/project_types/script/commands/enable.rb +37 -13
  24. data/lib/project_types/script/commands/push.rb +8 -13
  25. data/lib/project_types/script/config/extension_points.yml +9 -3
  26. data/lib/project_types/script/errors.rb +8 -0
  27. data/lib/project_types/script/forms/script_form.rb +5 -2
  28. data/lib/project_types/script/layers/application/create_script.rb +7 -6
  29. data/lib/project_types/script/layers/application/disable_script.rb +9 -7
  30. data/lib/project_types/script/layers/application/enable_script.rb +11 -9
  31. data/lib/project_types/script/layers/application/push_script.rb +6 -4
  32. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  33. data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +2 -2
  34. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +2 -2
  35. data/lib/project_types/script/layers/infrastructure/errors.rb +2 -0
  36. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -1
  37. data/lib/project_types/script/layers/infrastructure/script_repository.rb +1 -1
  38. data/lib/project_types/script/layers/infrastructure/script_service.rb +2 -0
  39. data/lib/project_types/script/messages/messages.rb +25 -31
  40. data/lib/project_types/script/script_project.rb +8 -4
  41. data/lib/project_types/script/templates/ts/as-pect.config.js +6 -0
  42. data/lib/project_types/script/ui/error_handler.rb +8 -0
  43. data/lib/project_types/script/ui/printing_spinner.rb +75 -0
  44. data/lib/shopify-cli/admin_api.rb +1 -2
  45. data/lib/shopify-cli/admin_api/populate_resource_command.rb +10 -1
  46. data/lib/shopify-cli/admin_api/schema.rb +20 -8
  47. data/lib/shopify-cli/command.rb +14 -11
  48. data/lib/shopify-cli/commands.rb +1 -0
  49. data/lib/shopify-cli/commands/config.rb +44 -0
  50. data/lib/shopify-cli/commands/connect.rb +8 -69
  51. data/lib/shopify-cli/commands/create.rb +2 -2
  52. data/lib/shopify-cli/commands/help.rb +1 -1
  53. data/lib/shopify-cli/commands/system.rb +14 -6
  54. data/lib/shopify-cli/context.rb +10 -1
  55. data/lib/shopify-cli/core.rb +0 -1
  56. data/lib/shopify-cli/core/entry_point.rb +7 -1
  57. data/lib/shopify-cli/core/executor.rb +3 -5
  58. data/lib/shopify-cli/core/finalize.rb +13 -0
  59. data/lib/shopify-cli/core/monorail.rb +1 -1
  60. data/lib/shopify-cli/db.rb +1 -1
  61. data/lib/shopify-cli/feature.rb +97 -0
  62. data/lib/shopify-cli/heroku.rb +4 -4
  63. data/lib/shopify-cli/messages/messages.rb +51 -12
  64. data/lib/shopify-cli/partners_api/organizations.rb +7 -7
  65. data/lib/shopify-cli/process_supervision.rb +8 -6
  66. data/lib/shopify-cli/project_type.rb +5 -7
  67. data/lib/shopify-cli/sub_command.rb +1 -0
  68. data/lib/shopify-cli/task.rb +2 -2
  69. data/lib/shopify-cli/tasks.rb +12 -4
  70. data/lib/shopify-cli/tasks/ensure_env.rb +72 -16
  71. data/lib/shopify-cli/tasks/select_org_and_shop.rb +77 -0
  72. data/lib/shopify-cli/tasks/update_dashboard_urls.rb +4 -3
  73. data/lib/shopify-cli/tunnel.rb +38 -14
  74. data/lib/shopify-cli/version.rb +1 -1
  75. data/lib/shopify_cli.rb +32 -9
  76. metadata +7 -4
  77. data/lib/project_types/script/forms/enable.rb +0 -24
  78. data/lib/project_types/script/forms/push.rb +0 -19
@@ -0,0 +1,77 @@
1
+ require 'shopify_cli'
2
+
3
+ module ShopifyCli
4
+ module Tasks
5
+ class SelectOrgAndShop < ShopifyCli::Task
6
+ attr_reader :ctx
7
+
8
+ def call(ctx, organization_id: nil, shop_domain: nil)
9
+ @ctx = ctx
10
+ return response(organization_id.to_i, shop_domain) unless organization_id.nil? || shop_domain.nil?
11
+ org = get_organization(organization_id)
12
+ shop_domain ||= get_shop_domain(org)
13
+ response(org["id"].to_i, shop_domain)
14
+ end
15
+
16
+ private
17
+
18
+ def response(organization_id, shop_domain)
19
+ {
20
+ organization_id: organization_id,
21
+ shop_domain: shop_domain,
22
+ }
23
+ end
24
+
25
+ def organizations
26
+ @organizations ||= ShopifyCli::PartnersAPI::Organizations.fetch_all(ctx)
27
+ end
28
+
29
+ def get_organization(organization_id)
30
+ @organization ||= if !organization_id.nil?
31
+ org = ShopifyCli::PartnersAPI::Organizations.fetch(ctx, id: organization_id)
32
+ if org.nil?
33
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.authentication_issue', ShopifyCli::TOOL_NAME))
34
+ ctx.abort(ctx.message('core.tasks.select_org_and_shop.error.organization_not_found'))
35
+ end
36
+ org
37
+ elsif organizations.count == 0
38
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.partners_notice'))
39
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.authentication_issue', ShopifyCli::TOOL_NAME))
40
+ ctx.abort(ctx.message('core.tasks.select_org_and_shop.error.no_organizations'))
41
+ elsif organizations.count == 1
42
+ org = organizations.first
43
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.organization', org['businessName'], org['id']))
44
+ org
45
+ else
46
+ org_id = CLI::UI::Prompt.ask(ctx.message('core.tasks.select_org_and_shop.organization_select')) do |handler|
47
+ organizations.each do |o|
48
+ handler.option(ctx.message('core.partners_api.org_name_and_id', o['businessName'], o['id'])) { o['id'] }
49
+ end
50
+ end
51
+ organizations.find { |o| o['id'] == org_id }
52
+ end
53
+ end
54
+
55
+ def get_shop_domain(organization)
56
+ valid_stores = organization['stores'].select do |store|
57
+ store['transferDisabled'] == true || store['convertableToPartnerTest'] == true
58
+ end
59
+
60
+ if valid_stores.count == 0
61
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.error.no_development_stores'))
62
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.create_store', organization['id']))
63
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.authentication_issue', ShopifyCli::TOOL_NAME))
64
+ elsif valid_stores.count == 1
65
+ domain = valid_stores.first['shopDomain']
66
+ ctx.puts(ctx.message('core.tasks.select_org_and_shop.development_store', domain))
67
+ domain
68
+ else
69
+ CLI::UI::Prompt.ask(
70
+ ctx.message('core.tasks.select_org_and_shop.development_store_select'),
71
+ options: valid_stores.map { |s| s['shopDomain'] }
72
+ )
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -28,16 +28,17 @@ module ShopifyCli
28
28
  end
29
29
 
30
30
  def construct_redirect_urls(urls, new_url, callback_url)
31
- urls.map do |url|
31
+ new_urls = urls.map do |url|
32
32
  if (match = url.match(NGROK_REGEX))
33
33
  "#{new_url}#{match[2]}"
34
34
  else
35
35
  url
36
36
  end
37
37
  end
38
- if urls.grep(/#{new_url}#{callback_url}/).empty?
39
- urls.push("#{new_url}#{callback_url}")
38
+ if new_urls.grep(/#{new_url}#{callback_url}/).empty?
39
+ new_urls.push("#{new_url}#{callback_url}")
40
40
  end
41
+ new_urls.uniq
41
42
  end
42
43
  end
43
44
  end
@@ -62,14 +62,19 @@ module ShopifyCli
62
62
  #
63
63
  def start(ctx, port: PORT)
64
64
  install(ctx)
65
- process = ShopifyCli::ProcessSupervision.start(:ngrok, ngrok_command(port))
66
- log = fetch_url(ctx, process.log_path)
67
- if log.account
68
- ctx.puts(ctx.message('core.tunnel.start_with_account', log.url, log.account))
65
+ url, account, seconds_remaining = start_ngrok(ctx, port)
66
+ if account
67
+ ctx.puts(ctx.message('core.tunnel.start_with_account', url, account))
69
68
  else
70
- ctx.puts(ctx.message('core.tunnel.start', log.url))
69
+ if seconds_remaining <= 0
70
+ ctx.puts(ctx.message('core.tunnel.timed_out'))
71
+ url, _account, seconds_remaining = restart_ngrok(ctx, port)
72
+ end
73
+ ctx.puts(ctx.message('core.tunnel.start', url))
74
+ ctx.puts(ctx.message('core.tunnel.will_timeout', seconds_to_hm(seconds_remaining)))
75
+ ctx.puts(ctx.message('core.tunnel.signup_suggestion', ShopifyCli::TOOL_NAME))
71
76
  end
72
- log.url
77
+ url
73
78
  end
74
79
 
75
80
  ##
@@ -83,7 +88,7 @@ module ShopifyCli
83
88
  #
84
89
  def auth(ctx, token)
85
90
  install(ctx)
86
- ctx.system(File.join(ShopifyCli::CACHE_DIR, 'ngrok'), 'authtoken', token)
91
+ ctx.system(File.join(ShopifyCli.cache_dir, 'ngrok'), 'authtoken', token)
87
92
  end
88
93
 
89
94
  ##
@@ -117,14 +122,14 @@ module ShopifyCli
117
122
  private
118
123
 
119
124
  def install(ctx)
120
- return if File.exist?(File.join(ShopifyCli::CACHE_DIR, 'ngrok'))
125
+ return if File.exist?(File.join(ShopifyCli.cache_dir, 'ngrok'))
121
126
  spinner = CLI::UI::SpinGroup.new
122
127
  spinner.add('Installing ngrok...') do
123
- zip_dest = File.join(ShopifyCli::CACHE_DIR, 'ngrok.zip')
128
+ zip_dest = File.join(ShopifyCli.cache_dir, 'ngrok.zip')
124
129
  unless File.exist?(zip_dest)
125
- ctx.system('curl', '-o', zip_dest, DOWNLOAD_URLS[ctx.os], chdir: ShopifyCli::CACHE_DIR)
130
+ ctx.system('curl', '-o', zip_dest, DOWNLOAD_URLS[ctx.os], chdir: ShopifyCli.cache_dir)
126
131
  end
127
- ctx.system('unzip', '-u', zip_dest, chdir: ShopifyCli::CACHE_DIR)
132
+ ctx.system('unzip', '-u', zip_dest, chdir: ShopifyCli.cache_dir)
128
133
  ctx.rm(zip_dest)
129
134
  end
130
135
  spinner.wait
@@ -138,13 +143,30 @@ module ShopifyCli
138
143
  end
139
144
 
140
145
  def ngrok_command(port)
141
- "exec #{File.join(ShopifyCli::CACHE_DIR, 'ngrok')} http -log=stdout -log-level=debug #{port}"
146
+ "exec #{File.join(ShopifyCli.cache_dir, 'ngrok')} http -inspect=false -log=stdout -log-level=debug #{port}"
142
147
  end
143
148
 
149
+ def seconds_to_hm(seconds)
150
+ format("%d hours %d minutes", seconds / 3600, seconds / 60 % 60)
151
+ end
152
+
153
+ def start_ngrok(ctx, port)
154
+ process = ShopifyCli::ProcessSupervision.start(:ngrok, ngrok_command(port))
155
+ log = fetch_url(ctx, process.log_path)
156
+ seconds_remaining = (process.time.to_i + log.timeout) - Time.now.to_i
157
+ [log.url, log.account, seconds_remaining]
158
+ end
159
+
160
+ def restart_ngrok(ctx, port)
161
+ unless ShopifyCli::ProcessSupervision.stop(:ngrok)
162
+ ctx.abort(ctx.message('core.tunnel.error.stop'))
163
+ end
164
+ start_ngrok(ctx, port)
165
+ end
144
166
  class LogParser # :nodoc:
145
167
  TIMEOUT = 10
146
168
 
147
- attr_reader :url, :account
169
+ attr_reader :url, :account, :timeout
148
170
 
149
171
  def initialize(log_path)
150
172
  @log_path = log_path
@@ -173,7 +195,9 @@ module ShopifyCli
173
195
  end
174
196
 
175
197
  def parse_account
176
- @account, _ = @log.match(/AccountName:([\w\s]+) SessionDuration/)&.captures
198
+ account, timeout, _ = @log.match(/AccountName:([\w\s]*) SessionDuration:([\d]+) PlanName/)&.captures
199
+ @account = account&.empty? ? nil : account
200
+ @timeout = timeout&.empty? ? 0 : timeout.to_i
177
201
  end
178
202
 
179
203
  def error
@@ -1,3 +1,3 @@
1
1
  module ShopifyCli
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.5'
3
3
  end
@@ -44,10 +44,6 @@ module ShopifyCli
44
44
  ROOT = File.expand_path('../..', __FILE__)
45
45
  PROJECT_TYPES_DIR = File.join(ROOT, 'lib', 'project_types')
46
46
  TEMP_DIR = File.join(ROOT, '.tmp')
47
- CACHE_DIR = File.join(File.expand_path(ENV.fetch('XDG_CACHE_HOME', '~/.cache')), TOOL_NAME)
48
- TOOL_CONFIG_PATH = File.join(File.expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config')), TOOL_NAME)
49
- LOG_FILE = File.join(TOOL_CONFIG_PATH, 'logs', 'log.log')
50
- DEBUG_LOG_FILE = File.join(TOOL_CONFIG_PATH, 'logs', 'debug.log')
51
47
 
52
48
  # programmer emoji if default install location, else wrench emoji
53
49
  EMOJI = ROOT == '/opt/shopify' ? "\u{1f469}\u{200d}\u{1f4bb}" : "\u{1f527}"
@@ -82,7 +78,7 @@ module ShopifyCli
82
78
  # ShopifyCli::Config
83
79
  autocall(:Config) { CLI::Kit::Config.new(tool_name: TOOL_NAME) }
84
80
  # ShopifyCli::Logger
85
- autocall(:Logger) { CLI::Kit::Logger.new(debug_log_file: DEBUG_LOG_FILE) }
81
+ autocall(:Logger) { CLI::Kit::Logger.new(debug_log_file: ShopifyCli.debug_log_file) }
86
82
  # ShopifyCli::Resolver
87
83
  autocall(:Resolver) do
88
84
  ShopifyCli::Core::HelpResolver.new(
@@ -93,7 +89,7 @@ module ShopifyCli
93
89
  # ShopifyCli::ErrorHandler
94
90
  autocall(:ErrorHandler) do
95
91
  CLI::Kit::ErrorHandler.new(
96
- log_file: ShopifyCli::LOG_FILE,
92
+ log_file: ShopifyCli.log_file,
97
93
  exception_reporter: nil,
98
94
  )
99
95
  end
@@ -105,6 +101,7 @@ module ShopifyCli
105
101
  autoload :Context, 'shopify-cli/context'
106
102
  autoload :Core, 'shopify-cli/core'
107
103
  autoload :DB, 'shopify-cli/db'
104
+ autoload :Feature, 'shopify-cli/feature'
108
105
  autoload :Form, 'shopify-cli/form'
109
106
  autoload :Git, 'shopify-cli/git'
110
107
  autoload :Helpers, 'shopify-cli/helpers'
@@ -126,7 +123,33 @@ module ShopifyCli
126
123
 
127
124
  require 'shopify-cli/messages/messages'
128
125
  Context.load_messages(ShopifyCli::Messages::MESSAGES)
129
- end
130
126
 
131
- # Make sure the cache dir always exists
132
- FileUtils.mkdir_p(ShopifyCli::CACHE_DIR)
127
+ def self.cache_dir
128
+ cache_dir = if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
129
+ TEMP_DIR
130
+ else
131
+ File.join(File.expand_path(ENV.fetch('XDG_CACHE_HOME', '~/.cache')), TOOL_NAME)
132
+ end
133
+
134
+ # Make sure the cache dir always exists
135
+ @cache_dir_exists ||= FileUtils.mkdir_p(cache_dir)
136
+
137
+ cache_dir
138
+ end
139
+
140
+ def self.tool_config_path
141
+ if ENV.key?('RUNNING_SHOPIFY_CLI_TESTS')
142
+ TEMP_DIR
143
+ else
144
+ File.join(File.expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config')), TOOL_NAME)
145
+ end
146
+ end
147
+
148
+ def self.log_file
149
+ File.join(tool_config_path, 'logs', 'log.log')
150
+ end
151
+
152
+ def self.debug_log_file
153
+ File.join(tool_config_path, 'logs', 'debug.log')
154
+ end
155
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-14 00:00:00.000000000 Z
11
+ date: 2020-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -216,8 +216,6 @@ files:
216
216
  - lib/project_types/script/config/extension_points.yml
217
217
  - lib/project_types/script/errors.rb
218
218
  - lib/project_types/script/forms/create.rb
219
- - lib/project_types/script/forms/enable.rb
220
- - lib/project_types/script/forms/push.rb
221
219
  - lib/project_types/script/forms/script_form.rb
222
220
  - lib/project_types/script/graphql/app_script_update_or_create.graphql
223
221
  - lib/project_types/script/graphql/script_service_proxy.graphql
@@ -249,6 +247,7 @@ files:
249
247
  - lib/project_types/script/templates/ts/as-pect.config.js
250
248
  - lib/project_types/script/templates/ts/as-pect.d.ts
251
249
  - lib/project_types/script/ui/error_handler.rb
250
+ - lib/project_types/script/ui/printing_spinner.rb
252
251
  - lib/project_types/script/ui/strict_spinner.rb
253
252
  - lib/rubygems_plugin.rb
254
253
  - lib/shopify-cli/admin_api.rb
@@ -257,6 +256,7 @@ files:
257
256
  - lib/shopify-cli/api.rb
258
257
  - lib/shopify-cli/command.rb
259
258
  - lib/shopify-cli/commands.rb
259
+ - lib/shopify-cli/commands/config.rb
260
260
  - lib/shopify-cli/commands/connect.rb
261
261
  - lib/shopify-cli/commands/create.rb
262
262
  - lib/shopify-cli/commands/help.rb
@@ -267,9 +267,11 @@ files:
267
267
  - lib/shopify-cli/core.rb
268
268
  - lib/shopify-cli/core/entry_point.rb
269
269
  - lib/shopify-cli/core/executor.rb
270
+ - lib/shopify-cli/core/finalize.rb
270
271
  - lib/shopify-cli/core/help_resolver.rb
271
272
  - lib/shopify-cli/core/monorail.rb
272
273
  - lib/shopify-cli/db.rb
274
+ - lib/shopify-cli/feature.rb
273
275
  - lib/shopify-cli/form.rb
274
276
  - lib/shopify-cli/git.rb
275
277
  - lib/shopify-cli/helpers.rb
@@ -296,6 +298,7 @@ files:
296
298
  - lib/shopify-cli/tasks/ensure_dev_store.rb
297
299
  - lib/shopify-cli/tasks/ensure_env.rb
298
300
  - lib/shopify-cli/tasks/ensure_loopback_url.rb
301
+ - lib/shopify-cli/tasks/select_org_and_shop.rb
299
302
  - lib/shopify-cli/tasks/update_dashboard_urls.rb
300
303
  - lib/shopify-cli/tunnel.rb
301
304
  - lib/shopify-cli/version.rb
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Forms
5
- class Enable < ScriptForm
6
- flag_arguments :api_key, :shop_domain
7
-
8
- def ask
9
- self.api_key ||= ask_api_key
10
- self.shop_domain ||= ask_shop_domain
11
- end
12
-
13
- private
14
-
15
- def ask_api_key
16
- ask_app_api_key(organization['apps'], message: ctx.message('script.forms.enable.ask_app_api_key'))
17
- end
18
-
19
- def ask_shop_domain
20
- super(organization, message: ctx.message('script.forms.enable.ask_shop_domain'))
21
- end
22
- end
23
- end
24
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Forms
5
- class Push < ScriptForm
6
- flag_arguments :api_key, :force
7
-
8
- def ask
9
- self.api_key ||= ask_api_key
10
- end
11
-
12
- private
13
-
14
- def ask_api_key
15
- ask_app_api_key(organization['apps'])
16
- end
17
- end
18
- end
19
- end