has_state_machine 1.0.0 → 1.2.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 +18 -1
- data/lib/has_state_machine/state.rb +24 -10
- data/lib/has_state_machine/version.rb +1 -1
- data/lib/ruby_lsp/has_state_machine/addon.rb +85 -0
- data/lib/ruby_lsp/has_state_machine/definition.rb +190 -0
- data/lib/ruby_lsp/has_state_machine/rails_server_addon.rb +48 -0
- data/lib/ruby_lsp/has_state_machine/workflow_resolver.rb +28 -0
- metadata +137 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4d16c6b958f2e470af9f3120259e802badad7fcd6b8a4ea1d004c84f64e8d09d
|
|
4
|
+
data.tar.gz: 2f9933db38477a1b1020303ab9848aa122fe7e699d153315b830144ffdbfd1a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 35f89aad901be7f976ee42573449c0d7412a633285e41f869f50d7be3215da2752470cf5c4b1299d483605f90b8925f5baa5065729b06f2121678518beeafdb4
|
|
7
|
+
data.tar.gz: cb4e1a772fa2aa9828adfd3ab6bb548e5f489f403f4574cc464e9fa77f4633b886de5c486e4bb9b014eeb71c8ede380fab19320f8b85023e9643b38b3b9866c8
|
data/README.md
CHANGED
|
@@ -96,6 +96,13 @@ module Workflow
|
|
|
96
96
|
# after_transition callbacks as well.
|
|
97
97
|
Rails.logger.info "== Transitioned from #{previous_state} ==\n"
|
|
98
98
|
end
|
|
99
|
+
|
|
100
|
+
# after_transition_commit runs only once the transition has been
|
|
101
|
+
# committed: after the record is saved for normal transitions, and
|
|
102
|
+
# outside the transaction for transactional transitions (see below).
|
|
103
|
+
after_transition_commit do
|
|
104
|
+
MyJob.perform_later(object)
|
|
105
|
+
end
|
|
99
106
|
end
|
|
100
107
|
end
|
|
101
108
|
```
|
|
@@ -206,10 +213,20 @@ module Workflow
|
|
|
206
213
|
rollback_transition unless notified_watchers?
|
|
207
214
|
end
|
|
208
215
|
|
|
216
|
+
after_transition_commit do
|
|
217
|
+
enqueue_external_work
|
|
218
|
+
end
|
|
219
|
+
|
|
209
220
|
private
|
|
210
221
|
|
|
222
|
+
def enqueue_external_work
|
|
223
|
+
# Any work you want to happen only after the transition is committed.
|
|
224
|
+
# Enqueuing a job, calling an external API, sending a webhook, etc.
|
|
225
|
+
end
|
|
226
|
+
|
|
211
227
|
def notified_watchers?
|
|
212
|
-
|
|
228
|
+
# Any dependent work that you want to run that should play a part in determining
|
|
229
|
+
# whether the transition was successful or not and needs to be rolled back.
|
|
213
230
|
end
|
|
214
231
|
end
|
|
215
232
|
end
|
|
@@ -15,6 +15,11 @@ module HasStateMachine
|
|
|
15
15
|
# for use on a HasStateMachine::State instance.
|
|
16
16
|
define_model_callbacks :transition, only: %i[before after]
|
|
17
17
|
|
|
18
|
+
##
|
|
19
|
+
# Defines the after_transition_commit callback. It runs only after a
|
|
20
|
+
# transition has committed.
|
|
21
|
+
define_model_callbacks :transition_commit, only: %i[after]
|
|
22
|
+
|
|
18
23
|
##
|
|
19
24
|
# possible_transitions - Retrieves the next available transitions for a given state.
|
|
20
25
|
# transactional? - Determines whether or not the transition should happen with a transactional block.
|
|
@@ -80,25 +85,34 @@ module HasStateMachine
|
|
|
80
85
|
|
|
81
86
|
##
|
|
82
87
|
# Makes the actual transition from one state to the next and
|
|
83
|
-
# runs the before and after transition callbacks.
|
|
88
|
+
# runs the before and after transition callbacks. The
|
|
89
|
+
# after_transition_commit callbacks run after the update completes
|
|
90
|
+
# and only when it succeeds.
|
|
84
91
|
def perform_transition!
|
|
85
|
-
run_callbacks :
|
|
86
|
-
|
|
92
|
+
run_callbacks :transition_commit do
|
|
93
|
+
run_callbacks :transition do
|
|
94
|
+
object.update("#{object.state_attribute}": state)
|
|
95
|
+
end
|
|
87
96
|
end
|
|
88
97
|
end
|
|
89
98
|
|
|
90
99
|
##
|
|
91
100
|
# Makes the actual transition from one state to the next and
|
|
92
101
|
# runs the before and after transition callbacks in a transaction
|
|
93
|
-
# to allow for roll backs.
|
|
102
|
+
# to allow for roll backs. The after_transition_commit callbacks run
|
|
103
|
+
# outside the transaction and only when it commits (not on rollback).
|
|
94
104
|
def perform_transactional_transition!
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
run_callbacks :transition_commit do
|
|
106
|
+
ActiveRecord::Base.transaction(requires_new: true, joinable: false) do
|
|
107
|
+
run_callbacks :transition do
|
|
108
|
+
rollback_transition unless object.update("#{object.state_attribute}": state)
|
|
109
|
+
end
|
|
98
110
|
end
|
|
99
|
-
end
|
|
100
111
|
|
|
101
|
-
|
|
112
|
+
@previous_state = previous_state
|
|
113
|
+
|
|
114
|
+
object.reload.public_send(object.state_attribute) == state
|
|
115
|
+
end
|
|
102
116
|
end
|
|
103
117
|
|
|
104
118
|
private
|
|
@@ -112,7 +126,7 @@ module HasStateMachine
|
|
|
112
126
|
# it has been transitioned to the new state. Useful in
|
|
113
127
|
# after_transition blocks
|
|
114
128
|
def previous_state
|
|
115
|
-
object.previous_changes[object.state_attribute]&.first
|
|
129
|
+
@previous_state.presence || object.previous_changes[object.state_attribute]&.first
|
|
116
130
|
end
|
|
117
131
|
|
|
118
132
|
def state_instance(desired_state, transient_values)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ruby_lsp/addon"
|
|
4
|
+
|
|
5
|
+
require "has_state_machine/version"
|
|
6
|
+
require_relative "definition"
|
|
7
|
+
|
|
8
|
+
::RubyLsp::Addon.depend_on_ruby_lsp!(">= 0.18.0", "< 1.0") if ::RubyLsp::Addon.respond_to?(:depend_on_ruby_lsp!)
|
|
9
|
+
|
|
10
|
+
module RubyLsp
|
|
11
|
+
module HasStateMachine
|
|
12
|
+
class Addon < ::RubyLsp::Addon
|
|
13
|
+
def activate(global_state, outgoing_queue)
|
|
14
|
+
@global_state = global_state
|
|
15
|
+
@rails_client = register_rails_server_addon(outgoing_queue)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def deactivate
|
|
19
|
+
@global_state = nil
|
|
20
|
+
@rails_client = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def name
|
|
24
|
+
"Has State Machine"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def version
|
|
28
|
+
::HasStateMachine::VERSION
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create_definition_listener(response_builder, uri, node_context, dispatcher)
|
|
32
|
+
Definition.new(
|
|
33
|
+
response_builder,
|
|
34
|
+
uri,
|
|
35
|
+
node_context,
|
|
36
|
+
dispatcher,
|
|
37
|
+
index: @global_state&.index,
|
|
38
|
+
rails_client: @rails_client
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def register_rails_server_addon(outgoing_queue)
|
|
45
|
+
register_rails_runner_client
|
|
46
|
+
rescue => error
|
|
47
|
+
handle_rails_registration_error(outgoing_queue, error)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def register_rails_runner_client
|
|
51
|
+
rails_addon = ::RubyLsp::Addon.get("Ruby LSP Rails", ">= 0") if ::RubyLsp::Addon.respond_to?(:get)
|
|
52
|
+
return unless rails_addon&.respond_to?(:rails_runner_client)
|
|
53
|
+
|
|
54
|
+
client = rails_addon.rails_runner_client
|
|
55
|
+
return unless client.respond_to?(:register_server_addon)
|
|
56
|
+
|
|
57
|
+
client.register_server_addon(File.expand_path("rails_server_addon.rb", __dir__))
|
|
58
|
+
client
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def handle_rails_registration_error(outgoing_queue, error)
|
|
62
|
+
unless addon_not_found?(error)
|
|
63
|
+
log(outgoing_queue, "Has State Machine Ruby LSP Rails integration unavailable: #{error.message}")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def addon_not_found?(error)
|
|
70
|
+
if defined?(::RubyLsp::Addon::AddonNotFoundError)
|
|
71
|
+
return true if error.is_a?(::RubyLsp::Addon::AddonNotFoundError)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
error.class.name&.end_with?("AddonNotFoundError")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def log(outgoing_queue, message)
|
|
78
|
+
return if outgoing_queue.nil? || outgoing_queue.closed?
|
|
79
|
+
return unless defined?(::RubyLsp::Notification)
|
|
80
|
+
|
|
81
|
+
outgoing_queue << ::RubyLsp::Notification.window_log_message(message)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "workflow_resolver"
|
|
4
|
+
|
|
5
|
+
module RubyLsp
|
|
6
|
+
module HasStateMachine
|
|
7
|
+
class Definition
|
|
8
|
+
SERVER_ADDON_NAME = "has_state_machine"
|
|
9
|
+
|
|
10
|
+
def initialize(response_builder, _uri, node_context, dispatcher, index: nil, rails_client: nil)
|
|
11
|
+
@response_builder = response_builder
|
|
12
|
+
@node_context = node_context
|
|
13
|
+
@index = index
|
|
14
|
+
@rails_client = rails_client
|
|
15
|
+
|
|
16
|
+
dispatcher.register(self, :on_call_node_enter)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def on_call_node_enter(node)
|
|
20
|
+
return unless current_target?(node)
|
|
21
|
+
return unless resolved_model_name
|
|
22
|
+
|
|
23
|
+
if object_call?(node)
|
|
24
|
+
push_entries(constant_entries(resolved_model_name))
|
|
25
|
+
elsif object_method_call?(node)
|
|
26
|
+
method_name = message(node)
|
|
27
|
+
entries = method_entries(resolved_model_name, method_name)
|
|
28
|
+
entries = association_entries(resolved_model_name, method_name) if entries.empty?
|
|
29
|
+
|
|
30
|
+
push_entries(entries)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
attr_reader :index, :node_context, :rails_client, :response_builder
|
|
37
|
+
|
|
38
|
+
def current_target?(node)
|
|
39
|
+
target = node_context.node if node_context.respond_to?(:node)
|
|
40
|
+
call_node = node_context.call_node if node_context.respond_to?(:call_node)
|
|
41
|
+
|
|
42
|
+
node.equal?(target) || node.equal?(call_node)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def resolved_model_name
|
|
46
|
+
return @resolved_model_name if defined?(@resolved_model_name)
|
|
47
|
+
return @resolved_model_name = nil unless current_class_name
|
|
48
|
+
|
|
49
|
+
@resolved_model_name = model_name_from_rails(workflow_namespace) || convention_model_name
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def convention_model_name
|
|
53
|
+
return @convention_model_name if defined?(@convention_model_name)
|
|
54
|
+
|
|
55
|
+
@convention_model_name = current_class_name && WorkflowResolver.model_name_for(current_class_name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def workflow_namespace
|
|
59
|
+
return @workflow_namespace if defined?(@workflow_namespace)
|
|
60
|
+
|
|
61
|
+
@workflow_namespace = current_class_name && WorkflowResolver.workflow_namespace_for(current_class_name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def current_class_name
|
|
65
|
+
return @current_class_name if defined?(@current_class_name)
|
|
66
|
+
return @current_class_name = nil unless node_context.respond_to?(:nesting)
|
|
67
|
+
|
|
68
|
+
@current_class_name = class_name_from_nesting(node_context.nesting)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def class_name_from_nesting(nesting)
|
|
72
|
+
parts = nesting.map(&:to_s).reject(&:empty?)
|
|
73
|
+
return if parts.empty?
|
|
74
|
+
|
|
75
|
+
# Nesting entries may already contain "::" (e.g. "Post::Draft").
|
|
76
|
+
parts.join("::").gsub(/:{3,}/, "::")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def model_name_from_rails(workflow_namespace)
|
|
80
|
+
return unless workflow_namespace && rails_client
|
|
81
|
+
|
|
82
|
+
result = rails_client.delegate_request(
|
|
83
|
+
server_addon_name: SERVER_ADDON_NAME,
|
|
84
|
+
request_name: "model_for_workflow_namespace",
|
|
85
|
+
workflow_namespace: workflow_namespace
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
response_name(result)
|
|
89
|
+
rescue
|
|
90
|
+
nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def association_entries(model_name, association_name)
|
|
94
|
+
association_model_name = association_model_name(model_name, association_name)
|
|
95
|
+
return [] unless association_model_name
|
|
96
|
+
|
|
97
|
+
constant_entries(association_model_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def association_model_name(model_name, association_name)
|
|
101
|
+
return unless rails_client&.respond_to?(:association_target)
|
|
102
|
+
|
|
103
|
+
result = rails_client.association_target(model_name: model_name, association_name: association_name)
|
|
104
|
+
response_name(result)
|
|
105
|
+
rescue
|
|
106
|
+
nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def response_name(result)
|
|
110
|
+
return unless result
|
|
111
|
+
|
|
112
|
+
result[:name] || result["name"]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def constant_entries(name)
|
|
116
|
+
return [] unless name && index
|
|
117
|
+
|
|
118
|
+
Array(index[name])
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def method_entries(model_name, method_name)
|
|
122
|
+
return [] unless index && method_name
|
|
123
|
+
|
|
124
|
+
if index.respond_to?(:resolve_method)
|
|
125
|
+
entries = index.resolve_method(method_name, model_name)
|
|
126
|
+
return Array(entries)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
Array(index[method_name]).select { |entry| entry_owner_name(entry) == model_name }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def entry_owner_name(entry)
|
|
133
|
+
owner = entry.owner if entry.respond_to?(:owner)
|
|
134
|
+
owner.name if owner.respond_to?(:name)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def push_entries(entries)
|
|
138
|
+
entries.each do |entry|
|
|
139
|
+
response_builder << location_for(entry)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def location_for(entry)
|
|
144
|
+
return entry unless defined?(::RubyLsp::Interface::Location)
|
|
145
|
+
|
|
146
|
+
location = entry_location(entry)
|
|
147
|
+
return entry unless location
|
|
148
|
+
|
|
149
|
+
::RubyLsp::Interface::Location.new(
|
|
150
|
+
uri: entry.uri.to_s,
|
|
151
|
+
range: range_for(location)
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def entry_location(entry)
|
|
156
|
+
return entry.location if entry.respond_to?(:location)
|
|
157
|
+
entry.name_location if entry.respond_to?(:name_location)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def range_for(location)
|
|
161
|
+
::RubyLsp::Interface::Range.new(
|
|
162
|
+
start: ::RubyLsp::Interface::Position.new(
|
|
163
|
+
line: location.start_line - 1,
|
|
164
|
+
character: location.start_column
|
|
165
|
+
),
|
|
166
|
+
end: ::RubyLsp::Interface::Position.new(
|
|
167
|
+
line: location.end_line - 1,
|
|
168
|
+
character: location.end_column
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def object_method_call?(node)
|
|
174
|
+
message(node) && object_call?(receiver(node))
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def object_call?(node)
|
|
178
|
+
node && receiver(node).nil? && message(node) == "object"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def receiver(node)
|
|
182
|
+
node.receiver if node.respond_to?(:receiver)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def message(node)
|
|
186
|
+
node.message.to_s if node.respond_to?(:message) && node.message
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ruby_lsp/ruby_lsp_rails/server"
|
|
4
|
+
|
|
5
|
+
module RubyLsp
|
|
6
|
+
module HasStateMachine
|
|
7
|
+
class RailsServerAddon < ::RubyLsp::Rails::ServerAddon
|
|
8
|
+
def name
|
|
9
|
+
"has_state_machine"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def execute(request, params)
|
|
13
|
+
with_request_error_handling(request) do
|
|
14
|
+
case request
|
|
15
|
+
when "model_for_workflow_namespace"
|
|
16
|
+
send_result(model_for_workflow_namespace(params.fetch("workflow_namespace")))
|
|
17
|
+
else
|
|
18
|
+
raise NotImplementedError, "Unknown request: #{request}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def model_for_workflow_namespace(workflow_namespace)
|
|
26
|
+
model = models_by_workflow_namespace[workflow_namespace]
|
|
27
|
+
return unless model
|
|
28
|
+
|
|
29
|
+
{name: model.name}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def models_by_workflow_namespace
|
|
33
|
+
@models_by_workflow_namespace ||= active_record_models.each_with_object({}) do |model, index|
|
|
34
|
+
next unless model.respond_to?(:workflow_namespace)
|
|
35
|
+
|
|
36
|
+
index[model.workflow_namespace] = model
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def active_record_models
|
|
41
|
+
@active_record_models ||= begin
|
|
42
|
+
::Rails.application&.eager_load!
|
|
43
|
+
::ActiveRecord::Base.descendants.reject(&:abstract_class?)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLsp
|
|
4
|
+
module HasStateMachine
|
|
5
|
+
module WorkflowResolver
|
|
6
|
+
WORKFLOW_PREFIX = "Workflow::"
|
|
7
|
+
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def model_name_for(workflow_class_name)
|
|
11
|
+
namespace = workflow_namespace_for(workflow_class_name)
|
|
12
|
+
return unless namespace&.start_with?(WORKFLOW_PREFIX)
|
|
13
|
+
|
|
14
|
+
name = namespace.delete_prefix(WORKFLOW_PREFIX)
|
|
15
|
+
return if name.empty?
|
|
16
|
+
|
|
17
|
+
name
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def workflow_namespace_for(workflow_class_name)
|
|
21
|
+
namespace = workflow_class_name.to_s.delete_prefix("::").sub(/::[^:]+\z/, "")
|
|
22
|
+
return if namespace.empty?
|
|
23
|
+
|
|
24
|
+
namespace
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: has_state_machine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Benjamin Hargett
|
|
@@ -31,6 +31,9 @@ dependencies:
|
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '1.5'
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '2.0'
|
|
34
37
|
type: :development
|
|
35
38
|
prerelease: false
|
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -38,6 +41,23 @@ dependencies:
|
|
|
38
41
|
- - ">="
|
|
39
42
|
- !ruby/object:Gem::Version
|
|
40
43
|
version: '1.5'
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '2.0'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: nokogiri
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "<"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.19'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "<"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.19'
|
|
41
61
|
- !ruby/object:Gem::Dependency
|
|
42
62
|
name: pry
|
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,6 +100,20 @@ dependencies:
|
|
|
80
100
|
- - ">="
|
|
81
101
|
- !ruby/object:Gem::Version
|
|
82
102
|
version: '0'
|
|
103
|
+
- !ruby/object:Gem::Dependency
|
|
104
|
+
name: parallel
|
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "<"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '2.0'
|
|
110
|
+
type: :development
|
|
111
|
+
prerelease: false
|
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "<"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '2.0'
|
|
83
117
|
- !ruby/object:Gem::Dependency
|
|
84
118
|
name: appraisal
|
|
85
119
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +128,104 @@ dependencies:
|
|
|
94
128
|
- - ">="
|
|
95
129
|
- !ruby/object:Gem::Version
|
|
96
130
|
version: '0'
|
|
131
|
+
- !ruby/object:Gem::Dependency
|
|
132
|
+
name: minitest
|
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - "~>"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '5.1'
|
|
138
|
+
type: :development
|
|
139
|
+
prerelease: false
|
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - "~>"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '5.1'
|
|
145
|
+
- !ruby/object:Gem::Dependency
|
|
146
|
+
name: ruby-lsp
|
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0.18'
|
|
152
|
+
type: :development
|
|
153
|
+
prerelease: false
|
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0.18'
|
|
159
|
+
- !ruby/object:Gem::Dependency
|
|
160
|
+
name: ruby-lsp-rails
|
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: 0.3.17
|
|
166
|
+
type: :development
|
|
167
|
+
prerelease: false
|
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: 0.3.17
|
|
173
|
+
- !ruby/object:Gem::Dependency
|
|
174
|
+
name: base64
|
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
180
|
+
type: :development
|
|
181
|
+
prerelease: false
|
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0'
|
|
187
|
+
- !ruby/object:Gem::Dependency
|
|
188
|
+
name: bigdecimal
|
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '0'
|
|
194
|
+
type: :development
|
|
195
|
+
prerelease: false
|
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
197
|
+
requirements:
|
|
198
|
+
- - ">="
|
|
199
|
+
- !ruby/object:Gem::Version
|
|
200
|
+
version: '0'
|
|
201
|
+
- !ruby/object:Gem::Dependency
|
|
202
|
+
name: drb
|
|
203
|
+
requirement: !ruby/object:Gem::Requirement
|
|
204
|
+
requirements:
|
|
205
|
+
- - ">="
|
|
206
|
+
- !ruby/object:Gem::Version
|
|
207
|
+
version: '0'
|
|
208
|
+
type: :development
|
|
209
|
+
prerelease: false
|
|
210
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
211
|
+
requirements:
|
|
212
|
+
- - ">="
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '0'
|
|
215
|
+
- !ruby/object:Gem::Dependency
|
|
216
|
+
name: mutex_m
|
|
217
|
+
requirement: !ruby/object:Gem::Requirement
|
|
218
|
+
requirements:
|
|
219
|
+
- - ">="
|
|
220
|
+
- !ruby/object:Gem::Version
|
|
221
|
+
version: '0'
|
|
222
|
+
type: :development
|
|
223
|
+
prerelease: false
|
|
224
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
225
|
+
requirements:
|
|
226
|
+
- - ">="
|
|
227
|
+
- !ruby/object:Gem::Version
|
|
228
|
+
version: '0'
|
|
97
229
|
description: HasStateMachine uses ruby classes to make creating a finite state machine
|
|
98
230
|
in your ActiveRecord models a breeze.
|
|
99
231
|
email:
|
|
@@ -114,6 +246,10 @@ files:
|
|
|
114
246
|
- lib/has_state_machine/state.rb
|
|
115
247
|
- lib/has_state_machine/state_helpers.rb
|
|
116
248
|
- lib/has_state_machine/version.rb
|
|
249
|
+
- lib/ruby_lsp/has_state_machine/addon.rb
|
|
250
|
+
- lib/ruby_lsp/has_state_machine/definition.rb
|
|
251
|
+
- lib/ruby_lsp/has_state_machine/rails_server_addon.rb
|
|
252
|
+
- lib/ruby_lsp/has_state_machine/workflow_resolver.rb
|
|
117
253
|
homepage: https://www.github.com/encampment/has_state_machine
|
|
118
254
|
licenses:
|
|
119
255
|
- MIT
|