light-services 2.2.1 โ 3.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.
- checksums.yaml +4 -4
- data/.github/config/rubocop_linter_action.yml +4 -4
- data/.github/workflows/ci.yml +12 -12
- data/.gitignore +1 -0
- data/.rubocop.yml +77 -7
- data/CHANGELOG.md +23 -0
- data/CLAUDE.md +139 -0
- data/Gemfile +16 -11
- data/Gemfile.lock +53 -27
- data/README.md +76 -13
- data/docs/arguments.md +267 -0
- data/docs/best-practices.md +153 -0
- data/docs/callbacks.md +476 -0
- data/docs/concepts.md +80 -0
- data/docs/configuration.md +168 -0
- data/docs/context.md +128 -0
- data/docs/crud.md +525 -0
- data/docs/errors.md +250 -0
- data/docs/generators.md +250 -0
- data/docs/outputs.md +135 -0
- data/docs/pundit-authorization.md +320 -0
- data/docs/quickstart.md +134 -0
- data/docs/readme.md +100 -0
- data/docs/recipes.md +14 -0
- data/docs/service-rendering.md +222 -0
- data/docs/steps.md +337 -0
- data/docs/summary.md +19 -0
- data/docs/testing.md +549 -0
- data/lib/generators/light_services/install/USAGE +15 -0
- data/lib/generators/light_services/install/install_generator.rb +41 -0
- data/lib/generators/light_services/install/templates/application_service.rb.tt +8 -0
- data/lib/generators/light_services/install/templates/application_service_spec.rb.tt +7 -0
- data/lib/generators/light_services/install/templates/initializer.rb.tt +30 -0
- data/lib/generators/light_services/service/USAGE +21 -0
- data/lib/generators/light_services/service/service_generator.rb +68 -0
- data/lib/generators/light_services/service/templates/service.rb.tt +48 -0
- data/lib/generators/light_services/service/templates/service_spec.rb.tt +40 -0
- data/lib/light/services/base.rb +23 -113
- data/lib/light/services/callbacks.rb +103 -0
- data/lib/light/services/collection.rb +97 -0
- data/lib/light/services/concerns/execution.rb +76 -0
- data/lib/light/services/concerns/parent_service.rb +34 -0
- data/lib/light/services/concerns/state_management.rb +30 -0
- data/lib/light/services/config.rb +4 -18
- data/lib/light/services/constants.rb +97 -0
- data/lib/light/services/dsl/arguments_dsl.rb +84 -0
- data/lib/light/services/dsl/outputs_dsl.rb +80 -0
- data/lib/light/services/dsl/steps_dsl.rb +205 -0
- data/lib/light/services/dsl/validation.rb +132 -0
- data/lib/light/services/exceptions.rb +7 -2
- data/lib/light/services/messages.rb +19 -31
- data/lib/light/services/rspec/matchers/define_argument.rb +174 -0
- data/lib/light/services/rspec/matchers/define_output.rb +147 -0
- data/lib/light/services/rspec/matchers/define_step.rb +225 -0
- data/lib/light/services/rspec/matchers/execute_step.rb +230 -0
- data/lib/light/services/rspec/matchers/have_error_on.rb +148 -0
- data/lib/light/services/rspec/matchers/have_warning_on.rb +148 -0
- data/lib/light/services/rspec/matchers/trigger_callback.rb +138 -0
- data/lib/light/services/rspec.rb +15 -0
- data/lib/light/services/settings/field.rb +86 -0
- data/lib/light/services/settings/step.rb +31 -16
- data/lib/light/services/utils.rb +38 -0
- data/lib/light/services/version.rb +1 -1
- data/lib/light/services.rb +2 -0
- data/light-services.gemspec +6 -8
- metadata +54 -26
- data/lib/light/services/class_based_collection/base.rb +0 -86
- data/lib/light/services/class_based_collection/mount.rb +0 -33
- data/lib/light/services/collection/arguments.rb +0 -34
- data/lib/light/services/collection/base.rb +0 -59
- data/lib/light/services/collection/outputs.rb +0 -16
- data/lib/light/services/settings/argument.rb +0 -68
- data/lib/light/services/settings/output.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a45a0a0ba2e870c7188f55865004d697646da536e3cecb05b9b0eb30fda9651d
|
|
4
|
+
data.tar.gz: 4ad5df86f1a1ff129ac85f3f2ed1ecda11466d52c8639fbbfda410951e8dc8c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75bbc704971352293401dfcfaf0191aceb3d19ebfd150ce4db1aac0140b4044ee65942ff205484379a7169342298a7164fb76f1fbbf1907d3bb33d99485d1b03
|
|
7
|
+
data.tar.gz: 231a847015fcabfa0373693c0f13ac31d2ea2d636aae355b5ec023838efd3a15ae0b4baba0d7604f3c8980272419078268d155cd9d5b4ca7ca9e22f976667c62
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
versions:
|
|
2
|
-
- rubocop: "1.
|
|
3
|
-
- rubocop-performance: "1.
|
|
4
|
-
- rubocop-rake: "0.
|
|
5
|
-
- rubocop-rspec: "
|
|
2
|
+
- rubocop: "1.81.7"
|
|
3
|
+
- rubocop-performance: "1.26.1"
|
|
4
|
+
- rubocop-rake: "0.7.1"
|
|
5
|
+
- rubocop-rspec: "3.8.0"
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -2,24 +2,24 @@ name: CI
|
|
|
2
2
|
on: push
|
|
3
3
|
|
|
4
4
|
jobs:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
rubocop:
|
|
6
|
+
name: Rubocop
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- name: Git Checkout
|
|
10
|
+
uses: actions/checkout@v2
|
|
11
|
+
|
|
12
|
+
- name: Rubocop
|
|
13
|
+
uses: andrewmcodes/rubocop-linter-action@v3.2.0
|
|
14
|
+
env:
|
|
15
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
16
16
|
|
|
17
17
|
rspec:
|
|
18
18
|
name: RSpec
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
strategy:
|
|
21
21
|
matrix:
|
|
22
|
-
ruby: [3.
|
|
22
|
+
ruby: [3.2, 3.3, 3.4, head, debug]
|
|
23
23
|
steps:
|
|
24
24
|
- name: Git Checkout
|
|
25
25
|
uses: actions/checkout@v2
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,34 +1,104 @@
|
|
|
1
|
-
|
|
1
|
+
plugins:
|
|
2
2
|
- rubocop-rake
|
|
3
3
|
- rubocop-rspec
|
|
4
4
|
- rubocop-performance
|
|
5
5
|
|
|
6
6
|
AllCops:
|
|
7
|
+
DisplayCopNames: true
|
|
8
|
+
DisplayStyleGuide: true
|
|
7
9
|
NewCops: enable
|
|
10
|
+
TargetRubyVersion: 3
|
|
11
|
+
|
|
12
|
+
Layout/FirstArrayElementIndentation:
|
|
13
|
+
EnforcedStyle: consistent
|
|
14
|
+
|
|
15
|
+
Layout/FirstHashElementIndentation:
|
|
16
|
+
EnforcedStyle: consistent
|
|
8
17
|
|
|
9
18
|
Layout/MultilineMethodCallIndentation:
|
|
10
19
|
EnforcedStyle: indented
|
|
11
20
|
|
|
21
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
|
22
|
+
EnforcedStyle: no_space
|
|
23
|
+
|
|
24
|
+
Lint/EmptyFile:
|
|
25
|
+
Enabled: true
|
|
26
|
+
|
|
27
|
+
Metrics/AbcSize:
|
|
28
|
+
Exclude:
|
|
29
|
+
- lib/light/services/dsl/steps_dsl.rb
|
|
30
|
+
- lib/light/services/messages.rb
|
|
31
|
+
Max: 20
|
|
32
|
+
|
|
12
33
|
Metrics/BlockLength:
|
|
13
34
|
Exclude:
|
|
14
35
|
- spec/**/*_spec.rb
|
|
15
36
|
|
|
37
|
+
Metrics/ClassLength:
|
|
38
|
+
Max: 150
|
|
39
|
+
|
|
40
|
+
Metrics/CyclomaticComplexity:
|
|
41
|
+
Max: 10
|
|
42
|
+
|
|
43
|
+
Metrics/MethodLength:
|
|
44
|
+
Max: 20
|
|
45
|
+
|
|
46
|
+
Metrics/PerceivedComplexity:
|
|
47
|
+
Max: 10
|
|
48
|
+
|
|
49
|
+
Naming/PredicatePrefix:
|
|
50
|
+
Enabled: false
|
|
51
|
+
|
|
52
|
+
RSpec/ExampleLength:
|
|
53
|
+
Max: 20
|
|
54
|
+
|
|
55
|
+
RSpec/MultipleDescribes:
|
|
56
|
+
Enabled: false
|
|
57
|
+
|
|
58
|
+
RSpec/MultipleExpectations:
|
|
59
|
+
Max: 10
|
|
60
|
+
|
|
61
|
+
RSpec/NestedGroups:
|
|
62
|
+
Max: 5
|
|
63
|
+
|
|
16
64
|
Security/Eval:
|
|
17
65
|
Exclude:
|
|
18
66
|
- spec/light/services/error_spec.rb
|
|
19
67
|
|
|
20
|
-
Style/
|
|
21
|
-
|
|
68
|
+
Style/ClassAndModuleChildren:
|
|
69
|
+
Exclude:
|
|
70
|
+
- spec/data/services/**/*.rb
|
|
22
71
|
|
|
23
72
|
Style/ClassVars:
|
|
24
73
|
Enabled: false
|
|
25
74
|
|
|
26
|
-
Style/
|
|
27
|
-
|
|
75
|
+
Style/ConditionalAssignment:
|
|
76
|
+
Enabled: false
|
|
77
|
+
|
|
78
|
+
Style/Documentation:
|
|
79
|
+
Enabled: false
|
|
28
80
|
|
|
29
81
|
Style/GuardClause:
|
|
30
82
|
Enabled: false
|
|
31
83
|
|
|
32
|
-
Style/
|
|
84
|
+
Style/OptionalBooleanParameter:
|
|
33
85
|
Exclude:
|
|
34
|
-
-
|
|
86
|
+
- lib/light/services/rspec/matchers/**/*.rb
|
|
87
|
+
|
|
88
|
+
Style/StringLiterals:
|
|
89
|
+
EnforcedStyle: double_quotes
|
|
90
|
+
|
|
91
|
+
Style/SymbolArray:
|
|
92
|
+
EnforcedStyle: brackets
|
|
93
|
+
|
|
94
|
+
Style/TrailingCommaInArguments:
|
|
95
|
+
EnforcedStyleForMultiline: diff_comma
|
|
96
|
+
|
|
97
|
+
Style/TrailingCommaInArrayLiteral:
|
|
98
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
99
|
+
|
|
100
|
+
Style/TrailingCommaInHashLiteral:
|
|
101
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
102
|
+
|
|
103
|
+
Style/WordArray:
|
|
104
|
+
EnforcedStyle: brackets
|
data/CHANGELOG.md
CHANGED
|
@@ -1 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
|
|
3
|
+
## 3.0.0 (2025-12-12)
|
|
4
|
+
|
|
5
|
+
### Breaking changes
|
|
6
|
+
|
|
7
|
+
- Removed support for symbol types (e.g., `:array`, `:hash`, `:boolean`). Use Ruby classes (e.g., `Array`, `Hash`, `[TrueClass, FalseClass]`) or dry-types
|
|
8
|
+
- Removed `benchmark: true` option
|
|
9
|
+
- Removed `verbose: true` option
|
|
10
|
+
- Bumped minimum supported Ruby version to **3.0**.
|
|
11
|
+
- Removed `errors.copy_to`
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Output type validation
|
|
16
|
+
- dry-types support for arguments and outputs (with coercion and constraints)
|
|
17
|
+
- Callback system (service + step callbacks)
|
|
18
|
+
- Built-in RSpec matchers for services
|
|
19
|
+
- Name validation for arguments, steps, and outputs
|
|
20
|
+
- `run` method fallback when no steps are defined
|
|
21
|
+
|
|
22
|
+
### Documentation
|
|
23
|
+
|
|
24
|
+
- Documentation moved into this repository and refreshed to match v3 behavior
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## About Light Services
|
|
6
|
+
|
|
7
|
+
Light Services is a Ruby gem providing a service architecture pattern for organizing business logic. Services are defined as classes with `arguments`, `steps`, and `outputs`, featuring transactions, inheritance, error handling, and context sharing.
|
|
8
|
+
|
|
9
|
+
## Development Commands
|
|
10
|
+
|
|
11
|
+
### Testing
|
|
12
|
+
```bash
|
|
13
|
+
# Run all tests
|
|
14
|
+
bundle exec rspec
|
|
15
|
+
|
|
16
|
+
# Run specific test file
|
|
17
|
+
bundle exec rspec spec/path/to/file_spec.rb
|
|
18
|
+
|
|
19
|
+
# Run with coverage (uses SimpleCov)
|
|
20
|
+
bundle exec rspec
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Linting
|
|
24
|
+
```bash
|
|
25
|
+
# Run RuboCop linter
|
|
26
|
+
bundle exec rubocop
|
|
27
|
+
|
|
28
|
+
# Auto-fix RuboCop issues
|
|
29
|
+
bundle exec rubocop -a
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Build and Release
|
|
33
|
+
```bash
|
|
34
|
+
# Build gem
|
|
35
|
+
bundle exec rake build
|
|
36
|
+
|
|
37
|
+
# Default task (runs tests)
|
|
38
|
+
bundle exec rake
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Architecture
|
|
42
|
+
|
|
43
|
+
### Core Components
|
|
44
|
+
|
|
45
|
+
1. **Base Service (`lib/light/services/base.rb:15`)**
|
|
46
|
+
- Main service class that all services inherit from
|
|
47
|
+
- Handles service lifecycle: initialization, execution, callbacks, error management
|
|
48
|
+
- Provides DSL for defining arguments, steps, and outputs
|
|
49
|
+
- Manages transactions and error propagation to parent services
|
|
50
|
+
|
|
51
|
+
2. **Callbacks System (`lib/light/services/callbacks.rb:5`)**
|
|
52
|
+
- Supports service and step-level callbacks
|
|
53
|
+
- Events: `before_service_run`, `after_service_run`, `around_service_run`, `on_service_success`, `on_service_failure`
|
|
54
|
+
- Step events: `before_step_run`, `after_step_run`, `around_step_run`, `on_step_success`, `on_step_failure`
|
|
55
|
+
|
|
56
|
+
3. **Settings**
|
|
57
|
+
- **Step (`lib/light/services/settings/step.rb:7`)**: Handles step execution with conditional logic (`if`, `unless`, `always`)
|
|
58
|
+
- **Field (`lib/light/services/settings/field.rb`)**: Manages argument and output validation and type checking
|
|
59
|
+
|
|
60
|
+
4. **Messages System (`lib/light/services/messages.rb`)**
|
|
61
|
+
- Collects errors and warnings with options for breaking, raising, or rolling back
|
|
62
|
+
- Supports copying messages between parent and child services
|
|
63
|
+
|
|
64
|
+
5. **Collection (`lib/light/services/collection.rb`)**
|
|
65
|
+
- Manages arguments and outputs as collections with validation and defaults
|
|
66
|
+
- Supports dry-types for advanced type validation and coercion
|
|
67
|
+
|
|
68
|
+
### Service DSL
|
|
69
|
+
|
|
70
|
+
Services use a declarative DSL:
|
|
71
|
+
```ruby
|
|
72
|
+
class ExampleService < Light::Services::Base
|
|
73
|
+
# Define input arguments
|
|
74
|
+
arg :name, type: String
|
|
75
|
+
arg :age, type: Integer, optional: true, default: 25
|
|
76
|
+
|
|
77
|
+
# Define execution steps
|
|
78
|
+
step :validate_input
|
|
79
|
+
step :process_data, if: :should_process?
|
|
80
|
+
step :cleanup, always: true
|
|
81
|
+
|
|
82
|
+
# Define outputs
|
|
83
|
+
output :result, type: Hash
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def validate_input
|
|
88
|
+
errors.add(:name, "required") if name.nil? || name.strip.empty?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def process_data
|
|
92
|
+
self.result = { name: name, age: age }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def cleanup
|
|
96
|
+
# Runs regardless of errors/warnings, unless done! was called
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def should_process?
|
|
100
|
+
!(name.nil? || name.strip.empty?)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Service Execution
|
|
106
|
+
|
|
107
|
+
- Services can be run with `.run(args)` or `.run!(args)` (raises on error)
|
|
108
|
+
- Use `.with(service_or_context)` to chain services with shared context
|
|
109
|
+
- Transactions automatically rollback on errors when `use_transactions: true`
|
|
110
|
+
- Steps run sequentially, stopping on errors unless `always: true`
|
|
111
|
+
|
|
112
|
+
### Error Handling
|
|
113
|
+
|
|
114
|
+
- Errors collected in `@errors` message collection
|
|
115
|
+
- Supports `break_on_error`, `raise_on_error`, `rollback_on_error` configuration
|
|
116
|
+
- Warnings work similarly with `@warnings` collection
|
|
117
|
+
- Parent services can inherit child errors/warnings based on configuration
|
|
118
|
+
|
|
119
|
+
### Testing Patterns
|
|
120
|
+
|
|
121
|
+
- Services are tested using RSpec with database transactions
|
|
122
|
+
- Use `DatabaseCleaner` for test isolation
|
|
123
|
+
- Mock database models and external dependencies
|
|
124
|
+
- Test both success and failure scenarios
|
|
125
|
+
- Validate arguments, outputs, and error conditions
|
|
126
|
+
|
|
127
|
+
## Configuration
|
|
128
|
+
|
|
129
|
+
### RuboCop Rules
|
|
130
|
+
- Target Ruby version: 2.7+
|
|
131
|
+
- Method length max: 20 lines
|
|
132
|
+
- Uses double quotes for strings
|
|
133
|
+
- Enables trailing commas for multiline structures
|
|
134
|
+
- Disables documentation requirements and guard clauses
|
|
135
|
+
|
|
136
|
+
### Database Support
|
|
137
|
+
- Optional ActiveRecord integration for transactions
|
|
138
|
+
- Uses SQLite3 for testing
|
|
139
|
+
- Database cleaner ensures test isolation
|
data/Gemfile
CHANGED
|
@@ -5,17 +5,22 @@ source "https://rubygems.org"
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
group :test do
|
|
8
|
-
|
|
9
|
-
gem "
|
|
10
|
-
gem "sqlite3", "~> 2.8"
|
|
8
|
+
# Optional type system support
|
|
9
|
+
gem "dry-types", "~> 1.0"
|
|
11
10
|
|
|
12
|
-
gem "
|
|
13
|
-
gem "
|
|
14
|
-
gem "
|
|
15
|
-
gem "
|
|
11
|
+
gem "activerecord", "< 8"
|
|
12
|
+
gem "connection_pool", "< 3"
|
|
13
|
+
gem "database_cleaner-active_record"
|
|
14
|
+
gem "sqlite3"
|
|
16
15
|
|
|
17
|
-
gem "
|
|
18
|
-
gem "
|
|
19
|
-
gem "
|
|
20
|
-
gem "
|
|
16
|
+
gem "codecov"
|
|
17
|
+
gem "rake"
|
|
18
|
+
gem "rspec"
|
|
19
|
+
gem "rspec-benchmark"
|
|
20
|
+
gem "simplecov"
|
|
21
|
+
|
|
22
|
+
gem "rubocop"
|
|
23
|
+
gem "rubocop-performance"
|
|
24
|
+
gem "rubocop-rake"
|
|
25
|
+
gem "rubocop-rspec"
|
|
21
26
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
light-services (
|
|
5
|
-
benchmark (>= 0.5)
|
|
4
|
+
light-services (3.0.0)
|
|
6
5
|
|
|
7
6
|
GEM
|
|
8
7
|
remote: https://rubygems.org/
|
|
9
8
|
specs:
|
|
10
|
-
activemodel (
|
|
11
|
-
activesupport (=
|
|
12
|
-
activerecord (
|
|
13
|
-
activemodel (=
|
|
14
|
-
activesupport (=
|
|
9
|
+
activemodel (7.2.3)
|
|
10
|
+
activesupport (= 7.2.3)
|
|
11
|
+
activerecord (7.2.3)
|
|
12
|
+
activemodel (= 7.2.3)
|
|
13
|
+
activesupport (= 7.2.3)
|
|
15
14
|
timeout (>= 0.4.0)
|
|
16
|
-
activesupport (
|
|
15
|
+
activesupport (7.2.3)
|
|
17
16
|
base64
|
|
17
|
+
benchmark (>= 0.3)
|
|
18
18
|
bigdecimal
|
|
19
19
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
20
20
|
connection_pool (>= 2.2.5)
|
|
21
21
|
drb
|
|
22
22
|
i18n (>= 1.6, < 2)
|
|
23
|
-
json
|
|
24
23
|
logger (>= 1.4.2)
|
|
25
24
|
minitest (>= 5.1)
|
|
26
25
|
securerandom (>= 0.3)
|
|
27
26
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
28
|
-
uri (>= 0.13.1)
|
|
29
27
|
ast (2.4.3)
|
|
30
28
|
base64 (0.3.0)
|
|
31
29
|
benchmark (0.5.0)
|
|
30
|
+
benchmark-malloc (0.2.0)
|
|
31
|
+
benchmark-perf (0.6.0)
|
|
32
|
+
benchmark-trend (0.4.0)
|
|
32
33
|
bigdecimal (3.3.1)
|
|
33
34
|
codecov (0.6.0)
|
|
34
35
|
simplecov (>= 0.15, < 0.22)
|
|
35
36
|
concurrent-ruby (1.3.5)
|
|
36
|
-
connection_pool (2.5.
|
|
37
|
+
connection_pool (2.5.5)
|
|
37
38
|
database_cleaner-active_record (2.2.2)
|
|
38
39
|
activerecord (>= 5.a)
|
|
39
40
|
database_cleaner-core (~> 2.0)
|
|
@@ -41,14 +42,31 @@ GEM
|
|
|
41
42
|
diff-lcs (1.6.2)
|
|
42
43
|
docile (1.4.1)
|
|
43
44
|
drb (2.2.3)
|
|
45
|
+
dry-core (1.1.0)
|
|
46
|
+
concurrent-ruby (~> 1.0)
|
|
47
|
+
logger
|
|
48
|
+
zeitwerk (~> 2.6)
|
|
49
|
+
dry-inflector (1.2.0)
|
|
50
|
+
dry-logic (1.6.0)
|
|
51
|
+
bigdecimal
|
|
52
|
+
concurrent-ruby (~> 1.0)
|
|
53
|
+
dry-core (~> 1.1)
|
|
54
|
+
zeitwerk (~> 2.6)
|
|
55
|
+
dry-types (1.8.3)
|
|
56
|
+
bigdecimal (~> 3.0)
|
|
57
|
+
concurrent-ruby (~> 1.0)
|
|
58
|
+
dry-core (~> 1.0)
|
|
59
|
+
dry-inflector (~> 1.0)
|
|
60
|
+
dry-logic (~> 1.4)
|
|
61
|
+
zeitwerk (~> 2.6)
|
|
44
62
|
i18n (1.14.7)
|
|
45
63
|
concurrent-ruby (~> 1.0)
|
|
46
|
-
json (2.
|
|
64
|
+
json (2.18.0)
|
|
47
65
|
language_server-protocol (3.17.0.5)
|
|
48
66
|
lint_roller (1.1.0)
|
|
49
67
|
logger (1.7.0)
|
|
50
68
|
mini_portile2 (2.8.9)
|
|
51
|
-
minitest (5.
|
|
69
|
+
minitest (5.27.0)
|
|
52
70
|
parallel (1.27.0)
|
|
53
71
|
parser (3.3.10.0)
|
|
54
72
|
ast (~> 2.4.1)
|
|
@@ -62,6 +80,11 @@ GEM
|
|
|
62
80
|
rspec-core (~> 3.13.0)
|
|
63
81
|
rspec-expectations (~> 3.13.0)
|
|
64
82
|
rspec-mocks (~> 3.13.0)
|
|
83
|
+
rspec-benchmark (0.6.0)
|
|
84
|
+
benchmark-malloc (~> 0.2)
|
|
85
|
+
benchmark-perf (~> 0.6)
|
|
86
|
+
benchmark-trend (~> 0.4)
|
|
87
|
+
rspec (>= 3.0)
|
|
65
88
|
rspec-core (3.13.6)
|
|
66
89
|
rspec-support (~> 3.13.0)
|
|
67
90
|
rspec-expectations (3.13.5)
|
|
@@ -103,32 +126,35 @@ GEM
|
|
|
103
126
|
simplecov_json_formatter (~> 0.1)
|
|
104
127
|
simplecov-html (0.13.2)
|
|
105
128
|
simplecov_json_formatter (0.1.4)
|
|
106
|
-
sqlite3 (2.8.
|
|
129
|
+
sqlite3 (2.8.1)
|
|
107
130
|
mini_portile2 (~> 2.8.0)
|
|
108
|
-
timeout (0.
|
|
131
|
+
timeout (0.5.0)
|
|
109
132
|
tzinfo (2.0.6)
|
|
110
133
|
concurrent-ruby (~> 1.0)
|
|
111
134
|
unicode-display_width (3.2.0)
|
|
112
135
|
unicode-emoji (~> 4.1)
|
|
113
136
|
unicode-emoji (4.1.0)
|
|
114
|
-
|
|
137
|
+
zeitwerk (2.7.3)
|
|
115
138
|
|
|
116
139
|
PLATFORMS
|
|
117
140
|
ruby
|
|
118
141
|
|
|
119
142
|
DEPENDENCIES
|
|
120
|
-
activerecord (
|
|
121
|
-
codecov
|
|
122
|
-
|
|
143
|
+
activerecord (< 8)
|
|
144
|
+
codecov
|
|
145
|
+
connection_pool (< 3)
|
|
146
|
+
database_cleaner-active_record
|
|
147
|
+
dry-types (~> 1.0)
|
|
123
148
|
light-services!
|
|
124
|
-
rake
|
|
125
|
-
rspec
|
|
126
|
-
|
|
127
|
-
rubocop
|
|
128
|
-
rubocop-
|
|
129
|
-
rubocop-
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
rake
|
|
150
|
+
rspec
|
|
151
|
+
rspec-benchmark
|
|
152
|
+
rubocop
|
|
153
|
+
rubocop-performance
|
|
154
|
+
rubocop-rake
|
|
155
|
+
rubocop-rspec
|
|
156
|
+
simplecov
|
|
157
|
+
sqlite3
|
|
132
158
|
|
|
133
159
|
BUNDLED WITH
|
|
134
160
|
2.5.10
|
data/README.md
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
# ๐ Light Services
|
|
2
2
|
|
|
3
|
-
Light Services is a simple yet powerful way to organize
|
|
3
|
+
Light Services is a simple yet powerful way to organize business logic in Ruby applications. Build services that are easy to test, maintain, and understand.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
[](https://codecov.io/gh/light-ruby/light-services)
|
|
7
7
|
|
|
8
|
+
[Get started with Quickstart](https://light-services.kodkod.me/quickstart)
|
|
9
|
+
|
|
8
10
|
## Features
|
|
9
11
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
12
|
+
- โจ **Simple**: Define your service as a class with `arguments`, `steps`, and `outputs`
|
|
13
|
+
- ๐ฆ **No runtime dependencies**: Works stand-alone without requiring external gems at runtime
|
|
14
|
+
- ๐ **Transactions**: Automatically rollback database changes if any step fails
|
|
15
|
+
- ๐งฌ **Inheritance**: Inherit from other services to reuse logic seamlessly
|
|
16
|
+
- โ ๏ธ **Error Handling**: Collect errors from steps and handle them your way
|
|
17
|
+
- ๐ **Context**: Run multiple services sequentially within the same context
|
|
18
|
+
- ๐งช **RSpec Matchers**: Built-in RSpec matchers for expressive service tests
|
|
19
|
+
- ๐ **Framework Agnostic**: Compatible with Rails, Hanami, or any Ruby framework
|
|
20
|
+
- ๐งฉ **Modularity**: Isolate and test your services with ease
|
|
21
|
+
- โ
**100% Test Coverage**: Thoroughly tested and reliable
|
|
22
|
+
- โ๏ธ **Battle-Tested**: In production use since 2017
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
gem "light-services", "~> 3.0"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
rails generate light_services:install
|
|
32
|
+
```
|
|
19
33
|
|
|
20
34
|
## Simple Example
|
|
21
35
|
|
|
@@ -50,8 +64,8 @@ end
|
|
|
50
64
|
class User::ResetPassword < Light::Services::Base
|
|
51
65
|
# Arguments
|
|
52
66
|
arg :user, type: User, optional: true
|
|
53
|
-
arg :email, type:
|
|
54
|
-
arg :send_email, type:
|
|
67
|
+
arg :email, type: String, optional: true
|
|
68
|
+
arg :send_email, type: [TrueClass, FalseClass], default: true
|
|
55
69
|
|
|
56
70
|
# Steps
|
|
57
71
|
step :validate
|
|
@@ -62,7 +76,7 @@ class User::ResetPassword < Light::Services::Base
|
|
|
62
76
|
|
|
63
77
|
# Outputs
|
|
64
78
|
output :user, type: User
|
|
65
|
-
output :reset_token, type:
|
|
79
|
+
output :reset_token, type: String
|
|
66
80
|
|
|
67
81
|
private
|
|
68
82
|
|
|
@@ -96,6 +110,55 @@ class User::ResetPassword < Light::Services::Base
|
|
|
96
110
|
end
|
|
97
111
|
```
|
|
98
112
|
|
|
113
|
+
[Get started with Light Services](https://light-services.kodkod.me/quickstart)
|
|
114
|
+
|
|
115
|
+
## Rails Generators
|
|
116
|
+
|
|
117
|
+
Light Services includes Rails generators to help you quickly set up and create services in your Rails application.
|
|
118
|
+
|
|
119
|
+
### Install Generator
|
|
120
|
+
|
|
121
|
+
Set up Light Services in your Rails application:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
bin/rails generate light_services:install
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This creates:
|
|
128
|
+
- `app/services/application_service.rb` - Base service class for your application
|
|
129
|
+
- `config/initializers/light_services.rb` - Configuration file
|
|
130
|
+
- `spec/services/application_service_spec.rb` - RSpec test file (if RSpec is detected)
|
|
131
|
+
|
|
132
|
+
**Options:**
|
|
133
|
+
- `--skip-initializer` - Skip creating the initializer file
|
|
134
|
+
- `--skip-spec` - Skip creating the spec file
|
|
135
|
+
|
|
136
|
+
### Service Generator
|
|
137
|
+
|
|
138
|
+
Create a new service class:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Basic service
|
|
142
|
+
bin/rails generate light_services:service user/create
|
|
143
|
+
|
|
144
|
+
# Service with predefined structure
|
|
145
|
+
bin/rails generate light_services:service CreateOrder \
|
|
146
|
+
--args=user product \
|
|
147
|
+
--steps=validate process \
|
|
148
|
+
--outputs=order
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This creates:
|
|
152
|
+
- `app/services/user/create.rb` - Service class file
|
|
153
|
+
- `spec/services/user/create_spec.rb` - RSpec test file (if RSpec is detected)
|
|
154
|
+
|
|
155
|
+
**Options:**
|
|
156
|
+
- `--args` - List of arguments for the service (e.g., `--args=user product`)
|
|
157
|
+
- `--steps` - List of steps for the service (e.g., `--steps=validate process`)
|
|
158
|
+
- `--outputs` - List of outputs for the service (e.g., `--outputs=result`)
|
|
159
|
+
- `--skip-spec` - Skip creating the spec file
|
|
160
|
+
- `--parent` - Parent class (default: ApplicationService)
|
|
161
|
+
|
|
99
162
|
## Documentation
|
|
100
163
|
|
|
101
164
|
You can find the full documentation at [light-services.kodkod.me](https://light-services.kodkod.me).
|