shopify-cli 2.10.0 → 2.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.yaml +117 -0
  3. data/.github/ISSUE_TEMPLATE/enhancement.yaml +38 -0
  4. data/.github/ISSUE_TEMPLATE/feature.yaml +47 -0
  5. data/.github/ISSUE_TEMPLATE.md +18 -0
  6. data/CHANGELOG.md +35 -3
  7. data/Gemfile.lock +1 -1
  8. data/dev.yml +3 -0
  9. data/lib/project_types/extension/commands/build.rb +3 -0
  10. data/lib/project_types/extension/commands/check.rb +3 -0
  11. data/lib/project_types/extension/commands/create.rb +3 -0
  12. data/lib/project_types/extension/commands/push.rb +16 -0
  13. data/lib/project_types/extension/commands/serve.rb +3 -0
  14. data/lib/project_types/extension/loaders/project.rb +28 -8
  15. data/lib/project_types/extension/messages/messages.rb +10 -2
  16. data/lib/project_types/extension/models/specification_handlers/default.rb +1 -1
  17. data/lib/project_types/extension/tasks/convert_server_config.rb +3 -1
  18. data/lib/project_types/script/cli.rb +5 -0
  19. data/lib/project_types/script/commands/connect.rb +3 -1
  20. data/lib/project_types/script/commands/create.rb +2 -0
  21. data/lib/project_types/script/commands/push.rb +6 -0
  22. data/lib/project_types/script/config/extension_points.yml +12 -0
  23. data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
  24. data/lib/project_types/script/graphql/module_upload_url_generate.graphql +5 -1
  25. data/lib/project_types/script/layers/application/build_script.rb +6 -3
  26. data/lib/project_types/script/layers/application/create_script.rb +1 -1
  27. data/lib/project_types/script/layers/application/project_dependencies.rb +1 -1
  28. data/lib/project_types/script/layers/application/push_script.rb +39 -31
  29. data/lib/project_types/script/layers/domain/errors.rb +7 -1
  30. data/lib/project_types/script/layers/domain/extension_point.rb +2 -2
  31. data/lib/project_types/script/layers/domain/push_package.rb +0 -3
  32. data/lib/project_types/script/layers/domain/script_project.rb +1 -0
  33. data/lib/project_types/script/layers/infrastructure/errors.rb +13 -3
  34. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +3 -20
  35. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +1 -0
  36. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +35 -8
  37. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +3 -20
  38. data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +15 -0
  39. data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +32 -0
  40. data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +18 -0
  41. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +7 -8
  42. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +17 -26
  43. data/lib/project_types/script/layers/infrastructure/script_service.rb +15 -9
  44. data/lib/project_types/script/layers/infrastructure/script_uploader.rb +22 -9
  45. data/lib/project_types/script/loaders/project.rb +2 -1
  46. data/lib/project_types/script/messages/messages.rb +92 -84
  47. data/lib/project_types/script/ui/error_handler.rb +39 -14
  48. data/lib/project_types/theme/commands/check.rb +2 -0
  49. data/lib/project_types/theme/commands/delete.rb +2 -0
  50. data/lib/project_types/theme/commands/init.rb +2 -0
  51. data/lib/project_types/theme/commands/language_server.rb +2 -0
  52. data/lib/project_types/theme/commands/package.rb +2 -0
  53. data/lib/project_types/theme/commands/publish.rb +2 -0
  54. data/lib/project_types/theme/commands/pull.rb +6 -1
  55. data/lib/project_types/theme/commands/push.rb +6 -1
  56. data/lib/project_types/theme/commands/serve.rb +2 -0
  57. data/lib/shopify_cli/command/sub_command.rb +2 -0
  58. data/lib/shopify_cli/command.rb +72 -0
  59. data/lib/shopify_cli/commands/app/create/node.rb +3 -0
  60. data/lib/shopify_cli/commands/app/create/rails.rb +3 -0
  61. data/lib/shopify_cli/commands/app/deploy.rb +2 -0
  62. data/lib/shopify_cli/commands/app/serve.rb +2 -0
  63. data/lib/shopify_cli/constants.rb +13 -1
  64. data/lib/shopify_cli/environment.rb +55 -35
  65. data/lib/shopify_cli/exception_reporter.rb +9 -0
  66. data/lib/shopify_cli/github/issue_url_generator.rb +19 -8
  67. data/lib/shopify_cli/identity_auth/env_auth_token.rb +34 -0
  68. data/lib/shopify_cli/identity_auth.rb +33 -15
  69. data/lib/shopify_cli/messages/messages.rb +2 -1
  70. data/lib/shopify_cli/partners_api.rb +7 -2
  71. data/lib/shopify_cli/services/app/create/rails_service.rb +37 -13
  72. data/lib/shopify_cli/theme/dev_server/cdn_fonts.rb +28 -8
  73. data/lib/shopify_cli/theme/dev_server/hot_reload/remote_file_reloader.rb +63 -0
  74. data/lib/shopify_cli/theme/dev_server/hot_reload.rb +22 -6
  75. data/lib/shopify_cli/theme/dev_server/local_assets.rb +0 -4
  76. data/lib/shopify_cli/theme/dev_server/proxy.rb +4 -5
  77. data/lib/shopify_cli/theme/dev_server.rb +0 -2
  78. data/lib/shopify_cli/theme/file.rb +4 -0
  79. data/lib/shopify_cli/theme/include_filter.rb +39 -17
  80. data/lib/shopify_cli/utilities.rb +7 -0
  81. data/lib/shopify_cli/version.rb +1 -1
  82. data/lib/shopify_cli.rb +1 -0
  83. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +11 -6
  84. data/vendor/deps/cli-kit/lib/cli/kit/util.rb +5 -1
  85. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +6 -4
  86. data/vendor/lib/semantic/version.rb +0 -1
  87. metadata +11 -5
  88. data/lib/project_types/rails/commands/create.rb +0 -210
  89. data/lib/shopify_cli/theme/dev_server/cdn/cdn_helper.rb +0 -49
  90. data/lib/shopify_cli/theme/dev_server/cdn_assets.rb +0 -69
@@ -5,88 +5,91 @@ module Script
5
5
  MESSAGES = {
6
6
  script: {
7
7
  help: <<~HELP,
8
- Suite of commands for developing script applications. See {{command:%1$s script <command> --help}} for usage of each command.
8
+ Suite of commands for developing script applications. Run {{command:%1$s script <command> --help}} for usage of each command.
9
9
  Usage: {{command:%1$s script [ %2$s ]}}
10
10
  HELP
11
11
 
12
12
  error: {
13
- deprecated_ep: "This project uses a Script API (%s) that has been deprecated. "\
14
- "This Script won't work in production.",
15
- deprecated_ep_cause: "Try using a different Script API.",
13
+ deprecated_ep: "This script won't run in a store because "\
14
+ "it uses a deprecated Script API (%s).",
15
+ deprecated_ep_cause: "Recreate this script using a supported Script API.",
16
16
  generic: "{{red:{{x}} Error}}",
17
17
  eacces_cause: "You don't have permission to write to this directory.",
18
- eacces_help: "Try again and choose a different directory.",
18
+ eacces_help: "Get permission for this directory or choose a different one.",
19
19
 
20
20
  enospc_cause: "You don't have enough disk space to do this action.",
21
- enospc_help: "Free up some space and try again.",
21
+ enospc_help: "Free up more space.",
22
22
 
23
23
  oauth_cause: "Something went wrong while authenticating your account with the Partner Dashboard.",
24
- oauth_help: "Try again.",
24
+ oauth_help: "Wait a few minutes and try again.",
25
25
 
26
- invalid_context_cause: "Your .shopify-cli.yml file is not correct. Values are missing for "\
26
+ invalid_context_cause: "Your .shopify-cli.yml is formatted incorrectly. It's missing values for "\
27
27
  "extension_point_type or script_name.",
28
- invalid_context_help: "Add these values and try again.",
28
+ invalid_context_help: "Add these values.",
29
29
 
30
- invalid_script_name_cause: "Invalid script name.",
31
- invalid_script_name_help: "Replace or remove unsupported characters. Valid characters "\
32
- "are numbers, letters, hyphens, or underscores.",
30
+ invalid_script_name_cause: "Script name contains unsupported characters.",
31
+ invalid_script_name_help: "Use only numbers, letters, hyphens, or underscores.",
33
32
 
34
- no_existing_apps_cause: "You don't have any apps in your Partner Dashboard.",
35
- no_existing_apps_help: "Create an app with {{command:shopify [node|rails] create}}" \
36
- " or visit https://partners.shopify.com/.",
33
+ no_existing_apps_cause: "Your script can't be pushed to an app because your Partner account "\
34
+ "doesn't have any apps.",
35
+ no_existing_apps_help: "Create an app.",
37
36
 
38
- no_existing_orgs_cause: "You don't have any partner organizations.",
39
- no_existing_orgs_help: "Visit https://partners.shopify.com/ to create a partners account.",
37
+ no_existing_orgs_cause: "Your account doesn't belong to a Partner Organization.",
38
+ no_existing_orgs_help: "Visit https://partners.shopify.com/ to create an account.",
40
39
 
41
40
  project_exists_cause: "A directory with this same name already exists.",
42
- project_exists_help: "Try again and enter a different name for the script.",
41
+ project_exists_help: "Choose a different name for your script.",
43
42
 
44
- invalid_extension_cause: "Invalid Script API %s.",
45
- invalid_extension_help: "Allowed values: %s.",
43
+ invalid_extension_cause: "The name of the Script API is incorrect: %s.",
44
+ invalid_extension_help: "Choose a supported API: %s.",
46
45
 
47
- invalid_language_cause: "Invalid language %s.",
48
- invalid_language_help: "Allowed values: %s.",
46
+ invalid_language_cause: "The language is not supported: %s.",
47
+ invalid_language_help: "Choose a supported language: %s.",
49
48
 
50
49
  missing_script_config_field_cause: "The %{filename} file is missing the required %{field} field.",
51
- missing_script_config_field_help: "Add the field and try again.",
50
+ missing_script_config_field_help: "Add the field.",
52
51
 
53
- script_config_parse_error_cause: "The %{filename} file contains invalid %{serialization_format}.",
54
- script_config_parse_error_help: "Fix the errors and try again.",
52
+ script_config_parse_error_cause: "The %{filename} file contains incorrect %{serialization_format}.",
53
+ script_config_parse_error_help: "Correct the errors.",
55
54
 
56
55
  no_script_config_file_cause: "The %{filename} file is missing.",
57
- no_script_config_file_help: "Create this file and try again.",
56
+ no_script_config_file_help: "Create this file.",
58
57
 
59
- app_not_connected_cause: "Script is not connected to an app.",
60
- app_not_connected_help: "Run shopify connect or enter fields for api-key and api-secret.",
58
+ app_not_connected_cause: "The script is not connected to an app.",
59
+ app_not_connected_help: "Run {{command:%{tool_name} script connect}}.",
61
60
 
62
- configuration_definition_error_cause: "In the %{filename} file, there was a problem with the "\
61
+ configuration_definition_error_cause: "In %{filename} there is a problem with the "\
63
62
  "configuration. %{message}",
64
- configuration_definition_error_help: "Fix the error and try again.",
63
+ configuration_definition_error_help: "Fix the error.",
65
64
 
66
- configuration_syntax_error_cause: "The %{filename} is not formatted properly.",
67
- configuration_syntax_error_help: "Fix the errors and try again.",
65
+ configuration_definition_errors_cause: "In %{filename}, there are %{error_count} problems with "\
66
+ "the configuration:\n%{concatenated_messages}\n",
67
+ configuration_definition_errors_help: "Correct the errors.",
68
68
 
69
- configuration_missing_keys_error_cause: "The %{filename} file is missing required keys: "\
69
+ configuration_syntax_error_cause: "The %{filename} is not formatted correctly.",
70
+ configuration_syntax_error_help: "Fix the errors.",
71
+
72
+ configuration_missing_keys_error_cause: "The %{filename} is missing required keys: "\
70
73
  "%{missing_keys}.",
71
- configuration_missing_keys_error_help: "Add the keys and try again.",
74
+ configuration_missing_keys_error_help: "Add the keys.",
72
75
 
73
- configuration_invalid_value_error_cause: "The %{filename} configuration only accepts "\
76
+ configuration_invalid_value_error_cause: "The %{filename} configuration accepts "\
74
77
  "one of the following types(s): %{valid_input_modes}.",
75
- configuration_invalid_value_error_help: "Change the type and try again.",
78
+ configuration_invalid_value_error_help: "Change the value of the type.",
76
79
 
77
80
  configuration_schema_field_missing_keys_error_cause: "A configuration entry in the %{filename} file "\
78
81
  "is missing required keys: %{missing_keys}.",
79
- configuration_definition_schema_field_missing_keys_error_help: "Add the keys and try again.",
82
+ configuration_definition_schema_field_missing_keys_error_help: "Add the keys.",
80
83
 
81
84
  configuration_schema_field_invalid_value_error_cause: "The configuration entries in the "\
82
- "%{filename} file only accept one of the following "\
85
+ "%{filename} file accept one of the following "\
83
86
  "type(s): %{valid_types}.",
84
- configuration_schema_field_invalid_value_error_help: "Change the types and try again.",
87
+ configuration_schema_field_invalid_value_error_help: "Change the value of the type.",
85
88
 
86
- script_not_found_cause: "Couldn't find a script %s for the Script API %s",
89
+ script_not_found_cause: "Can't find script %s for Script API %s",
87
90
 
88
- system_call_failure_cause: "An error was returned while running {{command:%{cmd}}}.",
89
- system_call_failure_help: "Review the following error and try again.\n{{red:%{out}}}",
91
+ system_call_failure_cause: "Something went wrong while running: {{command:%{cmd}}}.",
92
+ system_call_failure_help: "Correct the error.\n{{red:%{out}}}",
90
93
 
91
94
  metadata_validation_cause: "The Script API metadata is incorrect.",
92
95
  metadata_validation_help: "The 'schemaVersions.major' field contains an unsupported version.",
@@ -100,57 +103,58 @@ module Script
100
103
  metadata_schema_versions_missing_minor: "Invalid Script API metadata:" \
101
104
  " 'schemaVersions' is missing the 'minor' field",
102
105
 
103
- metadata_not_found_cause: "Script version file (%s) cannot be found.",
104
- metadata_not_found_help: "Ensure the 'shopify/scripts-toolchain-as' package is up to date and " \
105
- "'package.json' contains a 'scripts/build' entry with a " \
106
- "'--metadata build/metadata.json' argument",
106
+ metadata_not_found_cause: "Can't find the script version file (%{filename}).",
107
+ metadata_not_found_help: "Make sure your project is up-to-date and a script metadata file " \
108
+ "is accessible at %{filename}.",
107
109
 
108
110
  build_error_cause: "Something went wrong while building the script.",
109
- build_error_help: "Correct the errors and try again.",
111
+ build_error_help: "Correct the errors.",
110
112
 
111
113
  dependency_install_cause: "Something went wrong while installing the needed dependencies.",
112
- dependency_install_help: "Correct the errors and try again.",
114
+ dependency_install_help: "Correct the errors.",
113
115
 
114
116
  failed_api_request_cause: "Something went wrong while communicating with Shopify.",
115
117
  failed_api_request_help: "Try again.",
116
118
 
117
- forbidden_error_cause: "You do not have permission to do this action.",
119
+ forbidden_error_cause: "You don't have permission to do this action.",
118
120
 
119
121
  graphql_error_cause: "An error was returned: %s.",
120
- graphql_error_help: "\nReview the error and try again.",
122
+ graphql_error_help: "\nCorrect the error.",
121
123
 
122
- script_repush_cause: "A version of this script already exists on the app.",
124
+ script_repush_cause: "Can’t push the script because a version of this script already exists on the app.",
123
125
  script_repush_help: "Use {{cyan:--force}} to replace the existing script.",
124
126
 
125
127
  build_script_not_found: "The root package.json is missing the build command that " \
126
- "is needed to compile your script to WebAssembly.",
128
+ "is needed to compile your script to Wasm.",
127
129
  # rubocop:disable Layout/LineLength
128
130
  build_script_suggestion: "\n\nFor example, your package.json needs the following command:" \
129
131
  "\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=",
130
132
 
131
- web_assembly_binary_not_found: "WebAssembly binary not found.",
132
- web_assembly_binary_not_found_suggestion: "No WebAssembly binary found." \
133
- "Check that your build npm script outputs the generated binary to the root of the directory." \
134
- "Generated binary should match the script name: <script_name>.wasm",
133
+ 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",
135
136
 
136
137
  project_config_not_found: "Internal error - Script can't be created because the project's config file is missing from the repository.",
137
138
 
138
139
  invalid_project_config: "Internal error - Script can't be created because the project's config file is invalid in the repository.",
139
140
 
140
- script_upload_cause: "Fail to upload script.",
141
+ script_upload_cause: "Something went wrong and your script couldn't be pushed.",
141
142
  script_upload_help: "Try again.",
142
143
 
144
+ script_too_large_cause: "The size of your Wasm binary file is too large.",
145
+ script_too_large_help: "It must be less than %{max_size}.",
146
+
143
147
  api_library_not_found_cause: "Script can't be created because API library %{library_name} is missing from the dependencies",
144
- 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.",
148
+ api_library_not_found_help: "This can occur because the API library was removed from your system or there is a problem with dependencies in the repository.",
145
149
 
146
150
  language_library_for_api_not_found_cause: "Script can’t be pushed because the %{language} library for API %{api} is missing.",
147
151
  language_library_for_api_not_found_help: "Make sure extension_point.yml contains the correct API library.",
148
152
  no_scripts_found_in_app: "The selected apps have no scripts. Please, create them first on the partners' dashboard.",
149
- missing_env_file_variables: "The following variables are missing in the .env file: %s."\
150
- " It might happen when the script hasn't been previously connected to an app."\
151
- " To connect the script to an app, run {{command:%s script connect}}",
152
- missing_push_options: "The following options are required: %s."\
153
- " You can obtain them from the .env file generated after connecting the script to an app.",
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.",
154
158
  },
155
159
 
156
160
  create: {
@@ -158,26 +162,29 @@ module Script
158
162
  {{command:%1$s script create}}: Creates a script project.
159
163
  Usage: {{command:%1$s script create}}
160
164
  Options:
161
- {{command:--name=NAME}} Script project name. Use any string.
162
- {{command:--api=TYPE}} Script API name. Allowed values: %2$s.
163
- {{command:--language=LANGUAGE}} Programming language. Allowed values: %3$s.
165
+ {{command:--name=NAME}} Script project name.
166
+ {{command:--api=TYPE}} Script API name. Supported values: %2$s.
167
+ {{command:--language=LANGUAGE}} Programming language. Supported values: %3$s.
164
168
  HELP
165
169
 
166
170
  error: {
167
- operation_failed: "Script not created.",
171
+ operation_failed: "Something went wrong and the script wasn't created.",
168
172
  },
169
173
 
170
- change_directory_notice: "{{*}} Change directories to {{green:%s}} to run script commands",
171
- creating: "Creating script",
172
- created: "Created script",
174
+ change_directory_notice: "{{*}} Change directories to {{green:%s}} to run script commands.",
175
+ creating: "Creating script.",
176
+ created: "Created script.",
177
+ preparing_project: "Preparing script project structure.",
178
+ creating_wasm: "Creating configuration files.",
179
+ created_wasm: "Configuration files created.",
173
180
  },
174
181
 
175
182
  push: {
176
183
  help: <<~HELP,
177
- Build the script, upload it to Shopify, and register it to an app. If you've already pushed the script to this app, then use --force to replace the existing version on the app.
184
+ Build the script, upload it to Shopify, and register it to an app.
178
185
  Usage: {{command:%s script push}}
179
186
  Options:
180
- {{command:[--force]}} Replaces the existing script on the app with this version.
187
+ {{command:[--force]}} Replace the existing script with this version.
181
188
  {{command:[--api-key=API_KEY]}} The API key used to register an app with the script. This can be found on the app page on Partners Dashboard. Overrides the value in the .env file, if present.
182
189
  {{command:[--api-secret=API_SECRET]}} The API secret of the app the script is registered with. Overrides the value in the .env file, if present.
183
190
  {{command:[--uuid=UUID]}} The uuid of the script. Overrides the value in the .env file, if present.
@@ -200,34 +207,34 @@ module Script
200
207
  error: {
201
208
  operation_failed: "Couldn't connect script to app.",
202
209
  missing_env_file_variables: "The following variables are missing in the .env file: %s."\
203
- " To connect the script to an app, either enter the value into the .env file or delete the .env file, then run {{command:%s script connect}}",
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}}",
204
211
  },
205
212
  },
206
213
  javy: {
207
214
  help: <<~HELP,
208
- Compile the JavaScript code into WebAssembly.
215
+ Compile the JavaScript code into Wasm.
209
216
  Usage: {{command:%s script javy}}
210
217
  Options:
211
218
  {{command:--in}} The name of the JavaScript file that will be compiled.
212
- {{command:--out}} The name of the file that the WebAssembly should be written to.
219
+ {{command:--out}} The name of the file that the Wasm should be written to.
213
220
  HELP
214
221
  errors: {
215
- invalid_arguments: "Javy was run with invalid arguments. Run {{command: %s script javy --help}} for more information.",
222
+ invalid_arguments: "Javy was run with invalid arguments. Run {{command: %s script javy --help}}.",
216
223
  },
217
224
  },
218
225
 
219
226
  project_deps: {
220
- none_required: "{{v}} None required",
221
- checking_with_npm: "Checking dependencies with npm",
222
- installing: "Dependencies installing",
223
- installed: "Missing dependencies installed",
227
+ none_required: "{{v}} Dependencies are up to date.",
228
+ checking: "Checking dependencies.",
229
+ installing: "Installing dependencies.",
230
+ installed: "Installed missing dependencies.",
224
231
  },
225
232
 
226
233
  forms: {
227
234
  create: {
228
235
  select_extension_point: "Which Script API do you want to use?",
229
236
  select_language: "Which language do you want to use?",
230
- script_name: "Script name",
237
+ script_name: "What do you want to name your script?",
231
238
  },
232
239
  },
233
240
 
@@ -236,14 +243,15 @@ module Script
236
243
  building_script: "Building script",
237
244
  built: "Built",
238
245
  pushing: "Pushing",
246
+ pushing_script: "Pushing script",
239
247
  pushed: "Pushed",
240
248
  ensure_env: {
241
249
  organization: "Partner organization {{green:%s (%s)}}.",
242
250
  organization_select: "Which partner organization do you want to use?",
243
- app: "Script will be pushed to app {{green:%s}}.",
251
+ app: "Push script to app {{green:%s}}.",
244
252
  app_select: "Which app do you want to push this script to?",
245
- ask_connect_to_existing_script: "The selected app has some scripts. Do you want to replace any of the "\
246
- "existing scripts on the app with this script?",
253
+ ask_connect_to_existing_script: "This app contains scripts. Do you want to replace an "\
254
+ "existing script on the app with this script?",
247
255
  ask_which_script_to_connect_to: "Which script do you want to replace?",
248
256
  },
249
257
  },
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cli/ui"
2
4
 
3
5
  module Script
@@ -5,9 +7,9 @@ module Script
5
7
  module ErrorHandler
6
8
  def self.display(failed_op:, cause_of_error:, help_suggestion:)
7
9
  $stderr.puts(CLI::UI.fmt(ShopifyCLI::Context.message("script.error.generic")))
8
- full_msg = failed_op ? failed_op.dup : ""
9
- full_msg << " #{cause_of_error}" if cause_of_error
10
- full_msg << " #{help_suggestion}" if help_suggestion
10
+ full_msg = failed_op ? failed_op.dup : String.new
11
+ append_msg(full_msg, cause_of_error) if cause_of_error
12
+ append_msg(full_msg, help_suggestion) if help_suggestion
11
13
  $stderr.puts(CLI::UI.fmt(full_msg.strip))
12
14
  end
13
15
 
@@ -22,6 +24,11 @@ module Script
22
24
  display_and_raise(failed_op: failed_op, **messages)
23
25
  end
24
26
 
27
+ private_class_method def self.append_msg(full_msg, msg_to_append)
28
+ full_msg << " " unless /\s$/.match?(full_msg)
29
+ full_msg << msg_to_append
30
+ end
31
+
25
32
  def self.error_messages(e)
26
33
  case e
27
34
  when Errno::EACCES
@@ -100,8 +107,8 @@ module Script
100
107
  }
101
108
  when Layers::Domain::Errors::MetadataNotFoundError
102
109
  {
103
- cause_of_error: ShopifyCLI::Context.message("script.error.metadata_not_found_cause"),
104
- help_suggestion: ShopifyCLI::Context.message("script.error.metadata_not_found_help"),
110
+ cause_of_error: ShopifyCLI::Context.message("script.error.metadata_not_found_cause", filename: e.filename),
111
+ help_suggestion: ShopifyCLI::Context.message("script.error.metadata_not_found_help", filename: e.filename),
105
112
  }
106
113
  when Layers::Domain::Errors::MissingScriptConfigFieldError
107
114
  {
@@ -135,14 +142,26 @@ module Script
135
142
  help_suggestion: ShopifyCLI::Context.message("script.error.no_script_config_file_help"),
136
143
  }
137
144
  when Layers::Infrastructure::Errors::ScriptConfigurationDefinitionError
138
- {
139
- cause_of_error: ShopifyCLI::Context.message(
140
- "script.error.configuration_definition_error_cause",
141
- message: e.message,
142
- filename: e.filename,
143
- ),
144
- help_suggestion: ShopifyCLI::Context.message("script.error.configuration_definition_error_help"),
145
- }
145
+ if e.messages.count == 1
146
+ {
147
+ cause_of_error: ShopifyCLI::Context.message(
148
+ "script.error.configuration_definition_error_cause",
149
+ message: e.messages.fetch(0),
150
+ filename: e.filename,
151
+ ),
152
+ help_suggestion: ShopifyCLI::Context.message("script.error.configuration_definition_error_help"),
153
+ }
154
+ else
155
+ {
156
+ cause_of_error: ShopifyCLI::Context.message(
157
+ "script.error.configuration_definition_errors_cause",
158
+ concatenated_messages: e.messages.map { |m| "{{x}} #{m}" }.join("\n"),
159
+ filename: e.filename,
160
+ error_count: e.messages.count,
161
+ ),
162
+ help_suggestion: ShopifyCLI::Context.message("script.error.configuration_definition_errors_help"),
163
+ }
164
+ end
146
165
  when Layers::Infrastructure::Errors::ScriptConfigSyntaxError
147
166
  {
148
167
  cause_of_error: ShopifyCLI::Context.message(
@@ -154,7 +173,8 @@ module Script
154
173
  when Layers::Infrastructure::Errors::ScriptEnvAppNotConnectedError
155
174
  {
156
175
  cause_of_error: ShopifyCLI::Context.message("script.error.app_not_connected_cause"),
157
- help_suggestion: ShopifyCLI::Context.message("script.error.app_not_connected_help"),
176
+ help_suggestion: ShopifyCLI::Context.message("script.error.app_not_connected_help",
177
+ tool_name: ShopifyCLI::TOOL_NAME),
158
178
  }
159
179
  when Layers::Infrastructure::Errors::ScriptConfigMissingKeysError
160
180
  {
@@ -251,6 +271,11 @@ module Script
251
271
  cause_of_error: ShopifyCLI::Context.message("script.error.script_upload_cause"),
252
272
  help_suggestion: ShopifyCLI::Context.message("script.error.script_upload_help"),
253
273
  }
274
+ when Layers::Infrastructure::Errors::ScriptTooLargeError
275
+ {
276
+ cause_of_error: ShopifyCLI::Context.message("script.error.script_too_large_cause"),
277
+ help_suggestion: ShopifyCLI::Context.message("script.error.script_too_large_help", max_size: e.max_size),
278
+ }
254
279
  when Layers::Infrastructure::Errors::APILibraryNotFoundError
255
280
  {
256
281
  cause_of_error: ShopifyCLI::Context
@@ -4,6 +4,8 @@ require "theme_check"
4
4
  module Theme
5
5
  class Command
6
6
  class Check < ShopifyCLI::Command::SubCommand
7
+ recommend_default_ruby_range
8
+
7
9
  class Options < ShopifyCLI::Options
8
10
  def initialize(theme_check)
9
11
  super()
@@ -5,6 +5,8 @@ require "shopify_cli/theme/development_theme"
5
5
  module Theme
6
6
  class Command
7
7
  class Delete < ShopifyCLI::Command::SubCommand
8
+ recommend_default_ruby_range
9
+
8
10
  options do |parser, flags|
9
11
  parser.on("-d", "--development") { flags[:development] = true }
10
12
  parser.on("-a", "--show-all") { flags[:show_all] = true }
@@ -3,6 +3,8 @@
3
3
  module Theme
4
4
  class Command
5
5
  class Init < ShopifyCLI::Command::SubCommand
6
+ recommend_default_ruby_range
7
+
6
8
  options do |parser, flags|
7
9
  parser.on("-u", "--clone-url URL") { |url| flags[:clone_url] = url }
8
10
  end
@@ -4,6 +4,8 @@ require "theme_check"
4
4
  module Theme
5
5
  class Command
6
6
  class LanguageServer < ShopifyCLI::Command::SubCommand
7
+ recommend_default_ruby_range
8
+
7
9
  def call(*)
8
10
  ThemeCheck::LanguageServer.start
9
11
  end
@@ -5,6 +5,8 @@ require "json"
5
5
  module Theme
6
6
  class Command
7
7
  class Package < ShopifyCLI::Command::SubCommand
8
+ recommend_default_ruby_range
9
+
8
10
  THEME_DIRECTORIES = %w[
9
11
  assets
10
12
  config
@@ -4,6 +4,8 @@ require "shopify_cli/theme/theme"
4
4
  module Theme
5
5
  class Command
6
6
  class Publish < ShopifyCLI::Command::SubCommand
7
+ recommend_default_ruby_range
8
+
7
9
  options do |parser, flags|
8
10
  parser.on("-f", "--force") { flags[:force] = true }
9
11
  end
@@ -7,13 +7,18 @@ require "shopify_cli/theme/syncer"
7
7
  module Theme
8
8
  class Command
9
9
  class Pull < ShopifyCLI::Command::SubCommand
10
+ recommend_default_ruby_range
11
+
10
12
  options do |parser, flags|
11
13
  parser.on("-n", "--nodelete") { flags[:nodelete] = true }
12
14
  parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
13
15
  parser.on("-t", "--theme=NAME_OR_ID") { |theme| flags[:theme] = theme }
14
16
  parser.on("-l", "--live") { flags[:live] = true }
15
17
  parser.on("-d", "--development") { flags[:development] = true }
16
- parser.on("-o", "--only=PATTERN") { |pattern| flags[:includes] = pattern }
18
+ parser.on("-o", "--only=PATTERN") do |pattern|
19
+ flags[:includes] ||= []
20
+ flags[:includes] << pattern
21
+ end
17
22
  parser.on("-x", "--ignore=PATTERN") do |pattern|
18
23
  flags[:ignores] ||= []
19
24
  flags[:ignores] << pattern
@@ -8,6 +8,8 @@ require "shopify_cli/theme/syncer"
8
8
  module Theme
9
9
  class Command
10
10
  class Push < ShopifyCLI::Command::SubCommand
11
+ recommend_default_ruby_range
12
+
11
13
  options do |parser, flags|
12
14
  parser.on("-n", "--nodelete") { flags[:nodelete] = true }
13
15
  parser.on("-i", "--themeid=ID") { |theme_id| flags[:theme_id] = theme_id }
@@ -18,7 +20,10 @@ module Theme
18
20
  parser.on("-j", "--json") { flags[:json] = true }
19
21
  parser.on("-a", "--allow-live") { flags[:allow_live] = true }
20
22
  parser.on("-p", "--publish") { flags[:publish] = true }
21
- parser.on("-o", "--only=PATTERN") { |pattern| flags[:includes] = pattern }
23
+ parser.on("-o", "--only=PATTERN") do |pattern|
24
+ flags[:includes] ||= []
25
+ flags[:includes] << pattern
26
+ end
22
27
  parser.on("-x", "--ignore=PATTERN") do |pattern|
23
28
  flags[:ignores] ||= []
24
29
  flags[:ignores] << pattern
@@ -4,6 +4,8 @@ require "shopify_cli/theme/dev_server"
4
4
  module Theme
5
5
  class Command
6
6
  class Serve < ShopifyCLI::Command::SubCommand
7
+ recommend_default_ruby_range
8
+
7
9
  DEFAULT_HTTP_HOST = "127.0.0.1"
8
10
 
9
11
  options do |parser, flags|
@@ -9,6 +9,8 @@ module ShopifyCLI
9
9
  cmd = new(@ctx)
10
10
  args = cmd.options.parse(@_options, args || [])
11
11
  return call_help(parent_command, command_name) if cmd.options.help
12
+ check_ruby_version
13
+ check_node_version
12
14
  run_prerequisites
13
15
 
14
16
  cmd.call(args, command_name)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require "shopify_cli"
3
+ require "semantic/semantic"
3
4
 
4
5
  module ShopifyCLI
5
6
  class Command < CLI::Kit::BaseCommand
@@ -7,6 +8,8 @@ module ShopifyCLI
7
8
  autoload :AppSubCommand, "shopify_cli/command/app_sub_command"
8
9
  autoload :ProjectCommand, "shopify_cli/command/project_command"
9
10
 
11
+ VersionRange = Struct.new(:from, :to, keyword_init: true)
12
+
10
13
  extend Feature::Set
11
14
 
12
15
  attr_writer :ctx
@@ -26,6 +29,8 @@ module ShopifyCLI
26
29
  cmd = new(@ctx)
27
30
  cmd.options.parse(@_options, args)
28
31
  return call_help(command_name) if cmd.options.help
32
+ check_ruby_version
33
+ check_node_version
29
34
  run_prerequisites
30
35
  cmd.call(args, command_name)
31
36
  end
@@ -58,6 +63,73 @@ module ShopifyCLI
58
63
  )
59
64
  end
60
65
 
66
+ def recommend_ruby(from:, to:)
67
+ @compatible_ruby_range = VersionRange.new(
68
+ from: Semantic::Version.new(from),
69
+ to: Semantic::Version.new(to)
70
+ )
71
+ end
72
+
73
+ def recommend_default_ruby_range
74
+ recommend_ruby(
75
+ from: Constants::SupportedVersions::Ruby::FROM,
76
+ to: Constants::SupportedVersions::Ruby::TO
77
+ )
78
+ end
79
+
80
+ def check_ruby_version
81
+ check_version(
82
+ Environment.ruby_version,
83
+ range: @compatible_ruby_range,
84
+ runtime: "Ruby"
85
+ )
86
+ end
87
+
88
+ def recommend_node(from:, to:)
89
+ @compatible_node_range = VersionRange.new(
90
+ from: Semantic::Version.new(from),
91
+ to: Semantic::Version.new(to)
92
+ )
93
+ end
94
+
95
+ def recommend_default_node_range
96
+ recommend_node(
97
+ from: Constants::SupportedVersions::Node::FROM,
98
+ to: Constants::SupportedVersions::Node::TO
99
+ )
100
+ end
101
+
102
+ def check_node_version
103
+ context = Context.new
104
+ if @compatible_node_range && context.which("node").nil?
105
+ raise ShopifyCLI::Abort, context.message("core.errors.missing_node")
106
+ end
107
+
108
+ check_version(
109
+ Environment.node_version,
110
+ range: @compatible_node_range,
111
+ runtime: "Node",
112
+ context: context
113
+ )
114
+ end
115
+
116
+ def check_version(version, range:, runtime:, context: Context.new)
117
+ return if Environment.test?
118
+ return if range.nil?
119
+
120
+ version_without_pre_nor_build = Utilities.version_dropping_pre_and_build(version)
121
+ is_higher_than_bottom = version_without_pre_nor_build >= Utilities.version_dropping_pre_and_build(range.from)
122
+ is_lower_than_top = version_without_pre_nor_build < Utilities.version_dropping_pre_and_build(range.to)
123
+ return if is_higher_than_bottom && is_lower_than_top
124
+
125
+ context.warn("Your environment #{runtime} version, #{version},"\
126
+ " is outside of the range supported by the CLI,"\
127
+ " #{range.from}..<#{range.to},"\
128
+ " and might cause incompatibility issues.")
129
+ rescue StandardError => error
130
+ ExceptionReporter.report_error_silently(error)
131
+ end
132
+
61
133
  def prerequisite_task(*tasks_without_args, **tasks_with_args)
62
134
  @prerequisite_tasks ||= []
63
135
  @prerequisite_tasks += tasks_without_args.map { |t| PrerequisiteTask.new(t) }