redress 0.4.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.
- checksums.yaml +4 -4
- data/README.md +19 -23
- data/lib/redress/command.rb +18 -7
- data/lib/redress/form.rb +3 -10
- data/lib/redress/hooks/active_model.rb +21 -0
- data/lib/redress/identity.rb +1 -1
- data/lib/redress/types.rb +4 -0
- data/lib/redress/utils/model_name_string.rb +39 -0
- data/lib/redress.rb +5 -0
- metadata +76 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5428edcfea11f2b2ee5b5c46aadb3aae63ce35dade3cd6a208d1a38700c26b39
|
4
|
+
data.tar.gz: 54655c9cd0ead71f5283ede04efcf58e6cb2f8817202c297d37310c627258531
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bf394b4eaa4307db11cf8004dd5e045e6893c149cbaddf9e5baea1cb9c0e904e8702786ed78aac5fc2d111a91eb0887fb7333b9f3afe2a503169bd28464ace2
|
7
|
+
data.tar.gz: 0f80ac598c7da343a815f57279ca887d4a94aac2343717eb7cd5f3e6255e3f82f3b284b61ef5602e5f50ade520c41e0ac0eabfe5fa36ddec3d8230b8c3b27d03
|
data/README.md
CHANGED
@@ -32,6 +32,11 @@ The command pattern is sometimes called a service object, an operation, an actio
|
|
32
32
|
1. wisper
|
33
33
|
2. dry-struct
|
34
34
|
3. hashie
|
35
|
+
|
36
|
+
### Optional
|
37
|
+
|
38
|
+
To support validations just add activemodel to your project
|
39
|
+
|
35
40
|
4. activemodel
|
36
41
|
|
37
42
|
## Setup
|
@@ -63,12 +68,12 @@ class SimpleForm < ApplicationForm
|
|
63
68
|
mimic :user
|
64
69
|
|
65
70
|
define_schema do
|
66
|
-
attribute :nickname, Redress::Types::Strict::String.default(
|
67
|
-
attribute :name,
|
68
|
-
attribute :email,
|
71
|
+
attribute :nickname, Redress::Types::Strict::String.default('superman')
|
72
|
+
attribute :name, Redress::Types::StrippedString
|
73
|
+
attribute :email, Redress::Types::StrippedString
|
69
74
|
attribute :name_with_email, String
|
70
75
|
attribute :age, Redress::Types::Coercible::Integer
|
71
|
-
|
76
|
+
attribute :terms_of_service, Redress::Types::Bool
|
72
77
|
end
|
73
78
|
|
74
79
|
validates :name, presence: true
|
@@ -145,20 +150,7 @@ CommentForm.new(content: 'Hi').with_context(order: order)
|
|
145
150
|
# app/commands/application_command.rb
|
146
151
|
require 'redress/command'
|
147
152
|
|
148
|
-
class ApplicationCommand < Redress::
|
149
|
-
end
|
150
|
-
```
|
151
|
-
|
152
|
-
Or if you are using ActiveRecord:
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
# app/commands/application_command.rb
|
156
|
-
require 'redress/command'
|
157
|
-
|
158
|
-
class ApplicationCommand < Redress::Commad
|
159
|
-
def transaction(&block)
|
160
|
-
ActiveRecord::Base.transaction(&block) if block_given?
|
161
|
-
end
|
153
|
+
class ApplicationCommand < Redress::Command
|
162
154
|
end
|
163
155
|
```
|
164
156
|
|
@@ -173,11 +165,15 @@ module Users
|
|
173
165
|
end
|
174
166
|
|
175
167
|
def call
|
176
|
-
return
|
168
|
+
return Failure(@form) if @form.invalid?
|
177
169
|
|
178
|
-
user = User.
|
170
|
+
user = User.new(@form.attributes)
|
179
171
|
|
180
|
-
|
172
|
+
if user.save
|
173
|
+
Success(user)
|
174
|
+
else
|
175
|
+
Failure(user)
|
176
|
+
end
|
181
177
|
end
|
182
178
|
end
|
183
179
|
end
|
@@ -198,8 +194,8 @@ class UsersController < Account::BaseController
|
|
198
194
|
@user_form = SimpleForm.from_params(params)
|
199
195
|
|
200
196
|
Users::CreateCommand.call(@user_form) do |c|
|
201
|
-
c.
|
202
|
-
c.
|
197
|
+
c.success { head status: 201 }
|
198
|
+
c.failure { |form| render status: 422, json: { errors: form.errors } }
|
203
199
|
end
|
204
200
|
end
|
205
201
|
end
|
data/lib/redress/command.rb
CHANGED
@@ -1,21 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'dry/monads'
|
4
|
+
require 'dry/monads/do'
|
5
|
+
require 'dry/matcher/result_matcher'
|
4
6
|
|
5
7
|
module Redress
|
6
8
|
class Command
|
7
|
-
include
|
9
|
+
include Dry::Monads[:result]
|
8
10
|
|
9
11
|
def self.call(*args, &block)
|
10
|
-
|
11
|
-
|
12
|
+
result = new(*args).call
|
13
|
+
return result unless block_given?
|
14
|
+
|
15
|
+
Dry::Matcher::ResultMatcher.call(result, &block)
|
12
16
|
end
|
13
17
|
|
14
|
-
def self.run(*args)
|
18
|
+
def self.run(*args, &block)
|
15
19
|
command = new(*args)
|
16
|
-
|
17
|
-
command
|
20
|
+
result = command.call
|
21
|
+
return command unless block_given?
|
22
|
+
|
23
|
+
Dry::Matcher::ResultMatcher.call(result, &block)
|
24
|
+
|
18
25
|
command
|
19
26
|
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
20
31
|
end
|
21
32
|
end
|
data/lib/redress/form.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'hashie/mash'
|
4
|
-
require 'active_model'
|
5
4
|
require 'dry-struct'
|
6
5
|
|
7
6
|
require 'redress/utils/parse_attributes_from_params'
|
8
7
|
require 'redress/utils/build_form_from_model'
|
9
8
|
require 'redress/utils/attributes_hash'
|
9
|
+
require 'redress/utils/model_name_string'
|
10
10
|
|
11
11
|
module Redress
|
12
12
|
class Form < Dry::Struct
|
13
|
-
include ActiveModel::Validations
|
14
|
-
include ActiveModel::Conversion
|
15
|
-
|
16
13
|
DEFAULT_NAME = 'Form'
|
17
14
|
SPLITTER = '::'
|
18
15
|
|
@@ -21,12 +18,8 @@ module Redress
|
|
21
18
|
transform_keys(&:to_sym)
|
22
19
|
transform_types(&:omittable)
|
23
20
|
|
24
|
-
def self.model_name
|
25
|
-
ActiveModel::Name.new(self, nil, mimicked_model_name.to_s.camelize)
|
26
|
-
end
|
27
|
-
|
28
21
|
def self.mimic(model_name)
|
29
|
-
@model_name = model_name.
|
22
|
+
@model_name = Redress::Utils::ModelNameString.new(model_name).to_sym
|
30
23
|
end
|
31
24
|
|
32
25
|
def self.mimicked_model_name
|
@@ -37,7 +30,7 @@ module Redress
|
|
37
30
|
class_name = name.split(SPLITTER).last
|
38
31
|
return :form if class_name == DEFAULT_NAME
|
39
32
|
|
40
|
-
class_name.chomp(DEFAULT_NAME).
|
33
|
+
Redress::Utils::ModelNameString.new(class_name.chomp(DEFAULT_NAME)).to_sym
|
41
34
|
end
|
42
35
|
|
43
36
|
def self.from_params(params, options = nil)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
|
5
|
+
module Redress
|
6
|
+
module Hooks
|
7
|
+
module ActiveModel
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
base.include(::ActiveModel::Validations)
|
11
|
+
base.include(::ActiveModel::Conversion)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def model_name
|
16
|
+
::ActiveModel::Name.new(self, nil, mimicked_model_name.to_s.camelize)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/redress/identity.rb
CHANGED
data/lib/redress/types.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Redress
|
4
|
+
module Utils
|
5
|
+
class ModelNameString
|
6
|
+
attr_reader :original
|
7
|
+
|
8
|
+
def initialize(original)
|
9
|
+
@original = original.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_sym
|
13
|
+
underscore_original.to_sym
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def underscore_original
|
19
|
+
if original.respond_to?(:underscore)
|
20
|
+
original.underscore
|
21
|
+
else
|
22
|
+
underscore(original)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# File activesupport/lib/active_support/inflector/methods.rb, line 92
|
27
|
+
def underscore(camel_cased_word)
|
28
|
+
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
29
|
+
|
30
|
+
word = camel_cased_word.to_s.gsub('::', '/')
|
31
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
32
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
33
|
+
word.tr!('-', '_')
|
34
|
+
word.downcase!
|
35
|
+
word
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/redress.rb
CHANGED
metadata
CHANGED
@@ -1,225 +1,239 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redress
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Galeta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: dry-matcher
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-
|
28
|
+
name: dry-monads
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.4.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.4.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: dry-
|
42
|
+
name: dry-struct
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.4.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.4.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: dry-types
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.5.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.5.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: hashie
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: actionpack
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: '6.1'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: '6.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activemodel
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 4.2.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 4.2.0
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: coveralls
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- - "
|
115
|
+
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0
|
117
|
+
version: '0'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- - "
|
122
|
+
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: guard-rspec
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- - "
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
131
|
+
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- - "
|
136
|
+
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: pry
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
|
-
- - "
|
143
|
+
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0
|
145
|
+
version: '0'
|
132
146
|
type: :development
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
|
-
- - "
|
150
|
+
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0
|
152
|
+
version: '0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: pry-byebug
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
|
-
- - "
|
157
|
+
- - ">="
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
159
|
+
version: '0'
|
146
160
|
type: :development
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- - "
|
164
|
+
- - ">="
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
166
|
+
version: '0'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: pry-state
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
|
-
- - "
|
171
|
+
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: '0
|
173
|
+
version: '0'
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
|
-
- - "
|
178
|
+
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '0
|
180
|
+
version: '0'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: rake
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
|
-
- - "
|
185
|
+
- - ">="
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
187
|
+
version: '0'
|
174
188
|
type: :development
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
|
-
- - "
|
192
|
+
- - ">="
|
179
193
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
194
|
+
version: '0'
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: reek
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
184
198
|
requirements:
|
185
|
-
- - "
|
199
|
+
- - ">="
|
186
200
|
- !ruby/object:Gem::Version
|
187
|
-
version: '
|
201
|
+
version: '0'
|
188
202
|
type: :development
|
189
203
|
prerelease: false
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
|
-
- - "
|
206
|
+
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
|
-
version: '
|
208
|
+
version: '0'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
210
|
name: rspec
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
198
212
|
requirements:
|
199
|
-
- - "
|
213
|
+
- - ">="
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: '
|
215
|
+
version: '0'
|
202
216
|
type: :development
|
203
217
|
prerelease: false
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
205
219
|
requirements:
|
206
|
-
- - "
|
220
|
+
- - ">="
|
207
221
|
- !ruby/object:Gem::Version
|
208
|
-
version: '
|
222
|
+
version: '0'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: rubocop
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
|
-
- - "
|
227
|
+
- - ">="
|
214
228
|
- !ruby/object:Gem::Version
|
215
|
-
version: '0
|
229
|
+
version: '0'
|
216
230
|
type: :development
|
217
231
|
prerelease: false
|
218
232
|
version_requirements: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
|
-
- - "
|
234
|
+
- - ">="
|
221
235
|
- !ruby/object:Gem::Version
|
222
|
-
version: '0
|
236
|
+
version: '0'
|
223
237
|
description:
|
224
238
|
email:
|
225
239
|
- galeta.igor@gmail.com
|
@@ -234,10 +248,12 @@ files:
|
|
234
248
|
- lib/redress.rb
|
235
249
|
- lib/redress/command.rb
|
236
250
|
- lib/redress/form.rb
|
251
|
+
- lib/redress/hooks/active_model.rb
|
237
252
|
- lib/redress/identity.rb
|
238
253
|
- lib/redress/types.rb
|
239
254
|
- lib/redress/utils/attributes_hash.rb
|
240
255
|
- lib/redress/utils/build_form_from_model.rb
|
256
|
+
- lib/redress/utils/model_name_string.rb
|
241
257
|
- lib/redress/utils/parse_attributes_from_params.rb
|
242
258
|
homepage: https://github.com/galetahub/redress
|
243
259
|
licenses:
|
@@ -249,16 +265,16 @@ require_paths:
|
|
249
265
|
- lib
|
250
266
|
required_ruby_version: !ruby/object:Gem::Requirement
|
251
267
|
requirements:
|
252
|
-
- - "
|
268
|
+
- - ">="
|
253
269
|
- !ruby/object:Gem::Version
|
254
|
-
version:
|
270
|
+
version: 2.1.0
|
255
271
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
272
|
requirements:
|
257
273
|
- - ">="
|
258
274
|
- !ruby/object:Gem::Version
|
259
275
|
version: '0'
|
260
276
|
requirements: []
|
261
|
-
rubygems_version: 3.
|
277
|
+
rubygems_version: 3.2.26
|
262
278
|
signing_key:
|
263
279
|
specification_version: 4
|
264
280
|
summary: Build maintainable Ruby apps
|