shopify-cli 2.6.3 → 2.6.4
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/.github/PULL_REQUEST_TEMPLATE.md +15 -4
- data/.github/workflows/shopify.yml +3 -6
- data/CHANGELOG.md +71 -102
- data/Dockerfile +12 -2
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -3
- data/RELEASING.md +17 -30
- data/Rakefile +0 -5
- data/lib/project_types/extension/features/argo.rb +8 -2
- data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +1 -1
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +1 -1
- data/lib/project_types/node/commands/serve.rb +7 -16
- data/lib/project_types/node/messages/messages.rb +0 -5
- data/lib/project_types/php/commands/serve.rb +6 -9
- data/lib/project_types/php/messages/messages.rb +1 -4
- data/lib/project_types/rails/commands/serve.rb +7 -8
- data/lib/project_types/rails/messages/messages.rb +1 -4
- data/lib/project_types/script/commands/create.rb +3 -1
- data/lib/project_types/script/config/extension_points.yml +7 -0
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/layers/application/build_script.rb +2 -1
- data/lib/project_types/script/layers/application/push_script.rb +15 -1
- data/lib/project_types/script/layers/domain/push_package.rb +5 -2
- data/lib/project_types/script/layers/infrastructure/errors.rb +17 -0
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +10 -13
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +4 -13
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -2
- data/lib/project_types/script/layers/infrastructure/script_service.rb +6 -1
- data/lib/project_types/script/messages/messages.rb +6 -0
- data/lib/project_types/script/ui/error_handler.rb +16 -0
- data/lib/project_types/theme/commands/serve.rb +1 -0
- data/lib/project_types/theme/messages/messages.rb +5 -0
- data/lib/shopify_cli/app_type_detector.rb +32 -0
- data/lib/shopify_cli/command.rb +6 -1
- data/lib/shopify_cli/command_options/command_serve_options.rb +43 -0
- data/lib/shopify_cli/command_options.rb +7 -0
- data/lib/shopify_cli/commands/login.rb +3 -3
- data/lib/shopify_cli/commands/reporting.rb +38 -0
- data/lib/shopify_cli/commands/switch.rb +1 -1
- data/lib/shopify_cli/commands.rb +1 -0
- data/lib/shopify_cli/constants.rb +7 -3
- data/lib/shopify_cli/core/monorail.rb +9 -20
- data/lib/shopify_cli/environment.rb +15 -1
- data/lib/shopify_cli/exception_reporter.rb +24 -13
- data/lib/shopify_cli/messages/messages.rb +48 -19
- data/lib/shopify_cli/migrator/migration.rb +1 -1
- data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +1 -1
- data/lib/shopify_cli/migrator/migrations/1633691650_merge_reporting_configuration.rb +41 -0
- data/lib/shopify_cli/reporting_configuration_controller.rb +64 -0
- data/lib/shopify_cli/services/base_service.rb +13 -0
- data/lib/shopify_cli/services/reporting_service.rb +16 -0
- data/lib/shopify_cli/services.rb +6 -0
- data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -2
- data/lib/shopify_cli/theme/dev_server.rb +2 -2
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +4 -0
- data/shopify-cli.gemspec +1 -8
- data/utilities/docker/container.rb +76 -0
- data/utilities/docker.rb +44 -3
- metadata +14 -5
- data/lib/shopify_cli/exception_reporter/permission_controller.rb +0 -54
@@ -2,20 +2,17 @@
|
|
2
2
|
module PHP
|
3
3
|
class Command
|
4
4
|
class Serve < ShopifyCLI::SubCommand
|
5
|
-
|
5
|
+
include ShopifyCLI::CommandOptions::CommandServeOptions
|
6
6
|
|
7
7
|
prerequisite_task :ensure_env, :ensure_dev_store
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
flags[:host] = h.gsub('"', "")
|
12
|
-
end
|
13
|
-
end
|
9
|
+
parse_host_option
|
10
|
+
parse_port_option
|
14
11
|
|
15
12
|
def call(*)
|
16
13
|
project = ShopifyCLI::Project.current
|
17
|
-
|
18
|
-
|
14
|
+
tunnel_port = port.to_s
|
15
|
+
url = host || ShopifyCLI::Tunnel.start(@ctx, port: tunnel_port)
|
19
16
|
project.env.update(@ctx, :host, url)
|
20
17
|
ShopifyCLI::Tasks::UpdateDashboardURLS.call(
|
21
18
|
@ctx,
|
@@ -35,7 +32,7 @@ module PHP
|
|
35
32
|
ShopifyCLI::ProcessSupervision.start(:npm_watch, "npm run watch", force_spawn: true)
|
36
33
|
|
37
34
|
env = project.env.to_h
|
38
|
-
@ctx.system("php", "artisan", "serve", "--port",
|
35
|
+
@ctx.system("php", "artisan", "serve", "--port", tunnel_port, env: env)
|
39
36
|
end
|
40
37
|
end
|
41
38
|
|
@@ -133,12 +133,9 @@ module PHP
|
|
133
133
|
extended_help: <<~HELP,
|
134
134
|
{{bold:Options:}}
|
135
135
|
{{cyan:--host=HOST}}: Bypass running tunnel and use custom host. HOST must be HTTPS url.
|
136
|
+
{{cyan:--port=PORT}}: Use custom port.
|
136
137
|
HELP
|
137
138
|
|
138
|
-
error: {
|
139
|
-
host_must_be_https: "HOST must be a HTTPS url.",
|
140
|
-
},
|
141
|
-
|
142
139
|
open_info: <<~MESSAGE,
|
143
140
|
{{*}} To install and start using your app, open this URL in your browser:
|
144
141
|
{{green:%s}}
|
@@ -2,19 +2,18 @@
|
|
2
2
|
module Rails
|
3
3
|
class Command
|
4
4
|
class Serve < ShopifyCLI::SubCommand
|
5
|
+
include ShopifyCLI::CommandOptions::CommandServeOptions
|
6
|
+
|
5
7
|
prerequisite_task ensure_project_type: :rails
|
6
8
|
prerequisite_task :ensure_env, :ensure_dev_store
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
flags[:host] = h.gsub('"', "")
|
11
|
-
end
|
12
|
-
end
|
10
|
+
parse_host_option
|
11
|
+
parse_port_option
|
13
12
|
|
14
13
|
def call(*)
|
15
14
|
project = ShopifyCLI::Project.current
|
16
|
-
|
17
|
-
|
15
|
+
tunnel_port = port.to_s
|
16
|
+
url = host || ShopifyCLI::Tunnel.start(@ctx, port: tunnel_port)
|
18
17
|
project.env.update(@ctx, :host, url)
|
19
18
|
ShopifyCLI::Tasks::UpdateDashboardURLS.call(
|
20
19
|
@ctx,
|
@@ -30,7 +29,7 @@ module Rails
|
|
30
29
|
CLI::UI::Frame.open(@ctx.message("rails.serve.running_server")) do
|
31
30
|
env = ShopifyCLI::Project.current.env.to_h
|
32
31
|
env.delete("HOST")
|
33
|
-
env["PORT"] =
|
32
|
+
env["PORT"] = tunnel_port
|
34
33
|
env["GEM_PATH"] = Gem.gem_path(@ctx)
|
35
34
|
if @ctx.windows?
|
36
35
|
@ctx.system("ruby bin\\rails server", env: env)
|
@@ -170,12 +170,9 @@ module Rails
|
|
170
170
|
extended_help: <<~HELP,
|
171
171
|
{{bold:Options:}}
|
172
172
|
{{cyan:--host=HOST}}: Bypass running tunnel and use custom host. HOST must be HTTPS url.
|
173
|
+
{{cyan:--port=PORT}}: Use custom port.
|
173
174
|
HELP
|
174
175
|
|
175
|
-
error: {
|
176
|
-
host_must_be_https: "{{red:HOST must be a HTTPS url.}}",
|
177
|
-
},
|
178
|
-
|
179
176
|
open_info: <<~MESSAGE,
|
180
177
|
{{*}} To install and start using your app, open this URL in your browser:
|
181
178
|
{{green:%s}}
|
@@ -3,7 +3,9 @@
|
|
3
3
|
module Script
|
4
4
|
class Command
|
5
5
|
class Create < ShopifyCLI::SubCommand
|
6
|
-
|
6
|
+
unless ShopifyCLI::Environment.acceptance_test?
|
7
|
+
prerequisite_task :ensure_authenticated
|
8
|
+
end
|
7
9
|
|
8
10
|
options do |parser, flags|
|
9
11
|
parser.on("--name=NAME") { |name| flags[:name] = name }
|
@@ -42,3 +42,10 @@ shipping_methods:
|
|
42
42
|
typescript:
|
43
43
|
beta: true
|
44
44
|
repo: "https://github.com/Shopify/scripts-apis-examples"
|
45
|
+
discount_types:
|
46
|
+
beta: true
|
47
|
+
domain: 'discounts'
|
48
|
+
libraries:
|
49
|
+
typescript:
|
50
|
+
beta: true
|
51
|
+
repo: "https://github.com/Shopify/scripts-apis-examples"
|
@@ -10,6 +10,7 @@ mutation AppScriptSet(
|
|
10
10
|
$configurationUi: Boolean!,
|
11
11
|
$configurationDefinition: String!,
|
12
12
|
$moduleUploadUrl: String!,
|
13
|
+
$library: LibraryInput,
|
13
14
|
) {
|
14
15
|
appScriptSet(
|
15
16
|
uuid: $uuid
|
@@ -23,6 +24,7 @@ mutation AppScriptSet(
|
|
23
24
|
configurationUi: $configurationUi,
|
24
25
|
configurationDefinition: $configurationDefinition,
|
25
26
|
moduleUploadUrl: $moduleUploadUrl,
|
27
|
+
library: $library,
|
26
28
|
) {
|
27
29
|
userErrors {
|
28
30
|
field
|
@@ -5,7 +5,7 @@ module Script
|
|
5
5
|
module Application
|
6
6
|
class BuildScript
|
7
7
|
class << self
|
8
|
-
def call(ctx:, task_runner:, script_project:)
|
8
|
+
def call(ctx:, task_runner:, script_project:, library:)
|
9
9
|
CLI::UI::Frame.open(ctx.message("script.application.building")) do
|
10
10
|
begin
|
11
11
|
UI::StrictSpinner.spin(ctx.message("script.application.building_script")) do |spinner|
|
@@ -14,6 +14,7 @@ module Script
|
|
14
14
|
script_content: task_runner.build,
|
15
15
|
compiled_type: task_runner.compiled_type,
|
16
16
|
metadata: task_runner.metadata,
|
17
|
+
library: library,
|
17
18
|
)
|
18
19
|
spinner.update_title(ctx.message("script.application.built"))
|
19
20
|
end
|
@@ -11,14 +11,27 @@ module Script
|
|
11
11
|
task_runner = Infrastructure::Languages::TaskRunner
|
12
12
|
.for(ctx, script_project.language, script_project.script_name)
|
13
13
|
|
14
|
+
extension_point = ExtensionPoints.get(type: script_project.extension_point_type)
|
15
|
+
library_name = extension_point.libraries.for(script_project.language)&.package
|
16
|
+
raise Infrastructure::Errors::LanguageLibraryForAPINotFoundError.new(
|
17
|
+
language: script_project.language,
|
18
|
+
api: script_project.extension_point_type
|
19
|
+
) unless library_name
|
20
|
+
|
21
|
+
library = {
|
22
|
+
language: script_project.language,
|
23
|
+
version: task_runner.library_version(library_name),
|
24
|
+
}
|
25
|
+
|
14
26
|
ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
|
15
|
-
BuildScript.call(ctx: ctx, task_runner: task_runner, script_project: script_project)
|
27
|
+
BuildScript.call(ctx: ctx, task_runner: task_runner, script_project: script_project, library: library)
|
16
28
|
|
17
29
|
UI::PrintingSpinner.spin(ctx, ctx.message("script.application.pushing")) do |p_ctx, spinner|
|
18
30
|
package = Infrastructure::PushPackageRepository.new(ctx: p_ctx).get_push_package(
|
19
31
|
script_project: script_project,
|
20
32
|
compiled_type: task_runner.compiled_type,
|
21
33
|
metadata: task_runner.metadata,
|
34
|
+
library: library,
|
22
35
|
)
|
23
36
|
script_service = Infrastructure::ServiceLocator.script_service(
|
24
37
|
ctx: p_ctx,
|
@@ -32,6 +45,7 @@ module Script
|
|
32
45
|
metadata: package.metadata,
|
33
46
|
script_json: package.script_json,
|
34
47
|
module_upload_url: module_upload_url,
|
48
|
+
library: package.library,
|
35
49
|
)
|
36
50
|
script_project_repo.update_env(uuid: uuid)
|
37
51
|
spinner.update_title(p_ctx.message("script.application.pushed"))
|
@@ -10,7 +10,8 @@ module Script
|
|
10
10
|
:script_json,
|
11
11
|
:script_content,
|
12
12
|
:compiled_type,
|
13
|
-
:metadata
|
13
|
+
:metadata,
|
14
|
+
:library
|
14
15
|
|
15
16
|
def initialize(
|
16
17
|
id:,
|
@@ -19,7 +20,8 @@ module Script
|
|
19
20
|
script_content:,
|
20
21
|
compiled_type: nil,
|
21
22
|
metadata:,
|
22
|
-
script_json
|
23
|
+
script_json:,
|
24
|
+
library:
|
23
25
|
)
|
24
26
|
@id = id
|
25
27
|
@uuid = uuid
|
@@ -28,6 +30,7 @@ module Script
|
|
28
30
|
@compiled_type = compiled_type
|
29
31
|
@metadata = metadata
|
30
32
|
@script_json = script_json
|
33
|
+
@library = library
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
@@ -40,6 +40,23 @@ module Script
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
class APILibraryNotFoundError < ScriptProjectError
|
44
|
+
attr_reader :library_name
|
45
|
+
def initialize(library_name)
|
46
|
+
super()
|
47
|
+
@library_name = library_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class LanguageLibraryForAPINotFoundError < ScriptProjectError
|
52
|
+
attr_reader :language, :api
|
53
|
+
def initialize(language:, api:)
|
54
|
+
super()
|
55
|
+
@language = language
|
56
|
+
@api = api
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
43
60
|
class DependencyInstallError < ScriptProjectError; end
|
44
61
|
class DeprecatedEPError < ScriptProjectError; end
|
45
62
|
class EmptyResponseError < ScriptProjectError; end
|
@@ -5,7 +5,7 @@ module Script
|
|
5
5
|
module Infrastructure
|
6
6
|
module Languages
|
7
7
|
class AssemblyScriptTaskRunner
|
8
|
-
BYTECODE_FILE = "build
|
8
|
+
BYTECODE_FILE = "build/script.wasm"
|
9
9
|
METADATA_FILE = "build/metadata.json"
|
10
10
|
SCRIPT_SDK_BUILD = "npm run build"
|
11
11
|
|
@@ -47,6 +47,12 @@ module Script
|
|
47
47
|
Domain::Metadata.create_from_json(@ctx, raw_contents)
|
48
48
|
end
|
49
49
|
|
50
|
+
def library_version(library_name)
|
51
|
+
output = JSON.parse(CommandRunner.new(ctx: ctx).call("npm list --json"))
|
52
|
+
raise Errors::APILibraryNotFoundError.new(library_name), output unless output["dependencies"][library_name]
|
53
|
+
output["dependencies"][library_name]["version"]
|
54
|
+
end
|
55
|
+
|
50
56
|
private
|
51
57
|
|
52
58
|
def check_node_version!
|
@@ -80,19 +86,10 @@ module Script
|
|
80
86
|
end
|
81
87
|
|
82
88
|
def bytecode
|
83
|
-
|
84
|
-
filename = format(BYTECODE_FILE, name: "script")
|
85
|
-
|
86
|
-
bytecode_file = if ctx.file_exist?(filename)
|
87
|
-
filename
|
88
|
-
elsif ctx.file_exist?(legacy_filename)
|
89
|
-
legacy_filename
|
90
|
-
else
|
91
|
-
raise Errors::WebAssemblyBinaryNotFoundError
|
92
|
-
end
|
89
|
+
raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(BYTECODE_FILE)
|
93
90
|
|
94
|
-
contents = ctx.binread(
|
95
|
-
ctx.rm(
|
91
|
+
contents = ctx.binread(BYTECODE_FILE)
|
92
|
+
ctx.rm(BYTECODE_FILE)
|
96
93
|
|
97
94
|
contents
|
98
95
|
end
|
@@ -5,7 +5,7 @@ module Script
|
|
5
5
|
module Infrastructure
|
6
6
|
module Languages
|
7
7
|
class TypeScriptTaskRunner
|
8
|
-
BYTECODE_FILE = "build
|
8
|
+
BYTECODE_FILE = "build/index.wasm"
|
9
9
|
METADATA_FILE = "build/metadata.json"
|
10
10
|
SCRIPT_SDK_BUILD = "npm run build"
|
11
11
|
GEN_METADATA = "npm run gen-metadata"
|
@@ -82,19 +82,10 @@ module Script
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def bytecode
|
85
|
-
|
86
|
-
filename = format(BYTECODE_FILE, name: "index")
|
87
|
-
|
88
|
-
bytecode_file = if ctx.file_exist?(filename)
|
89
|
-
filename
|
90
|
-
elsif ctx.file_exist?(legacy_filename)
|
91
|
-
legacy_filename
|
92
|
-
else
|
93
|
-
raise Errors::WebAssemblyBinaryNotFoundError
|
94
|
-
end
|
85
|
+
raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(BYTECODE_FILE)
|
95
86
|
|
96
|
-
contents = ctx.binread(
|
97
|
-
ctx.rm(
|
87
|
+
contents = ctx.binread(BYTECODE_FILE)
|
88
|
+
ctx.rm(BYTECODE_FILE)
|
98
89
|
|
99
90
|
contents
|
100
91
|
end
|
@@ -7,7 +7,7 @@ module Script
|
|
7
7
|
include SmartProperties
|
8
8
|
property! :ctx, accepts: ShopifyCLI::Context
|
9
9
|
|
10
|
-
def create_push_package(script_project:, script_content:, compiled_type:, metadata:)
|
10
|
+
def create_push_package(script_project:, script_content:, compiled_type:, metadata:, library:)
|
11
11
|
build_file_path = file_path(script_project.id, compiled_type)
|
12
12
|
write_to_path(build_file_path, script_content)
|
13
13
|
|
@@ -19,10 +19,11 @@ module Script
|
|
19
19
|
compiled_type: compiled_type,
|
20
20
|
metadata: metadata,
|
21
21
|
script_json: script_project.script_json,
|
22
|
+
library: library
|
22
23
|
)
|
23
24
|
end
|
24
25
|
|
25
|
-
def get_push_package(script_project:, compiled_type:, metadata:)
|
26
|
+
def get_push_package(script_project:, compiled_type:, metadata:, library:)
|
26
27
|
build_file_path = file_path(script_project.id, compiled_type)
|
27
28
|
raise Domain::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
|
28
29
|
|
@@ -34,6 +35,7 @@ module Script
|
|
34
35
|
script_content: script_content,
|
35
36
|
metadata: metadata,
|
36
37
|
script_json: script_project.script_json,
|
38
|
+
library: library
|
37
39
|
)
|
38
40
|
end
|
39
41
|
|
@@ -18,7 +18,8 @@ module Script
|
|
18
18
|
force: false,
|
19
19
|
metadata:,
|
20
20
|
script_json:,
|
21
|
-
module_upload_url
|
21
|
+
module_upload_url:,
|
22
|
+
library:
|
22
23
|
)
|
23
24
|
query_name = "app_script_set"
|
24
25
|
variables = {
|
@@ -33,6 +34,10 @@ module Script
|
|
33
34
|
configurationUi: script_json.configuration_ui,
|
34
35
|
configurationDefinition: script_json.configuration&.to_json,
|
35
36
|
moduleUploadUrl: module_upload_url,
|
37
|
+
library: {
|
38
|
+
language: library[:language],
|
39
|
+
version: library[:version],
|
40
|
+
},
|
36
41
|
}
|
37
42
|
resp_hash = make_request(query_name: query_name, variables: variables)
|
38
43
|
user_errors = resp_hash["data"]["appScriptSet"]["userErrors"]
|
@@ -148,6 +148,12 @@ module Script
|
|
148
148
|
|
149
149
|
script_upload_cause: "Fail to upload script.",
|
150
150
|
script_upload_help: "Try again.",
|
151
|
+
|
152
|
+
api_library_not_found_cause: "Script can't be created because API library %{library_name} is missing from the dependencies",
|
153
|
+
api_library_not_found_help: "This error can occur because the API library was removed from your system or there is a problem with dependencies in the repository.",
|
154
|
+
|
155
|
+
language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
|
156
|
+
language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
|
151
157
|
},
|
152
158
|
|
153
159
|
create: {
|
@@ -250,6 +250,22 @@ module Script
|
|
250
250
|
cause_of_error: ShopifyCLI::Context.message("script.error.script_upload_cause"),
|
251
251
|
help_suggestion: ShopifyCLI::Context.message("script.error.script_upload_help"),
|
252
252
|
}
|
253
|
+
when Layers::Infrastructure::Errors::APILibraryNotFoundError
|
254
|
+
{
|
255
|
+
cause_of_error: ShopifyCLI::Context
|
256
|
+
.message("script.error.api_library_not_found_cause", library_name: e.library_name),
|
257
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.api_library_not_found_help"),
|
258
|
+
}
|
259
|
+
when Layers::Infrastructure::Errors::LanguageLibraryForAPINotFoundError
|
260
|
+
{
|
261
|
+
cause_of_error: ShopifyCLI::Context
|
262
|
+
.message(
|
263
|
+
"script.error.language_library_for_api_not_found_cause",
|
264
|
+
language: e.language,
|
265
|
+
api: e.api
|
266
|
+
),
|
267
|
+
help_suggestion: ShopifyCLI::Context.message("script.error.language_library_for_api_not_found_help"),
|
268
|
+
}
|
253
269
|
end
|
254
270
|
end
|
255
271
|
end
|
@@ -88,7 +88,12 @@ module Theme
|
|
88
88
|
serve: {
|
89
89
|
help: <<~HELP,
|
90
90
|
Uploads the current theme as a development theme to the connected store, then prints theme editor and preview URLs to your terminal. While running, changes will push to the store in real time.
|
91
|
+
|
91
92
|
Usage: {{command:%s theme serve}}
|
93
|
+
|
94
|
+
Options:
|
95
|
+
{{command:--port=PORT}} Local port to serve theme preview from
|
96
|
+
{{command:--poll}} Force polling to detect file changes
|
92
97
|
HELP
|
93
98
|
serve: "Viewing theme…",
|
94
99
|
open_fail: "Couldn't open the theme",
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
class AppTypeDetector
|
5
|
+
Error = Class.new(StandardError)
|
6
|
+
TypeNotFoundError = Class.new(Error)
|
7
|
+
|
8
|
+
def self.detect(project_directory:)
|
9
|
+
return :node if node?(project_directory: project_directory)
|
10
|
+
return :rails if rails?(project_directory: project_directory)
|
11
|
+
return :php if php?(project_directory: project_directory)
|
12
|
+
raise TypeNotFoundError, "Couldn't detect the project type in directory: #{project_directory}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.node?(project_directory:)
|
16
|
+
package_json_path = File.join(project_directory, "package.json")
|
17
|
+
return false unless File.exist?(package_json_path)
|
18
|
+
package_json = JSON.parse(File.read(package_json_path))
|
19
|
+
!package_json.dig("scripts", "dev").nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.rails?(project_directory:)
|
23
|
+
rails_binstub_path = File.join(project_directory, "bin/rails")
|
24
|
+
File.exist?(rails_binstub_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.php?(project_directory:)
|
28
|
+
bootstrap_app_path = File.join(project_directory, "bootstrap/app.php")
|
29
|
+
File.exist?(bootstrap_app_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/shopify_cli/command.rb
CHANGED
@@ -27,7 +27,12 @@ module ShopifyCLI
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def options(&block)
|
30
|
-
|
30
|
+
existing_options = @_options
|
31
|
+
# We prevent new options calls to override existing blocks by nesting them.
|
32
|
+
@_options = ->(parser, flags) {
|
33
|
+
existing_options&.call(parser, flags)
|
34
|
+
block.call(parser, flags)
|
35
|
+
}
|
31
36
|
end
|
32
37
|
|
33
38
|
def subcommand(const, cmd, path = nil)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "shopify_cli"
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
module CommandOptions
|
5
|
+
module CommandServeOptions
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
base.class_eval do
|
9
|
+
def port
|
10
|
+
return ShopifyCLI::Tunnel::PORT.to_s unless options.flags.key?(:port)
|
11
|
+
port = options.flags[:port].to_i
|
12
|
+
@ctx.abort(@ctx.message("core.app.serve.error.invalid_port", options.flags[:port])) unless port > 0
|
13
|
+
port
|
14
|
+
end
|
15
|
+
|
16
|
+
def host
|
17
|
+
host = options.flags[:host]
|
18
|
+
unless host.nil?
|
19
|
+
@ctx.abort(@ctx.message("core.app.serve.error.host_must_be_https")) if host.match(/^https/i).nil?
|
20
|
+
end
|
21
|
+
host
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def parse_host_option
|
28
|
+
options do |parser, flags|
|
29
|
+
parser.on("--host=HOST") do |h|
|
30
|
+
flags[:host] = h.gsub('"', "")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_port_option
|
36
|
+
options do |parser, flags|
|
37
|
+
parser.on("--port=PORT") { |port| flags[:port] = port }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -15,7 +15,7 @@ module ShopifyCLI
|
|
15
15
|
|
16
16
|
def call(*)
|
17
17
|
shop = (options.flags[:shop] || @ctx.getenv("SHOPIFY_SHOP" || nil))
|
18
|
-
ShopifyCLI::DB.set(shop: self.class.validate_shop(shop)) unless shop.nil?
|
18
|
+
ShopifyCLI::DB.set(shop: self.class.validate_shop(shop, context: @ctx)) unless shop.nil?
|
19
19
|
|
20
20
|
if shop.nil? && Shopifolk.check
|
21
21
|
Shopifolk.reset
|
@@ -41,9 +41,9 @@ module ShopifyCLI
|
|
41
41
|
ShopifyCLI::Context.message("core.login.help", ShopifyCLI::TOOL_NAME)
|
42
42
|
end
|
43
43
|
|
44
|
-
def self.validate_shop(shop)
|
44
|
+
def self.validate_shop(shop, context:)
|
45
45
|
permanent_domain = shop_to_permanent_domain(shop)
|
46
|
-
|
46
|
+
context.abort(context.message("core.login.invalid_shop", shop)) unless permanent_domain
|
47
47
|
permanent_domain
|
48
48
|
end
|
49
49
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "shopify_cli"
|
2
|
+
|
3
|
+
module ShopifyCLI
|
4
|
+
module Commands
|
5
|
+
class Reporting < ShopifyCLI::Command
|
6
|
+
def call(args, _name)
|
7
|
+
enable_reporting = reporting_enabled?(args)
|
8
|
+
Services::ReportingService.call(enable: enable_reporting)
|
9
|
+
|
10
|
+
message = if enable_reporting
|
11
|
+
@ctx.message("core.reporting.turned_on_message")
|
12
|
+
else
|
13
|
+
@ctx.message("core.reporting.turned_off_message", ShopifyCLI::TOOL_NAME)
|
14
|
+
end
|
15
|
+
@ctx.puts(message)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reporting_enabled?(args)
|
19
|
+
case args.first
|
20
|
+
when nil
|
21
|
+
@ctx.abort(@ctx.message("core.reporting.missing_argument", ShopifyCLI::TOOL_NAME))
|
22
|
+
when "on"
|
23
|
+
true
|
24
|
+
when "off"
|
25
|
+
false
|
26
|
+
else
|
27
|
+
@ctx.abort(
|
28
|
+
@ctx.message("core.reporting.invalid_argument", ShopifyCLI::TOOL_NAME, args.first)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.help
|
34
|
+
ShopifyCLI::Context.message("core.reporting.help", ShopifyCLI::TOOL_NAME)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -16,7 +16,7 @@ module ShopifyCLI
|
|
16
16
|
end
|
17
17
|
|
18
18
|
shop = if options.flags[:shop]
|
19
|
-
Login.validate_shop(options.flags[:shop])
|
19
|
+
Login.validate_shop(options.flags[:shop], context: @ctx)
|
20
20
|
elsif (org_id = DB.get(:organization_id))
|
21
21
|
res = ShopifyCLI::Tasks::SelectOrgAndShop.call(@ctx, organization_id: org_id)
|
22
22
|
res[:shop_domain]
|
data/lib/shopify_cli/commands.rb
CHANGED
@@ -23,6 +23,7 @@ module ShopifyCLI
|
|
23
23
|
register :Login, "login", "shopify_cli/commands/login", true
|
24
24
|
register :Logout, "logout", "shopify_cli/commands/logout", true
|
25
25
|
register :Populate, "populate", "shopify_cli/commands/populate", true
|
26
|
+
register :Reporting, "reporting", "shopify_cli/commands/reporting", true
|
26
27
|
register :Store, "store", "shopify_cli/commands/store", true
|
27
28
|
register :Switch, "switch", "shopify_cli/commands/switch", true
|
28
29
|
register :System, "system", "shopify_cli/commands/system", true
|
@@ -15,10 +15,10 @@ module ShopifyCLI
|
|
15
15
|
|
16
16
|
module Config
|
17
17
|
module Sections
|
18
|
-
module
|
19
|
-
NAME = "
|
18
|
+
module Analytics
|
19
|
+
NAME = "analytics"
|
20
20
|
module Fields
|
21
|
-
|
21
|
+
ENABLED = "enabled"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -39,7 +39,11 @@ module ShopifyCLI
|
|
39
39
|
|
40
40
|
# Environments
|
41
41
|
TEST = "SHOPIFY_CLI_TEST"
|
42
|
+
ACCEPTANCE_TEST = "SHOPIFY_CLI_ACCEPTANCE_TEST"
|
42
43
|
DEVELOPMENT = "SHOPIFY_CLI_DEVELOPMENT"
|
44
|
+
|
45
|
+
# Monorail
|
46
|
+
MONORAIL_REAL_EVENTS = "MONORAIL_REAL_EVENTS"
|
43
47
|
end
|
44
48
|
|
45
49
|
module Identity
|