shopify-cli 2.15.2 → 2.15.5
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/.vscode/settings.json +1 -2
- data/CHANGELOG.md +69 -22
- data/Gemfile.lock +1 -1
- data/Rakefile +8 -0
- data/ext/javy/hashes/javy-arm-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.3.0.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/ext/shopify-extensions/version +1 -1
- data/lib/project_types/extension/cli.rb +4 -0
- data/lib/project_types/extension/commands/check.rb +6 -1
- data/lib/project_types/extension/forms/questions/ask_template.rb +1 -2
- data/lib/project_types/extension/messages/messages.rb +0 -2
- data/lib/project_types/extension/models/development_server_requirements.rb +1 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension.rb +57 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config.rb +33 -0
- data/lib/project_types/extension/models/specification_handlers/beacon_extension_utils/script_config_repository.rb +75 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +16 -1
- data/lib/project_types/extension/models/specification_handlers/theme_app_extension.rb +4 -1
- data/lib/project_types/extension/tasks/configure_options.rb +2 -1
- data/lib/project_types/extension/tasks/convert_server_config.rb +13 -2
- data/lib/project_types/extension/tasks/merge_server_config.rb +5 -2
- data/lib/project_types/script/cli.rb +1 -0
- data/lib/project_types/script/layers/application/create_script.rb +14 -6
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +6 -21
- data/lib/project_types/script/layers/infrastructure/sparse_checkout_details.rb +35 -0
- data/lib/project_types/theme/cli.rb +1 -0
- data/lib/project_types/theme/commands/check.rb +4 -1
- data/lib/project_types/theme/commands/open.rb +2 -2
- data/lib/project_types/theme/commands/push.rb +1 -3
- data/lib/project_types/theme/commands/share.rb +56 -0
- data/lib/project_types/theme/messages/messages.rb +24 -3
- data/lib/shopify_cli/changelog.rb +97 -25
- data/lib/shopify_cli/command_options/command_serve_options.rb +10 -0
- data/lib/shopify_cli/commands/app/serve.rb +7 -7
- data/lib/shopify_cli/commands/login.rb +5 -2
- data/lib/shopify_cli/context.rb +13 -0
- data/lib/shopify_cli/identity_auth.rb +24 -4
- data/lib/shopify_cli/messages/messages.rb +17 -7
- data/lib/shopify_cli/release.rb +1 -1
- data/lib/shopify_cli/services/app/create/rails_service.rb +9 -1
- data/lib/shopify_cli/services/app/serve/node_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/php_service.rb +2 -25
- data/lib/shopify_cli/services/app/serve/rails_service.rb +8 -28
- data/lib/shopify_cli/services/app/serve/serve_service.rb +57 -0
- data/lib/shopify_cli/services.rb +1 -0
- data/lib/shopify_cli/tasks/update_dashboard_urls.rb +7 -9
- data/lib/shopify_cli/theme/dev_server/remote_watcher/json_files_update_job.rb +1 -0
- data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -8
- data/lib/shopify_cli/theme/dev_server.rb +3 -2
- data/lib/shopify_cli/theme/theme.rb +21 -7
- data/lib/shopify_cli/theme/theme_admin_api.rb +23 -8
- data/lib/shopify_cli/tunnel.rb +3 -13
- data/lib/shopify_cli/version.rb +1 -1
- data/vendor/deps/cli-ui/lib/cli/ui/os.rb +8 -0
- metadata +12 -2
@@ -23,19 +23,23 @@ module Script
|
|
23
23
|
)
|
24
24
|
|
25
25
|
# remove the need to pass the whole extension-point object to the infra layer
|
26
|
-
sparse_checkout_repo = extension_point.libraries.for(language).repo
|
27
26
|
type = extension_point.dasherize_type
|
28
27
|
domain = extension_point.domain
|
29
28
|
|
29
|
+
sparse_checkout_details = Infrastructure::SparseCheckoutDetails.new(
|
30
|
+
repo: extension_point.libraries.for(language).repo,
|
31
|
+
branch: sparse_checkout_branch,
|
32
|
+
path: "#{domain}/#{language}/#{type}/default",
|
33
|
+
input_queries_enabled: input_queries_enabled?,
|
34
|
+
)
|
35
|
+
|
30
36
|
project_creator = Infrastructure::Languages::ProjectCreator.for(
|
31
37
|
ctx: ctx,
|
32
38
|
language: language,
|
33
39
|
type: type,
|
34
40
|
project_name: title,
|
35
41
|
path_to_project: project.id,
|
36
|
-
|
37
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
38
|
-
sparse_checkout_set_path: "#{domain}/#{language}/#{type}/default"
|
42
|
+
sparse_checkout_details: sparse_checkout_details,
|
39
43
|
)
|
40
44
|
|
41
45
|
install_dependencies(ctx, language, title, project_creator)
|
@@ -49,12 +53,12 @@ module Script
|
|
49
53
|
task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language)
|
50
54
|
CLI::UI::Frame.open(ctx.message(
|
51
55
|
"core.git.pulling_from_to",
|
52
|
-
project_creator.
|
56
|
+
project_creator.sparse_checkout_details.repo,
|
53
57
|
title,
|
54
58
|
)) do
|
55
59
|
UI::StrictSpinner.spin(ctx.message(
|
56
60
|
"core.git.pulling",
|
57
|
-
project_creator.
|
61
|
+
project_creator.sparse_checkout_details.repo,
|
58
62
|
title,
|
59
63
|
)) do |spinner|
|
60
64
|
project_creator.setup_dependencies
|
@@ -75,6 +79,10 @@ module Script
|
|
75
79
|
ensure
|
76
80
|
script_project_repo.change_to_initial_directory
|
77
81
|
end
|
82
|
+
|
83
|
+
def input_queries_enabled?
|
84
|
+
ShopifyCLI::Feature.enabled?(:scripts_beta_input_queries)
|
85
|
+
end
|
78
86
|
end
|
79
87
|
end
|
80
88
|
end
|
@@ -10,9 +10,7 @@ module Script
|
|
10
10
|
property! :type, accepts: String
|
11
11
|
property! :project_name, accepts: String
|
12
12
|
property! :path_to_project, accepts: String
|
13
|
-
property! :
|
14
|
-
property! :sparse_checkout_branch, accepts: String
|
15
|
-
property! :sparse_checkout_set_path, accepts: String
|
13
|
+
property! :sparse_checkout_details, accepts: SparseCheckoutDetails
|
16
14
|
|
17
15
|
def self.for(
|
18
16
|
ctx:,
|
@@ -20,9 +18,7 @@ module Script
|
|
20
18
|
type:,
|
21
19
|
project_name:,
|
22
20
|
path_to_project:,
|
23
|
-
|
24
|
-
sparse_checkout_branch:,
|
25
|
-
sparse_checkout_set_path:
|
21
|
+
sparse_checkout_details:
|
26
22
|
)
|
27
23
|
|
28
24
|
project_creators = {
|
@@ -36,33 +32,22 @@ module Script
|
|
36
32
|
type: type,
|
37
33
|
project_name: project_name,
|
38
34
|
path_to_project: path_to_project,
|
39
|
-
|
40
|
-
sparse_checkout_branch: sparse_checkout_branch,
|
41
|
-
sparse_checkout_set_path: sparse_checkout_set_path
|
35
|
+
sparse_checkout_details: sparse_checkout_details,
|
42
36
|
)
|
43
37
|
end
|
44
38
|
|
45
39
|
# the sparse checkout process is common to all script types
|
46
40
|
def setup_dependencies
|
47
|
-
|
41
|
+
sparse_checkout_details.setup(ctx)
|
48
42
|
clean
|
49
43
|
end
|
50
44
|
|
51
45
|
private
|
52
46
|
|
53
|
-
def setup_sparse_checkout
|
54
|
-
ShopifyCLI::Git.sparse_checkout(
|
55
|
-
sparse_checkout_repo,
|
56
|
-
sparse_checkout_set_path,
|
57
|
-
sparse_checkout_branch,
|
58
|
-
ctx
|
59
|
-
)
|
60
|
-
end
|
61
|
-
|
62
47
|
def clean
|
63
|
-
source = File.join(path_to_project,
|
48
|
+
source = File.join(path_to_project, sparse_checkout_details.path, ".")
|
64
49
|
FileUtils.cp_r(source, path_to_project)
|
65
|
-
ctx.rm_rf(
|
50
|
+
ctx.rm_rf(sparse_checkout_details.path.split("/")[0])
|
66
51
|
ctx.rm_rf(".git")
|
67
52
|
end
|
68
53
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Script
|
4
|
+
module Layers
|
5
|
+
module Infrastructure
|
6
|
+
class SparseCheckoutDetails
|
7
|
+
include SmartProperties
|
8
|
+
property! :repo, accepts: String
|
9
|
+
property! :branch, accepts: String
|
10
|
+
property! :path, accepts: String
|
11
|
+
property! :input_queries_enabled, accepts: [true, false]
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.class == other.class &&
|
15
|
+
self.class.properties.all? { |name, _| self[name] == other[name] }
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup(ctx)
|
19
|
+
ShopifyCLI::Git.sparse_checkout(repo, patterns_to_checkout, branch, ctx)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def patterns_to_checkout
|
25
|
+
paths = [path]
|
26
|
+
unless input_queries_enabled
|
27
|
+
paths << "!#{path}/#{ScriptProjectRepository::INPUT_QUERY_PATH}"
|
28
|
+
paths << "!#{path}/schema.graphql"
|
29
|
+
end
|
30
|
+
paths.join(" ")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -16,6 +16,7 @@ module Theme
|
|
16
16
|
subcommand :Package, "package", Project.project_filepath("commands/package")
|
17
17
|
subcommand :Open, "open", Project.project_filepath("commands/open")
|
18
18
|
subcommand :List, "list", Project.project_filepath("commands/list")
|
19
|
+
subcommand :Share, "share", Project.project_filepath("commands/share")
|
19
20
|
subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
|
20
21
|
end
|
21
22
|
ShopifyCLI::Commands.register("Theme::Command", "theme")
|
@@ -24,7 +24,10 @@ module Theme
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def call(*)
|
27
|
-
@theme_check.run
|
27
|
+
@theme_check.run!
|
28
|
+
rescue ThemeCheck::Cli::Abort, ThemeCheck::ThemeCheckError => e
|
29
|
+
raise ShopifyCLI::Abort,
|
30
|
+
ShopifyCLI::Context.message("theme.check.error", e.full_message)
|
28
31
|
end
|
29
32
|
|
30
33
|
def self.help
|
@@ -17,8 +17,8 @@ module Theme
|
|
17
17
|
def call(_args, _name)
|
18
18
|
theme = find_theme(**options.flags)
|
19
19
|
|
20
|
-
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.editor_url))
|
21
|
-
@ctx.
|
20
|
+
@ctx.puts(@ctx.message("theme.open.details", theme.name, theme.preview_url, theme.editor_url))
|
21
|
+
@ctx.open_browser_url!(theme.preview_url)
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.help
|
@@ -104,9 +104,7 @@ module Theme
|
|
104
104
|
|
105
105
|
if unpublished
|
106
106
|
name = theme || ask_theme_name
|
107
|
-
|
108
|
-
new_theme.create
|
109
|
-
return new_theme
|
107
|
+
return ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root, name: name)
|
110
108
|
end
|
111
109
|
|
112
110
|
if theme
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "shopify_cli/theme/theme"
|
4
|
+
require "shopify_cli/theme/syncer"
|
5
|
+
require "project_types/theme/commands/common/root_helper"
|
6
|
+
|
7
|
+
module Theme
|
8
|
+
class Command
|
9
|
+
class Share < ShopifyCLI::Command::SubCommand
|
10
|
+
include Common::RootHelper
|
11
|
+
|
12
|
+
recommend_default_ruby_range
|
13
|
+
|
14
|
+
def call(_args, name)
|
15
|
+
root = root_value(options, name)
|
16
|
+
theme = create_theme(root)
|
17
|
+
|
18
|
+
upload(theme)
|
19
|
+
|
20
|
+
@ctx.done(done_message(theme))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.help
|
24
|
+
tool = ShopifyCLI::TOOL_NAME
|
25
|
+
@ctx.message("theme.share.help", tool, tool)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_theme(root)
|
31
|
+
ShopifyCLI::Theme::Theme.create_unpublished(@ctx, root: root)
|
32
|
+
end
|
33
|
+
|
34
|
+
def upload(theme)
|
35
|
+
syncer = ShopifyCLI::Theme::Syncer.new(@ctx, theme: theme)
|
36
|
+
syncer.start_threads
|
37
|
+
|
38
|
+
CLI::UI::Frame.open(upload_message(theme)) do
|
39
|
+
UI::SyncProgressBar.new(syncer).progress(:upload_theme!)
|
40
|
+
end
|
41
|
+
|
42
|
+
raise ShopifyCLI::AbortSilent if syncer.has_any_error?
|
43
|
+
ensure
|
44
|
+
syncer.shutdown
|
45
|
+
end
|
46
|
+
|
47
|
+
def upload_message(theme)
|
48
|
+
@ctx.message("theme.share.upload", theme.name, theme.id, theme.shop)
|
49
|
+
end
|
50
|
+
|
51
|
+
def done_message(theme)
|
52
|
+
@ctx.message("theme.share.done", theme.name, theme.preview_url, theme.editor_url)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -8,8 +8,9 @@ module Theme
|
|
8
8
|
Usage: {{command:%1$s theme [ %2$s ]}}
|
9
9
|
HELP
|
10
10
|
ensure_user_error: "You are not authorized to edit themes on %s.",
|
11
|
-
ensure_user_try_this:
|
12
|
-
|
11
|
+
ensure_user_try_this: <<~ENSURE_USER,
|
12
|
+
Check if your user is activated, has permission to edit themes at the store, and try to re-login.
|
13
|
+
ENSURE_USER
|
13
14
|
init: {
|
14
15
|
help: <<~HELP,
|
15
16
|
{{command:%s theme init}}: Clones a Git repository to use as a starting point for building a new theme.
|
@@ -181,7 +182,7 @@ module Theme
|
|
181
182
|
CUSTOMIZE_OR_PREVIEW
|
182
183
|
ensure_user: <<~ENSURE_USER,
|
183
184
|
You are not authorized to edit themes on %s.
|
184
|
-
|
185
|
+
Check if your user is activated, has permission to edit themes at the store, and try to re-login.
|
185
186
|
ENSURE_USER
|
186
187
|
address_already_in_use: "The address \"%s\" is already in use.",
|
187
188
|
try_port_option: "Use the --port=PORT option to serve the theme in a different port.",
|
@@ -191,6 +192,7 @@ module Theme
|
|
191
192
|
Check your theme for errors, suggestions, and best practices.
|
192
193
|
Usage: {{command:%s check}}
|
193
194
|
HELP
|
195
|
+
error: "Theme check failed with error:\n%s",
|
194
196
|
},
|
195
197
|
delete: {
|
196
198
|
help: <<~HELP,
|
@@ -262,6 +264,9 @@ module Theme
|
|
262
264
|
details: <<~DETAILS,
|
263
265
|
{{*}} {{bold:%s}}
|
264
266
|
|
267
|
+
Preview your theme:
|
268
|
+
{{green:%s}}
|
269
|
+
|
265
270
|
Customize your theme in the Theme Editor:
|
266
271
|
{{green:%s}}
|
267
272
|
|
@@ -285,6 +290,22 @@ module Theme
|
|
285
290
|
Usage: {{command:%s theme list}}
|
286
291
|
HELP
|
287
292
|
},
|
293
|
+
share: {
|
294
|
+
help: <<~HELP,
|
295
|
+
{{command:%s theme share}}: Creates a shareable, unpublished, and new theme on your theme library with a randomized name.
|
296
|
+
Works like an alias to {{command:theme push -u -t=RANDOMIZED_NAME}}.
|
297
|
+
|
298
|
+
Usage: {{command:%s theme share [ ROOT ]}}
|
299
|
+
HELP
|
300
|
+
done: <<~DONE,
|
301
|
+
{{green:The {{bold:%s}} theme was pushed successfully}}
|
302
|
+
|
303
|
+
{{info:Share your theme preview:}}
|
304
|
+
{{underline:%s}}
|
305
|
+
|
306
|
+
DONE
|
307
|
+
upload: "Pushing theme files to %s (#%s) on %s",
|
308
|
+
},
|
288
309
|
},
|
289
310
|
}.freeze
|
290
311
|
end
|
@@ -1,23 +1,32 @@
|
|
1
|
+
require "date"
|
1
2
|
require "shopify_cli/sed"
|
3
|
+
require "octokit"
|
2
4
|
|
3
5
|
module ShopifyCLI
|
4
6
|
class Changelog
|
5
7
|
CHANGELOG_FILE = File.join(ShopifyCLI::ROOT, "CHANGELOG.md")
|
8
|
+
CHANGE_CATEGORIES = %w(Added Changed Deprecated Removed Fixed Security)
|
6
9
|
|
7
10
|
def initialize
|
8
11
|
load(File.read(CHANGELOG_FILE))
|
9
12
|
end
|
10
13
|
|
11
14
|
def update_version!(new_version)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
changes[new_version] = changes["Unreleased"]
|
16
|
+
changes[new_version][:date] = Date.today.iso8601
|
17
|
+
changes["Unreleased"] = { changes: [], date: nil }
|
18
|
+
save!
|
19
|
+
end
|
20
|
+
|
21
|
+
def update!
|
22
|
+
pr = pr_for_current_branch
|
23
|
+
category = CLI::UI::Prompt.ask("What type of change?", options: CHANGE_CATEGORIES)
|
24
|
+
add_change(category, { pr_id: pr.number, desc: pr.title })
|
25
|
+
save!
|
17
26
|
end
|
18
27
|
|
19
28
|
def release_notes(version)
|
20
|
-
changes[version].map do |change_category, changes|
|
29
|
+
changes[version][:changes].map do |change_category, changes|
|
21
30
|
<<~CHANGES
|
22
31
|
### #{change_category}
|
23
32
|
#{changes.map { |change| entry(**change) }.join("\n")}
|
@@ -25,17 +34,61 @@ module ShopifyCLI
|
|
25
34
|
end.join("\n")
|
26
35
|
end
|
27
36
|
|
37
|
+
def add_change(category, change)
|
38
|
+
changes["Unreleased"][:changes][category] << change
|
39
|
+
end
|
40
|
+
|
28
41
|
def entry(pr_id:, desc:)
|
29
42
|
"* [##{pr_id}](https://github.com/Shopify/shopify-cli/pull/#{pr_id}): #{desc}"
|
30
43
|
end
|
31
44
|
|
45
|
+
def full_contents
|
46
|
+
sorted_changes = changes.each_key.sort_by do |change|
|
47
|
+
if change == "Unreleased"
|
48
|
+
[Float::INFINITY] * 3 # end of the list
|
49
|
+
else
|
50
|
+
major, minor, patch = change.split(".").map(&:to_i)
|
51
|
+
[major, minor, patch]
|
52
|
+
end
|
53
|
+
end.reverse
|
54
|
+
[
|
55
|
+
heading,
|
56
|
+
*sorted_changes.each.map { |version| release_notes_with_header(version) }.join,
|
57
|
+
remainder,
|
58
|
+
].map { |section| section.chomp << "\n" }.join
|
59
|
+
end
|
60
|
+
|
61
|
+
def save!
|
62
|
+
File.write(CHANGELOG_FILE, full_contents)
|
63
|
+
end
|
64
|
+
|
32
65
|
private
|
33
66
|
|
67
|
+
attr_reader :heading, :remainder
|
68
|
+
|
69
|
+
def release_notes_with_header(version)
|
70
|
+
header_line =
|
71
|
+
if version == "Unreleased"
|
72
|
+
"[Unreleased]"
|
73
|
+
else
|
74
|
+
date = changes[version][:date]
|
75
|
+
"Version #{version}#{" - #{date}" if date}"
|
76
|
+
end
|
77
|
+
|
78
|
+
[
|
79
|
+
"## #{header_line}",
|
80
|
+
release_notes(version),
|
81
|
+
].reject(&:empty?).map { |section| section.chomp << "\n\n" }.join
|
82
|
+
end
|
83
|
+
|
34
84
|
def changes
|
35
85
|
@changes ||= Hash.new do |h, k|
|
36
|
-
h[k] =
|
37
|
-
|
38
|
-
|
86
|
+
h[k] = {
|
87
|
+
date: nil,
|
88
|
+
changes: Hash.new do |h2, k2|
|
89
|
+
h2[k2] = []
|
90
|
+
end,
|
91
|
+
}
|
39
92
|
end
|
40
93
|
end
|
41
94
|
|
@@ -43,34 +96,53 @@ module ShopifyCLI
|
|
43
96
|
state = :initial
|
44
97
|
change_category = nil
|
45
98
|
current_version = nil
|
99
|
+
@heading = ""
|
46
100
|
@remainder = ""
|
47
101
|
log.each_line do |line|
|
48
102
|
case state
|
49
103
|
when :initial
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
104
|
+
if line.chomp == "\#\# [Unreleased]"
|
105
|
+
state = :unreleased
|
106
|
+
current_version = "Unreleased"
|
107
|
+
# Ensure Unreleased changeset exists even if no changes have happened yet
|
108
|
+
changes["Unreleased"]
|
109
|
+
else
|
110
|
+
@heading << line
|
111
|
+
end
|
112
|
+
when :unreleased, :prior_versions
|
54
113
|
if /\A\#\#\# (?<category>\w+)/ =~ line
|
55
114
|
change_category = category
|
56
|
-
elsif %r{\A\* \[\#(?<
|
57
|
-
changes[current_version][change_category] << { pr_id:
|
58
|
-
elsif /\A\#\# Version (?<version>\d+\.\d+\.\d+)
|
115
|
+
elsif %r{\A\* \[\#(?<id>\d+)\]\(https://github.com/Shopify/shopify-cli/pull/\k<id>\): (?<desc>.+)\n} =~ line
|
116
|
+
changes[current_version][:changes][change_category] << { pr_id: id, desc: desc }
|
117
|
+
elsif /\A\#\# Version (?<version>\d+\.\d+\.\d+)( - (?<date>\d{4}-\d{2}-\d{2}))?/ =~ line
|
59
118
|
current_version = version
|
60
|
-
state =
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
119
|
+
state = :prior_versions
|
120
|
+
major, minor, _patch = current_version.split(".")
|
121
|
+
if major.to_i <= 2 && minor.to_i < 7
|
122
|
+
# Changelog starts to become irregular in 2.6.x
|
123
|
+
state = :finished
|
124
|
+
end
|
125
|
+
changes[current_version][:date] = date unless state == :finished
|
67
126
|
elsif !line.match?(/\s*\n/)
|
68
127
|
raise "Unrecognized line: #{line.inspect}"
|
69
128
|
end
|
70
|
-
when :finished
|
71
|
-
@remainder << line
|
72
129
|
end
|
130
|
+
@remainder << line if state == :finished
|
73
131
|
end
|
74
132
|
end
|
133
|
+
|
134
|
+
def pr_for_current_branch
|
135
|
+
current_branch = %x(git branch --show-current).chomp
|
136
|
+
search_term = "repo:Shopify/shopify-cli is:pr is:open head:#{current_branch}"
|
137
|
+
results = Octokit::Client.new.search_issues(search_term)
|
138
|
+
case results.total_count
|
139
|
+
when 0
|
140
|
+
raise "PR not opened yet!"
|
141
|
+
when (2..)
|
142
|
+
raise "Multiple open PRs, not sure which one to use for changelog!"
|
143
|
+
end
|
144
|
+
|
145
|
+
results.items.first
|
146
|
+
end
|
75
147
|
end
|
76
148
|
end
|
@@ -20,6 +20,10 @@ module ShopifyCLI
|
|
20
20
|
end
|
21
21
|
host
|
22
22
|
end
|
23
|
+
|
24
|
+
def no_update
|
25
|
+
options.flags[:no_update] || false
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
@@ -37,6 +41,12 @@ module ShopifyCLI
|
|
37
41
|
parser.on("--port=PORT") { |port| flags[:port] = port }
|
38
42
|
end
|
39
43
|
end
|
44
|
+
|
45
|
+
def parse_no_update_option
|
46
|
+
options do |parser, flags|
|
47
|
+
parser.on("--no-update") { flags[:no_update] = true }
|
48
|
+
end
|
49
|
+
end
|
40
50
|
end
|
41
51
|
end
|
42
52
|
end
|
@@ -8,12 +8,9 @@ module ShopifyCLI
|
|
8
8
|
|
9
9
|
recommend_default_ruby_range
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
parser.on("--port=PORT") { |port| flags[:port] = port }
|
16
|
-
end
|
11
|
+
parse_host_option
|
12
|
+
parse_port_option
|
13
|
+
parse_no_update_option
|
17
14
|
|
18
15
|
def call(*)
|
19
16
|
case detect_app
|
@@ -21,18 +18,21 @@ module ShopifyCLI
|
|
21
18
|
Services::App::Serve::RailsService.call(
|
22
19
|
host: host,
|
23
20
|
port: port,
|
21
|
+
no_update: no_update,
|
24
22
|
context: @ctx
|
25
23
|
)
|
26
24
|
when :node
|
27
25
|
Services::App::Serve::NodeService.call(
|
28
26
|
host: host,
|
29
27
|
port: port,
|
28
|
+
no_update: no_update,
|
30
29
|
context: @ctx
|
31
30
|
)
|
32
31
|
when :php
|
33
32
|
Services::App::Serve::PHPService.call(
|
34
33
|
host: host,
|
35
34
|
port: port,
|
35
|
+
no_update: no_update,
|
36
36
|
context: @ctx
|
37
37
|
)
|
38
38
|
end
|
@@ -43,7 +43,7 @@ module ShopifyCLI
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def self.extended_help
|
46
|
-
ShopifyCLI::Context.message("app.
|
46
|
+
ShopifyCLI::Context.message("core.app.serve.extended_help")
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -30,7 +30,7 @@ module ShopifyCLI
|
|
30
30
|
if @ctx.ci? && (password = options.flags[:password] || @ctx.getenv("SHOPIFY_PASSWORD"))
|
31
31
|
ShopifyCLI::DB.set(shopify_exchange_token: password)
|
32
32
|
else
|
33
|
-
IdentityAuth.new(ctx: @ctx).authenticate
|
33
|
+
IdentityAuth.new(ctx: @ctx).authenticate(spinner: true)
|
34
34
|
org = select_organization
|
35
35
|
ShopifyCLI::DB.set(organization_id: org["id"].to_i) unless org.nil?
|
36
36
|
Whoami.call([], "whoami")
|
@@ -75,7 +75,10 @@ module ShopifyCLI
|
|
75
75
|
private
|
76
76
|
|
77
77
|
def select_organization
|
78
|
-
organizations =
|
78
|
+
organizations = []
|
79
|
+
CLI::UI::Spinner.spin(@ctx.message("core.login.spinner.loading_organizations")) do
|
80
|
+
organizations = ShopifyCLI::PartnersAPI::Organizations.fetch_all(@ctx)
|
81
|
+
end
|
79
82
|
|
80
83
|
if organizations.count == 0
|
81
84
|
nil
|
data/lib/shopify_cli/context.rb
CHANGED
@@ -4,6 +4,7 @@ require "fileutils"
|
|
4
4
|
require "rbconfig"
|
5
5
|
require "net/http"
|
6
6
|
require "json"
|
7
|
+
require "bundler"
|
7
8
|
|
8
9
|
module ShopifyCLI
|
9
10
|
##
|
@@ -642,6 +643,18 @@ module ShopifyCLI
|
|
642
643
|
end
|
643
644
|
end
|
644
645
|
|
646
|
+
# Uses bundle to grab the version of a gem
|
647
|
+
#
|
648
|
+
# #### Parameters
|
649
|
+
# - gem: the name of the gem to check
|
650
|
+
#
|
651
|
+
# #### Returns
|
652
|
+
# - version: a Semantic::Version object with the gem version
|
653
|
+
def ruby_gem_version(gem)
|
654
|
+
version = Bundler.load.specs.find { |s| s.name == gem }.version
|
655
|
+
::Semantic::Version.new(version.to_s)
|
656
|
+
end
|
657
|
+
|
645
658
|
private
|
646
659
|
|
647
660
|
def ctx_path(fname)
|
@@ -56,8 +56,10 @@ module ShopifyCLI
|
|
56
56
|
|
57
57
|
attr_accessor :response_query
|
58
58
|
|
59
|
-
def authenticate
|
60
|
-
return if
|
59
|
+
def authenticate(spinner: false)
|
60
|
+
return if with_spinner(spinner, ctx.message("core.login.spinner.initiating")) do
|
61
|
+
attempt_reauthenticate
|
62
|
+
end
|
61
63
|
|
62
64
|
initiate_authentication
|
63
65
|
|
@@ -66,7 +68,21 @@ module ShopifyCLI
|
|
66
68
|
rescue IdentityAuth::Timeout => e
|
67
69
|
ctx.abort(e.message)
|
68
70
|
end
|
69
|
-
|
71
|
+
with_spinner(spinner, ctx.message("core.login.spinner.finalizing")) do
|
72
|
+
request_exchange_tokens
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def with_spinner(spinner, message, &block)
|
77
|
+
result = nil
|
78
|
+
if spinner
|
79
|
+
CLI::UI::Spinner.spin(message) do
|
80
|
+
result = block.call
|
81
|
+
end
|
82
|
+
else
|
83
|
+
result = block.call
|
84
|
+
end
|
85
|
+
result
|
70
86
|
end
|
71
87
|
|
72
88
|
def fetch_or_auth_partners_token
|
@@ -100,10 +116,14 @@ module ShopifyCLI
|
|
100
116
|
end
|
101
117
|
|
102
118
|
def reauthenticate
|
103
|
-
return if
|
119
|
+
return if attempt_reauthenticate
|
104
120
|
ctx.abort(ctx.message("core.identity_auth.error.reauthenticate", ShopifyCLI::TOOL_NAME))
|
105
121
|
end
|
106
122
|
|
123
|
+
def attempt_reauthenticate
|
124
|
+
refresh_exchange_tokens || refresh_access_tokens
|
125
|
+
end
|
126
|
+
|
107
127
|
def code_challenge
|
108
128
|
@code_challenge ||= Base64.urlsafe_encode64(
|
109
129
|
OpenSSL::Digest::SHA256.digest(code_verifier),
|