cmdx 0.5.0 → 1.0.0

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.cursor/rules/cursor-instructions.mdc +6 -0
  4. data/.rubocop.yml +16 -1
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +31 -1
  7. data/README.md +72 -25
  8. data/docs/ai_prompts.md +309 -0
  9. data/docs/basics/call.md +225 -14
  10. data/docs/basics/chain.md +271 -0
  11. data/docs/basics/context.md +232 -33
  12. data/docs/basics/setup.md +76 -12
  13. data/docs/callbacks.md +273 -0
  14. data/docs/configuration.md +158 -28
  15. data/docs/getting_started.md +134 -22
  16. data/docs/interruptions/exceptions.md +189 -11
  17. data/docs/interruptions/faults.md +187 -44
  18. data/docs/interruptions/halt.md +179 -35
  19. data/docs/logging.md +194 -53
  20. data/docs/middlewares.md +735 -0
  21. data/docs/outcomes/result.md +296 -10
  22. data/docs/outcomes/states.md +203 -31
  23. data/docs/outcomes/statuses.md +275 -30
  24. data/docs/parameters/coercions.md +402 -29
  25. data/docs/parameters/defaults.md +249 -25
  26. data/docs/parameters/definitions.md +238 -72
  27. data/docs/parameters/namespacing.md +250 -27
  28. data/docs/parameters/validations.md +193 -168
  29. data/docs/testing.md +550 -0
  30. data/docs/tips_and_tricks.md +95 -43
  31. data/docs/workflows.md +319 -0
  32. data/lib/cmdx/.DS_Store +0 -0
  33. data/lib/cmdx/callback.rb +69 -0
  34. data/lib/cmdx/callback_registry.rb +106 -0
  35. data/lib/cmdx/chain.rb +190 -0
  36. data/lib/cmdx/chain_inspector.rb +149 -0
  37. data/lib/cmdx/chain_serializer.rb +175 -0
  38. data/lib/cmdx/coercions/array.rb +37 -0
  39. data/lib/cmdx/coercions/big_decimal.rb +33 -0
  40. data/lib/cmdx/coercions/boolean.rb +41 -1
  41. data/lib/cmdx/coercions/complex.rb +31 -0
  42. data/lib/cmdx/coercions/date.rb +39 -0
  43. data/lib/cmdx/coercions/date_time.rb +39 -0
  44. data/lib/cmdx/coercions/float.rb +31 -0
  45. data/lib/cmdx/coercions/hash.rb +42 -0
  46. data/lib/cmdx/coercions/integer.rb +32 -0
  47. data/lib/cmdx/coercions/rational.rb +31 -0
  48. data/lib/cmdx/coercions/string.rb +31 -0
  49. data/lib/cmdx/coercions/time.rb +39 -0
  50. data/lib/cmdx/coercions/virtual.rb +31 -0
  51. data/lib/cmdx/configuration.rb +217 -9
  52. data/lib/cmdx/context.rb +173 -2
  53. data/lib/cmdx/core_ext/hash.rb +72 -0
  54. data/lib/cmdx/core_ext/module.rb +94 -0
  55. data/lib/cmdx/core_ext/object.rb +105 -0
  56. data/lib/cmdx/correlator.rb +217 -0
  57. data/lib/cmdx/error.rb +210 -8
  58. data/lib/cmdx/errors.rb +256 -1
  59. data/lib/cmdx/fault.rb +177 -2
  60. data/lib/cmdx/faults.rb +158 -2
  61. data/lib/cmdx/immutator.rb +121 -2
  62. data/lib/cmdx/lazy_struct.rb +261 -18
  63. data/lib/cmdx/log_formatters/json.rb +46 -0
  64. data/lib/cmdx/log_formatters/key_value.rb +46 -0
  65. data/lib/cmdx/log_formatters/line.rb +54 -0
  66. data/lib/cmdx/log_formatters/logstash.rb +64 -0
  67. data/lib/cmdx/log_formatters/pretty_json.rb +57 -0
  68. data/lib/cmdx/log_formatters/pretty_key_value.rb +51 -0
  69. data/lib/cmdx/log_formatters/pretty_line.rb +60 -0
  70. data/lib/cmdx/log_formatters/raw.rb +54 -0
  71. data/lib/cmdx/logger.rb +85 -0
  72. data/lib/cmdx/logger_ansi.rb +93 -7
  73. data/lib/cmdx/logger_serializer.rb +116 -0
  74. data/lib/cmdx/middleware.rb +74 -0
  75. data/lib/cmdx/middleware_registry.rb +106 -0
  76. data/lib/cmdx/middlewares/correlate.rb +266 -0
  77. data/lib/cmdx/middlewares/timeout.rb +232 -0
  78. data/lib/cmdx/parameter.rb +228 -1
  79. data/lib/cmdx/parameter_inspector.rb +61 -0
  80. data/lib/cmdx/parameter_registry.rb +125 -0
  81. data/lib/cmdx/parameter_serializer.rb +83 -0
  82. data/lib/cmdx/parameter_validator.rb +62 -0
  83. data/lib/cmdx/parameter_value.rb +109 -1
  84. data/lib/cmdx/parameters_inspector.rb +59 -0
  85. data/lib/cmdx/parameters_serializer.rb +102 -0
  86. data/lib/cmdx/railtie.rb +123 -3
  87. data/lib/cmdx/result.rb +367 -25
  88. data/lib/cmdx/result_ansi.rb +105 -9
  89. data/lib/cmdx/result_inspector.rb +76 -0
  90. data/lib/cmdx/result_logger.rb +90 -3
  91. data/lib/cmdx/result_serializer.rb +137 -0
  92. data/lib/cmdx/rspec/result_matchers.rb +917 -0
  93. data/lib/cmdx/rspec/task_matchers.rb +570 -0
  94. data/lib/cmdx/task.rb +405 -37
  95. data/lib/cmdx/task_serializer.rb +74 -2
  96. data/lib/cmdx/utils/ansi_color.rb +95 -0
  97. data/lib/cmdx/utils/log_timestamp.rb +48 -0
  98. data/lib/cmdx/utils/monotonic_runtime.rb +71 -4
  99. data/lib/cmdx/utils/name_affix.rb +78 -0
  100. data/lib/cmdx/validators/custom.rb +82 -0
  101. data/lib/cmdx/validators/exclusion.rb +94 -0
  102. data/lib/cmdx/validators/format.rb +102 -8
  103. data/lib/cmdx/validators/inclusion.rb +104 -0
  104. data/lib/cmdx/validators/length.rb +128 -0
  105. data/lib/cmdx/validators/numeric.rb +128 -0
  106. data/lib/cmdx/validators/presence.rb +93 -7
  107. data/lib/cmdx/version.rb +7 -1
  108. data/lib/cmdx/workflow.rb +394 -0
  109. data/lib/cmdx.rb +25 -64
  110. data/lib/generators/cmdx/install_generator.rb +37 -1
  111. data/lib/generators/cmdx/task_generator.rb +69 -1
  112. data/lib/generators/cmdx/templates/install.rb +8 -12
  113. data/lib/generators/cmdx/workflow_generator.rb +109 -0
  114. metadata +54 -15
  115. data/docs/basics/run.md +0 -34
  116. data/docs/batch.md +0 -53
  117. data/docs/example.md +0 -82
  118. data/docs/hooks.md +0 -62
  119. data/lib/cmdx/batch.rb +0 -43
  120. data/lib/cmdx/parameters.rb +0 -35
  121. data/lib/cmdx/run.rb +0 -39
  122. data/lib/cmdx/run_inspector.rb +0 -26
  123. data/lib/cmdx/run_serializer.rb +0 -20
  124. data/lib/cmdx/task_hook.rb +0 -18
  125. data/lib/generators/cmdx/batch_generator.rb +0 -30
  126. /data/lib/generators/cmdx/templates/{batch.rb.tt → workflow.rb.tt} +0 -0
data/lib/cmdx/railtie.rb CHANGED
@@ -1,12 +1,102 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CMDx
4
+ ##
5
+ # Railtie provides seamless integration between CMDx and Ruby on Rails applications.
6
+ # It automatically configures Rails-specific features including internationalization,
7
+ # autoloading paths, and directory structure conventions for CMDx tasks and workflows.
8
+ #
9
+ # The Railtie handles two main integration aspects:
10
+ # 1. **I18n Configuration**: Automatically loads CMDx locale files for available locales
11
+ # 2. **Autoloading Setup**: Configures Rails autoloaders for CMDx command objects
12
+ #
13
+ # ## Directory Structure
14
+ #
15
+ # The Railtie expects CMDx command objects to be organized in the following structure:
16
+ # ```
17
+ # app/
18
+ # cmds/
19
+ # workflows/ # Workflow command objects
20
+ # order_processing_workflow.rb
21
+ # tasks/ # Task command objects
22
+ # process_order_task.rb
23
+ # send_email_task.rb
24
+ # ```
25
+ #
26
+ # ## Automatic Features
27
+ #
28
+ # When CMDx is included in a Rails application, the Railtie automatically:
29
+ # - Adds `app/cmds` to Rails autoload paths
30
+ # - Configures autoloader to collapse `app/cmds/workflows` and `app/cmds/tasks` directories
31
+ # - Loads appropriate locale files from CMDx gem for error messages and validations
32
+ # - Reloads I18n configuration to include CMDx translations
33
+ #
34
+ # @example Rails application structure
35
+ # # app/cmds/tasks/process_order_task.rb
36
+ # class ProcessOrderTask < CMDx::Task
37
+ # required :order_id, type: :integer
38
+ #
39
+ # def call
40
+ # context.order = Order.find(order_id)
41
+ # context.order.process!
42
+ # end
43
+ # end
44
+ #
45
+ # @example Using in Rails controllers
46
+ # class OrdersController < ApplicationController
47
+ # def process
48
+ # result = ProcessOrderTask.call(order_id: params[:id])
49
+ #
50
+ # if result.success?
51
+ # redirect_to order_path(result.context.order), notice: 'Order processed!'
52
+ # else
53
+ # redirect_to order_path(params[:id]), alert: result.metadata[:reason]
54
+ # end
55
+ # end
56
+ # end
57
+ #
58
+ # @example I18n integration
59
+ # # CMDx automatically loads locale files for validation messages
60
+ # # en.yml, es.yml, etc. are automatically available
61
+ # result = MyTask.call(invalid_param: nil)
62
+ # result.errors.full_messages # Uses localized error messages
63
+ #
64
+ # @see Configuration Configuration options for Rails integration
65
+ # @see Task Task base class for command objects
66
+ # @see Workflow Workflow base class for multi-task operations
67
+ # @since 1.0.0
4
68
  class Railtie < Rails::Railtie
5
69
 
6
- CONCEPTS = %w[batches tasks].freeze
7
-
8
70
  railtie_name :cmdx
9
71
 
72
+ ##
73
+ # Configures internationalization (I18n) for CMDx in Rails applications.
74
+ # Automatically loads locale files from the CMDx gem for all configured
75
+ # application locales, ensuring error messages and validations are properly localized.
76
+ #
77
+ # This initializer:
78
+ # 1. Iterates through all configured application locales
79
+ # 2. Checks for corresponding CMDx locale files
80
+ # 3. Adds found locale files to I18n load path
81
+ # 4. Reloads I18n configuration
82
+ #
83
+ # @param app [Rails::Application] the Rails application instance
84
+ # @return [void]
85
+ #
86
+ # @example Available locales
87
+ # # If Rails app has config.i18n.available_locales = [:en, :es]
88
+ # # This will load:
89
+ # # - lib/locales/en.yml (CMDx English translations)
90
+ # # - lib/locales/es.yml (CMDx Spanish translations)
91
+ #
92
+ # @example Localized error messages
93
+ # # With Spanish locale active
94
+ # class MyTask < CMDx::Task
95
+ # required :name, presence: true
96
+ # end
97
+ #
98
+ # result = MyTask.call(name: "")
99
+ # result.errors.full_messages # Returns Spanish error messages
10
100
  initializer("cmdx.configure_locales") do |app|
11
101
  Array(app.config.i18n.available_locales).each do |locale|
12
102
  path = File.expand_path("../../../lib/locales/#{locale}.yml", __FILE__)
@@ -18,10 +108,40 @@ module CMDx
18
108
  I18n.reload!
19
109
  end
20
110
 
111
+ ##
112
+ # Configures Rails autoloading for CMDx command objects.
113
+ # Sets up proper autoloading paths and directory collapsing to ensure
114
+ # CMDx tasks and workflows are loaded correctly in Rails applications.
115
+ #
116
+ # This initializer:
117
+ # 1. Adds `app/cmds` to Rails autoload paths
118
+ # 2. Configures all autoloaders to collapse concept directories
119
+ # 3. Ensures proper class name resolution for nested directories
120
+ #
121
+ # Directory collapsing means that files in `app/cmds/tasks/` will be loaded
122
+ # as if they were directly in `app/cmds/`, allowing for better organization
123
+ # without affecting class naming conventions.
124
+ #
125
+ # @param app [Rails::Application] the Rails application instance
126
+ # @return [void]
127
+ #
128
+ # @example Directory structure and class loading
129
+ # # File: app/cmds/tasks/process_order_task.rb
130
+ # # Class: ProcessOrderTask (not Tasks::ProcessOrderTask)
131
+ #
132
+ # # File: app/cmds/workflows/order_processing_workflow.rb
133
+ # # Class: OrderProcessingWorkflow (not Workflows::OrderProcessingWorkflow)
134
+ #
135
+ # @example Autoloading in action
136
+ # # Rails will automatically load these classes when referenced:
137
+ # ProcessOrderTask.call(order_id: 123) # Loads from app/cmds/tasks/
138
+ # OrderProcessingWorkflow.call(orders: [...]) # Loads from app/cmds/workflows/
21
139
  initializer("cmdx.configure_rails_auto_load_paths") do |app|
22
140
  app.config.autoload_paths += %w[app/cmds]
141
+
142
+ types = %w[workflows tasks]
23
143
  app.autoloaders.each do |autoloader|
24
- CONCEPTS.each do |concept|
144
+ types.each do |concept|
25
145
  dir = app.root.join("app/cmds/#{concept}")
26
146
  autoloader.collapse(dir)
27
147
  end