shopify-cli 2.8.0 → 2.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +18 -0
  3. data/CHANGELOG.md +34 -0
  4. data/Gemfile.lock +1 -1
  5. data/RELEASING.md +4 -3
  6. data/ext/javy/javy.rb +1 -1
  7. data/lib/project_types/extension/commands/push.rb +2 -2
  8. data/lib/project_types/extension/messages/messages.rb +1 -1
  9. data/lib/project_types/extension/models/development_server.rb +2 -4
  10. data/lib/project_types/rails/gem.rb +1 -2
  11. data/lib/project_types/script/cli.rb +10 -0
  12. data/lib/project_types/script/commands/connect.rb +1 -1
  13. data/lib/project_types/script/commands/create.rb +8 -2
  14. data/lib/project_types/script/commands/push.rb +35 -12
  15. data/lib/project_types/script/config/extension_points.yml +12 -0
  16. data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
  17. data/lib/project_types/script/graphql/module_upload_url_generate.graphql +5 -1
  18. data/lib/project_types/script/layers/application/build_script.rb +6 -3
  19. data/lib/project_types/script/layers/application/connect_app.rb +11 -5
  20. data/lib/project_types/script/layers/application/extension_points.rb +50 -26
  21. data/lib/project_types/script/layers/application/project_dependencies.rb +1 -1
  22. data/lib/project_types/script/layers/application/push_script.rb +41 -30
  23. data/lib/project_types/script/layers/domain/errors.rb +10 -3
  24. data/lib/project_types/script/layers/domain/extension_point.rb +16 -2
  25. data/lib/project_types/script/layers/domain/push_package.rb +0 -3
  26. data/lib/project_types/script/layers/domain/script_config.rb +6 -4
  27. data/lib/project_types/script/layers/domain/script_project.rb +1 -0
  28. data/lib/project_types/script/layers/infrastructure/errors.rb +47 -23
  29. data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +2 -12
  30. data/lib/project_types/script/layers/infrastructure/languages/project_creator.rb +1 -0
  31. data/lib/project_types/script/layers/infrastructure/languages/task_runner.rb +1 -0
  32. data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +2 -12
  33. data/lib/project_types/script/layers/infrastructure/languages/wasm_project_creator.rb +15 -0
  34. data/lib/project_types/script/layers/infrastructure/languages/wasm_task_runner.rb +36 -0
  35. data/lib/project_types/script/layers/infrastructure/metadata_repository.rb +18 -0
  36. data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +7 -8
  37. data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +45 -54
  38. data/lib/project_types/script/layers/infrastructure/script_service.rb +35 -12
  39. data/lib/project_types/script/layers/infrastructure/script_uploader.rb +22 -9
  40. data/lib/project_types/script/loaders/project.rb +44 -0
  41. data/lib/project_types/script/loaders/specification_handler.rb +22 -0
  42. data/lib/project_types/script/messages/messages.rb +38 -19
  43. data/lib/project_types/script/ui/error_handler.rb +52 -30
  44. data/lib/project_types/theme/commands/pull.rb +45 -17
  45. data/lib/project_types/theme/commands/push.rb +62 -27
  46. data/lib/project_types/theme/commands/serve.rb +5 -0
  47. data/lib/project_types/theme/messages/messages.rb +33 -18
  48. data/lib/shopify_cli/constants.rb +7 -2
  49. data/lib/shopify_cli/context.rb +66 -12
  50. data/lib/shopify_cli/core/executor.rb +4 -4
  51. data/lib/shopify_cli/environment.rb +50 -20
  52. data/lib/shopify_cli/identity_auth.rb +4 -3
  53. data/lib/shopify_cli/messages/messages.rb +2 -0
  54. data/lib/shopify_cli/method_object.rb +21 -9
  55. data/lib/shopify_cli/resources/env_file.rb +5 -1
  56. data/lib/shopify_cli/result.rb +61 -59
  57. data/lib/shopify_cli/task.rb +5 -3
  58. data/lib/shopify_cli/theme/dev_server/hot-reload.js +19 -1
  59. data/lib/shopify_cli/theme/dev_server/hot_reload.rb +18 -2
  60. data/lib/shopify_cli/theme/dev_server/proxy.rb +1 -0
  61. data/lib/shopify_cli/theme/dev_server/reload_mode.rb +34 -0
  62. data/lib/shopify_cli/theme/dev_server.rb +6 -21
  63. data/lib/shopify_cli/theme/file.rb +2 -2
  64. data/lib/shopify_cli/theme/filter/path_matcher.rb +38 -0
  65. data/lib/shopify_cli/theme/ignore_filter.rb +14 -18
  66. data/lib/shopify_cli/theme/include_filter.rb +43 -0
  67. data/lib/shopify_cli/theme/syncer.rb +17 -2
  68. data/lib/shopify_cli/theme/theme.rb +26 -4
  69. data/lib/shopify_cli/version.rb +1 -1
  70. data/lib/shopify_cli.rb +6 -1
  71. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +10 -5
  72. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +6 -4
  73. data/vendor/deps/ruby2_keywords/LICENSE +22 -0
  74. data/vendor/deps/ruby2_keywords/README.md +67 -0
  75. data/vendor/deps/ruby2_keywords/Rakefile +54 -0
  76. data/vendor/deps/ruby2_keywords/lib/ruby2_keywords.rb +57 -0
  77. data/vendor/deps/ruby2_keywords/ruby2_keywords.gemspec +18 -0
  78. data/vendor/deps/ruby2_keywords/test/test_keyword.rb +41 -0
  79. metadata +16 -2
@@ -15,10 +15,11 @@ module Script
15
15
  end
16
16
 
17
17
  class MissingScriptConfigFieldError < ScriptProjectError
18
- attr_reader :field
19
- def initialize(field)
18
+ attr_reader :field, :filename
19
+ def initialize(field:, filename:)
20
20
  super()
21
21
  @field = field
22
+ @filename = filename
22
23
  end
23
24
  end
24
25
 
@@ -31,7 +32,13 @@ module Script
31
32
  end
32
33
  end
33
34
 
34
- class MetadataNotFoundError < ScriptProjectError; end
35
+ class MetadataNotFoundError < ScriptProjectError
36
+ attr_reader :filename
37
+ def initialize(filename)
38
+ super()
39
+ @filename = filename
40
+ end
41
+ end
35
42
 
36
43
  class MetadataValidationError < ScriptProjectError; end
37
44
  end
@@ -18,6 +18,10 @@ module Script
18
18
  @beta
19
19
  end
20
20
 
21
+ def stable?
22
+ !beta?
23
+ end
24
+
21
25
  def deprecated?
22
26
  @deprecated
23
27
  end
@@ -26,14 +30,20 @@ module Script
26
30
  @type.gsub("_", "-")
27
31
  end
28
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
+
29
39
  class ExtensionPointLibraries
30
40
  def initialize(config)
31
41
  @config = config
32
42
  end
33
43
 
34
44
  def all
35
- @all ||= @config.map do |language, libray_config|
36
- ExtensionPointLibrary.new(language, libray_config)
45
+ @all ||= @config.map do |language, library_config|
46
+ ExtensionPointLibrary.new(language, library_config)
37
47
  end
38
48
  end
39
49
 
@@ -57,6 +67,10 @@ module Script
57
67
  @beta
58
68
  end
59
69
 
70
+ def stable?
71
+ !beta?
72
+ end
73
+
60
74
  def versioned?
61
75
  @version
62
76
  end
@@ -9,7 +9,6 @@ module Script
9
9
  :extension_point_type,
10
10
  :script_config,
11
11
  :script_content,
12
- :compiled_type,
13
12
  :metadata,
14
13
  :library
15
14
 
@@ -18,7 +17,6 @@ module Script
18
17
  uuid:,
19
18
  extension_point_type:,
20
19
  script_content:,
21
- compiled_type: nil,
22
20
  metadata:,
23
21
  script_config:,
24
22
  library:
@@ -27,7 +25,6 @@ module Script
27
25
  @uuid = uuid
28
26
  @extension_point_type = extension_point_type
29
27
  @script_content = script_content
30
- @compiled_type = compiled_type
31
28
  @metadata = metadata
32
29
  @script_config = script_config
33
30
  @library = library
@@ -4,13 +4,13 @@ module Script
4
4
  module Layers
5
5
  module Domain
6
6
  class ScriptConfig
7
- attr_reader :content, :version, :title, :description, :configuration_ui, :configuration
7
+ attr_reader :content, :version, :title, :description, :configuration_ui, :configuration, :filename
8
8
 
9
9
  REQUIRED_FIELDS = %w(version title)
10
10
 
11
- def initialize(content:)
11
+ def initialize(content:, filename:)
12
+ @filename = filename
12
13
  validate_content!(content)
13
-
14
14
  @content = content
15
15
  @version = @content["version"].to_s
16
16
  @title = @content["title"]
@@ -23,7 +23,9 @@ module Script
23
23
 
24
24
  def validate_content!(content)
25
25
  REQUIRED_FIELDS.each do |field|
26
- raise Errors::MissingScriptConfigFieldError, field if content[field].nil?
26
+ if content[field].nil?
27
+ raise Errors::MissingScriptConfigFieldError.new(field: field, filename: filename)
28
+ end
27
29
  end
28
30
  end
29
31
  end
@@ -16,6 +16,7 @@ module Script
16
16
  property! :language, accepts: String
17
17
 
18
18
  property :script_config, accepts: ScriptConfig
19
+ property :input_query, accepts: String
19
20
 
20
21
  def initialize(*)
21
22
  super
@@ -5,63 +5,78 @@ module Script
5
5
  module Infrastructure
6
6
  module Errors
7
7
  class BuildError < ScriptProjectError; end
8
- class ScriptConfigSyntaxError < ScriptProjectError; end
8
+
9
+ class ScriptConfigurationDefinitionError < ScriptProjectError
10
+ attr_reader :filename
11
+ def initialize(message:, filename:)
12
+ @filename = filename
13
+ super(message)
14
+ end
15
+ end
16
+
17
+ class ScriptConfigSyntaxError < ScriptProjectError
18
+ attr_reader :filename
19
+ def initialize(filename)
20
+ @filename = filename
21
+ super()
22
+ end
23
+ end
9
24
 
10
25
  class ScriptConfigMissingKeysError < ScriptProjectError
11
- attr_reader :missing_keys
12
- def initialize(missing_keys)
26
+ attr_reader :missing_keys, :filename
27
+ def initialize(missing_keys:, filename:)
13
28
  super()
14
29
  @missing_keys = missing_keys
30
+ @filename = filename
15
31
  end
16
32
  end
17
33
 
18
34
  class ScriptConfigInvalidValueError < ScriptProjectError
19
- attr_reader :valid_input_modes
20
- def initialize(valid_input_modes)
35
+ attr_reader :valid_input_modes, :filename
36
+ def initialize(valid_input_modes:, filename:)
21
37
  super()
22
38
  @valid_input_modes = valid_input_modes
39
+ @filename = filename
23
40
  end
24
41
  end
25
42
 
26
43
  class ScriptConfigFieldsMissingKeysError < ScriptProjectError
27
- attr_reader :missing_keys
28
- def initialize(missing_keys)
44
+ attr_reader :missing_keys, :filename
45
+ def initialize(missing_keys:, filename:)
29
46
  super()
30
47
  @missing_keys = missing_keys
48
+ @filename = filename
31
49
  end
32
50
  end
33
51
 
34
52
  class ScriptConfigFieldsInvalidValueError < ScriptProjectError
35
- attr_reader :valid_types
36
- def initialize(valid_types)
53
+ attr_reader :valid_types, :filename
54
+ def initialize(valid_types:, filename:)
37
55
  super()
38
56
  @valid_types = valid_types
57
+ @filename = filename
39
58
  end
40
59
  end
41
60
 
42
- class InvalidScriptConfigYmlDefinitionError < ScriptProjectError; end
61
+ class ScriptEnvAppNotConnectedError < ScriptProjectError; end
43
62
 
44
- class InvalidScriptJsonDefinitionError < ScriptProjectError; end
45
-
46
- class MissingScriptConfigYmlFieldError < ScriptProjectError
47
- attr_reader :field
48
- def initialize(field)
63
+ class ScriptConfigParseError < ScriptProjectError
64
+ attr_reader :filename, :serialization_format
65
+ def initialize(filename:, serialization_format:)
49
66
  super()
50
- @field = field
67
+ @filename = filename
68
+ @serialization_format = serialization_format
51
69
  end
52
70
  end
53
71
 
54
- class MissingScriptJsonFieldError < ScriptProjectError
55
- attr_reader :field
56
- def initialize(field)
72
+ class NoScriptConfigFileError < ScriptProjectError
73
+ attr_reader :filename
74
+ def initialize(filename)
57
75
  super()
58
- @field = field
76
+ @filename = filename
59
77
  end
60
78
  end
61
79
 
62
- class NoScriptConfigYmlFileError < ScriptProjectError; end
63
- class NoScriptConfigFileError < ScriptProjectError; end
64
-
65
80
  class APILibraryNotFoundError < ScriptProjectError
66
81
  attr_reader :library_name
67
82
  def initialize(library_name)
@@ -144,6 +159,15 @@ module Script
144
159
  class ScriptUploadError < ScriptProjectError; end
145
160
  class ProjectConfigNotFoundError < ScriptProjectError; end
146
161
  class InvalidProjectConfigError < ScriptProjectError; end
162
+
163
+ class ScriptTooLargeError < ScriptProjectError
164
+ attr_reader :max_size
165
+
166
+ def initialize(max_size)
167
+ super()
168
+ @max_size = max_size
169
+ end
170
+ end
147
171
  end
148
172
  end
149
173
  end
@@ -21,10 +21,6 @@ module Script
21
21
  bytecode
22
22
  end
23
23
 
24
- def compiled_type
25
- "wasm"
26
- end
27
-
28
24
  def install_dependencies
29
25
  check_node_version!
30
26
 
@@ -37,14 +33,8 @@ module Script
37
33
  ctx.dir_exist?("node_modules")
38
34
  end
39
35
 
40
- def metadata
41
- unless @ctx.file_exist?(METADATA_FILE)
42
- msg = @ctx.message("script.error.metadata_not_found_cause", METADATA_FILE)
43
- raise Domain::Errors::MetadataNotFoundError, msg
44
- end
45
-
46
- raw_contents = File.read(METADATA_FILE)
47
- Domain::Metadata.create_from_json(@ctx, raw_contents)
36
+ def metadata_file_location
37
+ METADATA_FILE
48
38
  end
49
39
 
50
40
  def library_version(library_name)
@@ -28,6 +28,7 @@ module Script
28
28
  project_creators = {
29
29
  "assemblyscript" => AssemblyScriptProjectCreator,
30
30
  "typescript" => TypeScriptProjectCreator,
31
+ "wasm" => WasmProjectCreator,
31
32
  }
32
33
 
33
34
  raise Errors::ProjectCreatorNotFoundError unless project_creators[language]
@@ -8,6 +8,7 @@ module Script
8
8
  TASK_RUNNERS = {
9
9
  "assemblyscript" => AssemblyScriptTaskRunner,
10
10
  "typescript" => TypeScriptTaskRunner,
11
+ "wasm" => WasmTaskRunner,
11
12
  }
12
13
 
13
14
  def self.for(ctx, language, script_name)
@@ -22,10 +22,6 @@ module Script
22
22
  bytecode
23
23
  end
24
24
 
25
- def compiled_type
26
- "wasm"
27
- end
28
-
29
25
  def install_dependencies
30
26
  check_node_version!
31
27
 
@@ -38,14 +34,8 @@ module Script
38
34
  ctx.dir_exist?("node_modules")
39
35
  end
40
36
 
41
- def metadata
42
- unless @ctx.file_exist?(METADATA_FILE)
43
- msg = @ctx.message("script.error.metadata_not_found_cause", METADATA_FILE)
44
- raise Domain::Errors::MetadataNotFoundError, msg
45
- end
46
-
47
- raw_contents = File.read(METADATA_FILE)
48
- Domain::Metadata.create_from_json(@ctx, raw_contents)
37
+ def metadata_file_location
38
+ METADATA_FILE
49
39
  end
50
40
 
51
41
  def library_version(library_name)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ module Languages
7
+ class WasmProjectCreator < ProjectCreator
8
+ def self.config_file
9
+ "script.config.yml"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Script
4
+ module Layers
5
+ module Infrastructure
6
+ module Languages
7
+ class WasmTaskRunner
8
+ BYTECODE_FILE = "script.wasm"
9
+ attr_reader :ctx, :script_name
10
+
11
+ def initialize(ctx, script_name)
12
+ @ctx = ctx
13
+ @script_name = script_name
14
+ end
15
+
16
+ def dependencies_installed?
17
+ true
18
+ end
19
+
20
+ def library_version(_library_name)
21
+ nil
22
+ end
23
+
24
+ def metadata_file_location
25
+ "metadata.json"
26
+ end
27
+
28
+ def build
29
+ raise Errors::WebAssemblyBinaryNotFoundError unless ctx.file_exist?(BYTECODE_FILE)
30
+ ctx.binread(BYTECODE_FILE)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Script
3
+ module Layers
4
+ module Infrastructure
5
+ class MetadataRepository
6
+ include SmartProperties
7
+ property! :ctx, accepts: ShopifyCLI::Context
8
+
9
+ def get_metadata(file_location)
10
+ raise Domain::Errors::MetadataNotFoundError, file_location unless ctx.file_exist?(file_location)
11
+
12
+ raw_contents = File.read(file_location)
13
+ Domain::Metadata.create_from_json(ctx, raw_contents)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -7,8 +7,8 @@ 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:, library:)
11
- build_file_path = file_path(script_project.id, compiled_type)
10
+ def create_push_package(script_project:, script_content:, metadata:, library:)
11
+ build_file_path = file_path(script_project.id)
12
12
  write_to_path(build_file_path, script_content)
13
13
 
14
14
  Domain::PushPackage.new(
@@ -16,16 +16,15 @@ module Script
16
16
  uuid: script_project.uuid,
17
17
  extension_point_type: script_project.extension_point_type,
18
18
  script_content: script_content,
19
- compiled_type: compiled_type,
20
19
  metadata: metadata,
21
20
  script_config: script_project.script_config,
22
21
  library: library
23
22
  )
24
23
  end
25
24
 
26
- def get_push_package(script_project:, compiled_type:, metadata:, library:)
27
- build_file_path = file_path(script_project.id, compiled_type)
28
- raise Domain::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
25
+ def get_push_package(script_project:, metadata:, library:)
26
+ build_file_path = file_path(script_project.id)
27
+ raise Domain::Errors::PushPackageNotFoundError unless ctx.file_exist?(build_file_path)
29
28
 
30
29
  script_content = ctx.binread(build_file_path)
31
30
  Domain::PushPackage.new(
@@ -46,8 +45,8 @@ module Script
46
45
  ctx.binwrite(path, content)
47
46
  end
48
47
 
49
- def file_path(path_to_script, compiled_type)
50
- "#{path_to_script}/build/script.#{compiled_type}"
48
+ def file_path(path_to_script)
49
+ "#{path_to_script}/build/script.wasm"
51
50
  end
52
51
  end
53
52
  end
@@ -10,6 +10,7 @@ module Script
10
10
  property :initial_directory, accepts: String
11
11
 
12
12
  MUTABLE_ENV_VALUES = %i(uuid)
13
+ INPUT_QUERY_PATH = "input.graphql"
13
14
 
14
15
  def create_project_directory
15
16
  raise Infrastructure::Errors::ScriptProjectAlreadyExistsError, directory if ctx.dir_exist?(directory)
@@ -38,13 +39,7 @@ module Script
38
39
  language: language
39
40
  )
40
41
 
41
- Domain::ScriptProject.new(
42
- id: ctx.root,
43
- env: project.env,
44
- script_name: script_name,
45
- extension_point_type: extension_point_type,
46
- language: language
47
- )
42
+ build_script_project(script_config: nil)
48
43
  end
49
44
 
50
45
  def get
@@ -56,7 +51,8 @@ module Script
56
51
  script_name: script_name,
57
52
  extension_point_type: extension_point_type,
58
53
  language: language,
59
- script_config: script_config_repository.get!
54
+ script_config: script_config_repository.get!,
55
+ input_query: read_input_query,
60
56
  )
61
57
  end
62
58
 
@@ -68,14 +64,7 @@ module Script
68
64
  end
69
65
  end
70
66
 
71
- Domain::ScriptProject.new(
72
- id: ctx.root,
73
- env: project.env,
74
- script_name: script_name,
75
- extension_point_type: extension_point_type,
76
- language: language,
77
- script_config: script_config_repository.get!,
78
- )
67
+ build_script_project
79
68
  end
80
69
 
81
70
  def create_env(api_key:, secret:, uuid:)
@@ -87,19 +76,19 @@ module Script
87
76
  }
88
77
  ).write(ctx)
89
78
 
90
- Domain::ScriptProject.new(
91
- id: ctx.root,
92
- env: project.env,
93
- script_name: script_name,
94
- extension_point_type: extension_point_type,
95
- language: language,
96
- script_config: script_config_repository.get!,
97
- )
79
+ build_script_project
98
80
  end
99
81
 
100
82
  def update_script_config(title:)
101
83
  script_config = script_config_repository.update!(title: title)
84
+ build_script_project(script_config: script_config)
85
+ end
86
+
87
+ private
102
88
 
89
+ def build_script_project(
90
+ script_config: script_config_repository.get!
91
+ )
103
92
  Domain::ScriptProject.new(
104
93
  id: ctx.root,
105
94
  env: project.env,
@@ -110,8 +99,6 @@ module Script
110
99
  )
111
100
  end
112
101
 
113
- private
114
-
115
102
  def change_directory(directory:)
116
103
  ctx.chdir(directory)
117
104
  end
@@ -160,16 +147,23 @@ module Script
160
147
 
161
148
  def script_config_repository
162
149
  @script_config_repository ||= begin
150
+ script_config_yml_repo = ScriptConfigYmlRepository.new(ctx: ctx)
163
151
  supported_repos = [
164
- ScriptConfigYmlRepository.new(ctx: ctx),
152
+ script_config_yml_repo,
165
153
  ScriptJsonRepository.new(ctx: ctx),
166
154
  ]
167
155
  repo = supported_repos.find(&:active?)
168
- raise Infrastructure::Errors::NoScriptConfigYmlFileError if repo.nil?
156
+ if repo.nil?
157
+ raise Infrastructure::Errors::NoScriptConfigFileError, script_config_yml_repo.filename
158
+ end
169
159
  repo
170
160
  end
171
161
  end
172
162
 
163
+ def read_input_query
164
+ ctx.read(INPUT_QUERY_PATH) if ctx.file_exist?(INPUT_QUERY_PATH)
165
+ end
166
+
173
167
  class ScriptConfigRepository
174
168
  include SmartProperties
175
169
  property! :ctx, accepts: ShopifyCLI::Context
@@ -179,7 +173,7 @@ module Script
179
173
  end
180
174
 
181
175
  def get!
182
- raise Infrastructure::Errors::NoScriptConfigFileError unless active?
176
+ raise Infrastructure::Errors::NoScriptConfigFileError, filename unless active?
183
177
 
184
178
  content = ctx.read(filename)
185
179
  hash = file_content_to_hash(content)
@@ -196,6 +190,10 @@ module Script
196
190
  from_h(hash)
197
191
  end
198
192
 
193
+ def filename
194
+ raise NotImplementedError
195
+ end
196
+
199
197
  private
200
198
 
201
199
  def update_hash(hash:, title:)
@@ -204,14 +202,7 @@ module Script
204
202
  end
205
203
 
206
204
  def from_h(hash)
207
- Domain::ScriptConfig.new(content: hash)
208
- rescue Domain::Errors::MissingScriptConfigFieldError => e
209
- raise missing_field_error, e.field
210
- end
211
-
212
- # to be implemented by subclasses
213
- def filename
214
- raise NotImplementedError
205
+ Domain::ScriptConfig.new(content: hash, filename: filename)
215
206
  end
216
207
 
217
208
  def file_content_to_hash(file_content)
@@ -221,26 +212,22 @@ module Script
221
212
  def hash_to_file_content(hash)
222
213
  raise NotImplementedError
223
214
  end
224
-
225
- def missing_field_error
226
- raise NotImplementedError
227
- end
228
215
  end
229
216
 
230
217
  class ScriptConfigYmlRepository < ScriptConfigRepository
231
- private
232
-
233
218
  def filename
234
219
  "script.config.yml"
235
220
  end
236
221
 
222
+ private
223
+
237
224
  def file_content_to_hash(file_content)
238
225
  begin
239
226
  hash = YAML.load(file_content)
240
227
  rescue Psych::SyntaxError
241
- raise Errors::InvalidScriptConfigYmlDefinitionError
228
+ raise parse_error
242
229
  end
243
- raise Errors::InvalidScriptConfigYmlDefinitionError unless hash.is_a?(Hash)
230
+ raise parse_error unless hash.is_a?(Hash)
244
231
  hash
245
232
  end
246
233
 
@@ -248,30 +235,34 @@ module Script
248
235
  YAML.dump(hash)
249
236
  end
250
237
 
251
- def missing_field_error
252
- Errors::MissingScriptConfigYmlFieldError
238
+ def parse_error
239
+ Errors::ScriptConfigParseError.new(filename: filename, serialization_format: "YAML")
253
240
  end
254
241
  end
255
242
 
256
243
  class ScriptJsonRepository < ScriptConfigRepository
257
- private
258
-
259
244
  def filename
260
245
  "script.json"
261
246
  end
262
247
 
248
+ private
249
+
263
250
  def file_content_to_hash(file_content)
264
- JSON.parse(file_content)
265
- rescue JSON::ParserError
266
- raise Errors::InvalidScriptJsonDefinitionError
251
+ begin
252
+ hash = JSON.parse(file_content)
253
+ rescue JSON::ParserError
254
+ raise parse_error
255
+ end
256
+ raise parse_error unless hash.is_a?(Hash)
257
+ hash
267
258
  end
268
259
 
269
260
  def hash_to_file_content(hash)
270
261
  JSON.pretty_generate(hash)
271
262
  end
272
263
 
273
- def missing_field_error
274
- Errors::MissingScriptJsonFieldError
264
+ def parse_error
265
+ Errors::ScriptConfigParseError.new(filename: filename, serialization_format: "JSON")
275
266
  end
276
267
  end
277
268
  end