foobara 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +5 -0
  3. data/.rubocop.yml +20 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +10 -0
  6. data/DECISION_LOG.md +220 -0
  7. data/Guardfile +9 -0
  8. data/LICENSE-AGPL.txt +666 -0
  9. data/LICENSE.txt +4 -0
  10. data/README.md +50 -0
  11. data/Rakefile +10 -0
  12. data/concepts.md +153 -0
  13. data/projects/builtin_types/lib/foobara/builtin_types.rb +67 -0
  14. data/projects/builtin_types/src/README.md +140 -0
  15. data/projects/builtin_types/src/array/casters/arrayable.rb +22 -0
  16. data/projects/builtin_types/src/array/supported_processors/element_type_declaration.rb +41 -0
  17. data/projects/builtin_types/src/array/supported_validators/size.rb +43 -0
  18. data/projects/builtin_types/src/associative_array/casters/array.rb +22 -0
  19. data/projects/builtin_types/src/associative_array/supported_processors/key_type_declaration.rb +44 -0
  20. data/projects/builtin_types/src/associative_array/supported_processors/value_type_declaration.rb +44 -0
  21. data/projects/builtin_types/src/atomic_duck.rb +6 -0
  22. data/projects/builtin_types/src/attributes/casters/array.rb +33 -0
  23. data/projects/builtin_types/src/attributes/casters/hash.rb +28 -0
  24. data/projects/builtin_types/src/attributes/supported_processors/element_type_declarations.rb +89 -0
  25. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +40 -0
  26. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/symbolize_defaults.rb +31 -0
  27. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/hash_with_symbolic_keys.rb +37 -0
  28. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/valid_attribute_names.rb +60 -0
  29. data/projects/builtin_types/src/attributes/supported_transformers/defaults.rb +41 -0
  30. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +55 -0
  31. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_of_symbols.rb +47 -0
  32. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/array_with_valid_attribute_names.rb +54 -0
  33. data/projects/builtin_types/src/attributes/supported_validators/required.rb +51 -0
  34. data/projects/builtin_types/src/big_decimal/casters/integer.rb +21 -0
  35. data/projects/builtin_types/src/big_decimal/casters/string.rb +24 -0
  36. data/projects/builtin_types/src/boolean/casters/numeric.rb +21 -0
  37. data/projects/builtin_types/src/boolean/casters/string_or_symbol.rb +27 -0
  38. data/projects/builtin_types/src/builtin_types.rb +189 -0
  39. data/projects/builtin_types/src/date/casters/hash.rb +23 -0
  40. data/projects/builtin_types/src/date/casters/string.rb +40 -0
  41. data/projects/builtin_types/src/datetime/casters/date.rb +21 -0
  42. data/projects/builtin_types/src/datetime/casters/hash.rb +77 -0
  43. data/projects/builtin_types/src/datetime/casters/seconds_since_epoch.rb +21 -0
  44. data/projects/builtin_types/src/datetime/casters/string.rb +31 -0
  45. data/projects/builtin_types/src/duck/supported_casters/allow_nil.rb +38 -0
  46. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb +29 -0
  47. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb +31 -0
  48. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb +31 -0
  49. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb +43 -0
  50. data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +42 -0
  51. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/cast_one_of.rb +37 -0
  52. data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/module_desugarizer.rb +41 -0
  53. data/projects/builtin_types/src/duck/supported_validators/one_of.rb +41 -0
  54. data/projects/builtin_types/src/duck.rb +6 -0
  55. data/projects/builtin_types/src/duckture.rb +6 -0
  56. data/projects/builtin_types/src/email/transformers/downcase.rb +15 -0
  57. data/projects/builtin_types/src/email/validator_base.rb +94 -0
  58. data/projects/builtin_types/src/float/casters/integer.rb +21 -0
  59. data/projects/builtin_types/src/float/casters/string.rb +24 -0
  60. data/projects/builtin_types/src/integer/casters/string.rb +23 -0
  61. data/projects/builtin_types/src/number/supported_validators/max.rb +41 -0
  62. data/projects/builtin_types/src/number/supported_validators/min.rb +41 -0
  63. data/projects/builtin_types/src/string/casters/numeric.rb +21 -0
  64. data/projects/builtin_types/src/string/casters/symbol.rb +21 -0
  65. data/projects/builtin_types/src/string/supported_transformers/downcase.rb +11 -0
  66. data/projects/builtin_types/src/string/supported_validators/matches.rb +41 -0
  67. data/projects/builtin_types/src/string/supported_validators/max_length.rb +37 -0
  68. data/projects/builtin_types/src/symbol/casters/string.rb +21 -0
  69. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/desugarizers/set_size.rb +32 -0
  70. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/type_declaration_validators/size_matches.rb +50 -0
  71. data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations.rb +59 -0
  72. data/projects/callback/lib/foobara/callback.rb +1 -0
  73. data/projects/callback/src/block/after.rb +10 -0
  74. data/projects/callback/src/block/around.rb +10 -0
  75. data/projects/callback/src/block/before.rb +10 -0
  76. data/projects/callback/src/block/concerns/block_parameter_not_allowed.rb +21 -0
  77. data/projects/callback/src/block/concerns/block_parameter_required.rb +21 -0
  78. data/projects/callback/src/block/concerns/keyword_argumentable_block.rb +31 -0
  79. data/projects/callback/src/block/concerns/single_argument_block.rb +22 -0
  80. data/projects/callback/src/block/concerns/type.rb +17 -0
  81. data/projects/callback/src/block/error.rb +10 -0
  82. data/projects/callback/src/block.rb +83 -0
  83. data/projects/callback/src/registry/base.rb +90 -0
  84. data/projects/callback/src/registry/chained_conditioned.rb +24 -0
  85. data/projects/callback/src/registry/chained_multiple_action.rb +24 -0
  86. data/projects/callback/src/registry/conditioned.rb +101 -0
  87. data/projects/callback/src/registry/multiple_action.rb +110 -0
  88. data/projects/callback/src/registry/single_action.rb +15 -0
  89. data/projects/callback/src/runner.rb +89 -0
  90. data/projects/callback/src/set.rb +56 -0
  91. data/projects/command/lib/foobara/command.rb +9 -0
  92. data/projects/command/src/command/entity_helpers.rb +145 -0
  93. data/projects/command/src/command.rb +36 -0
  94. data/projects/command/src/concerns/callbacks.rb +93 -0
  95. data/projects/command/src/concerns/description.rb +23 -0
  96. data/projects/command/src/concerns/domain_mappers.rb +35 -0
  97. data/projects/command/src/concerns/entities.rb +88 -0
  98. data/projects/command/src/concerns/errors.rb +181 -0
  99. data/projects/command/src/concerns/errors_type.rb +124 -0
  100. data/projects/command/src/concerns/inputs.rb +59 -0
  101. data/projects/command/src/concerns/inputs_type.rb +58 -0
  102. data/projects/command/src/concerns/namespace.rb +49 -0
  103. data/projects/command/src/concerns/reflection.rb +137 -0
  104. data/projects/command/src/concerns/result.rb +25 -0
  105. data/projects/command/src/concerns/result_type.rb +29 -0
  106. data/projects/command/src/concerns/runtime.rb +119 -0
  107. data/projects/command/src/concerns/state_machine.rb +12 -0
  108. data/projects/command/src/concerns/subcommands.rb +102 -0
  109. data/projects/command/src/concerns/transactions.rb +81 -0
  110. data/projects/command/src/state_machine.rb +57 -0
  111. data/projects/command/src/transformed_command.rb +459 -0
  112. data/projects/command_connectors/lib/foobara/command_connectors.rb +12 -0
  113. data/projects/command_connectors/src/command_connector.rb +401 -0
  114. data/projects/command_connectors/src/command_registry/allowed_rule.rb +29 -0
  115. data/projects/command_connectors/src/command_registry/exposed_command.rb +140 -0
  116. data/projects/command_connectors/src/command_registry/exposed_domain.rb +30 -0
  117. data/projects/command_connectors/src/command_registry/exposed_organization.rb +30 -0
  118. data/projects/command_connectors/src/command_registry.rb +257 -0
  119. data/projects/command_connectors/src/commands/describe.rb +36 -0
  120. data/projects/command_connectors/src/commands/list_commands.rb +51 -0
  121. data/projects/command_connectors/src/commands/ping.rb +21 -0
  122. data/projects/command_connectors/src/commands/query_git_commit_info.rb +81 -0
  123. data/projects/command_connectors/src/request.rb +99 -0
  124. data/projects/command_connectors/src/response.rb +17 -0
  125. data/projects/command_connectors/src/serializer.rb +25 -0
  126. data/projects/command_connectors/src/serializers/aggregate_serializer.rb +32 -0
  127. data/projects/command_connectors/src/serializers/atomic_serializer.rb +25 -0
  128. data/projects/command_connectors/src/serializers/entities_to_primary_keys_serializer.rb +28 -0
  129. data/projects/command_connectors/src/serializers/errors_serializer.rb +18 -0
  130. data/projects/command_connectors/src/serializers/json_serializer.rb +20 -0
  131. data/projects/command_connectors/src/serializers/noop_serializer.rb +20 -0
  132. data/projects/command_connectors/src/serializers/record_store_serializer.rb +31 -0
  133. data/projects/command_connectors/src/serializers/success_serializer.rb +14 -0
  134. data/projects/command_connectors/src/serializers/yaml_serializer.rb +20 -0
  135. data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +35 -0
  136. data/projects/command_connectors/src/transformers/load_aggregates_pre_commit_transformer.rb +36 -0
  137. data/projects/command_connectors_http/lib/foobara/command_connectors_http.rb +6 -0
  138. data/projects/command_connectors_http/src/http/commands/get_options.rb +16 -0
  139. data/projects/command_connectors_http/src/http/commands/help/presenter/command.rb +14 -0
  140. data/projects/command_connectors_http/src/http/commands/help/presenter/domain.rb +14 -0
  141. data/projects/command_connectors_http/src/http/commands/help/presenter/entity.rb +14 -0
  142. data/projects/command_connectors_http/src/http/commands/help/presenter/error.rb +14 -0
  143. data/projects/command_connectors_http/src/http/commands/help/presenter/model.rb +14 -0
  144. data/projects/command_connectors_http/src/http/commands/help/presenter/organization.rb +14 -0
  145. data/projects/command_connectors_http/src/http/commands/help/presenter/processor.rb +14 -0
  146. data/projects/command_connectors_http/src/http/commands/help/presenter/processor_class.rb +14 -0
  147. data/projects/command_connectors_http/src/http/commands/help/presenter/root.rb +14 -0
  148. data/projects/command_connectors_http/src/http/commands/help/presenter/type.rb +14 -0
  149. data/projects/command_connectors_http/src/http/commands/help/presenter.rb +162 -0
  150. data/projects/command_connectors_http/src/http/commands/help/templates/command.html.erb +11 -0
  151. data/projects/command_connectors_http/src/http/commands/help/templates/domain.html.erb +1 -0
  152. data/projects/command_connectors_http/src/http/commands/help/templates/entity.html.erb +1 -0
  153. data/projects/command_connectors_http/src/http/commands/help/templates/error.html.erb +1 -0
  154. data/projects/command_connectors_http/src/http/commands/help/templates/model.html.erb +1 -0
  155. data/projects/command_connectors_http/src/http/commands/help/templates/organization.html.erb +1 -0
  156. data/projects/command_connectors_http/src/http/commands/help/templates/processor.html.erb +1 -0
  157. data/projects/command_connectors_http/src/http/commands/help/templates/processor_class.html.erb +1 -0
  158. data/projects/command_connectors_http/src/http/commands/help/templates/root.html.erb +3 -0
  159. data/projects/command_connectors_http/src/http/commands/help/templates/type.html.erb +1 -0
  160. data/projects/command_connectors_http/src/http/commands/help.rb +98 -0
  161. data/projects/command_connectors_http/src/http/request.rb +98 -0
  162. data/projects/command_connectors_http/src/http/response.rb +14 -0
  163. data/projects/command_connectors_http/src/http.rb +84 -0
  164. data/projects/common/lib/foobara/common.rb +11 -0
  165. data/projects/common/src/data_path.rb +272 -0
  166. data/projects/common/src/error.rb +215 -0
  167. data/projects/common/src/error_collection.rb +97 -0
  168. data/projects/common/src/error_key.rb +168 -0
  169. data/projects/common/src/outcome.rb +101 -0
  170. data/projects/common/src/possible_error.rb +80 -0
  171. data/projects/common/src/runtime_error.rb +24 -0
  172. data/projects/concerns/lib/foobara/concerns.rb +1 -0
  173. data/projects/concerns/src/concern.rb +93 -0
  174. data/projects/delegate/lib/foobara/delegate.rb +1 -0
  175. data/projects/delegate/src/extensions/module.rb +12 -0
  176. data/projects/domain/lib/foobara/domain.rb +25 -0
  177. data/projects/domain/src/domain.rb +65 -0
  178. data/projects/domain/src/domain_mapper/registry.rb +47 -0
  179. data/projects/domain/src/domain_mapper.rb +162 -0
  180. data/projects/domain/src/domain_module_extension.rb +510 -0
  181. data/projects/domain/src/extensions/foobara.rb +69 -0
  182. data/projects/domain/src/global_domain.rb +14 -0
  183. data/projects/domain/src/global_organization.rb +12 -0
  184. data/projects/domain/src/is_manifestable.rb +68 -0
  185. data/projects/domain/src/manifestable.rb +12 -0
  186. data/projects/domain/src/module_extension.rb +122 -0
  187. data/projects/domain/src/organization.rb +52 -0
  188. data/projects/domain/src/organization_module_extension.rb +50 -0
  189. data/projects/entity/lib/foobara/entity.rb +27 -0
  190. data/projects/entity/src/concerns/associations.rb +241 -0
  191. data/projects/entity/src/concerns/attributes.rb +170 -0
  192. data/projects/entity/src/concerns/callbacks.rb +97 -0
  193. data/projects/entity/src/concerns/initialization.rb +127 -0
  194. data/projects/entity/src/concerns/persistence.rb +142 -0
  195. data/projects/entity/src/concerns/primary_key.rb +43 -0
  196. data/projects/entity/src/concerns/queries.rb +96 -0
  197. data/projects/entity/src/concerns/reflection.rb +51 -0
  198. data/projects/entity/src/concerns/transactions.rb +31 -0
  199. data/projects/entity/src/concerns/types.rb +31 -0
  200. data/projects/entity/src/entity.rb +61 -0
  201. data/projects/entity/src/extensions/builtin_types/entity/casters/hash.rb +33 -0
  202. data/projects/entity/src/extensions/builtin_types/entity/validators/attributes_declaration.rb +32 -0
  203. data/projects/entity/src/extensions/builtin_types/entity.rb +6 -0
  204. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/attributes_handler_desugarizer.rb +14 -0
  205. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/hash_desugarizer.rb +43 -0
  206. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/model_class_desugarizer.rb +21 -0
  207. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/primary_key_desugarizer.rb +19 -0
  208. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/to_type_transformer.rb +64 -0
  209. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_is_symbol.rb +35 -0
  210. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_present.rb +27 -0
  211. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration/validate_primary_key_references_attribute.rb +36 -0
  212. data/projects/entity/src/extensions/type_declarations/handlers/extend_entity_type_declaration.rb +11 -0
  213. data/projects/entity/src/new_prepend.rb +21 -0
  214. data/projects/entity/src/not_found_error.rb +72 -0
  215. data/projects/enumerated/lib/foobara/enumerated.rb +1 -0
  216. data/projects/enumerated/src/accessors.rb +61 -0
  217. data/projects/enumerated/src/values.rb +121 -0
  218. data/projects/foobara/lib/foobara/all.rb +44 -0
  219. data/projects/in_memory_crud_driver/lib/foobara/in_memory_crud_driver.rb +3 -0
  220. data/projects/in_memory_crud_driver/src/in_memory.rb +10 -0
  221. data/projects/in_memory_crud_driver_minimal/lib/foobara/in_memory_crud_driver_minimal.rb +1 -0
  222. data/projects/in_memory_crud_driver_minimal/src/in_memory_minimal.rb +113 -0
  223. data/projects/manifest/lib/foobara/manifest.rb +4 -0
  224. data/projects/manifest/src/foobara/manifest/array.rb +13 -0
  225. data/projects/manifest/src/foobara/manifest/attributes.rb +40 -0
  226. data/projects/manifest/src/foobara/manifest/base_manifest.rb +161 -0
  227. data/projects/manifest/src/foobara/manifest/command.rb +59 -0
  228. data/projects/manifest/src/foobara/manifest/domain.rb +43 -0
  229. data/projects/manifest/src/foobara/manifest/entity.rb +35 -0
  230. data/projects/manifest/src/foobara/manifest/error.rb +33 -0
  231. data/projects/manifest/src/foobara/manifest/model.rb +43 -0
  232. data/projects/manifest/src/foobara/manifest/organization.rb +45 -0
  233. data/projects/manifest/src/foobara/manifest/possible_error.rb +30 -0
  234. data/projects/manifest/src/foobara/manifest/processor.rb +11 -0
  235. data/projects/manifest/src/foobara/manifest/processor_class.rb +11 -0
  236. data/projects/manifest/src/foobara/manifest/root_manifest.rb +112 -0
  237. data/projects/manifest/src/foobara/manifest/type.rb +86 -0
  238. data/projects/manifest/src/foobara/manifest/type_declaration.rb +117 -0
  239. data/projects/model/lib/foobara/model.rb +23 -0
  240. data/projects/model/src/concerns/reflection.rb +22 -0
  241. data/projects/model/src/concerns/types.rb +104 -0
  242. data/projects/model/src/extensions/builtin_types/model/casters/hash.rb +23 -0
  243. data/projects/model/src/extensions/builtin_types/model/transformers/mutable.rb +26 -0
  244. data/projects/model/src/extensions/builtin_types/model/validators/attributes_declaration.rb +33 -0
  245. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +24 -0
  246. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +32 -0
  247. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +119 -0
  248. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +57 -0
  249. data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +21 -0
  250. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +37 -0
  251. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +25 -0
  252. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +46 -0
  253. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +28 -0
  254. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +27 -0
  255. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +31 -0
  256. data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -0
  257. data/projects/model/src/model.rb +320 -0
  258. data/projects/monorepo/lib/foobara/monorepo/project.rb +52 -0
  259. data/projects/monorepo/lib/foobara/monorepo.rb +63 -0
  260. data/projects/namespace/lib/foobara/namespace.rb +4 -0
  261. data/projects/namespace/src/ambiguous_registry.rb +104 -0
  262. data/projects/namespace/src/base_registry.rb +66 -0
  263. data/projects/namespace/src/extensions/module.rb +5 -0
  264. data/projects/namespace/src/is_namespace.rb +352 -0
  265. data/projects/namespace/src/namespace/lookup_mode.rb +41 -0
  266. data/projects/namespace/src/namespace.rb +61 -0
  267. data/projects/namespace/src/namespace_helpers.rb +273 -0
  268. data/projects/namespace/src/prefixless_registry.rb +54 -0
  269. data/projects/namespace/src/scoped.rb +113 -0
  270. data/projects/namespace/src/unambiguous_registry.rb +65 -0
  271. data/projects/persistence/lib/foobara/persistence.rb +22 -0
  272. data/projects/persistence/src/entity_attributes_crud_driver.rb +241 -0
  273. data/projects/persistence/src/entity_base/table.rb +14 -0
  274. data/projects/persistence/src/entity_base/transaction/concerns/entity_callback_handling.rb +157 -0
  275. data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +83 -0
  276. data/projects/persistence/src/entity_base/transaction/concerns/transaction_tracking.rb +53 -0
  277. data/projects/persistence/src/entity_base/transaction/state_machine.rb +27 -0
  278. data/projects/persistence/src/entity_base/transaction.rb +163 -0
  279. data/projects/persistence/src/entity_base/transaction_table/concerns/queries.rb +42 -0
  280. data/projects/persistence/src/entity_base/transaction_table/concerns/record_tracking.rb +134 -0
  281. data/projects/persistence/src/entity_base/transaction_table.rb +620 -0
  282. data/projects/persistence/src/entity_base.rb +114 -0
  283. data/projects/persistence/src/persistence.rb +172 -0
  284. data/projects/state_machine/lib/foobara/state_machine.rb +1 -0
  285. data/projects/state_machine/src/callbacks.rb +158 -0
  286. data/projects/state_machine/src/log_entry.rb +13 -0
  287. data/projects/state_machine/src/state_machine.rb +91 -0
  288. data/projects/state_machine/src/sugar.rb +125 -0
  289. data/projects/state_machine/src/transition_log.rb +19 -0
  290. data/projects/state_machine/src/validations.rb +69 -0
  291. data/projects/thread_parent/lib/foobara/thread_parent.rb +1 -0
  292. data/projects/thread_parent/src/thread_parent.rb +38 -0
  293. data/projects/type_declarations/lib/foobara/type_declarations.rb +131 -0
  294. data/projects/type_declarations/src/attributes.rb +34 -0
  295. data/projects/type_declarations/src/caster.rb +7 -0
  296. data/projects/type_declarations/src/desugarizer.rb +25 -0
  297. data/projects/type_declarations/src/dsl/attributes.rb +199 -0
  298. data/projects/type_declarations/src/element_processor.rb +7 -0
  299. data/projects/type_declarations/src/error_extension.rb +73 -0
  300. data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +31 -0
  301. data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +37 -0
  302. data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +22 -0
  303. data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +36 -0
  304. data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +14 -0
  305. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +28 -0
  306. data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +20 -0
  307. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +25 -0
  308. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +34 -0
  309. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +60 -0
  310. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +21 -0
  311. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +16 -0
  312. data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +75 -0
  313. data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +23 -0
  314. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +30 -0
  315. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +24 -0
  316. data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +13 -0
  317. data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +29 -0
  318. data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +65 -0
  319. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +32 -0
  320. data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +39 -0
  321. data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +26 -0
  322. data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +28 -0
  323. data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +24 -0
  324. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +26 -0
  325. data/projects/type_declarations/src/processor.rb +7 -0
  326. data/projects/type_declarations/src/to_type_transformer.rb +11 -0
  327. data/projects/type_declarations/src/transformer.rb +7 -0
  328. data/projects/type_declarations/src/type_builder.rb +112 -0
  329. data/projects/type_declarations/src/type_declaration_error.rb +9 -0
  330. data/projects/type_declarations/src/type_declaration_handler.rb +120 -0
  331. data/projects/type_declarations/src/type_declaration_handler_registry.rb +27 -0
  332. data/projects/type_declarations/src/type_declaration_validator.rb +19 -0
  333. data/projects/type_declarations/src/type_declarations.rb +128 -0
  334. data/projects/type_declarations/src/typed_transformer.rb +89 -0
  335. data/projects/type_declarations/src/validator.rb +7 -0
  336. data/projects/type_declarations/src/with_registries.rb +41 -0
  337. data/projects/types/lib/foobara/types.rb +11 -0
  338. data/projects/types/src/element_processor.rb +7 -0
  339. data/projects/types/src/extensions/error.rb +32 -0
  340. data/projects/types/src/type/concerns/reflection.rb +79 -0
  341. data/projects/types/src/type/concerns/supported_processor_registration.rb +56 -0
  342. data/projects/types/src/type.rb +375 -0
  343. data/projects/types/src/types.rb +4 -0
  344. data/projects/value/lib/foobara/value.rb +7 -0
  345. data/projects/value/src/caster.rb +84 -0
  346. data/projects/value/src/data_error.rb +27 -0
  347. data/projects/value/src/processor/casting.rb +123 -0
  348. data/projects/value/src/processor/multi.rb +63 -0
  349. data/projects/value/src/processor/pipeline.rb +27 -0
  350. data/projects/value/src/processor/runner.rb +38 -0
  351. data/projects/value/src/processor/selection.rb +90 -0
  352. data/projects/value/src/processor.rb +358 -0
  353. data/projects/value/src/transformer.rb +84 -0
  354. data/projects/value/src/validator.rb +53 -0
  355. data/projects/version/lib/foobara/version.rb +4 -0
  356. data/projects/version/src/version.rb +5 -0
  357. data/projects/weak_object_set/lib/foobara/weak_object_set.rb +3 -0
  358. data/projects/weak_object_set/src/weak_object_set.rb +163 -0
  359. metadata +445 -0
@@ -0,0 +1,56 @@
1
+ module Foobara
2
+ module Callback
3
+ class Set
4
+ attr_accessor :callbacks
5
+
6
+ def initialize(callback_hash = {})
7
+ self.callbacks = {}
8
+
9
+ callback_hash.each do |type, blocks|
10
+ send("#{type}=", blocks.dup)
11
+ end
12
+ end
13
+
14
+ foobara_delegate :size, to: :callbacks
15
+
16
+ def union(set)
17
+ unioned = Set.new(callbacks)
18
+
19
+ set.callbacks.each_pair do |type, blocks|
20
+ next if blocks.empty?
21
+
22
+ unioned_blocks = unioned[type]
23
+ blocks.each { |block| unioned_blocks << block }
24
+ end
25
+
26
+ unioned
27
+ end
28
+
29
+ def |(other)
30
+ union(other)
31
+ end
32
+
33
+ def [](type)
34
+ send(type)
35
+ end
36
+
37
+ Block.types.each do |type|
38
+ define_method type do
39
+ callbacks[type] ||= []
40
+ end
41
+
42
+ define_method "#{type}=" do |blocks|
43
+ callbacks[type] ||= blocks
44
+ end
45
+
46
+ define_method "each_#{type}" do |&block|
47
+ send(type).each(&block)
48
+ end
49
+
50
+ define_method "has_#{type}_callbacks?" do
51
+ !send(type).empty?
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ module Foobara
2
+ class Command
3
+ class << self
4
+ def install!
5
+ Namespace.global.foobara_add_category_for_subclass_of(:command, self)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,145 @@
1
+ module Foobara
2
+ class Command
3
+ module EntityHelpers
4
+ module_function
5
+
6
+ def type_declaration_for_record_aggregate_update(entity_class, initial = true)
7
+ declaration = entity_class.attributes_type.declaration_data
8
+ # TODO: just slice out the element type declarations
9
+ declaration = Util.deep_dup(declaration)
10
+
11
+ declaration.delete(:defaults)
12
+ declaration.delete(:required)
13
+
14
+ if initial
15
+ declaration[:required] = [entity_class.primary_key_attribute]
16
+ end
17
+
18
+ entity_class.associations.each_pair do |data_path, type|
19
+ if type.extends?(BuiltinTypes[:entity])
20
+ target_class = type.target_class
21
+
22
+ entry = type_declaration_value_at(declaration, DataPath.new(data_path).path)
23
+ entry.clear
24
+ entry.merge!(type_declaration_for_record_aggregate_update(target_class, false))
25
+ end
26
+ end
27
+
28
+ declaration
29
+ end
30
+
31
+ def type_declaration_for_record_atom_update(entity_class)
32
+ declaration = entity_class.attributes_type.declaration_data
33
+ # TODO: just slice out the element type declarations
34
+ declaration = Util.deep_dup(declaration)
35
+
36
+ declaration.delete(:defaults)
37
+ declaration[:required] = [entity_class.primary_key_attribute]
38
+
39
+ # expect all associations to be expressed as primary key values
40
+ # TODO: should we have a special type for encapsulating primary keys types??
41
+ entity_class.associations.each_pair do |data_path, type|
42
+ if type.extends?(BuiltinTypes[:entity])
43
+ target_class = type.target_class
44
+ # TODO: do we really need declaration_data? Why cant we use the type directly?
45
+ # TODO: make this work with the type directly for performance reasons.
46
+ primary_key_type_declaration = target_class.primary_key_type.declaration_data
47
+ entry = type_declaration_value_at(declaration, DataPath.new(data_path).path)
48
+ entry.clear
49
+ entry.merge!(primary_key_type_declaration)
50
+ end
51
+ end
52
+
53
+ declaration
54
+ end
55
+
56
+ def type_declaration_for_find_by(entity_class)
57
+ element_type_declarations = {}
58
+
59
+ entity_class.attributes_type.element_types.each_pair do |attribute_name, attribute_type|
60
+ element_type_declarations[attribute_name] = attribute_type.reference_or_declaration_data
61
+ end
62
+
63
+ handler = Domain.global.foobara_type_builder.handler_for_class(
64
+ TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
65
+ )
66
+
67
+ handler.desugarize(
68
+ type: "::attributes",
69
+ element_type_declarations:
70
+ )
71
+ end
72
+
73
+ def update_aggregate(object, value, type = object.class.model_type)
74
+ return value if object.nil?
75
+
76
+ if type.extends?(BuiltinTypes[:model])
77
+ element_types = type.element_types.element_types
78
+
79
+ value.each_pair do |attribute_name, new_value|
80
+ current_value = object.read_attribute(attribute_name)
81
+
82
+ attribute_type = element_types[attribute_name]
83
+
84
+ updated_value = update_aggregate(current_value, new_value, attribute_type)
85
+
86
+ object.write_attribute(attribute_name, updated_value)
87
+ end
88
+
89
+ object
90
+ elsif type.extends?(BuiltinTypes[:attributes])
91
+ element_types = type.element_types
92
+
93
+ object = object.dup
94
+ object ||= {}
95
+
96
+ value.each_pair do |attribute_name, new_value|
97
+ current_value = object[attribute_name]
98
+ attribute_type = element_types[attribute_name]
99
+
100
+ updated_value = update_aggregate(current_value, new_value, attribute_type)
101
+
102
+ object[attribute_name] = updated_value
103
+ end
104
+
105
+ object
106
+ elsif type.extends?(BuiltinTypes[:tuple])
107
+ # :nocov:
108
+ raise "Tuple not yet supported"
109
+ # :nocov:
110
+ elsif type.extends?(BuiltinTypes[:associative_array])
111
+ # :nocov:
112
+ raise "Associated array not yet supported"
113
+ # :nocov:
114
+ elsif type.extends?(BuiltinTypes[:array])
115
+ element_type = type.element_type
116
+
117
+ value.map.with_index do |element, index|
118
+ update_aggregate(object[index], element, element_type)
119
+ end
120
+ else
121
+ value
122
+ end
123
+ end
124
+
125
+ def type_declaration_value_at(declaration, path_parts)
126
+ return declaration if path_parts.empty?
127
+
128
+ path_part, *path_parts = path_parts
129
+
130
+ declaration = case path_part
131
+ when :"#"
132
+ declaration[:element_type_declaration]
133
+ when Symbol, Integer
134
+ declaration[:element_type_declarations][path_part]
135
+ else
136
+ # :nocov:
137
+ raise "Bad path part #{path_part}"
138
+ # :nocov:
139
+ end
140
+
141
+ type_declaration_value_at(declaration, path_parts)
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,36 @@
1
+ module Foobara
2
+ class Command
3
+ include TruncatedInspect
4
+
5
+ include Concerns::Description
6
+ include Concerns::Namespace
7
+
8
+ include Concerns::InputsType
9
+ include Concerns::ErrorsType
10
+ include Concerns::ResultType
11
+
12
+ include Concerns::Inputs
13
+ include Concerns::Errors
14
+ include Concerns::Result
15
+
16
+ include Concerns::Runtime
17
+ include Concerns::Callbacks
18
+ include Concerns::StateMachine
19
+ include Concerns::Transactions
20
+ include Concerns::Entities
21
+ include Concerns::Subcommands
22
+ include Concerns::DomainMappers
23
+ include Concerns::Reflection
24
+
25
+ attr_reader :raw_inputs
26
+
27
+ def initialize(inputs = {})
28
+ @raw_inputs = inputs
29
+ super()
30
+ end
31
+ end
32
+
33
+ Command.after_subclass_defined do |subclass|
34
+ Command.all << subclass
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ module Foobara
2
+ class Command
3
+ module Concerns
4
+ module Callbacks
5
+ include Concern
6
+
7
+ module ClassMethods
8
+ def subclass_defined_callbacks
9
+ @subclass_defined_callbacks ||= Foobara::Callback::Registry::SingleAction.new
10
+ end
11
+
12
+ def inherited(subclass)
13
+ super
14
+
15
+ subclass_defined_callbacks.runner.callback_data(subclass).run
16
+ end
17
+
18
+ def after_subclass_defined(&)
19
+ subclass_defined_callbacks.register_callback(:after, &)
20
+ end
21
+
22
+ def callback_state_machine_target
23
+ Foobara::Command::StateMachine
24
+ end
25
+
26
+ foobara_delegate :remove_all_callbacks, to: :callback_state_machine_target
27
+ end
28
+
29
+ on_include do
30
+ [self, singleton_class].each do |target|
31
+ %i[before after].each do |type|
32
+ target.define_method "#{type}_any_transition" do |&block|
33
+ callback_state_machine_target.register_transition_callback(type) do |state_machine:, **args|
34
+ block.call(command: state_machine.owner, **args)
35
+ end
36
+ end
37
+ end
38
+
39
+ target.define_method "around_any_transition" do |&block|
40
+ callback_state_machine_target.register_transition_callback(
41
+ :around
42
+ ) do |state_machine:, **args, &do_transition_block|
43
+ block.call(command: state_machine.owner, **args, &do_transition_block)
44
+ end
45
+ end
46
+
47
+ target.define_method :error_any_transition do |&block|
48
+ callback_state_machine_target.register_transition_callback(:error) do |error|
49
+ callback_data = error.callback_data
50
+
51
+ state_machine = callback_data[:state_machine]
52
+ command = state_machine.owner
53
+ from = callback_data[:from]
54
+ transition = callback_data[:transition]
55
+ to = callback_data[:to]
56
+
57
+ block.call(error:, command:, state_machine:, from:, to:, transition:)
58
+ end
59
+ end
60
+ end
61
+
62
+ Foobara::Command::StateMachine.transitions.each do |transition|
63
+ [self, singleton_class].each do |target|
64
+ %i[before after].each do |type|
65
+ target.define_method "#{type}_#{transition}" do |&block|
66
+ callback_state_machine_target.register_transition_callback(
67
+ type, transition:
68
+ ) do |state_machine:, **args|
69
+ block.call(command: state_machine.owner, **args)
70
+ end
71
+ end
72
+ end
73
+
74
+ target.define_method "around_#{transition}" do |&block|
75
+ callback_state_machine_target.register_transition_callback(
76
+ :around, transition:
77
+ ) do |state_machine:, **args, &do_transition_block|
78
+ block.call(command: state_machine.owner, **args, &do_transition_block)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def callback_state_machine_target
88
+ state_machine
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,23 @@
1
+ module Foobara
2
+ class Command
3
+ module Concerns
4
+ module Description
5
+ include Concern
6
+
7
+ module ClassMethods
8
+ def description(*args)
9
+ if args.empty?
10
+ @description
11
+ elsif args.size == 1
12
+ @description = args.first
13
+ else
14
+ # :nocov:
15
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 0 or 1)"
16
+ # :nocov:
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Foobara
2
+ class Command
3
+ module Concerns
4
+ module DomainMappers
5
+ include Concern
6
+
7
+ def run_mapped_subcommand!(subcommand_class, unmapped_inputs)
8
+ inputs = domain_map!(unmapped_inputs, to: subcommand_class, strict: true)
9
+
10
+ result = run_subcommand!(subcommand_class, inputs)
11
+
12
+ result_mapper = self.class.domain.foobara_domain_mapper_registry.lookup(
13
+ from: result,
14
+ to: result_type,
15
+ strict: true
16
+ )
17
+
18
+ if result_mapper
19
+ result_mapper.map(result)
20
+ else
21
+ result
22
+ end
23
+ end
24
+
25
+ def domain_map(...)
26
+ self.class.domain.foobara_domain_map(...)
27
+ end
28
+
29
+ def domain_map!(...)
30
+ self.class.domain.foobara_domain_map!(...)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,88 @@
1
+ module Foobara
2
+ class Command
3
+ module Concerns
4
+ module Entities
5
+ include Concern
6
+
7
+ module ClassMethods
8
+ # Only needed for entities not discoverable through the inputs
9
+ def depends_on_entities(*entities_to_add)
10
+ if entities_to_add.empty?
11
+ @depends_on_entities ||= Set.new
12
+ else
13
+ entities_to_add.each do |entity_class|
14
+ depends_on_entity(entity_class)
15
+ end
16
+ end
17
+ end
18
+
19
+ def depends_on_entity(entity_class)
20
+ depends_on_entities << entity_class
21
+ end
22
+
23
+ def entity_class_paths
24
+ # TODO: bust this cache when changing inputs_type??
25
+ @entity_class_paths ||= Entity.construct_associations(
26
+ inputs_type
27
+ ).transform_values(&:target_class)
28
+ end
29
+
30
+ # TODO: move to better concern!
31
+ # TODO: make work with inheritance
32
+ def to_load(*paths)
33
+ h = @to_load_paths_and_error_classes || {}
34
+
35
+ paths.each do |path|
36
+ path = DataPath.new(path)
37
+ entity_class = entity_class_paths[path.to_s]
38
+ error_class = Entity::NotFoundError.subclass(self, entity_class, path)
39
+ h[path.to_s] = error_class
40
+ possible_error(error_class)
41
+ end
42
+
43
+ @to_load_paths_and_error_classes = h.sort_by do |path, _error_class|
44
+ [DataPath.new(path).path.size, path]
45
+ end.to_h
46
+ end
47
+
48
+ def load_all
49
+ to_load(*entity_class_paths.keys)
50
+ end
51
+
52
+ def to_load_paths_and_error_classes
53
+ @to_load_paths_and_error_classes
54
+ end
55
+ end
56
+
57
+ def load_entities(data_path)
58
+ error_class = self.class.to_load_paths_and_error_classes[data_path.to_s]
59
+ entity_class = error_class.entity_class
60
+
61
+ thunks = DataPath.values_at(data_path, inputs)
62
+
63
+ thunks_to_load = thunks.reject(&:created?)
64
+
65
+ begin
66
+ # here... filter out created entities...
67
+ if thunks_to_load.size == 1
68
+ entity_class.load(thunks_to_load.first)
69
+ else
70
+ entity_class.load_many(thunks_to_load)
71
+ end
72
+
73
+ thunks_to_load
74
+ rescue Entity::NotFoundError => e
75
+ add_runtime_error(error_class.new(e.criteria))
76
+ end
77
+ end
78
+
79
+ # TODO: make this work with collections...
80
+ def load_records
81
+ self.class.to_load.each_key do |data_path|
82
+ load_entities(data_path)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,181 @@
1
+ module Foobara
2
+ class Command
3
+ module Concerns
4
+ module Errors
5
+ include Concern
6
+
7
+ module ClassMethods
8
+ def lookup_input_error_class(symbol, path)
9
+ key = ErrorKey.new(symbol:, path:, category: :data)
10
+ key = key.to_s_type
11
+
12
+ unless error_context_type_map.key?(key)
13
+ # :nocov:
14
+ raise "No error class was registered for #{key}"
15
+ # :nocov:
16
+ end
17
+
18
+ error_context_type_map[key].error_class
19
+ end
20
+
21
+ def lookup_runtime_error_class(symbol)
22
+ key = ErrorKey.new(symbol:, category: :runtime)
23
+ key = key.to_s_type
24
+
25
+ unless error_context_type_map.key?(key)
26
+ # :nocov:
27
+ raise "No error class was registered for #{key}"
28
+ # :nocov:
29
+ end
30
+
31
+ error_context_type_map[key].error_class
32
+ end
33
+
34
+ def lookup_error_class(key)
35
+ key = ErrorKey.to_s_type(key)
36
+
37
+ unless error_context_type_map.key?(key)
38
+ # :nocov:
39
+ raise "No error class was registered for #{key}"
40
+ # :nocov:
41
+ end
42
+
43
+ error_context_type_map[key].error_class
44
+ end
45
+ end
46
+
47
+ attr_reader :error_collection
48
+
49
+ def initialize
50
+ @error_collection = ErrorCollection.new
51
+ end
52
+
53
+ foobara_delegate :has_errors?, to: :error_collection
54
+
55
+ private
56
+
57
+ def add_error(error)
58
+ error = process_error(error)
59
+ error_collection.add_error(error)
60
+ end
61
+
62
+ def add_input_error(*args, **opts)
63
+ error = if args.size == 1 && opts.empty?
64
+ error = args.first
65
+
66
+ unless error.is_a?(Value::DataError)
67
+ # :nocov:
68
+ raise ArgumentError, "expected an DataError or keyword arguments to construct one"
69
+ # :nocov:
70
+ end
71
+
72
+ error
73
+ elsif args.empty? || (args.size == 1 && args.first.is_a?(Hash))
74
+ error_args = opts.merge(args.first || {})
75
+ symbol = error_args[:symbol]
76
+ path = Util.array(error_args[:input] || error_args[:path])
77
+
78
+ error_args = error_args.except(:input)
79
+
80
+ unless symbol
81
+ # :nocov:
82
+ raise ArgumentError, "missing error symbol"
83
+ # :nocov:
84
+ end
85
+
86
+ unless path
87
+ # :nocov:
88
+ raise ArgumentError, "missing input"
89
+ # :nocov:
90
+ end
91
+
92
+ error_class = self.class.lookup_input_error_class(symbol, path)
93
+ error_class.new(**error_args.merge(path:))
94
+ elsif args.size == 2 || args.size == 3
95
+ input, symbol, message = args
96
+ context = opts
97
+
98
+ error_class = self.class.lookup_input_error_class(symbol, input)
99
+ error_class.new(path: Util.array(input), symbol:, context:, message:)
100
+ else
101
+ # :nocov:
102
+ raise ArgumentError,
103
+ "Invalid arguments given. Expected an error or args for an error"
104
+ # :nocov:
105
+ end
106
+
107
+ add_error(error)
108
+ end
109
+
110
+ def add_subcommand_error(subcommand, error)
111
+ error.runtime_path = [subcommand.class.full_command_symbol, *Util.array(error.runtime_path)]
112
+ add_error(error)
113
+ halt!
114
+ end
115
+
116
+ def add_runtime_error(*args, halt: true, **opts)
117
+ error = if args.size == 1 && opts.empty? && (
118
+ args.first.is_a?(::Class) || args.first.is_a?(Foobara::RuntimeError)
119
+ )
120
+ error = args.first
121
+
122
+ if error.is_a?(::Class) && error < Foobara::RuntimeError
123
+ error = error.new
124
+ end
125
+
126
+ unless error.is_a?(Foobara::RuntimeError)
127
+ # :nocov:
128
+ raise ArgumentError,
129
+ "expected a Foobara::RuntimeError or keyword arguments to construct one"
130
+ # :nocov:
131
+ end
132
+
133
+ error
134
+ elsif args.empty? || (args.size == 1 && args.first.is_a?(Hash))
135
+ error_args = opts.merge(args.first || {})
136
+ symbol = error_args[:symbol]
137
+
138
+ unless symbol
139
+ # :nocov:
140
+ raise ArgumentError, "missing error symbol"
141
+ # :nocov:
142
+ end
143
+
144
+ error_class = self.class.lookup_runtime_error_class(symbol)
145
+ error_class.new(**error_args)
146
+ elsif args.is_a?(::Array) && (args.size == 1 || args.size == 2)
147
+ symbol, message = args
148
+ context = opts
149
+
150
+ error_class = self.class.lookup_runtime_error_class(symbol)
151
+ error_class.new(symbol:, context:, message:)
152
+ else
153
+ # :nocov:
154
+ raise ArgumentError, "Invalid arguments given. Expected an error or args/opts to build error"
155
+ # :nocov:
156
+ end
157
+
158
+ add_error(error)
159
+ if halt
160
+ halt!
161
+ else
162
+ error
163
+ end
164
+ end
165
+
166
+ def process_error(error)
167
+ return error unless error.runtime_path.empty?
168
+
169
+ context = error.context
170
+
171
+ error_class = self.class.lookup_error_class(error.key)
172
+ context_type = error_class.context_type
173
+
174
+ error.context = context_type.process_value!(context || {})
175
+
176
+ error
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end