shopify-cli 1.0.4 → 1.2.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +21 -1
  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/cli.rb +1 -0
  16. data/lib/project_types/extension/features/argo_config.rb +60 -0
  17. data/lib/project_types/extension/messages/messages.rb +3 -0
  18. data/lib/project_types/extension/models/type.rb +1 -0
  19. data/lib/project_types/extension/models/types/checkout_post_purchase.rb +5 -2
  20. data/lib/project_types/extension/tasks/create_extension.rb +1 -1
  21. data/lib/project_types/extension/tasks/get_app.rb +1 -1
  22. data/lib/project_types/extension/tasks/update_draft.rb +1 -1
  23. data/lib/project_types/node/commands/create.rb +4 -4
  24. data/lib/project_types/node/commands/deploy/heroku.rb +6 -1
  25. data/lib/project_types/node/commands/generate/billing.rb +7 -5
  26. data/lib/project_types/node/commands/generate/page.rb +9 -5
  27. data/lib/project_types/node/commands/generate/webhook.rb +5 -1
  28. data/lib/project_types/node/commands/serve.rb +5 -5
  29. data/lib/project_types/node/messages/messages.rb +5 -1
  30. data/lib/project_types/rails/commands/create.rb +56 -5
  31. data/lib/project_types/rails/commands/generate.rb +1 -0
  32. data/lib/project_types/rails/commands/generate/webhook.rb +3 -2
  33. data/lib/project_types/rails/commands/serve.rb +11 -7
  34. data/lib/project_types/rails/gem.rb +61 -6
  35. data/lib/project_types/rails/messages/messages.rb +32 -12
  36. data/lib/project_types/script/commands/create.rb +1 -5
  37. data/lib/project_types/script/commands/disable.rb +1 -2
  38. data/lib/project_types/script/commands/enable.rb +5 -5
  39. data/lib/project_types/script/commands/push.rb +1 -6
  40. data/lib/project_types/script/config/extension_points.yml +4 -4
  41. data/lib/project_types/script/errors.rb +8 -0
  42. data/lib/project_types/script/forms/create.rb +1 -1
  43. data/lib/project_types/script/layers/domain/errors.rb +2 -0
  44. data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +36 -1
  45. data/lib/project_types/script/layers/infrastructure/errors.rb +8 -0
  46. data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -2
  47. data/lib/project_types/script/messages/messages.rb +22 -48
  48. data/lib/project_types/script/ui/error_handler.rb +12 -0
  49. data/lib/rubygems_plugin.rb +18 -10
  50. data/lib/shopify-cli/admin_api/populate_resource_command.rb +1 -1
  51. data/lib/shopify-cli/command.rb +12 -6
  52. data/lib/shopify-cli/commands/connect.rb +7 -75
  53. data/lib/shopify-cli/commands/create.rb +1 -1
  54. data/lib/shopify-cli/commands/system.rb +21 -12
  55. data/lib/shopify-cli/context.rb +68 -0
  56. data/lib/shopify-cli/core/entry_point.rb +4 -1
  57. data/lib/shopify-cli/core/executor.rb +3 -5
  58. data/lib/shopify-cli/core/monorail.rb +1 -1
  59. data/lib/shopify-cli/db.rb +1 -1
  60. data/lib/shopify-cli/git.rb +1 -1
  61. data/lib/shopify-cli/heroku.rb +21 -5
  62. data/lib/shopify-cli/js_deps.rb +2 -2
  63. data/lib/shopify-cli/js_system.rb +2 -2
  64. data/lib/shopify-cli/messages/messages.rb +35 -25
  65. data/lib/shopify-cli/process_supervision.rb +60 -21
  66. data/lib/shopify-cli/project.rb +17 -9
  67. data/lib/shopify-cli/project_type.rb +3 -2
  68. data/lib/shopify-cli/sub_command.rb +1 -0
  69. data/lib/shopify-cli/task.rb +2 -2
  70. data/lib/shopify-cli/tasks.rb +11 -4
  71. data/lib/shopify-cli/tasks/ensure_env.rb +74 -17
  72. data/lib/shopify-cli/tunnel.rb +22 -7
  73. data/lib/shopify-cli/version.rb +1 -1
  74. data/lib/shopify_cli.rb +35 -9
  75. data/shopify-cli.gemspec +4 -1
  76. data/vendor/deps/cli-kit/REVISION +1 -1
  77. data/vendor/deps/cli-kit/lib/cli/kit.rb +1 -1
  78. data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +2 -2
  79. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +12 -6
  80. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +9 -11
  81. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +8 -2
  82. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +7 -7
  83. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +48 -17
  84. data/vendor/deps/cli-ui/REVISION +1 -1
  85. data/vendor/deps/cli-ui/lib/cli/ui.rb +5 -4
  86. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +9 -3
  87. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +1 -0
  88. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -2
  89. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -0
  90. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +13 -5
  91. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +29 -2
  92. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +21 -10
  93. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  94. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +11 -2
  95. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -0
  96. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -3
  97. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +6 -8
  98. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +2 -0
  99. data/vendor/gen/lib/gen.rb +39 -0
  100. data/vendor/gen/lib/gen/commands.rb +18 -0
  101. data/vendor/gen/lib/gen/commands/help.rb +20 -0
  102. data/vendor/gen/lib/gen/commands/new.rb +21 -0
  103. data/vendor/gen/lib/gen/entry_point.rb +10 -0
  104. data/vendor/gen/lib/gen/generator.rb +165 -0
  105. data/vendor/gen/template/.gitignore +2 -0
  106. data/vendor/gen/template/Gemfile +10 -0
  107. data/vendor/gen/template/README.md +1 -0
  108. data/vendor/gen/template/bin/testunit +23 -0
  109. data/vendor/gen/template/bin/update-deps +97 -0
  110. data/vendor/gen/template/dev-gems.yml +3 -0
  111. data/vendor/gen/template/dev-vendor.yml +4 -0
  112. data/vendor/gen/template/exe/__app__-gems +17 -0
  113. data/vendor/gen/template/exe/__app__-vendor +18 -0
  114. data/vendor/gen/template/lib/__app__.rb +33 -0
  115. data/vendor/gen/template/lib/__app__/commands.rb +18 -0
  116. data/vendor/gen/template/lib/__app__/commands/example.rb +19 -0
  117. data/vendor/gen/template/lib/__app__/commands/help.rb +21 -0
  118. data/vendor/gen/template/lib/__app__/entry_point.rb +10 -0
  119. data/vendor/gen/template/test/example_test.rb +17 -0
  120. data/vendor/gen/template/test/test_helper.rb +22 -0
  121. metadata +26 -4
  122. data/Vagrantfile +0 -17
  123. data/lib/project_types/script/forms/script_form.rb +0 -69
@@ -44,6 +44,10 @@ module Script
44
44
  cause_of_error: ShopifyCli::Context.message('script.error.invalid_context_cause'),
45
45
  help_suggestion: ShopifyCli::Context.message('script.error.invalid_context_help'),
46
46
  }
47
+ when Errors::InvalidConfigYAMLError
48
+ {
49
+ cause_of_error: ShopifyCli::Context.message('script.error.invalid_config', e.config_file),
50
+ }
47
51
  when Errors::InvalidScriptNameError
48
52
  {
49
53
  cause_of_error: ShopifyCli::Context.message('script.error.invalid_script_name_cause'),
@@ -138,6 +142,14 @@ module Script
138
142
  {
139
143
  cause_of_error: ShopifyCli::Context.message('script.error.shop_script_undefined_cause'),
140
144
  }
145
+ when Layers::Infrastructure::Errors::PackagesOutdatedError
146
+ {
147
+ cause_of_error: ShopifyCli::Context.message(
148
+ 'script.error.packages_outdated_cause',
149
+ e.outdated_packages.join(', ')
150
+ ),
151
+ help_suggestion: ShopifyCli::Context.message('script.error.packages_outdated_help'),
152
+ }
141
153
  end
142
154
  end
143
155
  end
@@ -1,17 +1,25 @@
1
1
  Gem.post_uninstall do |uninstaller|
2
2
  if uninstaller.spec.name == 'shopify-cli'
3
- require 'fileutils'
3
+ if RUBY_PLATFORM.match(/mingw32/)
4
+ bat_path = File.dirname(RbConfig.ruby)
5
+ bat = "#{bat_path}\\shopify.bat"
4
6
 
5
- symlink = '/usr/local/bin/shopify'
7
+ # delete the auto-generated batch script
8
+ File.unlink(bat)
9
+ else
10
+ require 'fileutils'
6
11
 
7
- # delete the symbolic link IFF it exists AND it does not point to a file
8
- # (i.e., it's been left hanging as a result of the uninstall, as expected)
9
- #
10
- # if the file still exists, either the uninstall failed (possible but
11
- # unlikely) OR
12
- # there's another installation of the gem in another ruby folder that has
13
- # overwritten it, so leave the symbolic link alone
14
- system("sudo rm -f #{symlink}") if File.symlink?(symlink) && !File.exist?(symlink)
12
+ symlink = '/usr/local/bin/shopify'
13
+
14
+ # delete the symbolic link IFF it exists AND it does not point to a file
15
+ # (i.e., it's been left hanging as a result of the uninstall, as expected)
16
+ #
17
+ # if the file still exists, either the uninstall failed (possible but
18
+ # unlikely) OR
19
+ # there's another installation of the gem in another ruby folder that has
20
+ # overwritten it, so leave the symbolic link alone
21
+ system("sudo rm -f #{symlink}") if File.symlink?(symlink) && !File.exist?(symlink)
22
+ end
15
23
  end
16
24
 
17
25
  true
@@ -118,7 +118,7 @@ module ShopifyCli
118
118
  kwargs = { input: data }
119
119
  kwargs[:shop] = @shop
120
120
  resp = AdminAPI.query(
121
- @ctx, "create_#{snake_case_resource_type}", kwargs
121
+ @ctx, "create_#{snake_case_resource_type}", **kwargs
122
122
  )
123
123
  @ctx.abort(resp['errors']) if resp['errors']
124
124
  @ctx.done(message(resp['data'])) unless @silent
@@ -9,17 +9,19 @@ module ShopifyCli
9
9
  attr_accessor :options
10
10
 
11
11
  class << self
12
- attr_writer :ctx
12
+ attr_writer :ctx, :task_registry
13
13
 
14
14
  def call(args, command_name)
15
15
  subcommand, resolved_name = subcommand_registry.lookup_command(args.first)
16
16
  if subcommand
17
17
  subcommand.ctx = @ctx
18
+ subcommand.task_registry = @task_registry
18
19
  subcommand.call(args, resolved_name, command_name)
19
20
  else
20
21
  cmd = new(@ctx)
21
22
  cmd.options.parse(@_options, args)
22
23
  return call_help(command_name) if cmd.options.help
24
+ run_prerequisites
23
25
  cmd.call(args, command_name)
24
26
  end
25
27
  end
@@ -41,13 +43,16 @@ module ShopifyCli
41
43
  end
42
44
 
43
45
  def prerequisite_task(*tasks)
44
- tasks.each do |task|
45
- prerequisite_tasks[task] = ShopifyCli::Tasks::Registry[task]
46
- end
46
+ @prerequisite_tasks ||= []
47
+ @prerequisite_tasks += tasks
48
+ end
49
+
50
+ def run_prerequisites
51
+ (@prerequisite_tasks || []).each { |task| task_registry[task]&.call(@ctx) }
47
52
  end
48
53
 
49
- def prerequisite_tasks
50
- @prerequisite_tasks ||= {}
54
+ def task_registry
55
+ @task_registry || ShopifyCli::Tasks::Registry
51
56
  end
52
57
 
53
58
  def call_help(*cmds)
@@ -57,6 +62,7 @@ module ShopifyCli
57
62
  end
58
63
 
59
64
  def initialize(ctx = nil)
65
+ super()
60
66
  @ctx = ctx || ShopifyCli::Context.new
61
67
  self.options = Options.new
62
68
  end
@@ -12,21 +12,14 @@ module ShopifyCli
12
12
  @ctx.puts prod_warning if [:rails, :node].include?(Project.current_project_type)
13
13
  end
14
14
 
15
- env_data = begin
16
- Resources::EnvFile.parse_external_env
17
- rescue Errno::ENOENT
18
- {}
19
- end
20
-
21
- org = fetch_org
22
- id = org['id']
23
- app = get_app(id, org['apps'])
24
- shop = get_shop(org['stores'], id)
25
-
26
- write_env(app, shop, env_data[:scopes], env_data[:extra])
27
- write_cli_yml(project_type, id) unless Project.has_current?
15
+ org = ShopifyCli::Tasks::EnsureEnv.call(@ctx, regenerate: true)
16
+ write_cli_yml(project_type, org['id']) unless Project.has_current?
17
+ api_key = Project.current(force_reload: true).env['api_key']
18
+ @ctx.puts(@ctx.message('core.connect.connected', get_app(org['apps'], api_key).first["title"]))
19
+ end
28
20
 
29
- @ctx.puts(@ctx.message('core.connect.connected', app['title']))
21
+ def get_app(apps, api_key)
22
+ apps.select { |app| app["apiKey"] == api_key }
30
23
  end
31
24
 
32
25
  def ask_project_type
@@ -37,67 +30,6 @@ module ShopifyCli
37
30
  end
38
31
  end
39
32
 
40
- def fetch_org
41
- orgs = PartnersAPI::Organizations.fetch_with_app(@ctx)
42
- org_id = if orgs.count == 1
43
- orgs.first["id"]
44
- else
45
- CLI::UI::Prompt.ask(@ctx.message('core.connect.organization_select')) do |handler|
46
- orgs.each do |org|
47
- handler.option(
48
- @ctx.message('core.partners_api.org_name_and_id', org['businessName'], org['id'])
49
- ) { org["id"] }
50
- end
51
- end
52
- end
53
- org = orgs.find { |o| o["id"] == org_id }
54
- org
55
- end
56
-
57
- def get_app(org_id, apps)
58
- if apps.count == 1
59
- apps.first
60
- elsif apps.count == 0
61
- @ctx.puts(@ctx.message('core.connect.no_apps'))
62
- title = CLI::UI::Prompt.ask(@ctx.message('core.connect.app_name'))
63
- type = CLI::UI::Prompt.ask(@ctx.message('core.connect.app_type.select')) do |handler|
64
- handler.option(@ctx.message('core.connect.app_type.select_public')) { 'public' }
65
- handler.option(@ctx.message('core.connect.app_type.select_custom')) { 'custom' }
66
- end
67
- ShopifyCli::Tasks::CreateApiClient.call(@ctx, org_id: org_id, title: title, type: type)
68
- else
69
- CLI::UI::Prompt.ask(@ctx.message('core.connect.app_select')) do |handler|
70
- apps.each { |app| handler.option(app["title"]) { app } }
71
- end
72
- end
73
- end
74
-
75
- def get_shop(shops, id)
76
- if shops.count == 1
77
- shop = shops.first["shopDomain"]
78
- elsif shops.count == 0
79
- @ctx.puts(@ctx.message('core.connect.no_development_stores', id))
80
- else
81
- shop = CLI::UI::Prompt.ask(@ctx.message('core.connect.development_store_select')) do |handler|
82
- shops.each { |s| handler.option(s["shopName"]) { s["shopDomain"] } }
83
- end
84
- end
85
- shop
86
- end
87
-
88
- def write_env(app, shop, scopes, extra)
89
- scopes = 'write_products,write_customers,write_draft_orders' if scopes.nil?
90
- extra = {} if extra.nil?
91
-
92
- Resources::EnvFile.new(
93
- api_key: app["apiKey"],
94
- secret: app["apiSecretKeys"].first["secret"],
95
- shop: shop,
96
- scopes: scopes,
97
- extra: extra,
98
- ).write(@ctx)
99
- end
100
-
101
33
  def write_cli_yml(project_type, org_id)
102
34
  ShopifyCli::Project.write(
103
35
  @ctx,
@@ -32,7 +32,7 @@ module ShopifyCli
32
32
  end
33
33
 
34
34
  def self.help
35
- project_types = all_visible_type.map(&:project_type).join(" | ")
35
+ project_types = all_visible_type.map(&:project_type).sort.join(" | ")
36
36
  ShopifyCli::Context.message('core.create.help', ShopifyCli::TOOL_NAME, project_types)
37
37
  end
38
38
 
@@ -36,11 +36,13 @@ module ShopifyCli
36
36
  cli_constants_extra = %w(
37
37
  PROJECT_TYPES_DIR
38
38
  TEMP_DIR
39
- CACHE_DIR
40
- TOOL_CONFIG_PATH
41
- LOG_FILE
42
- DEBUG_LOG_FILE
43
39
  )
40
+ cli_path_methods = [
41
+ :cache_dir,
42
+ :tool_config_path,
43
+ :log_file,
44
+ :debug_log_file,
45
+ ]
44
46
 
45
47
  cli_constants += cli_constants_extra if show_all_details
46
48
 
@@ -48,6 +50,12 @@ module ShopifyCli
48
50
  cli_constants.each do |s|
49
51
  @ctx.puts(" " + @ctx.message('core.system.const', s, ShopifyCli.const_get(s.to_sym)) + "\n")
50
52
  end
53
+
54
+ if show_all_details
55
+ cli_path_methods.each do |m|
56
+ @ctx.puts(" " + @ctx.message('core.system.const', m.upcase, ShopifyCli.send(m)) + "\n")
57
+ end
58
+ end
51
59
  end
52
60
 
53
61
  def display_cli_ruby(_show_all_details)
@@ -60,13 +68,14 @@ module ShopifyCli
60
68
  end
61
69
 
62
70
  def display_utility_commands(_show_all_details)
63
- commands = %w(git curl tar unzip)
71
+ commands = %w(git curl tar)
64
72
 
65
73
  @ctx.puts("\n" + @ctx.message('core.system.command_header'))
66
74
  commands.each do |s|
67
- output, status = @ctx.capture2e('which', s)
68
- if status.success?
69
- @ctx.puts(" " + @ctx.message('core.system.command_with_path', s, output))
75
+ cmd_path = @ctx.which(s)
76
+
77
+ if !cmd_path.nil?
78
+ @ctx.puts(" " + @ctx.message('core.system.command_with_path', s, cmd_path))
70
79
  else
71
80
  @ctx.puts(" " + @ctx.message('core.system.command_not_found', s))
72
81
  end
@@ -74,7 +83,7 @@ module ShopifyCli
74
83
  end
75
84
 
76
85
  def display_ngrok
77
- ngrok_location = File.join(ShopifyCli::CACHE_DIR, 'ngrok')
86
+ ngrok_location = File.join(ShopifyCli.cache_dir, @ctx.windows? ? 'ngrok.exe' : 'ngrok')
78
87
  if File.exist?(ngrok_location)
79
88
  @ctx.puts(" " + @ctx.message('core.system.ngrok_available', ngrok_location))
80
89
  else
@@ -94,11 +103,11 @@ module ShopifyCli
94
103
  def display_project(project_type, commands)
95
104
  @ctx.puts("\n" + @ctx.message('core.system.project.header', project_type))
96
105
  commands.each do |s|
97
- output, status = @ctx.capture2e('which', s)
98
- if status.success?
106
+ cmd_path = @ctx.which(s)
107
+ if !cmd_path.nil?
99
108
  version_output, _ = @ctx.capture2e(s, '--version')
100
109
  version = version_output.match(/(\d+\.[^\s]+)/)[0]
101
- @ctx.puts(" " + @ctx.message('core.system.project.command_with_path', s, output.strip, version.strip))
110
+ @ctx.puts(" " + @ctx.message('core.system.project.command_with_path', s, cmd_path.strip, version.strip))
102
111
  else
103
112
  @ctx.puts(" " + @ctx.message('core.system.project.command_not_found', s))
104
113
  end
@@ -2,6 +2,8 @@
2
2
  require 'shopify_cli'
3
3
  require 'fileutils'
4
4
  require 'rbconfig'
5
+ require 'net/http'
6
+ require 'json'
5
7
 
6
8
  module ShopifyCli
7
9
  ##
@@ -11,6 +13,11 @@ module ShopifyCli
11
13
  # resoures.
12
14
  #
13
15
  class Context
16
+ GEM_LATEST_URI = URI.parse('https://rubygems.org/api/v1/versions/shopify-cli/latest.json')
17
+ VERSION_CHECK_SECTION = 'versioncheck'
18
+ LAST_CHECKED_AT_FIELD = 'last_checked_at'
19
+ VERSION_CHECK_INTERVAL = 86400
20
+
14
21
  class << self
15
22
  attr_reader :messages
16
23
 
@@ -56,6 +63,7 @@ module ShopifyCli
56
63
  host = uname
57
64
  return :mac if /darwin/.match(host)
58
65
  return :linux if /linux/.match(host)
66
+ return :windows if /mingw32/.match(host)
59
67
  end
60
68
 
61
69
  # will return true if the cli is running on an apple computer.
@@ -68,6 +76,11 @@ module ShopifyCli
68
76
  os == :linux
69
77
  end
70
78
 
79
+ # will return true if the cli is running on Windows
80
+ def windows?
81
+ os == :windows
82
+ end
83
+
71
84
  # will return true if the cli is being run from an installation, and not a
72
85
  # development instance. The gem installation will not have a 'test' directory.
73
86
  # See `#development?` for checking for development environment.
@@ -418,6 +431,45 @@ module ShopifyCli
418
431
  end
419
432
  end
420
433
 
434
+ # Checks if the given command exists in the system
435
+ #
436
+ # #### Parameters
437
+ # - `cmd`: The command to test
438
+ #
439
+ # #### Returns
440
+ # The path of the executable if it is found
441
+ #
442
+ # @todo This is currently a duplicate of CLI::Kit::System.which() - we should make that method public when we make
443
+ # Kit changes and make this a wrapper instead.
444
+ def which(cmd)
445
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
446
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
447
+ exts.each do |ext|
448
+ exe = File.join(File.expand_path(path), "#{cmd}#{ext}")
449
+ return exe if File.executable?(exe) && !File.directory?(exe)
450
+ end
451
+ end
452
+
453
+ nil
454
+ end
455
+
456
+ # Checks if there's a newer version of the CLI available and returns version string if
457
+ # this should be conveyed to the user (i.e., if it's been over 24 hours since last check)
458
+ #
459
+ # #### Parameters
460
+ #
461
+ # #### Returns
462
+ # - `version`: string of newer version available, IFF new version is available AND it's time to inform user,
463
+ # : nil otherwise
464
+ #
465
+ def new_version
466
+ if (time_of_last_check + VERSION_CHECK_INTERVAL) < (now = Time.now.to_i)
467
+ update_time_of_last_check(now)
468
+ latest_version = retrieve_latest_gem_version
469
+ latest_version unless latest_version == ShopifyCli::VERSION
470
+ end
471
+ end
472
+
421
473
  private
422
474
 
423
475
  def ctx_path(fname)
@@ -428,5 +480,21 @@ module ShopifyCli
428
480
  File.join(root, fname)
429
481
  end
430
482
  end
483
+
484
+ def retrieve_latest_gem_version
485
+ response = Net::HTTP.get_response(GEM_LATEST_URI)
486
+ latest = JSON.parse(response.body)
487
+ latest["version"]
488
+ rescue
489
+ nil
490
+ end
491
+
492
+ def time_of_last_check
493
+ (val = ShopifyCli::Config.get(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD)) ? val.to_i : 0
494
+ end
495
+
496
+ def update_time_of_last_check(time)
497
+ ShopifyCli::Config.set(VERSION_CHECK_SECTION, LAST_CHECKED_AT_FIELD, time)
498
+ end
431
499
  end
432
500
  end
@@ -28,6 +28,9 @@ module ShopifyCli
28
28
  ctx.puts(
29
29
  ctx.message('core.warning.development_version', File.join(ShopifyCli::ROOT, 'bin', ShopifyCli::TOOL_NAME))
30
30
  )
31
+ else
32
+ new_version = ctx.new_version
33
+ ctx.puts(ctx.message('core.warning.new_version', ShopifyCli::VERSION, new_version)) unless new_version.nil?
31
34
  end
32
35
 
33
36
  ProjectType.load_type(Project.current_project_type)
@@ -35,7 +38,7 @@ module ShopifyCli
35
38
  task_registry = ShopifyCli::Tasks::Registry
36
39
 
37
40
  command, command_name, args = ShopifyCli::Resolver.call(args)
38
- executor = ShopifyCli::Core::Executor.new(ctx, task_registry, log_file: ShopifyCli::LOG_FILE)
41
+ executor = ShopifyCli::Core::Executor.new(ctx, task_registry, log_file: ShopifyCli.log_file)
39
42
  ShopifyCli::Core::Monorail.log(command_name, args) do
40
43
  executor.call(command, command_name, args)
41
44
  end
@@ -3,16 +3,14 @@ require 'shopify_cli'
3
3
  module ShopifyCli
4
4
  module Core
5
5
  class Executor < CLI::Kit::Executor
6
- def initialize(ctx, task_registry, *args)
6
+ def initialize(ctx, task_registry, *args, **kwargs)
7
7
  @ctx = ctx || ShopifyCli::Context.new
8
8
  @task_registry = task_registry || ShopifyCli::Tasks::TaskRegistry.new
9
- super(*args)
9
+ super(*args, **kwargs)
10
10
  end
11
11
 
12
12
  def call(command, command_name, args)
13
- command.prerequisite_tasks.each do |task, _|
14
- @task_registry[task]&.call(@ctx)
15
- end
13
+ command.task_registry = @task_registry
16
14
  command.ctx = @ctx
17
15
  super
18
16
  end