shopify-cli 2.13.0 → 2.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +5 -0
- data/.github/CONTRIBUTING.md +1 -1
- data/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- data/.github/workflows/stale.yml +46 -0
- data/CHANGELOG.md +36 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +43 -11
- data/Rakefile +43 -0
- data/ext/javy/hashes/javy-arm-macos-v0.2.1.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-linux-v0.2.1.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-macos-v0.2.1.gz.sha256 +1 -0
- data/ext/javy/hashes/javy-x86_64-windows-v0.2.1.gz.sha256 +1 -0
- data/ext/javy/version +1 -1
- data/ext/shopify-extensions/version +1 -1
- data/lib/project_types/extension/forms/questions/ask_template.rb +5 -8
- data/lib/project_types/extension/messages/messages.rb +10 -0
- data/lib/project_types/extension/models/development_server_requirements.rb +13 -7
- data/lib/project_types/extension/models/npm_package.rb +19 -1
- data/lib/project_types/extension/models/server_config/development_renderer.rb +4 -3
- data/lib/project_types/extension/models/server_config/root.rb +2 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +13 -0
- data/lib/project_types/script/cli.rb +0 -4
- data/lib/project_types/script/config/extension_points.yml +18 -6
- data/lib/project_types/script/layers/application/build_script.rb +3 -18
- data/lib/project_types/script/layers/application/push_script.rb +12 -10
- data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -1
- data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +0 -1
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +2 -10
- data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +1 -23
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +1 -1
- data/lib/project_types/script/messages/messages.rb +2 -2
- data/lib/project_types/theme/commands/package.rb +1 -0
- data/lib/project_types/theme/commands/pull.rb +2 -2
- data/lib/project_types/theme/commands/push.rb +2 -2
- data/lib/project_types/theme/conversions/base_glob.rb +20 -5
- data/lib/project_types/theme/messages/messages.rb +9 -0
- data/lib/shopify_cli/changelog.rb +76 -0
- data/lib/shopify_cli/command.rb +8 -7
- data/lib/shopify_cli/commands/app/deploy.rb +0 -1
- data/lib/shopify_cli/context.rb +2 -2
- data/lib/shopify_cli/core/entry_point.rb +1 -1
- data/lib/shopify_cli/core/monorail.rb +14 -6
- data/lib/shopify_cli/environment.rb +19 -11
- data/lib/shopify_cli/exception_reporter.rb +2 -0
- data/lib/shopify_cli/messages/messages.rb +11 -5
- data/lib/shopify_cli/packager.rb +1 -1
- data/lib/shopify_cli/release.rb +94 -0
- data/lib/shopify_cli/result.rb +14 -0
- data/lib/shopify_cli/sed.rb +19 -0
- data/lib/shopify_cli/services/app/create/node_service.rb +2 -14
- data/lib/shopify_cli/services/app/create/php_service.rb +1 -6
- data/lib/shopify_cli/services/app/create/rails_service.rb +4 -12
- data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +5 -5
- data/lib/shopify_cli/theme/dev_server/watcher.rb +10 -2
- data/lib/shopify_cli/theme/development_theme.rb +2 -5
- data/lib/shopify_cli/theme/syncer.rb +20 -25
- data/lib/shopify_cli/theme/theme.rb +28 -31
- data/lib/shopify_cli/theme/theme_admin_api.rb +72 -0
- data/lib/shopify_cli/transform_data_structure.rb +3 -2
- data/lib/shopify_cli/tunnel.rb +9 -0
- data/lib/shopify_cli/version.rb +1 -1
- data/shipit.yml +3 -0
- data/shopify-cli.gemspec +12 -3
- metadata +18 -10
- data/lib/project_types/rails/ruby.rb +0 -17
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +0 -36
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -109
@@ -18,7 +18,8 @@ module Script
|
|
18
18
|
|
19
19
|
def build
|
20
20
|
compile
|
21
|
-
|
21
|
+
rescue Errors::SystemCallFailureError => e
|
22
|
+
raise Errors::BuildError, e.out
|
22
23
|
end
|
23
24
|
|
24
25
|
def install_dependencies
|
@@ -95,15 +96,6 @@ module Script
|
|
95
96
|
raise Errors::BuildScriptNotFoundError,
|
96
97
|
"Build script not found" if build_script.nil?
|
97
98
|
end
|
98
|
-
|
99
|
-
def bytecode
|
100
|
-
raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(BYTECODE_FILE)
|
101
|
-
|
102
|
-
contents = ctx.binread(BYTECODE_FILE)
|
103
|
-
ctx.rm(BYTECODE_FILE)
|
104
|
-
|
105
|
-
contents
|
106
|
-
end
|
107
99
|
end
|
108
100
|
end
|
109
101
|
end
|
@@ -7,23 +7,6 @@ module Script
|
|
7
7
|
include SmartProperties
|
8
8
|
property! :ctx, accepts: ShopifyCLI::Context
|
9
9
|
|
10
|
-
def create_push_package(script_project:, script_content:, metadata:, library:)
|
11
|
-
build_file_path = file_path(script_project.id)
|
12
|
-
write_to_path(build_file_path, script_content)
|
13
|
-
|
14
|
-
Domain::PushPackage.new(
|
15
|
-
id: build_file_path,
|
16
|
-
uuid: script_project.uuid,
|
17
|
-
extension_point_type: script_project.extension_point_type,
|
18
|
-
title: script_project.title,
|
19
|
-
description: script_project.description,
|
20
|
-
script_content: script_content,
|
21
|
-
metadata: metadata,
|
22
|
-
script_config: script_project.script_config,
|
23
|
-
library: library
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
10
|
def get_push_package(script_project:, metadata:, library:)
|
28
11
|
build_file_path = file_path(script_project.id)
|
29
12
|
raise Domain::Errors::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
|
@@ -44,13 +27,8 @@ module Script
|
|
44
27
|
|
45
28
|
private
|
46
29
|
|
47
|
-
def write_to_path(path, content)
|
48
|
-
ctx.mkdir_p(File.dirname(path))
|
49
|
-
ctx.binwrite(path, content)
|
50
|
-
end
|
51
|
-
|
52
30
|
def file_path(path_to_script)
|
53
|
-
"#{path_to_script}/build/
|
31
|
+
"#{path_to_script}/build/index.wasm"
|
54
32
|
end
|
55
33
|
end
|
56
34
|
end
|
@@ -135,8 +135,8 @@ module Script
|
|
135
135
|
"\nbuild: npx shopify-scripts-toolchain-as build --src src/shopify_main.ts --binary build/<script_name>.wasm --metadata build/metadata.json -- --lib node_modules --optimize --use Date=",
|
136
136
|
|
137
137
|
web_assembly_binary_not_found: "Wasm binary not found.",
|
138
|
-
web_assembly_binary_not_found_suggestion: "Check that
|
139
|
-
"
|
138
|
+
web_assembly_binary_not_found_suggestion: "Check that a valid Wasm binary is present. " \
|
139
|
+
"The Wasm binary's filepath must be 'build/index.wasm'.",
|
140
140
|
|
141
141
|
project_config_not_found: "Internal error - Script can't be created because the project's config file is missing from the repository.",
|
142
142
|
|
@@ -26,11 +26,11 @@ module Theme
|
|
26
26
|
parser.on("-d", "--development") { flags[:development] = true }
|
27
27
|
parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
|
28
28
|
flags[:includes] ||= []
|
29
|
-
flags[:includes]
|
29
|
+
flags[:includes] |= pattern
|
30
30
|
end
|
31
31
|
parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
|
32
32
|
flags[:ignores] ||= []
|
33
|
-
flags[:ignores]
|
33
|
+
flags[:ignores] |= pattern
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -30,11 +30,11 @@ module Theme
|
|
30
30
|
parser.on("-p", "--publish") { flags[:publish] = true }
|
31
31
|
parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
|
32
32
|
flags[:includes] ||= []
|
33
|
-
flags[:includes]
|
33
|
+
flags[:includes] |= pattern
|
34
34
|
end
|
35
35
|
parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
|
36
36
|
flags[:ignores] ||= []
|
37
|
-
flags[:ignores]
|
37
|
+
flags[:ignores] |= pattern
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -10,8 +10,22 @@ module Theme
|
|
10
10
|
|
11
11
|
def convert(parser)
|
12
12
|
argv = parser.default_argv
|
13
|
-
|
13
|
+
values = []
|
14
|
+
|
15
|
+
option_indexes(argv).each do |option_index|
|
16
|
+
values += option_values(argv, parser, option_index)
|
17
|
+
end
|
18
|
+
|
19
|
+
values
|
20
|
+
end
|
21
|
+
|
22
|
+
def options
|
23
|
+
raise "`#{self.class.name}#options` must be defined"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
14
27
|
|
28
|
+
def option_values(argv, parser, option_index)
|
15
29
|
return [] if option_index.nil?
|
16
30
|
|
17
31
|
start_index = option_index + 1
|
@@ -26,12 +40,13 @@ module Theme
|
|
26
40
|
values
|
27
41
|
end
|
28
42
|
|
29
|
-
def
|
30
|
-
|
43
|
+
def option_indexes(argv)
|
44
|
+
argv
|
45
|
+
.each_with_index
|
46
|
+
.select { |item, _index| options.include?(item) }
|
47
|
+
.map(&:last)
|
31
48
|
end
|
32
49
|
|
33
|
-
private
|
34
|
-
|
35
50
|
def options_map(parser)
|
36
51
|
map = {}
|
37
52
|
parser.top.list.each do |option|
|
@@ -7,6 +7,8 @@ module Theme
|
|
7
7
|
Suite of commands for developing Shopify themes. See {{command:%1$s theme <command> --help}} for usage of each command.
|
8
8
|
Usage: {{command:%1$s theme [ %2$s ]}}
|
9
9
|
HELP
|
10
|
+
ensure_user_error: "You are not authorized to edit themes on %s.",
|
11
|
+
ensure_user_try_this: "Make sure you are a user of that store, and allowed to edit themes.",
|
10
12
|
|
11
13
|
init: {
|
12
14
|
help: <<~HELP,
|
@@ -122,6 +124,13 @@ module Theme
|
|
122
124
|
error: {
|
123
125
|
address_binding_error: "Couldn't bind to localhost."\
|
124
126
|
" To serve your theme, set a different address with {{command:%s theme serve --host=<address>}}",
|
127
|
+
invalid_subdirectory: <<~MESSAGE,
|
128
|
+
The presence of %s in the directory structure isn't supported.
|
129
|
+
|
130
|
+
Move any files to a parent folder, then delete unsupported subdirectories.
|
131
|
+
|
132
|
+
• Required directory structure: https://shopify.dev/themes/architecture#directory-structure-and-component-types
|
133
|
+
MESSAGE
|
125
134
|
},
|
126
135
|
serving: <<~SERVING,
|
127
136
|
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "shopify_cli/sed"
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
class Changelog
|
5
|
+
CHANGELOG_FILE = File.join(ShopifyCLI::ROOT, "CHANGELOG.md")
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
load(File.read(CHANGELOG_FILE))
|
9
|
+
end
|
10
|
+
|
11
|
+
def update_version!(new_version)
|
12
|
+
Sed.new.replace_inline(
|
13
|
+
CHANGELOG_FILE,
|
14
|
+
"## \\[Unreleased\\]",
|
15
|
+
"## [Unreleased]\\n\\n## Version #{new_version}"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def release_notes(version)
|
20
|
+
changes[version].map do |change_category, changes|
|
21
|
+
<<~CHANGES
|
22
|
+
### #{change_category}
|
23
|
+
#{changes.map { |change| entry(**change) }.join("\n")}
|
24
|
+
CHANGES
|
25
|
+
end.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def entry(pr_id:, desc:)
|
29
|
+
"* [##{pr_id}](https://github.com/Shopify/shopify-cli/pull/#{pr_id}): #{desc}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def changes
|
35
|
+
@changes ||= Hash.new do |h, k|
|
36
|
+
h[k] = Hash.new do |h2, k2|
|
37
|
+
h2[k2] = []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def load(log)
|
43
|
+
state = :initial
|
44
|
+
change_category = nil
|
45
|
+
current_version = nil
|
46
|
+
@remainder = ""
|
47
|
+
log.each_line do |line|
|
48
|
+
case state
|
49
|
+
when :initial
|
50
|
+
next unless line.chomp == "\#\# [Unreleased]"
|
51
|
+
state = :unreleased
|
52
|
+
current_version = "Unreleased"
|
53
|
+
when :unreleased, :last_version
|
54
|
+
if /\A\#\#\# (?<category>\w+)/ =~ line
|
55
|
+
change_category = category
|
56
|
+
elsif %r{\A\* \[\#(?<pr_id>\d+)\]\(https://github.com/Shopify/shopify-cli/pull/\d+\): (?<desc>.+)\n} =~ line
|
57
|
+
changes[current_version][change_category] << { pr_id: pr_id, desc: desc }
|
58
|
+
elsif /\A\#\# Version (?<version>\d+\.\d+\.\d+)/ =~ line
|
59
|
+
current_version = version
|
60
|
+
state =
|
61
|
+
case state
|
62
|
+
when :unreleased
|
63
|
+
:last_version
|
64
|
+
else
|
65
|
+
:finished
|
66
|
+
end
|
67
|
+
elsif !line.match?(/\s*\n/)
|
68
|
+
raise "Unrecognized line: #{line.inspect}"
|
69
|
+
end
|
70
|
+
when :finished
|
71
|
+
@remainder << line
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/shopify_cli/command.rb
CHANGED
@@ -36,6 +36,13 @@ module ShopifyCLI
|
|
36
36
|
end
|
37
37
|
rescue OptionParser::InvalidOption => error
|
38
38
|
arg = error.args.first
|
39
|
+
store_name = arg.match(/\A--(?<store_name>.*\.myshopify\.com)\z/)&.[](:store_name)
|
40
|
+
if store_name && !arg.match?(/\A--(store|shop)=/)
|
41
|
+
# Sometimes it may look like --invalidoption=https://storename.myshopify.com
|
42
|
+
store_name = store_name.sub(%r{\A(.*=)?(https?://)?}, "")
|
43
|
+
raise ShopifyCLI::Abort,
|
44
|
+
@ctx.message("core.errors.option_parser.invalid_option_store_equals", arg, store_name)
|
45
|
+
end
|
39
46
|
raise ShopifyCLI::Abort, @ctx.message("core.errors.option_parser.invalid_option", arg)
|
40
47
|
rescue OptionParser::MissingArgument => error
|
41
48
|
arg = error.args.first
|
@@ -102,16 +109,10 @@ module ShopifyCLI
|
|
102
109
|
def check_node_version
|
103
110
|
return unless @compatible_node_range
|
104
111
|
|
105
|
-
context = Context.new
|
106
|
-
if context.which("node").nil?
|
107
|
-
raise ShopifyCLI::Abort, context.message("core.errors.missing_node")
|
108
|
-
end
|
109
|
-
|
110
112
|
check_version(
|
111
113
|
Environment.node_version,
|
112
114
|
range: @compatible_node_range,
|
113
|
-
runtime: "Node"
|
114
|
-
context: context
|
115
|
+
runtime: "Node"
|
115
116
|
)
|
116
117
|
end
|
117
118
|
|
data/lib/shopify_cli/context.rb
CHANGED
@@ -103,7 +103,7 @@ module ShopifyCLI
|
|
103
103
|
# any command run by the context.
|
104
104
|
attr_accessor :env
|
105
105
|
|
106
|
-
def initialize(root: Dir.pwd, env: ($original_env || ENV).
|
106
|
+
def initialize(root: Dir.pwd, env: ($original_env || ENV).to_h) # :nodoc:
|
107
107
|
self.root = root
|
108
108
|
self.env = env
|
109
109
|
end
|
@@ -164,7 +164,7 @@ module ShopifyCLI
|
|
164
164
|
|
165
165
|
# will return true while tests are running, either locally or on CI
|
166
166
|
def testing?
|
167
|
-
ci? || ENV["
|
167
|
+
ci? || ENV["SHOPIFY_CLI_TEST"]
|
168
168
|
end
|
169
169
|
|
170
170
|
##
|
@@ -5,7 +5,7 @@ module ShopifyCLI
|
|
5
5
|
module EntryPoint
|
6
6
|
class << self
|
7
7
|
def call(args, ctx = Context.new)
|
8
|
-
if ctx.development?
|
8
|
+
if ctx.development? && !ctx.testing?
|
9
9
|
ctx.warn(
|
10
10
|
ctx.message("core.warning.development_version", File.join(ShopifyCLI::ROOT, "bin", ShopifyCLI::TOOL_NAME))
|
11
11
|
)
|
@@ -17,11 +17,7 @@ module ShopifyCLI
|
|
17
17
|
|
18
18
|
def log(name, args, &block) # rubocop:disable Lint/UnusedMethodArgument
|
19
19
|
command, command_name = Commands::Registry.lookup_command(name)
|
20
|
-
|
21
|
-
if command
|
22
|
-
subcommand, subcommand_name = command.subcommand_registry.lookup_command(args.first)
|
23
|
-
final_command << subcommand_name if subcommand
|
24
|
-
end
|
20
|
+
full_command = self.full_command(command, args, resolved_command: [command_name])
|
25
21
|
|
26
22
|
start_time = now_in_milliseconds
|
27
23
|
err = nil
|
@@ -35,9 +31,21 @@ module ShopifyCLI
|
|
35
31
|
# If there's an error, we don't prompt from here and we let the exception
|
36
32
|
# reporter do that.
|
37
33
|
if report?(prompt: err.nil?)
|
38
|
-
send_event(start_time,
|
34
|
+
send_event(start_time, full_command, args - full_command, err&.message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def full_command(command, args, resolved_command:)
|
40
|
+
resolved_command = resolved_command.dup
|
41
|
+
if command
|
42
|
+
subcommand, subcommand_name = command.subcommand_registry.lookup_command(args.first)
|
43
|
+
resolved_command << subcommand_name if subcommand
|
44
|
+
if subcommand&.subcommand_registry
|
45
|
+
resolved_command = full_command(subcommand, args.drop(1), resolved_command: resolved_command)
|
39
46
|
end
|
40
47
|
end
|
48
|
+
resolved_command
|
41
49
|
end
|
42
50
|
|
43
51
|
private
|
@@ -12,23 +12,31 @@ module ShopifyCLI
|
|
12
12
|
]
|
13
13
|
|
14
14
|
def self.ruby_version(context: Context.new)
|
15
|
-
|
16
|
-
raise ShopifyCLI::Abort,
|
17
|
-
|
18
|
-
::Semantic::Version.new(
|
15
|
+
output, status = context.capture2e("ruby", "--version")
|
16
|
+
raise ShopifyCLI::Abort, context.message("core.errors.missing_ruby") unless status.success?
|
17
|
+
version = output.match(/ruby (\d+\.\d+\.\d+)/)[1]
|
18
|
+
::Semantic::Version.new(version)
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.node_version(context: Context.new)
|
22
|
-
|
23
|
-
raise ShopifyCLI::Abort,
|
24
|
-
|
25
|
-
::Semantic::Version.new(
|
22
|
+
output, status = context.capture2e("node", "--version")
|
23
|
+
raise ShopifyCLI::Abort, context.message("core.errors.missing_node") unless status.success?
|
24
|
+
version = output.match(/v(\d+\.\d+\.\d+)/)[1]
|
25
|
+
::Semantic::Version.new(version)
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.npm_version(context: Context.new)
|
29
|
-
|
30
|
-
raise ShopifyCLI::Abort,
|
31
|
-
|
29
|
+
output, status = context.capture2e("npm", "--version")
|
30
|
+
raise ShopifyCLI::Abort, context.message("core.errors.missing_npm") unless status.success?
|
31
|
+
version = output.match(/(\d+\.\d+\.\d+)/)[1]
|
32
|
+
::Semantic::Version.new(version)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.rails_version(context: Context.new)
|
36
|
+
output, status = context.capture2e("rails", "--version")
|
37
|
+
context.abort(context.message("core.app.create.rails.error.install_failure", "rails")) unless status.success?
|
38
|
+
version = output.match(/Rails (\d+\.\d+\.\d+)/)[1]
|
39
|
+
::Semantic::Version.new(version)
|
32
40
|
end
|
33
41
|
|
34
42
|
def self.interactive=(interactive)
|
@@ -15,9 +15,17 @@ module ShopifyCLI
|
|
15
15
|
},
|
16
16
|
core: {
|
17
17
|
errors: {
|
18
|
-
missing_node: "Node is required to continue. Install
|
18
|
+
missing_node: "Node.js is required to continue. Install Node.js here: https://nodejs.org/en/download.",
|
19
|
+
missing_npm: "npm is required to continue. Install npm here: https://www.npmjs.com/get-npm.",
|
20
|
+
missing_ruby: "Ruby is required to continue. Install Ruby here: https://www.ruby-lang.org/en/downloads.",
|
19
21
|
option_parser: {
|
20
22
|
invalid_option: "The option {{command:%s}} is not supported.",
|
23
|
+
invalid_option_store_equals: <<~MESSAGE,
|
24
|
+
The option {{command:%s}} isn't recognized.
|
25
|
+
|
26
|
+
Try this:
|
27
|
+
{{command:--store=%s}}.
|
28
|
+
MESSAGE
|
21
29
|
missing_argument: "The required argument {{command:%s}} is missing.",
|
22
30
|
},
|
23
31
|
},
|
@@ -95,8 +103,6 @@ module ShopifyCLI
|
|
95
103
|
HELP
|
96
104
|
error: {
|
97
105
|
node_required: "node is required to create an app project. Download at https://nodejs.org/en/download.",
|
98
|
-
node_version_failure: "Failed to get the current node version. Please make sure it is installed as " \
|
99
|
-
"per the instructions at https://nodejs.org/en.",
|
100
106
|
npm_required: "npm is required to create an app project. Download at https://www.npmjs.com/get-npm.",
|
101
107
|
npm_version_failure: "Failed to get the current npm version. Please make sure it is installed as per " \
|
102
108
|
"the instructions at https://www.npmjs.com/get-npm.",
|
@@ -131,8 +137,6 @@ module ShopifyCLI
|
|
131
137
|
{{underline:https://getcomposer.org/download/}}
|
132
138
|
COMPOSER
|
133
139
|
npm_required: "npm is required to create an app project. Download at https://www.npmjs.com/get-npm.",
|
134
|
-
npm_version_failure: "Failed to get the current npm version. Please make sure it is installed as per " \
|
135
|
-
"the instructions at https://www.npmjs.com/get-npm.",
|
136
140
|
app_setup: "Failed to set up the app",
|
137
141
|
},
|
138
142
|
|
@@ -283,6 +287,8 @@ module ShopifyCLI
|
|
283
287
|
localization: {
|
284
288
|
error: {
|
285
289
|
bundle_too_large: "Total size of all locale files must be less than %s.",
|
290
|
+
duplicate_locale_code: "Duplicate locale found: `%s`; locale codes"\
|
291
|
+
" should be unique and are case insensitive.",
|
286
292
|
file_empty: "Locale file `%s` is empty.",
|
287
293
|
file_too_large: "Locale file `%s` too large; size must be less than %s.",
|
288
294
|
invalid_file_extension: "Invalid locale filename: `%s`; only .json files are allowed.",
|
data/lib/shopify_cli/packager.rb
CHANGED
@@ -81,7 +81,7 @@ module ShopifyCLI
|
|
81
81
|
puts "Grabbing sha256 checksum from Rubygems.org"
|
82
82
|
require "digest/sha2"
|
83
83
|
require "open-uri"
|
84
|
-
gem_checksum = open("https://rubygems.org/downloads/shopify-cli-#{ShopifyCLI::VERSION}.gem") do |io|
|
84
|
+
gem_checksum = URI.open("https://rubygems.org/downloads/shopify-cli-#{ShopifyCLI::VERSION}.gem") do |io|
|
85
85
|
Digest::SHA256.new.hexdigest(io.read)
|
86
86
|
end
|
87
87
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "shopify_cli/sed"
|
2
|
+
require "shopify_cli/changelog"
|
3
|
+
require "octokit"
|
4
|
+
|
5
|
+
module ShopifyCLI
|
6
|
+
class Release
|
7
|
+
def initialize(new_version, github_access_token)
|
8
|
+
@new_version = new_version
|
9
|
+
@changelog = ShopifyCLI::Changelog.new
|
10
|
+
@github = Octokit::Client.new(access_token: github_access_token)
|
11
|
+
end
|
12
|
+
|
13
|
+
def prepare!
|
14
|
+
ensure_updated_main
|
15
|
+
create_release_branch
|
16
|
+
update_changelog
|
17
|
+
update_versions_in_files
|
18
|
+
commit
|
19
|
+
pr = create_pr
|
20
|
+
system("open #{pr["html_url"]}")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :new_version, :changelog, :github
|
26
|
+
|
27
|
+
def ensure_updated_main
|
28
|
+
current_branch = %x(git branch --show-current)
|
29
|
+
unless current_branch == "main"
|
30
|
+
raise "Must be on the main branch to package a release!"
|
31
|
+
end
|
32
|
+
unless system("git pull")
|
33
|
+
raise "git pull failed, cannot be sure there aren't new commits!"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_release_branch
|
38
|
+
puts "Checking out release branch"
|
39
|
+
unless system("git checkout -b #{release_branch_name}")
|
40
|
+
puts "Cannot check out release branch!"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def update_changelog
|
45
|
+
if release_notes.empty?
|
46
|
+
puts "No unreleased CHANGELOG updates found!"
|
47
|
+
else
|
48
|
+
puts "Updating CHANGELOG"
|
49
|
+
changelog.update_version!(new_version)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def update_versions_in_files
|
54
|
+
version_file = File.join(ShopifyCLI::ROOT, "lib/shopify_cli/version.rb")
|
55
|
+
puts "Updating version.rb"
|
56
|
+
ShopifyCLI::Sed.new.replace_inline(version_file, ShopifyCLI::VERSION, new_version)
|
57
|
+
gemfile_lock = File.join(ShopifyCLI::ROOT, "Gemfile.lock")
|
58
|
+
puts "Updating Gemfile.lock"
|
59
|
+
ShopifyCLI::Sed.new.replace_inline(
|
60
|
+
gemfile_lock,
|
61
|
+
"shopify-cli (#{ShopifyCLI::VERSION})",
|
62
|
+
"shopify-cli (#{new_version})",
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
def commit
|
67
|
+
puts "Committing"
|
68
|
+
unless system("git commit -am 'Packaging for release v#{new_version}'")
|
69
|
+
puts "Commit failed!"
|
70
|
+
end
|
71
|
+
unless system("git push -u origin #{release_branch_name}")
|
72
|
+
puts "Failed to push branch!"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_pr
|
77
|
+
github.create_pull_request(
|
78
|
+
"Shopify/shopify-cli",
|
79
|
+
"main",
|
80
|
+
release_branch_name,
|
81
|
+
"Packaging for release v#{new_version}",
|
82
|
+
release_notes
|
83
|
+
).tap { |results| puts "Created PR ##{results["number"]}" }
|
84
|
+
end
|
85
|
+
|
86
|
+
def release_branch_name
|
87
|
+
@release_branch_name ||= "release_#{new_version.split(".").join("_")}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def release_notes
|
91
|
+
@release_notes ||= changelog.release_notes("Unreleased")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/shopify_cli/result.rb
CHANGED
@@ -181,6 +181,13 @@ module ShopifyCLI
|
|
181
181
|
self
|
182
182
|
end
|
183
183
|
|
184
|
+
##
|
185
|
+
# returns the value this success represents
|
186
|
+
#
|
187
|
+
def unwrap!
|
188
|
+
value
|
189
|
+
end
|
190
|
+
|
184
191
|
##
|
185
192
|
# returns the success value and ignores the fallback value that was either
|
186
193
|
# provided as a method argument or by passing a block. However, the caller
|
@@ -339,6 +346,13 @@ module ShopifyCLI
|
|
339
346
|
raise ArgumentError, "expected either a fallback value or a block" unless (args.length == 1) ^ block
|
340
347
|
block ? block.call(@error) : args.pop
|
341
348
|
end
|
349
|
+
|
350
|
+
##
|
351
|
+
# raises the error this failure represents
|
352
|
+
#
|
353
|
+
def unwrap!
|
354
|
+
raise error
|
355
|
+
end
|
342
356
|
end
|
343
357
|
|
344
358
|
##
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ShopifyCLI
|
2
|
+
class Sed
|
3
|
+
class SedError < StandardError; end
|
4
|
+
|
5
|
+
def replace_inline(filename, pattern, output)
|
6
|
+
command =
|
7
|
+
case CLI::Kit::System.os
|
8
|
+
when :mac
|
9
|
+
"sed -i ''"
|
10
|
+
when :linux
|
11
|
+
"sed -i"
|
12
|
+
else
|
13
|
+
raise "Unrecognized system!"
|
14
|
+
end
|
15
|
+
success = system("#{command} 's/#{pattern}/#{output}/' #{filename}")
|
16
|
+
raise SedError unless success
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|