shopify-cli 2.11.2 → 2.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +5 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +1 -1
  4. data/.github/workflows/shopify.yml +2 -1
  5. data/.rubocop.yml +1 -1
  6. data/.ruby-version +1 -1
  7. data/CHANGELOG.md +44 -1
  8. data/Gemfile.lock +18 -18
  9. data/Rakefile +16 -0
  10. data/bin/shopify +12 -8
  11. data/dev.yml +1 -1
  12. data/docs/users/installation.md +1 -44
  13. data/ext/javy/hashes/javy-arm-macos-v0.2.0.gz.sha256 +1 -0
  14. data/ext/javy/hashes/javy-arm-macos-v0.2.1.gz.sha256 +1 -0
  15. data/ext/javy/hashes/javy-x86_64-linux-v0.2.0.gz.sha256 +1 -0
  16. data/ext/javy/hashes/javy-x86_64-linux-v0.2.1.gz.sha256 +1 -0
  17. data/ext/javy/hashes/javy-x86_64-macos-v0.2.0.gz.sha256 +1 -0
  18. data/ext/javy/hashes/javy-x86_64-macos-v0.2.1.gz.sha256 +1 -0
  19. data/ext/javy/hashes/javy-x86_64-windows-v0.2.0.gz.sha256 +1 -0
  20. data/ext/javy/hashes/javy-x86_64-windows-v0.2.1.gz.sha256 +1 -0
  21. data/ext/javy/version +1 -1
  22. data/lib/project_types/extension/features/argo_setup_steps.rb +4 -6
  23. data/lib/project_types/extension/models/npm_package.rb +19 -1
  24. data/lib/project_types/extension/models/server_config/development_renderer.rb +4 -3
  25. data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +114 -0
  26. data/lib/project_types/extension/tasks/configure_features.rb +15 -2
  27. data/lib/project_types/extension/tasks/convert_server_config.rb +2 -1
  28. data/lib/project_types/script/cli.rb +2 -4
  29. data/lib/project_types/script/commands/create.rb +5 -5
  30. data/lib/project_types/script/commands/push.rb +4 -6
  31. data/lib/project_types/script/config/extension_points.yml +0 -10
  32. data/lib/project_types/script/errors.rb +1 -1
  33. data/lib/project_types/script/forms/create.rb +7 -20
  34. data/lib/project_types/script/layers/application/build_script.rb +9 -26
  35. data/lib/project_types/script/layers/application/connect_app.rb +3 -2
  36. data/lib/project_types/script/layers/application/create_script.rb +9 -10
  37. data/lib/project_types/script/layers/application/project_dependencies.rb +12 -14
  38. data/lib/project_types/script/layers/application/push_script.rb +14 -10
  39. data/lib/project_types/script/layers/domain/errors.rb +3 -3
  40. data/lib/project_types/script/layers/domain/push_package.rb +6 -0
  41. data/lib/project_types/script/layers/domain/script_config.rb +2 -4
  42. data/lib/project_types/script/layers/domain/script_project.rb +3 -2
  43. data/lib/project_types/script/layers/infrastructure/errors.rb +11 -0
  44. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +0 -16
  45. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +0 -1
  46. data/lib/project_types/script/layers/infrastructure/languages/tool_version_checker.rb +26 -0
  47. data/lib/project_types/script/layers/infrastructure/languages/typescript_project_creator.rb +22 -10
  48. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +32 -29
  49. data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +0 -3
  50. data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +1 -1
  51. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +3 -21
  52. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +14 -26
  53. data/lib/project_types/script/layers/infrastructure/script_service.rb +4 -2
  54. data/lib/project_types/script/loaders/project.rb +8 -7
  55. data/lib/project_types/script/messages/messages.rb +22 -21
  56. data/lib/project_types/script/ui/error_handler.rb +17 -4
  57. data/lib/project_types/script/ui/strict_spinner.rb +4 -6
  58. data/lib/project_types/theme/cli.rb +2 -0
  59. data/lib/project_types/theme/commands/common/root_helper.rb +71 -0
  60. data/lib/project_types/theme/commands/init.rb +2 -0
  61. data/lib/project_types/theme/commands/list.rb +34 -0
  62. data/lib/project_types/theme/commands/open.rb +65 -0
  63. data/lib/project_types/theme/commands/package.rb +1 -0
  64. data/lib/project_types/theme/commands/pull.rb +18 -10
  65. data/lib/project_types/theme/commands/push.rb +17 -9
  66. data/lib/project_types/theme/commands/serve.rb +6 -2
  67. data/lib/project_types/theme/conversions/base_glob.rb +50 -0
  68. data/lib/project_types/theme/conversions/ignore_glob.rb +15 -0
  69. data/lib/project_types/theme/conversions/include_glob.rb +15 -0
  70. data/lib/project_types/theme/forms/select.rb +11 -39
  71. data/lib/project_types/theme/messages/messages.rb +38 -7
  72. data/lib/project_types/theme/presenters/theme_presenter.rb +48 -0
  73. data/lib/project_types/theme/presenters/themes_presenter.rb +32 -0
  74. data/lib/shopify_cli/api.rb +1 -1
  75. data/lib/shopify_cli/commands/app/create/node.rb +1 -0
  76. data/lib/shopify_cli/commands/app/create/php.rb +1 -0
  77. data/lib/shopify_cli/commands/app/create/rails.rb +1 -0
  78. data/lib/shopify_cli/commands/app/deploy.rb +1 -1
  79. data/lib/shopify_cli/constants.rb +2 -2
  80. data/lib/shopify_cli/context.rb +13 -15
  81. data/lib/shopify_cli/core/entry_point.rb +1 -1
  82. data/lib/shopify_cli/core/monorail.rb +14 -6
  83. data/lib/shopify_cli/environment.rb +6 -0
  84. data/lib/shopify_cli/exception_reporter.rb +2 -0
  85. data/lib/shopify_cli/git.rb +9 -1
  86. data/lib/shopify_cli/messages/messages.rb +21 -1
  87. data/lib/shopify_cli/packager.rb +1 -1
  88. data/lib/shopify_cli/result.rb +14 -0
  89. data/lib/shopify_cli/services/app/create/rails_service.rb +1 -1
  90. data/lib/shopify_cli/tasks/ensure_git_dependency.rb +14 -0
  91. data/lib/shopify_cli/tasks.rb +1 -0
  92. data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +5 -5
  93. data/lib/shopify_cli/theme/dev_server/proxy.rb +14 -2
  94. data/lib/shopify_cli/theme/dev_server/watcher.rb +10 -2
  95. data/lib/shopify_cli/theme/development_theme.rb +2 -5
  96. data/lib/shopify_cli/theme/include_filter.rb +4 -2
  97. data/lib/shopify_cli/theme/syncer.rb +40 -36
  98. data/lib/shopify_cli/theme/theme.rb +16 -27
  99. data/lib/shopify_cli/theme/theme_admin_api.rb +71 -0
  100. data/lib/shopify_cli/transform_data_structure.rb +3 -2
  101. data/lib/shopify_cli/version.rb +1 -1
  102. data/shipit.yml +3 -0
  103. data/shopify-cli.gemspec +9 -2
  104. data/shopify-dev +9 -11
  105. metadata +26 -8
  106. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_project_creator.rb +0 -25
  107. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +0 -98
@@ -5,21 +5,28 @@ module Script
5
5
  module Infrastructure
6
6
  module Languages
7
7
  class TypeScriptTaskRunner < TaskRunner
8
+ NODE_MIN_VERSION = "14.15.0"
9
+ NPM_MIN_VERSION = "5.2.0"
10
+
8
11
  BYTECODE_FILE = "build/index.wasm"
9
12
  METADATA_FILE = "build/metadata.json"
10
13
  SCRIPT_SDK_BUILD = "npm run build"
11
14
  GEN_METADATA = "npm run gen-metadata"
15
+ NPM_SET_REGISTRY_COMMAND = "npm --userconfig ./.npmrc config set @shopify:registry https://registry.npmjs.com"
16
+ NPM_SET_ENGINE_STRICT_COMMAND = "npm --userconfig ./.npmrc config set engine-strict true"
17
+ NPM_INSTALL_COMMAND = "npm install --no-audit --no-optional --legacy-peer-deps --loglevel error"
12
18
 
13
19
  def build
14
20
  compile
15
- bytecode
21
+ rescue Errors::SystemCallFailureError => e
22
+ raise Errors::BuildError, e.out
16
23
  end
17
24
 
18
25
  def install_dependencies
19
- check_node_version!
26
+ run_cmd_with_env_check(NPM_INSTALL_COMMAND)
20
27
 
21
- output, status = ctx.capture2e("npm install --no-audit --no-optional --legacy-peer-deps --loglevel error")
22
- raise Errors::DependencyInstallError, output unless status.success?
28
+ rescue Errors::SystemCallFailureError => e
29
+ raise Errors::DependencyInstallError, e.out
23
30
  end
24
31
 
25
32
  def dependencies_installed?
@@ -32,14 +39,32 @@ module Script
32
39
  end
33
40
 
34
41
  def library_version(library_name)
35
- output = JSON.parse(CommandRunner.new(ctx: ctx).call("npm -s list --json"))
42
+ output = JSON.parse(run_cmd_with_env_check("npm -s list --json"))
36
43
  library_version_from_npm_list(output, library_name)
37
44
  rescue Errors::SystemCallFailureError => error
38
45
  library_version_from_npm_list_error_output(error, library_name)
39
46
  end
40
47
 
48
+ def set_npm_config
49
+ run_cmd_with_env_check(NPM_SET_REGISTRY_COMMAND)
50
+ run_cmd_with_env_check(NPM_SET_ENGINE_STRICT_COMMAND)
51
+ end
52
+
41
53
  private
42
54
 
55
+ def ensure_environment
56
+ return if defined?(@environment_checked)
57
+ @environment_checked = true
58
+
59
+ ToolVersionChecker.check_node(minimum_version: NODE_MIN_VERSION)
60
+ ToolVersionChecker.check_npm(minimum_version: NPM_MIN_VERSION)
61
+ end
62
+
63
+ def run_cmd_with_env_check(cmd)
64
+ ensure_environment
65
+ CommandRunner.new(ctx: ctx).call(cmd)
66
+ end
67
+
43
68
  def library_version_from_npm_list_error_output(error, library_name)
44
69
  # npm list can return a failure status code, even when returning the correct data.
45
70
  # This causes the CommandRunner to throw a SystemCallFailure error that contains the data.
@@ -58,23 +83,10 @@ module Script
58
83
  end
59
84
  end
60
85
 
61
- def check_node_version!
62
- output, status = @ctx.capture2e("node", "--version")
63
- raise Errors::DependencyInstallError, output unless status.success?
64
-
65
- require "semantic/semantic"
66
- version = ::Semantic::Version.new(output[1..-1])
67
- unless version >= ::Semantic::Version.new(TypeScriptProjectCreator::MIN_NODE_VERSION)
68
- raise Errors::DependencyInstallError,
69
- "Node version must be >= v#{TypeScriptProjectCreator::MIN_NODE_VERSION}. "\
70
- "Current version: #{output.strip}."
71
- end
72
- end
73
-
74
86
  def compile
75
87
  check_compilation_dependencies!
76
- CommandRunner.new(ctx: ctx).call(SCRIPT_SDK_BUILD)
77
- CommandRunner.new(ctx: ctx).call(GEN_METADATA)
88
+ run_cmd_with_env_check(SCRIPT_SDK_BUILD)
89
+ run_cmd_with_env_check(GEN_METADATA)
78
90
  end
79
91
 
80
92
  def check_compilation_dependencies!
@@ -84,15 +96,6 @@ module Script
84
96
  raise Errors::BuildScriptNotFoundError,
85
97
  "Build script not found" if build_script.nil?
86
98
  end
87
-
88
- def bytecode
89
- raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(BYTECODE_FILE)
90
-
91
- contents = ctx.binread(BYTECODE_FILE)
92
- ctx.rm(BYTECODE_FILE)
93
-
94
- contents
95
- end
96
99
  end
97
100
  end
98
101
  end
@@ -5,9 +5,6 @@ module Script
5
5
  module Infrastructure
6
6
  module Languages
7
7
  class WasmProjectCreator < ProjectCreator
8
- def self.config_file
9
- "script.config.yml"
10
- end
11
8
  end
12
9
  end
13
10
  end
@@ -5,7 +5,7 @@ module Script
5
5
  module Infrastructure
6
6
  module Languages
7
7
  class WasmTaskRunner < TaskRunner
8
- BYTECODE_FILE = "script.wasm"
8
+ BYTECODE_FILE = "build/index.wasm"
9
9
 
10
10
  def dependencies_installed?
11
11
  true
@@ -7,21 +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
- script_content: script_content,
19
- metadata: metadata,
20
- script_config: script_project.script_config,
21
- library: library
22
- )
23
- end
24
-
25
10
  def get_push_package(script_project:, metadata:, library:)
26
11
  build_file_path = file_path(script_project.id)
27
12
  raise Domain::Errors::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
@@ -31,6 +16,8 @@ module Script
31
16
  id: build_file_path,
32
17
  uuid: script_project.uuid,
33
18
  extension_point_type: script_project.extension_point_type,
19
+ title: script_project.title,
20
+ description: script_project.description,
34
21
  script_content: script_content,
35
22
  metadata: metadata,
36
23
  script_config: script_project.script_config,
@@ -40,13 +27,8 @@ module Script
40
27
 
41
28
  private
42
29
 
43
- def write_to_path(path, content)
44
- ctx.mkdir_p(File.dirname(path))
45
- ctx.binwrite(path, content)
46
- end
47
-
48
30
  def file_path(path_to_script)
49
- "#{path_to_script}/build/script.wasm"
31
+ "#{path_to_script}/build/index.wasm"
50
32
  end
51
33
  end
52
34
  end
@@ -27,7 +27,7 @@ module Script
27
27
  change_directory(directory: initial_directory)
28
28
  end
29
29
 
30
- def create(script_name:, extension_point_type:, language:)
30
+ def create(title:, extension_point_type:, language:)
31
31
  validate_metadata!(extension_point_type, language)
32
32
 
33
33
  ShopifyCLI::Project.write(
@@ -35,7 +35,8 @@ module Script
35
35
  project_type: :script,
36
36
  organization_id: nil,
37
37
  extension_point_type: extension_point_type,
38
- script_name: script_name,
38
+ title: title,
39
+ description: nil,
39
40
  language: language
40
41
  )
41
42
 
@@ -48,7 +49,8 @@ module Script
48
49
  Domain::ScriptProject.new(
49
50
  id: project.directory,
50
51
  env: project.env,
51
- script_name: script_name,
52
+ title: title,
53
+ description: description,
52
54
  extension_point_type: extension_point_type,
53
55
  language: language,
54
56
  script_config: script_config_repository.get!,
@@ -79,11 +81,6 @@ module Script
79
81
  build_script_project
80
82
  end
81
83
 
82
- def update_script_config(title:)
83
- script_config = script_config_repository.update!(title: title)
84
- build_script_project(script_config: script_config)
85
- end
86
-
87
84
  private
88
85
 
89
86
  def build_script_project(
@@ -92,7 +89,8 @@ module Script
92
89
  Domain::ScriptProject.new(
93
90
  id: ctx.root,
94
91
  env: project.env,
95
- script_name: script_name,
92
+ title: title,
93
+ description: description,
96
94
  extension_point_type: extension_point_type,
97
95
  language: language,
98
96
  script_config: script_config,
@@ -111,8 +109,12 @@ module Script
111
109
  project_config_value!("extension_point_type")
112
110
  end
113
111
 
114
- def script_name
115
- project_config_value!("script_name")
112
+ def title
113
+ project_config_value!("title")
114
+ end
115
+
116
+ def description
117
+ project_config_value("description")
116
118
  end
117
119
 
118
120
  def language
@@ -134,7 +136,7 @@ module Script
134
136
  end
135
137
 
136
138
  def default_language
137
- "assemblyscript"
139
+ "wasm"
138
140
  end
139
141
 
140
142
  def validate_metadata!(extension_point_type, language)
@@ -181,26 +183,12 @@ module Script
181
183
  from_h(hash)
182
184
  end
183
185
 
184
- def update!(title:)
185
- hash = get!.content
186
- update_hash(hash: hash, title: title)
187
-
188
- ctx.write(filename, hash_to_file_content(hash))
189
-
190
- from_h(hash)
191
- end
192
-
193
186
  def filename
194
187
  raise NotImplementedError
195
188
  end
196
189
 
197
190
  private
198
191
 
199
- def update_hash(hash:, title:)
200
- hash["version"] ||= "2"
201
- hash["title"] = title
202
- end
203
-
204
192
  def from_h(hash)
205
193
  Domain::ScriptConfig.new(content: hash, filename: filename)
206
194
  end
@@ -15,6 +15,8 @@ module Script
15
15
  def set_app_script(
16
16
  uuid:,
17
17
  extension_point_type:,
18
+ title:,
19
+ description:,
18
20
  force: false,
19
21
  metadata:,
20
22
  script_config:,
@@ -26,8 +28,8 @@ module Script
26
28
  variables = {
27
29
  uuid: uuid,
28
30
  extensionPointName: extension_point_type.upcase,
29
- title: script_config.title,
30
- description: script_config.description,
31
+ title: title,
32
+ description: description,
31
33
  force: force,
32
34
  schemaMajorVersion: metadata.schema_major_version.to_s, # API expects string value
33
35
  schemaMinorVersion: metadata.schema_minor_version.to_s, # API expects string value
@@ -20,21 +20,22 @@ module Script
20
20
  project.env = env
21
21
  project
22
22
  rescue SmartProperties::InitializationError, SmartProperties::InvalidValueError => error
23
- handle_error(error, context: context, env_file_present: env_file_present)
23
+ handle_error(error, context: context)
24
24
  end
25
25
 
26
- def self.handle_error(error, context:, env_file_present:)
27
- if env_file_present
26
+ def self.handle_error(error, context:)
27
+ if ShopifyCLI::Environment.interactive?
28
28
  properties_hash = { api_key: "SHOPIFY_API_KEY", secret: "SHOPIFY_API_SECRET" }
29
29
  missing_env_variables = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
30
- raise ShopifyCLI::Abort,
31
- context.message("script.error.missing_env_file_variables", missing_env_variables, ShopifyCLI::TOOL_NAME)
30
+ message = context.message("script.error.missing_env_file_variables", missing_env_variables)
31
+ message += context.message("script.error.missing_env_file_variables_solution", ShopifyCLI::TOOL_NAME)
32
32
  else
33
33
  properties_hash = { api_key: "--api-key", secret: "--api-secret" }
34
34
  missing_options = error.properties.map { |p| properties_hash[p.name] }.compact.join(", ")
35
- raise ShopifyCLI::Abort, context.message("script.error.missing_push_options", missing_options,
36
- ShopifyCli::TOOL_NAME)
35
+ message = context.message("script.error.missing_push_options_ci", missing_options)
36
+ message += context.message("script.error.missing_push_options_ci_solution", ShopifyCLI::TOOL_NAME)
37
37
  end
38
+ raise ShopifyCLI::Abort, message
38
39
  end
39
40
 
40
41
  def self.env_file_exists?(directory)
@@ -24,11 +24,11 @@ module Script
24
24
  oauth_help: "Wait a few minutes and try again.",
25
25
 
26
26
  invalid_context_cause: "Your .shopify-cli.yml is formatted incorrectly. It's missing values for "\
27
- "extension_point_type or script_name.",
27
+ "extension_point_type or title.",
28
28
  invalid_context_help: "Add these values.",
29
29
 
30
- invalid_script_name_cause: "Script name contains unsupported characters.",
31
- invalid_script_name_help: "Use only numbers, letters, hyphens, or underscores.",
30
+ invalid_script_title_cause: "Script title contains unsupported characters.",
31
+ invalid_script_title_help: "Use only numbers, letters, hyphens, or underscores.",
32
32
 
33
33
  no_existing_apps_cause: "Your script can't be pushed to an app because your Partner account "\
34
34
  "doesn't have any apps.",
@@ -37,8 +37,8 @@ module Script
37
37
  no_existing_orgs_cause: "Your account doesn't belong to a Partner Organization.",
38
38
  no_existing_orgs_help: "Visit https://partners.shopify.com/ to create an account.",
39
39
 
40
- project_exists_cause: "A directory with this same name already exists.",
41
- project_exists_help: "Choose a different name for your script.",
40
+ project_exists_cause: "A directory with this same title already exists.",
41
+ project_exists_help: "Choose a different title for your script.",
42
42
 
43
43
  invalid_extension_cause: "The name of the Script API is incorrect: %s.",
44
44
  invalid_extension_help: "Choose a supported API: %s.",
@@ -113,6 +113,10 @@ module Script
113
113
  dependency_install_cause: "Something went wrong while installing the needed dependencies.",
114
114
  dependency_install_help: "Correct the errors.",
115
115
 
116
+ invalid_environment_cause: "Your environment %{tool} version, %{env_version}, "\
117
+ "is too low. It must be at least %{minimum_version}.",
118
+ invalid_environment_help: "Update %{tool}.",
119
+
116
120
  failed_api_request_cause: "Something went wrong while communicating with Shopify.",
117
121
  failed_api_request_help: "Try again.",
118
122
 
@@ -131,8 +135,8 @@ module Script
131
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=",
132
136
 
133
137
  web_assembly_binary_not_found: "Wasm binary not found.",
134
- web_assembly_binary_not_found_suggestion: "Check that there is a valid Wasm binary in the root directory" \
135
- "Your Wasm binary should match the script name: <script_name>.wasm",
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'.",
136
140
 
137
141
  project_config_not_found: "Internal error - Script can't be created because the project's config file is missing from the repository.",
138
142
 
@@ -150,11 +154,13 @@ module Script
150
154
  language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
151
155
  language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
152
156
  no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
153
- missing_env_file_variables: "The following are missing in the .env file: %s."\
154
- " To add it, run {{command:%s script connect}}",
155
- missing_push_options: "The following are missing: %s. "\
156
- "To add them to a CI environment:\n\t1. Run a connect command {{command:%s script connect}}\n\t2. Navigate to the .env file at the root of your project\n\t"\
157
- "3. Copy the missing values, then pass them through as arguments.",
157
+ missing_push_options_ci: "The following are missing: %s. ",
158
+ missing_push_options_ci_solution: "To add them to a CI environment:\n\t1. Run a connect command " \
159
+ "({{command:%1$s script connect}})\n\t2. Navigate to the .env file at the root of your project\n\t" \
160
+ "3. Copy the missing values and pass them through as arguments in {{command:%1$s script push}}",
161
+ missing_env_file_variables: "The following are missing in the .env file: %s. ",
162
+ missing_env_file_variables_solution: "To add it, connect your script with " \
163
+ "{{command:%1$s script connect}} ",
158
164
  },
159
165
 
160
166
  create: {
@@ -162,9 +168,9 @@ module Script
162
168
  {{command:%1$s script create}}: Creates a script project.
163
169
  Usage: {{command:%1$s script create}}
164
170
  Options:
165
- {{command:--name=NAME}} Script project name.
171
+ {{command:--title=TITLE}} Script project title.
166
172
  {{command:--api=TYPE}} Script API name. Supported values: %2$s.
167
- {{command:--language=LANGUAGE}} Programming language. Supported values: %3$s.
173
+ {{command:--language=LANGUAGE}} Programming language. Defaults to wasm. Supported values: %3$s.
168
174
  HELP
169
175
 
170
176
  error: {
@@ -191,9 +197,7 @@ module Script
191
197
  HELP
192
198
 
193
199
  error: {
194
- operation_failed_no_uuid: "UUID is required to push in a CI environment.",
195
- operation_failed_with_api_key: "Couldn't push script to app (API key: %{api_key}).",
196
- operation_failed_no_api_key: "Couldn't push script to app.",
200
+ operation_failed: "Couldn't push script to app.",
197
201
  },
198
202
 
199
203
  script_pushed: "{{v}} Script pushed to app (API key: %{api_key}).",
@@ -206,8 +210,6 @@ module Script
206
210
  HELP
207
211
  error: {
208
212
  operation_failed: "Couldn't connect script to app.",
209
- missing_env_file_variables: "The following variables are missing in the .env file: %s."\
210
- " To connect the script to an app, enter the value into the .env file or delete the .env file, and then run {{command:%s script connect}}",
211
213
  },
212
214
  },
213
215
  javy: {
@@ -233,8 +235,7 @@ module Script
233
235
  forms: {
234
236
  create: {
235
237
  select_extension_point: "Which Script API do you want to use?",
236
- select_language: "Which language do you want to use?",
237
- script_name: "What do you want to name your script?",
238
+ script_title: "What do you want to title your script?",
238
239
  },
239
240
  },
240
241
 
@@ -59,10 +59,10 @@ module Script
59
59
  Script::Layers::Application::ExtensionPoints.languages(type: e.extension_point_type).join(", ")
60
60
  ),
61
61
  }
62
- when Errors::InvalidScriptNameError
62
+ when Errors::InvalidScriptTitleError
63
63
  {
64
- cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_name_cause"),
65
- help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_name_help"),
64
+ cause_of_error: ShopifyCLI::Context.message("script.error.invalid_script_title_cause"),
65
+ help_suggestion: ShopifyCLI::Context.message("script.error.invalid_script_title_help"),
66
66
  }
67
67
  when Errors::NoExistingAppsError
68
68
  {
@@ -96,7 +96,7 @@ module Script
96
96
  {
97
97
  cause_of_error: ShopifyCLI::Context.message(
98
98
  "script.error.script_not_found_cause",
99
- e.script_name,
99
+ e.title,
100
100
  e.extension_point_type
101
101
  ),
102
102
  }
@@ -237,6 +237,19 @@ module Script
237
237
  ),
238
238
  help_suggestion: ShopifyCLI::Context.message("script.error.graphql_error_help"),
239
239
  }
240
+ when Layers::Infrastructure::Errors::InvalidEnvironmentError
241
+ {
242
+ cause_of_error: ShopifyCLI::Context.message(
243
+ "script.error.invalid_environment_cause",
244
+ tool: e.tool,
245
+ env_version: e.env_version,
246
+ minimum_version: e.minimum_version,
247
+ ),
248
+ help_suggestion: ShopifyCLI::Context.message(
249
+ "script.error.invalid_environment_help",
250
+ tool: e.tool,
251
+ ),
252
+ }
240
253
  when Layers::Infrastructure::Errors::SystemCallFailureError
241
254
  {
242
255
  cause_of_error: ShopifyCLI::Context
@@ -8,12 +8,10 @@ module Script
8
8
  def self.spin(title, auto_debrief: false)
9
9
  exception = nil
10
10
  CLI::UI::Spinner.spin(title, auto_debrief: auto_debrief) do |*args|
11
- begin
12
- yield(*args)
13
- rescue StandardError => e
14
- exception = e
15
- CLI::UI::Spinner::TASK_FAILED
16
- end
11
+ yield(*args)
12
+ rescue StandardError => e
13
+ exception = e
14
+ CLI::UI::Spinner::TASK_FAILED
17
15
  end
18
16
  raise exception if exception
19
17
  end
@@ -14,6 +14,8 @@ module Theme
14
14
  subcommand :Check, "check", Project.project_filepath("commands/check")
15
15
  subcommand :Publish, "publish", Project.project_filepath("commands/publish")
16
16
  subcommand :Package, "package", Project.project_filepath("commands/package")
17
+ subcommand :Open, "open", Project.project_filepath("commands/open")
18
+ subcommand :List, "list", Project.project_filepath("commands/list")
17
19
  subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
18
20
  end
19
21
  ShopifyCLI::Commands.register("Theme::Command", "theme")
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Theme
4
+ class Command
5
+ module Common
6
+ module RootHelper
7
+ def root_value(options, name)
8
+ argv = default_argv(options)
9
+ command_index = argv.index(name.to_s)
10
+
11
+ return "." if command_index.nil?
12
+
13
+ next_index = command_index + 1
14
+ option_by_key = options_map(options)
15
+
16
+ while next_index < argv.size
17
+ element = argv[next_index]
18
+ key, value = key_value_tuple(element)
19
+ option = option_by_key[key]
20
+
21
+ return element if option.nil?
22
+
23
+ # Skip the option argument
24
+ next_index += 1 if !option.arg.nil? && !value
25
+
26
+ # PATTERN arguments take precedence over the `root`
27
+ if option.arg =~ /PATTERN/ && !value
28
+ next_index += 1 while option_argument?(argv, next_index, option_by_key)
29
+ next
30
+ end
31
+
32
+ next_index += 1
33
+ end
34
+
35
+ "."
36
+ end
37
+
38
+ private
39
+
40
+ def default_argv(options)
41
+ options.parser.default_argv.compact
42
+ end
43
+
44
+ def options_map(options)
45
+ map = {}
46
+ options_list(options).each do |option|
47
+ map[option.short.first] = option
48
+ map[option.long.first] = option
49
+ end
50
+ map
51
+ end
52
+
53
+ def options_list(options)
54
+ options.parser.top.list
55
+ end
56
+
57
+ def option_argument?(argv, next_index, option_by_key)
58
+ return false unless next_index < argv.size
59
+
60
+ element = argv[next_index]
61
+ key, _value = key_value_tuple(element)
62
+ option_by_key[key].nil?
63
+ end
64
+
65
+ def key_value_tuple(element)
66
+ element.split("=")
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -9,6 +9,8 @@ module Theme
9
9
  parser.on("-u", "--clone-url URL") { |url| flags[:clone_url] = url }
10
10
  end
11
11
 
12
+ prerequisite_task :ensure_git_dependency
13
+
12
14
  DEFAULT_CLONE_URL = "https://github.com/Shopify/dawn.git"
13
15
 
14
16
  def call(args, _name)
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shopify_cli/theme/theme"
4
+ require "project_types/theme/presenters/themes_presenter"
5
+
6
+ module Theme
7
+ class Command
8
+ class List < ShopifyCLI::Command::SubCommand
9
+ recommend_default_ruby_range
10
+
11
+ def call(_args, _name)
12
+ @ctx.puts(@ctx.message("theme.list.title", shop))
13
+
14
+ themes_presenter.all.each do |theme|
15
+ @ctx.puts(" #{theme}")
16
+ end
17
+ end
18
+
19
+ def self.help
20
+ @ctx.message("theme.list.help", ShopifyCLI::TOOL_NAME, ShopifyCLI::TOOL_NAME)
21
+ end
22
+
23
+ private
24
+
25
+ def themes_presenter
26
+ Theme::Presenters::ThemesPresenter.new(@ctx, nil)
27
+ end
28
+
29
+ def shop
30
+ ShopifyCLI::AdminAPI.get_shop_or_abort(@ctx)
31
+ end
32
+ end
33
+ end
34
+ end