lucidMachines 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e45b69e99c6fa792a59c07f778c2650116e627698dd6c7f59e19ea18d3999bdd
4
+ data.tar.gz: 75161768c35466c9b18479d4e29b89a689394f64a232779892abf1c158f1cf26
5
+ SHA512:
6
+ metadata.gz: 26e5d9dc07e9a3ab1f62da9c9b0a69e6944d700051c900ab4874db4b88b20790833021afcaef0156d9d6a1e7778d5814ea1d2994f6bad4edabcac6277b1c2b0c
7
+ data.tar.gz: d759259eb5c5c22f4795392efdfbacac30d140c5183f1268b79b51aebc6685da6b125ac5caebeb9e01456f0a7dbb14448fb38ed95ae496cf3b8999884f39ed5a
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /export/
@@ -0,0 +1 @@
1
+ ,jiii,jiii-mi,25.01.2019 22:33,file:///home/jiii/.config/libreoffice/4;
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at poqudrof@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in lucid-machines.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lucidMachines (0.1.2)
5
+ aasm
6
+ aasm-diagram
7
+ ruby-graphviz
8
+ thor
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ aasm (5.0.6)
14
+ concurrent-ruby (~> 1.0)
15
+ aasm-diagram (0.1.2)
16
+ aasm (~> 5.0, >= 4.12)
17
+ ruby-graphviz (~> 1.2)
18
+ concurrent-ruby (1.1.5)
19
+ rake (10.5.0)
20
+ ruby-graphviz (1.2.4)
21
+ thor (0.20.3)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 2.0)
28
+ lucidMachines!
29
+ rake (~> 10.0)
30
+
31
+ BUNDLED WITH
32
+ 2.0.1
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Lucid::Machines
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lucid/machines`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'lucid-machines'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install lucid-machines
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lucid-machines. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+ ## Code of Conduct
38
+
39
+ Everyone interacting in the Lucid::Machines project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/lucid-machines/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/aasm_export.rb ADDED
@@ -0,0 +1,380 @@
1
+ # coding: utf-8
2
+
3
+ module ChartReader
4
+
5
+ class AASMExport
6
+
7
+ EventCallbacks = ["before", "guards", "guard",
8
+ "before_enter", "enter",
9
+ "before_success",
10
+ "success", "after",
11
+ "error", "ensure"]
12
+
13
+ GlobalEventCallbacks = ["before_all_events", "after_all_events",
14
+ "error_on_all_events", "ensure_on_all_events"]
15
+
16
+ StateCallbacks = ["before_exit", "exit",
17
+ "before_enter", "enter",
18
+ "after_exit", "after_enter"]
19
+
20
+ TransitionCallbacks = ["guard", "guards", "after", "success"]
21
+ GlobalTransitionCallbacks = ["after_all_transitions"]
22
+
23
+ attr_reader :method_names
24
+
25
+ def initialize(chart)
26
+ @chart = chart
27
+ init_method_names
28
+ create
29
+ end
30
+
31
+ def init_method_names
32
+ @method_names = []
33
+ end
34
+
35
+ def method_names
36
+ # @method_names = @method_names.uniq
37
+ # return @method_names
38
+
39
+ # unique, no trailing spaces, inside spaces are underscores
40
+ @method_names.uniq.map{|t| sanitize(t)}
41
+ end
42
+
43
+ def sanitize(name)
44
+ name.strip.tr " ", "_"
45
+ end
46
+
47
+ def create
48
+ @states = @chart.get_blocks_of_type "state"
49
+ @states = @states + @chart.get_blocks_of_type("Process")
50
+ # puts "States count: " + @states.size.to_s
51
+
52
+ @events = @chart.get_blocks_of_type "event"
53
+ @events = @events + @chart.get_blocks_of_type("Decision")
54
+ # puts "Events count: " + @events.size.to_s
55
+
56
+ ## Arrows between states are also events
57
+ ## handled in generate_events_code
58
+
59
+ create_multi_events
60
+ end
61
+
62
+ attr_reader :transitions
63
+
64
+ def create_multi_events
65
+ transitions = @chart.get_blocks_of_type("transition") +
66
+ @chart.get_blocks_of_type("Summing Junction")
67
+
68
+ # puts transitions.size.to_s + " found"
69
+
70
+ @transitions = {}
71
+ # Hash with events as keys
72
+ ## Values: Array of [from_state, to_state]
73
+ ## ex: { event1 => [[[state1], state2], [[state1, state4], state3]] }
74
+
75
+ # puts "raw transitions found " + transitions.size.to_s
76
+
77
+ ## select the valid one
78
+ transitions.each do |t|
79
+ # Link from a block.
80
+ # and link to a block.
81
+ # and link from or to an event.
82
+
83
+ from_states = t.links_from_type("state") + t.links_from_type("Process")
84
+ to_state = t.links_to_type("state") + t.links_to_type("Process")
85
+
86
+ event = t.links_to_type("event") + t.links_from_type("event")
87
+ event = event + t.links_to_type("Decision") + t.links_from_type("Decision")
88
+
89
+ priority = 0
90
+ t.links_from.each do |l, e|
91
+ if(l.text.to_i != 0)
92
+ priority = l.text.to_i
93
+ end
94
+ end
95
+
96
+ ## Remove possible duplicate links...
97
+ from_states.uniq!
98
+ to_state.uniq!
99
+ event.uniq!
100
+
101
+ if from_states.size < 1 or to_state.size != 1 or event.size != 1
102
+ print_warning(event, from_states, to_state)
103
+ next
104
+ end
105
+
106
+ event = event.first
107
+ to_state = to_state.first
108
+
109
+ # puts "Adding, from " + from_states.first.text + " to " + to_state.text + " through " + event.text
110
+ ## get the ID from the link.
111
+
112
+ # Find the priority
113
+ all_links = t.links_to.merge(t.links_from)
114
+ prio = 0
115
+ from_states.each do |s|
116
+ link = all_links.key(to_state)
117
+ next if link.nil? or link.text.nil?
118
+ link_prio = link.to_i
119
+ prio = link_prio if link_prio > prio
120
+ end
121
+ # puts "Priority found " + prio.to_s if prio != 0
122
+
123
+ @transitions[event] = [] if @transitions[event].nil?
124
+ @transitions[event] << [from_states, to_state, priority, t]
125
+ end
126
+
127
+ # puts "Transitions found " + @transitions.size.to_s
128
+
129
+ end
130
+
131
+ def print_warning(event, from_states, to_state)
132
+
133
+ if(event.size != 1)
134
+ puts "Warning: Transition without any event !" if event.size == 0
135
+
136
+ if event.size > 1
137
+ puts "Warning: Transition with multiple events !"
138
+ event.each do |e|
139
+ puts " - Event: " + e.to_s
140
+ end
141
+ end
142
+ end
143
+
144
+ if(to_state != 1)
145
+ puts "Warning: Transition without output !" if to_state.size == 0
146
+ puts "Warning: Transition with multiple outputs !" if to_state.size > 1
147
+ end
148
+
149
+ if(from_states.size < 1)
150
+ puts "Warning: Transition without input !" if from_states.size == 0
151
+ end
152
+ end
153
+
154
+
155
+ def generate_state_code
156
+ states_code = ""
157
+ @states.each do |state|
158
+
159
+ code = " state :" + sanitize(state.text)
160
+ code = code + ", :initial => true" if state.initial
161
+
162
+ callback_code = generate_callback(state, "method", StateCallbacks)
163
+
164
+ states_code = states_code + code + callback_code + "\n"
165
+ end
166
+ states_code + "\n"
167
+ end
168
+
169
+
170
+
171
+ def generate_events_code
172
+
173
+ events_code = ""
174
+
175
+ ## Arrows between two blocks are events.
176
+ @chart.links.each_value do |link|
177
+ if (@chart.blocks[link.source].type == "state" or
178
+ @chart.blocks[link.source].type == "process") and
179
+ (@chart.blocks[link.destination].type == "state" or
180
+ @chart.blocks[link.destination].type == "process") and
181
+ not link.text.nil?
182
+
183
+ name = sanitize(link.text)
184
+
185
+ code = <<-SMALL_EVENT
186
+ event :#{name} do
187
+ transitions :from => :#{@chart.blocks[link.source].text}, :to => :#{@chart.blocks[link.destination].text}
188
+ end
189
+
190
+ SMALL_EVENT
191
+
192
+ events_code = events_code + code
193
+ end
194
+ end
195
+
196
+ @events.each do |event|
197
+ code = " event :" + sanitize(event.text)
198
+
199
+ ## Add event :before :after...
200
+ callback_code = generate_callback(event, "method", EventCallbacks)
201
+
202
+ code = code + callback_code + " do \n"
203
+
204
+ ## Add the code if it is defined.
205
+ code = code + generate_code_callback(event, EventCallbacks)
206
+
207
+ ## Simple case: This event links from and to a state
208
+ inputs = event.links_from_type "state"
209
+ outputs = event.links_to_type "state"
210
+
211
+ inputs = inputs + event.links_from_type("Process")
212
+ outputs = outputs + event.links_to_type("Process")
213
+
214
+
215
+ if inputs.size > 0 and outputs.size == 1
216
+ transition = transition_code(event,
217
+ inputs,
218
+ outputs.first)
219
+ code = code + transition + "\n"
220
+
221
+ end
222
+
223
+ unless @transitions[event].nil?
224
+ ## Sort by ID if present
225
+
226
+ @sorted = @transitions[event].each.sort do |tr|
227
+ input, output, priority = tr
228
+ priority
229
+ end
230
+
231
+ @sorted.each do |t|
232
+ inputs, output, priority, t_element = t
233
+ transition = transition_code(event, inputs, output)
234
+ transition_callback = generate_callback(t_element,
235
+ "method",
236
+ TransitionCallbacks)
237
+ code = code + transition + transition_callback + "\n"
238
+ end
239
+ end
240
+
241
+ code = code + " end\n\n"
242
+ events_code = events_code + code
243
+ end
244
+
245
+ events_code
246
+ end
247
+
248
+ def transition_code(event, inputs, output)
249
+
250
+ code = " transitions :from => "
251
+ if inputs.size == 1
252
+ code = code + ":" + sanitize(inputs[0].text)
253
+ else
254
+ code = code + "["
255
+ inputs.each do |input|
256
+ code = code + ":" + sanitize(input.text) + ","
257
+ end
258
+ ## remove last ","
259
+ code = code.chop + "]"
260
+ end
261
+
262
+ code = code + ", :to => :" + sanitize(output.text)
263
+ ## TODO: add options
264
+
265
+ # TransitionCallbacks
266
+ ## Add event :before :after... METHOD out of this
267
+ ## Not yet testable
268
+ # callback_code = generate_callback(event, "method", TransitionCallbacks)
269
+ callback_code = ""
270
+
271
+ return code + callback_code
272
+ end
273
+
274
+ def generate_callback(event, element_type, callbacks)
275
+
276
+ ## TODO: Handle the Guards -> create an array
277
+ l1 = event.links_to.each.select{|link, e| e.type.eql? element_type }
278
+ l2 = event.links_from.each.select{|link, e| e.type.eql? element_type }
279
+ links = l1 + l2
280
+ code = ""
281
+ unless links.empty?
282
+ links.each do |l|
283
+
284
+ link = l[0]
285
+ element = l[1]
286
+ if(callbacks.any? link.text)
287
+ code = code + ", :" + sanitize(link.text) +
288
+ " => :" + sanitize(element.text)
289
+
290
+ @method_names << element.text
291
+ end
292
+ end
293
+ end
294
+ return code
295
+ end
296
+
297
+ def generate_code_callback(event, callbacks)
298
+ l1 = event.links_to.each.select{|link, e| e.type.eql? "code" }
299
+ l2 = event.links_from.each.select{|link, e| e.type.eql? "code" }
300
+ links = l1 + l2
301
+ code = ""
302
+
303
+ unless links.empty?
304
+ links.each do |l|
305
+ link = l[0]
306
+ element = l[1]
307
+
308
+ if(callbacks.any? link.text)
309
+ code = code + " " + link.text + " do"
310
+
311
+ if link.text == "error"
312
+ code = code + " |e|\n"
313
+ else
314
+ code = code + "\n"
315
+ end
316
+ indent = " "
317
+ element.text.split("\n").each do |t|
318
+ code = code + indent + t
319
+ end
320
+
321
+ code = code + "\n end\n"
322
+ end
323
+ end
324
+ end
325
+ return code
326
+ end
327
+
328
+ # Generate code that creates methods for each
329
+ # method declared in the graph.
330
+ def generate_methods_placeholder
331
+ code = "\n"
332
+ method_names().each do |method_name|
333
+
334
+ code = code + <<-METH
335
+ def #{method_name}
336
+ puts "Please implement the method #{method_name}"
337
+ true
338
+ end
339
+
340
+ METH
341
+ end
342
+ return code
343
+ end
344
+
345
+ # Generate methods that are not already
346
+ # Defined in the class.
347
+ def generate_methods_placeholder_for(klass, debug: true)
348
+ method_names().each do |method_name|
349
+ if klass.method_defined? method_name.to_sym
350
+ puts "Found: #{method_name}. " if debug
351
+ next
352
+ end
353
+
354
+ puts "To implement: #{method_name}. " if debug
355
+ klass.define_method method_name.to_sym do
356
+ puts "Please implement the method #{method_name}"
357
+ true
358
+ end
359
+
360
+ end
361
+ end
362
+
363
+ # Export the document to code (String)
364
+ # It exports only the aasm code, not the
365
+ # methods called by it.
366
+ def export
367
+ start = <<-START
368
+ aasm do
369
+ START
370
+
371
+ finish = <<-END
372
+ end
373
+ END
374
+ return start + generate_state_code +
375
+ generate_events_code + finish
376
+ # generate_methods_placeholder
377
+ end
378
+ end
379
+
380
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "lucid/machines"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here