shopify-cli 2.25.0 → 2.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/dev.yml +0 -3
  5. data/lib/project_types/script/cli.rb +0 -79
  6. data/lib/project_types/script/commands/connect.rb +3 -8
  7. data/lib/project_types/script/commands/create.rb +4 -29
  8. data/lib/project_types/script/commands/javy.rb +3 -8
  9. data/lib/project_types/script/commands/push.rb +4 -41
  10. data/lib/project_types/script/messages/messages.rb +1 -258
  11. data/lib/project_types/theme/commands/common/shop_helper.rb +13 -0
  12. data/lib/project_types/theme/commands/delete.rb +4 -1
  13. data/lib/project_types/theme/commands/list.rb +3 -4
  14. data/lib/project_types/theme/commands/open.rb +4 -1
  15. data/lib/project_types/theme/commands/publish.rb +4 -1
  16. data/lib/project_types/theme/commands/pull.rb +3 -1
  17. data/lib/project_types/theme/commands/push.rb +3 -1
  18. data/lib/project_types/theme/messages/messages.rb +5 -5
  19. data/lib/shopify_cli/messages/messages.rb +1 -1
  20. data/lib/shopify_cli/packager.rb +12 -3
  21. data/lib/shopify_cli/release.rb +4 -2
  22. data/lib/shopify_cli/version.rb +1 -1
  23. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +1 -1
  24. metadata +3 -48
  25. data/lib/project_types/script/config/extension_points.yml +0 -45
  26. data/lib/project_types/script/errors.rb +0 -10
  27. data/lib/project_types/script/forms/ask_app.rb +0 -27
  28. data/lib/project_types/script/forms/ask_org.rb +0 -30
  29. data/lib/project_types/script/forms/ask_script_uuid.rb +0 -22
  30. data/lib/project_types/script/forms/create.rb +0 -33
  31. data/lib/project_types/script/forms/run_against_shopify_org.rb +0 -14
  32. data/lib/project_types/script/graphql/app_script_set.graphql +0 -46
  33. data/lib/project_types/script/graphql/get_app_scripts.graphql +0 -6
  34. data/lib/project_types/script/graphql/module_upload_url_generate.graphql +0 -13
  35. data/lib/project_types/script/graphql/script_service_proxy.graphql +0 -7
  36. data/lib/project_types/script/layers/application/build_script.rb +0 -25
  37. data/lib/project_types/script/layers/application/connect_app.rb +0 -86
  38. data/lib/project_types/script/layers/application/create_script.rb +0 -90
  39. data/lib/project_types/script/layers/application/extension_points.rb +0 -66
  40. data/lib/project_types/script/layers/application/project_dependencies.rb +0 -26
  41. data/lib/project_types/script/layers/application/push_script.rb +0 -74
  42. data/lib/project_types/script/layers/domain/app_bridge.rb +0 -16
  43. data/lib/project_types/script/layers/domain/errors.rb +0 -47
  44. data/lib/project_types/script/layers/domain/extension_point.rb +0 -81
  45. data/lib/project_types/script/layers/domain/metadata.rb +0 -46
  46. data/lib/project_types/script/layers/domain/push_package.rb +0 -41
  47. data/lib/project_types/script/layers/domain/script_config.rb +0 -32
  48. data/lib/project_types/script/layers/domain/script_project.rb +0 -61
  49. data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +0 -53
  50. data/lib/project_types/script/layers/infrastructure/api_clients/script_service_api_client.rb +0 -35
  51. data/lib/project_types/script/layers/infrastructure/command_runner.rb +0 -19
  52. data/lib/project_types/script/layers/infrastructure/errors.rb +0 -211
  53. data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +0 -37
  54. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -62
  55. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +0 -47
  56. data/lib/project_types/script/layers/infrastructure/languages/tool_version_checker.rb +0 -26
  57. data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +0 -45
  58. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +0 -103
  59. data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +0 -12
  60. data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +0 -32
  61. data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +0 -18
  62. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +0 -36
  63. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +0 -273
  64. data/lib/project_types/script/layers/infrastructure/script_service.rb +0 -135
  65. data/lib/project_types/script/layers/infrastructure/script_uploader.rb +0 -40
  66. data/lib/project_types/script/layers/infrastructure/service_locator.rb +0 -20
  67. data/lib/project_types/script/layers/infrastructure/sparse_checkout_details.rb +0 -35
  68. data/lib/project_types/script/ui/error_handler.rb +0 -331
  69. data/lib/project_types/script/ui/printing_spinner.rb +0 -75
  70. data/lib/project_types/script/ui/strict_spinner.rb +0 -20
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "shopify_cli"
4
-
5
- module Script
6
- module Layers
7
- module Application
8
- class CreateScript
9
- class << self
10
- def call(ctx:, language:, sparse_checkout_branch:, title:, extension_point_type:)
11
- script_project_repo = Infrastructure::ScriptProjectRepository.new(
12
- ctx: ctx,
13
- directory: title,
14
- initial_directory: ctx.root
15
- )
16
-
17
- in_new_directory_context(script_project_repo) do
18
- extension_point = ExtensionPoints.get(type: extension_point_type)
19
- project = script_project_repo.create(
20
- title: title,
21
- extension_point_type: extension_point_type,
22
- language: language
23
- )
24
-
25
- # remove the need to pass the whole extension-point object to the infra layer
26
- type = extension_point.dasherize_type
27
- domain = extension_point.domain
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
-
36
- project_creator = Infrastructure::Languages::ProjectCreator.for(
37
- ctx: ctx,
38
- language: language,
39
- type: type,
40
- project_name: title,
41
- path_to_project: project.id,
42
- sparse_checkout_details: sparse_checkout_details,
43
- )
44
-
45
- install_dependencies(ctx, language, title, project_creator)
46
- project
47
- end
48
- end
49
-
50
- private
51
-
52
- def install_dependencies(ctx, language, title, project_creator)
53
- task_runner = Infrastructure::Languages::TaskRunner.for(ctx, language)
54
- CLI::UI::Frame.open(ctx.message(
55
- "core.git.pulling_from_to",
56
- project_creator.sparse_checkout_details.repo,
57
- title,
58
- )) do
59
- UI::StrictSpinner.spin(ctx.message(
60
- "core.git.pulling",
61
- project_creator.sparse_checkout_details.repo,
62
- title,
63
- )) do |spinner|
64
- project_creator.setup_dependencies
65
- spinner.update_title(ctx.message("core.git.pulled", title))
66
- end
67
- end
68
- ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
69
- end
70
-
71
- def in_new_directory_context(script_project_repo)
72
- script_project_repo.create_project_directory
73
- yield
74
- rescue Infrastructure::Errors::ScriptProjectAlreadyExistsError
75
- raise
76
- rescue
77
- script_project_repo.delete_project_directory
78
- raise
79
- ensure
80
- script_project_repo.change_to_initial_directory
81
- end
82
-
83
- def input_queries_enabled?
84
- ShopifyCLI::Feature.enabled?(:scripts_beta_input_queries)
85
- end
86
- end
87
- end
88
- end
89
- end
90
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Application
6
- class ExtensionPoints
7
- class << self
8
- def get(type:)
9
- extension_point_repository.get_extension_point(type)
10
- end
11
-
12
- def types
13
- extension_point_repository.extension_point_types
14
- end
15
-
16
- def available_types
17
- available_extension_points.map(&:type)
18
- end
19
-
20
- def deprecated_types
21
- extension_point_repository
22
- .extension_points
23
- .select(&:deprecated?)
24
- .map(&:type)
25
- end
26
-
27
- def all_languages
28
- available_extension_points
29
- .map { |ep| ep.library_languages(include_betas: include_beta_languages?) }
30
- .flatten
31
- .uniq
32
- end
33
-
34
- def languages(type:)
35
- get(type: type).library_languages(include_betas: include_beta_languages?)
36
- end
37
-
38
- def supported_language?(type:, language:)
39
- languages(type: type).include?(language.downcase)
40
- end
41
-
42
- private
43
-
44
- def available_extension_points
45
- extension_point_repository.extension_points.select do |ep|
46
- next false if ep.deprecated?
47
- ep.stable? || include_beta_extension_points?
48
- end
49
- end
50
-
51
- def extension_point_repository
52
- Infrastructure::ExtensionPointRepository.new
53
- end
54
-
55
- def include_beta_languages?
56
- ShopifyCLI::Feature.enabled?(:scripts_beta_languages)
57
- end
58
-
59
- def include_beta_extension_points?
60
- ShopifyCLI::Feature.enabled?(:scripts_beta_extension_points)
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,26 +0,0 @@
1
- module Script
2
- module Layers
3
- module Application
4
- class ProjectDependencies
5
- def self.install(ctx:, task_runner:)
6
- CLI::UI::Frame.open(ctx.message("script.project_deps.checking")) do
7
- if task_runner.dependencies_installed?
8
- ctx.puts(ctx.message("script.project_deps.none_required"))
9
- else
10
- UI::StrictSpinner.spin(ctx.message("script.project_deps.installing")) do |spinner|
11
- task_runner.install_dependencies
12
- spinner.update_title(ctx.message("script.project_deps.installed"))
13
- end
14
- end
15
- true
16
- rescue Infrastructure::Errors::DependencyInstallError => e
17
- CLI::UI::Frame.with_frame_color_override(:red) do
18
- ctx.puts("\n#{e.message}")
19
- end
20
- raise e
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Application
6
- class PushScript
7
- class << self
8
- def call(ctx:, force:, project:)
9
- script_project_repo = Infrastructure::ScriptProjectRepository.new(ctx: ctx)
10
- script_project = script_project_repo.get
11
- script_project.env = project.env
12
- task_runner = Infrastructure::Languages::TaskRunner
13
- .for(ctx, script_project.language)
14
-
15
- extension_point = ExtensionPoints.get(type: script_project.extension_point_type)
16
-
17
- library = extension_point.libraries.for(script_project.language)
18
-
19
- raise Infrastructure::Errors::LanguageLibraryForAPINotFoundError.new(
20
- language: script_project.language,
21
- api: script_project.extension_point_type
22
- ) if library.nil? && (script_project.language != "wasm")
23
-
24
- ProjectDependencies.install(ctx: ctx, task_runner: task_runner)
25
- BuildScript.call(ctx: ctx, task_runner: task_runner)
26
-
27
- CLI::UI::Frame.open(ctx.message("script.application.pushing")) do
28
- UI::PrintingSpinner.spin(ctx, ctx.message("script.application.pushing_script")) do |p_ctx, spinner|
29
- library_name = library&.package
30
- library_data = {
31
- language: script_project.language,
32
- version: task_runner.library_version(library_name),
33
- } if library_name
34
-
35
- metadata_file_location = task_runner.metadata_file_location
36
- metadata = Infrastructure::MetadataRepository.new(ctx: ctx).get_metadata(metadata_file_location)
37
-
38
- package = Infrastructure::PushPackageRepository.new(ctx: p_ctx).get_push_package(
39
- script_project: script_project,
40
- metadata: metadata,
41
- library: library_data,
42
- )
43
-
44
- script_service = Infrastructure::ServiceLocator.script_service(
45
- ctx: p_ctx,
46
- api_key: script_project.api_key
47
- )
48
- module_upload_url = Infrastructure::ScriptUploader.new(script_service).upload(package.script_content)
49
-
50
- uuid = script_service.set_app_script(
51
- uuid: package.uuid,
52
- extension_point_type: package.extension_point_type,
53
- title: package.title,
54
- description: package.description,
55
- force: force,
56
- metadata: package.metadata,
57
- script_config: package.script_config,
58
- app_bridge: script_project.app_bridge,
59
- module_upload_url: module_upload_url,
60
- library: package.library,
61
- input_query: script_project.input_query,
62
- )
63
- if ShopifyCLI::Environment.interactive?
64
- script_project_repo.update_env(uuid: uuid)
65
- end
66
- spinner.update_title(p_ctx.message("script.application.pushed"))
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class AppBridge
7
- attr_reader :create_path, :details_path
8
-
9
- def initialize(create_path:, details_path:)
10
- @create_path = create_path
11
- @details_path = details_path
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- module Errors
7
- class PushPackageNotFoundError < ScriptProjectError; end
8
-
9
- class InvalidExtensionPointError < ScriptProjectError
10
- attr_reader :type
11
- def initialize(type)
12
- super()
13
- @type = type
14
- end
15
- end
16
-
17
- class MissingScriptConfigFieldError < ScriptProjectError
18
- attr_reader :field, :filename
19
- def initialize(field:, filename:)
20
- super()
21
- @field = field
22
- @filename = filename
23
- end
24
- end
25
-
26
- class ScriptNotFoundError < ScriptProjectError
27
- attr_reader :title, :extension_point_type
28
- def initialize(extension_point_type, title)
29
- super()
30
- @title = title
31
- @extension_point_type = extension_point_type
32
- end
33
- end
34
-
35
- class MetadataNotFoundError < ScriptProjectError
36
- attr_reader :filename
37
- def initialize(filename)
38
- super()
39
- @filename = filename
40
- end
41
- end
42
-
43
- class MetadataValidationError < ScriptProjectError; end
44
- end
45
- end
46
- end
47
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class ExtensionPoint
7
- attr_reader :type, :beta, :deprecated, :libraries, :domain
8
-
9
- def initialize(type, config)
10
- @type = type
11
- @beta = config["beta"] || false
12
- @deprecated = config["deprecated"] || false
13
- @domain = config["domain"] || nil
14
- @libraries = ExtensionPointLibraries.new(config["libraries"])
15
- end
16
-
17
- def beta?
18
- @beta
19
- end
20
-
21
- def stable?
22
- !beta?
23
- end
24
-
25
- def deprecated?
26
- @deprecated
27
- end
28
-
29
- def dasherize_type
30
- @type.gsub("_", "-")
31
- end
32
-
33
- def library_languages(include_betas: false)
34
- @libraries.all.map do |library|
35
- include_betas || library.stable? ? library.language : nil
36
- end.compact
37
- end
38
-
39
- class ExtensionPointLibraries
40
- def initialize(config)
41
- @config = config
42
- end
43
-
44
- def all
45
- @all ||= @config.map do |language, library_config|
46
- ExtensionPointLibrary.new(language, library_config)
47
- end
48
- end
49
-
50
- def for(language)
51
- all.find { |ep| ep.language == language }
52
- end
53
- end
54
-
55
- class ExtensionPointLibrary
56
- attr_reader :language, :version, :beta, :package, :repo
57
-
58
- def initialize(language, config)
59
- @language = language
60
- @beta = config["beta"] || false
61
- @package = config["package"]
62
- @version = config["package-version"]
63
- @repo = config["repo"]
64
- end
65
-
66
- def beta?
67
- @beta
68
- end
69
-
70
- def stable?
71
- !beta?
72
- end
73
-
74
- def versioned?
75
- @version
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class Metadata
7
- attr_reader :schema_major_version, :schema_minor_version
8
-
9
- def initialize(schema_major_version, schema_minor_version)
10
- @schema_major_version = schema_major_version
11
- @schema_minor_version = schema_minor_version
12
- end
13
-
14
- class << self
15
- def create_from_json(ctx, metadata_json)
16
- err_tag = nil
17
- metadata_hash = JSON.parse(metadata_json)
18
-
19
- schema_versions = metadata_hash["schemaVersions"] || {}
20
-
21
- version = schema_versions.values.first || {}
22
- schema_major_version = version["major"]
23
- schema_minor_version = version["minor"]
24
-
25
- if schema_versions.empty?
26
- err_tag = "script.error.metadata_schema_versions_missing"
27
- elsif schema_versions.count != 1
28
- # Scripts may be attached to more than one EP in the future but not right now
29
- err_tag = "script.error.metadata_schema_versions_single_key"
30
- elsif schema_major_version.nil?
31
- err_tag = "script.error.metadata_schema_versions_missing_major"
32
- elsif schema_minor_version.nil?
33
- err_tag = "script.error.metadata_schema_versions_missing_minor"
34
- end
35
-
36
- Metadata.new(schema_major_version, schema_minor_version)
37
- rescue JSON::ParserError
38
- err_tag = "script.error.metadata_validation_cause"
39
- ensure
40
- raise Errors::MetadataValidationError, ctx.message(err_tag) if err_tag
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class PushPackage
7
- attr_reader :id,
8
- :uuid,
9
- :extension_point_type,
10
- :title,
11
- :description,
12
- :script_config,
13
- :script_content,
14
- :metadata,
15
- :library
16
-
17
- def initialize(
18
- id:,
19
- uuid:,
20
- extension_point_type:,
21
- title:,
22
- description:,
23
- script_content:,
24
- metadata:,
25
- script_config:,
26
- library:
27
- )
28
- @id = id
29
- @uuid = uuid
30
- @extension_point_type = extension_point_type
31
- @title = title
32
- @description = description
33
- @script_content = script_content
34
- @metadata = metadata
35
- @script_config = script_config
36
- @library = library
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class ScriptConfig
7
- attr_reader :content, :version, :configuration_ui, :configuration, :filename
8
-
9
- REQUIRED_FIELDS = %w(version)
10
-
11
- def initialize(content:, filename:)
12
- @filename = filename
13
- validate_content!(content)
14
- @content = content
15
- @version = @content["version"].to_s
16
- @configuration_ui = @content.fetch("configurationUi", true)
17
- @configuration = @content["configuration"]
18
- end
19
-
20
- private
21
-
22
- def validate_content!(content)
23
- REQUIRED_FIELDS.each do |field|
24
- if content[field].nil?
25
- raise Errors::MissingScriptConfigFieldError.new(field: field, filename: filename)
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Domain
6
- class ScriptProject
7
- include SmartProperties
8
-
9
- UUID_ENV_KEY = "UUID"
10
-
11
- property! :id, accepts: String
12
- property :env, accepts: ShopifyCLI::Resources::EnvFile
13
-
14
- property! :extension_point_type, accepts: String
15
- property! :title, accepts: String
16
- property :description, accepts: String
17
- property! :language, accepts: String
18
-
19
- property :script_config, accepts: ScriptConfig
20
- property :app_bridge, accepts: AppBridge
21
- property :input_query, accepts: String
22
-
23
- def initialize(*)
24
- super
25
-
26
- ShopifyCLI::Core::Monorail.metadata = {
27
- "script_name" => title,
28
- "extension_point_type" => extension_point_type,
29
- "language" => language,
30
- }
31
- end
32
-
33
- def api_key
34
- env&.api_key
35
- end
36
-
37
- def api_secret
38
- env&.secret
39
- end
40
-
41
- def uuid
42
- uuid_defined? && !raw_uuid.empty? ? raw_uuid : nil
43
- end
44
-
45
- def uuid_defined?
46
- !raw_uuid.nil?
47
- end
48
-
49
- def env_valid?
50
- api_key && api_secret && uuid_defined?
51
- end
52
-
53
- private
54
-
55
- def raw_uuid
56
- env&.extra&.[](UUID_ENV_KEY)
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,53 +0,0 @@
1
- module Script
2
- module Layers
3
- module Infrastructure
4
- module ApiClients
5
- class PartnersProxyApiClient
6
- def initialize(ctx, api_key)
7
- @ctx = ctx
8
- @api_key = api_key
9
- end
10
-
11
- def query(query_name, variables: {})
12
- proxy_response = ShimAPI.query(@ctx, query_name, api_key: @api_key, variables: variables.to_json)
13
- raise_if_graphql_failed(proxy_response)
14
-
15
- response = proxy_response.dig("data", "scriptServiceProxy")
16
- raise Errors::InvalidResponseError unless response
17
-
18
- JSON.parse(response)
19
- end
20
-
21
- private
22
-
23
- def raise_if_graphql_failed(response)
24
- raise Errors::EmptyResponseError if response.nil?
25
-
26
- return unless response.key?("errors")
27
- case error_code(response["errors"])
28
- when "forbidden"
29
- raise Errors::ForbiddenError
30
- else
31
- raise Errors::GraphqlError, response["errors"]
32
- end
33
- end
34
-
35
- def error_code(errors)
36
- errors.map do |e|
37
- code = e.dig("extensions", "code")
38
- return code if code
39
- end
40
- end
41
-
42
- class ShimAPI < ShopifyCLI::PartnersAPI
43
- def query(query_name, variables: {})
44
- variables[:query] = load_query(query_name)
45
- super("script_service_proxy", variables: variables)
46
- end
47
- end
48
- private_constant(:ShimAPI)
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,35 +0,0 @@
1
- module Script
2
- module Layers
3
- module Infrastructure
4
- module ApiClients
5
- class ScriptServiceApiClient
6
- LOCAL_INSTANCE_URL = "https://script-service.myshopify.io"
7
-
8
- def initialize(ctx, api_key)
9
- instance_url = script_service_url
10
- @api = ShopifyCLI::API.new(
11
- ctx: ctx,
12
- url: "#{instance_url}/graphql",
13
- token: { "APP_KEY" => api_key }.compact.to_json,
14
- auth_header: "X-Shopify-Authenticated-Tokens"
15
- )
16
- end
17
-
18
- def query(query_name, variables: {})
19
- @api.query(query_name, variables: variables)
20
- end
21
-
22
- private
23
-
24
- def script_service_url
25
- if ::ShopifyCLI::Environment.use_spin?
26
- "https://script-service.#{::ShopifyCLI::Environment.spin_url}"
27
- else
28
- LOCAL_INSTANCE_URL
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Script
4
- module Layers
5
- module Infrastructure
6
- class CommandRunner
7
- include SmartProperties
8
-
9
- property! :ctx, accepts: ShopifyCLI::Context
10
-
11
- def call(cmd)
12
- out, status = ctx.capture2e(cmd)
13
- raise Errors::SystemCallFailureError.new(out: out.chomp, cmd: cmd) unless status.success?
14
- out
15
- end
16
- end
17
- end
18
- end
19
- end