nutella_framework 0.3.1 → 0.4.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +3 -4
  4. data/VERSION +1 -1
  5. data/data/startup +3 -3
  6. data/framework_components/example_framework_interface/dandelion-flowers-card.jpg +0 -0
  7. data/framework_components/example_framework_interface/index.html +18 -0
  8. data/framework_components/main_interface/main_interface_bot.rb +183 -0
  9. data/framework_components/main_interface/public/index.html +54 -0
  10. data/framework_components/main_interface/views/index.erb +63 -0
  11. data/framework_components/order.json.example +6 -0
  12. data/framework_components/runs_list_bot/app_runs_list_bot.rb +15 -0
  13. data/lib/{core/commands → commands}/broker.rb +2 -2
  14. data/lib/{core/commands → commands}/checkup.rb +2 -2
  15. data/lib/commands/compile.rb +13 -0
  16. data/lib/commands/dependencies.rb +13 -0
  17. data/lib/commands/help.rb +35 -0
  18. data/lib/{core/commands → commands}/install.rb +19 -15
  19. data/lib/commands/meta/command.rb +19 -0
  20. data/lib/commands/meta/run_command.rb +114 -0
  21. data/lib/{core → commands/meta}/template_command.rb +1 -1
  22. data/lib/commands/new.rb +60 -0
  23. data/lib/commands/runs.rb +54 -0
  24. data/lib/commands/start.rb +321 -0
  25. data/lib/commands/stop.rb +101 -0
  26. data/lib/{core/commands → commands}/template.rb +59 -39
  27. data/lib/config/current_app_utils.rb +51 -0
  28. data/lib/config/persisted_hash.rb +14 -12
  29. data/lib/config/runlist.rb +116 -16
  30. data/lib/{cli → core}/nutella_cli.rb +1 -1
  31. data/lib/core/nutella_core.rb +2 -6
  32. data/lib/nutella_framework.rb +5 -3
  33. data/lib/nutella_lib_framework/api.rb +333 -0
  34. data/lib/tmux/tmux.rb +76 -0
  35. data/nutella_framework.gemspec +42 -29
  36. data/test/commands/test_cmd_cli_params_parsing.rb +56 -0
  37. data/test/commands/test_command_template.rb +31 -0
  38. data/test/config/test_current_app_utils.rb +34 -0
  39. data/test/config/test_persisted_hash.rb +48 -0
  40. data/test/config/test_runlist.rb +15 -23
  41. data/test/framework_apis/test_framework_api.rb +74 -0
  42. metadata +74 -27
  43. data/actors/main_interface/main_interface_bot.rb +0 -163
  44. data/actors/main_interface/public/index.html +0 -51
  45. data/actors/main_interface/views/index.erb +0 -45
  46. data/lib/config/current_project.rb +0 -58
  47. data/lib/core/command.rb +0 -12
  48. data/lib/core/commands/compile.rb +0 -21
  49. data/lib/core/commands/dependencies.rb +0 -21
  50. data/lib/core/commands/help.rb +0 -28
  51. data/lib/core/commands/new.rb +0 -60
  52. data/lib/core/commands/runs.rb +0 -52
  53. data/lib/core/commands/start.rb +0 -271
  54. data/lib/core/commands/stop.rb +0 -100
  55. data/lib/core/run_command.rb +0 -106
  56. data/lib/core/tmux.rb +0 -38
  57. data/test/config/test_config.rb +0 -48
  58. data/test/config/test_project.rb +0 -34
  59. data/test/test_run_command.rb +0 -54
  60. /data/{actors → framework_components}/main_interface/startup +0 -0
  61. /data/{actors → framework_components}/main_interface/views/not_found_404.erb +0 -0
@@ -0,0 +1,333 @@
1
+ require 'nutella_lib'
2
+ require 'config/runlist'
3
+
4
+ module Nutella
5
+
6
+
7
+ # Initializes this component as a framework component
8
+ # @param [String] broker_hostname
9
+ # @param [String] component_id
10
+ def self.init_as_f_component( broker_hostname, component_id )
11
+ @app_id = nil
12
+ @run_id = nil
13
+ @component_id = component_id
14
+ @resource_id = nil
15
+ @mqtt = SimpleMQTTClient.new broker_hostname
16
+ end
17
+
18
+
19
+ # Parse command line arguments for framework level components
20
+ #
21
+ # @param [Array] args command line arguments array
22
+ # @return [String] broker
23
+ def self.parse_f_component_args(args)
24
+ if args.length < 1
25
+ STDERR.puts 'Couldn\'t read broker address from the command line, impossible to initialize component!'
26
+ return
27
+ end
28
+ return args[0]
29
+ end
30
+
31
+
32
+ module Net
33
+
34
+ # Provides access to the net.app sub-module
35
+ def Net.f; Nutella::Net::Framework end
36
+
37
+
38
+ # This module implements the pub/sub and request/response APIs at the framework-level
39
+ module Framework
40
+
41
+
42
+ # @!group Framework-level communication APIs
43
+
44
+ # Subscribes to a channel or to a set of channels at the framework-level.
45
+ #
46
+ # @param [String] channel the framework-level channel or filter we are subscribing to. Can contain wildcard(s)
47
+ # @param [Proc] callback a lambda expression that is fired whenever a message is received.
48
+ # The passed callback takes the following parameters:
49
+ # - [String] message: the received message. Messages that are not JSON are discarded.
50
+ # - [String] channel: the framework-level channel the message was received on (optional, only for wildcard subscriptions)
51
+ # - [Hash] from: the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
52
+ def self.subscribe (channel, callback)
53
+ Nutella::Net.subscribe_to(channel, callback, nil, nil)
54
+ end
55
+
56
+
57
+ # Un-subscribes from a framework-level channel
58
+ #
59
+ # @param [String] channel the framework-level channel we want to unsubscribe from. Can contain wildcard(s).
60
+ def self.unsubscribe( channel )
61
+ Nutella::Net.unsubscribe_to(channel, nil, nil)
62
+ end
63
+
64
+
65
+ # Publishes a message to an framework-level channel
66
+ #
67
+ # @param [String] channel the framework-level channel we want to publish the message to. *CANNOT* contain wildcard(s)!
68
+ # @param [Object] message the message we are publishing. This can be,
69
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
70
+ def self.publish(channel, message=nil)
71
+ Nutella::Net.publish_to(channel, message, nil, nil)
72
+ end
73
+
74
+
75
+ # Performs a synchronous request at the framework-level
76
+ #
77
+ # @param [String] channel the framework-level channel we want to make the request to. *CANNOT* contain wildcard(s)!
78
+ # @param [Object] message the body of request. This can be,
79
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
80
+ def self.sync_request ( channel, message=nil )
81
+ Nutella::Net.sync_request_to(channel, message, nil, nil)
82
+ end
83
+
84
+
85
+ # Performs an asynchronous request at the framework-level
86
+ #
87
+ # @param [String] channel the framework-level channel we want to make the request to. *CANNOT* contain wildcard(s)!
88
+ # @param [Object] message the body of request. This can be,
89
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
90
+ # @param [Proc] callback the callback that is fired whenever a response is received. It takes one parameter (response).
91
+ def self.async_request ( channel, message=nil, callback )
92
+ Nutella::Net.async_request_to(channel, message, callback, nil, nil)
93
+ end
94
+
95
+
96
+ # Handles requests on a certain framework-level channel
97
+ #
98
+ # @param [String] channel tha framework-level channel we want to listen for requests on. Can contain wildcard(s).
99
+ # @param [Proc] callback a lambda expression that is fired whenever a message is received.
100
+ # The passed callback takes the following parameters:
101
+ # - [String] the received message (payload). Messages that are not JSON are discarded.
102
+ # - [Hash] the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
103
+ # - [*returns* Hash] The response sent back to the client that performed the request. Whatever is returned by the callback is marshaled into a JSON string and sent via MQTT.
104
+ def self.handle_requests( channel, callback )
105
+ Nutella::Net.handle_requests_on(channel, callback, nil, nil)
106
+ end
107
+
108
+ # @!endgroup
109
+
110
+ # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
111
+
112
+ # @!group Framework-level APIs to communicate at the run-level
113
+
114
+ # Allows framework-level APIs to subscribe to a run-level channel within a specific run
115
+ #
116
+ # @param [String] app_id the specific application we are subscribing to
117
+ # @param [String] run_id the specific run we are subscribing to
118
+ # @param [String] channel the run-level channel we are subscribing to. Can be wildcard.
119
+ # @param [Proc] callback the callback that is fired whenever a message is received on the channel.
120
+ # The passed callback takes the following parameters:
121
+ # - [String] message: the received message. Messages that are not JSON are discarded.
122
+ # - [String] channel: the framework-level channel the message was received on (optional, only for wildcard subscriptions)
123
+ # - [Hash] from: the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
124
+ def self.subscribe_to_run( app_id, run_id, channel, callback )
125
+ Nutella::Net.subscribe_to(channel, callback, app_id, run_id)
126
+ end
127
+
128
+
129
+ # Allows framework-level APIs to unsubscribe from a run-level channel within a specific run
130
+ #
131
+ # @param [String] app_id the specific application we are un-subscribing from
132
+ # @param [String] run_id the specific run we are un-subscribing from
133
+ # @param [String] channel the run-level channel we want to unsubscribe from. Can contain wildcard(s).
134
+ def self.unsubscribe_to_run( app_id, run_id, channel )
135
+ Nutella::Net.unsubscribe_to(channel, app_id, run_id)
136
+ end
137
+
138
+
139
+ # Allows framework-level APIs to publish to a run-level channel within a specific run
140
+ #
141
+ # @param [String] app_id the specific application we are publishing to
142
+ # @param [String] run_id the specific run we are publishing to
143
+ # @param [String] channel the run-level channel we want to publish the message to. *CANNOT* contain wildcard(s)!
144
+ # @param [String] message the message we are publishing. This can be,
145
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
146
+ def self.publish_to_run( app_id, run_id, channel, message )
147
+ Nutella::Net.publish_to(channel, message, app_id, run_id)
148
+ end
149
+
150
+
151
+ # Allows framework-level APIs to make a synchronous request to a run-level channel within a specific run
152
+ #
153
+ # @param [String] app_id the specific application we are making the request to
154
+ # @param [String] run_id the specific run we are making the request to
155
+ # @param [String] channel the channel we want to make the request to. *CANNOT* contain wildcard(s)!
156
+ # @param [Object] request the body of request. This can be,
157
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
158
+ def self.sync_request_to_run( app_id, run_id, channel, request)
159
+ Nutella::Net.sync_request_to(channel, request, app_id, run_id)
160
+ end
161
+
162
+
163
+ # Allows framework-level APIs to make an asynchronous request to a run-level channel within a specific run
164
+ #
165
+ # @param [String] app_id the specific application we are making the request to
166
+ # @param [String] run_id the specific run we are making the request to
167
+ # @param [String] channel the channel we want to make the request to. *CANNOT* contain wildcard(s)!
168
+ # @param [Object] request the body of request. This can be,
169
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
170
+ # @param [Proc] callback the callback that is fired whenever a response is received. It takes one parameter (response).
171
+ def self.async_request_to_run( app_id, run_id, channel, request, callback)
172
+ Nutella::Net.async_request_to(channel, request, callback, app_id, run_id)
173
+ end
174
+
175
+
176
+ # Allows framework-level APIs to handle requests on a run-level channel within a specific run
177
+ #
178
+ # @param [String] app_id the specific application requests are coming from
179
+ # @param [String] run_id the specific run requests are coming from
180
+ # @param [String] channel we want to listen for requests on. Can contain wildcard(s).
181
+ # @param [Proc] callback a lambda expression that is fired whenever a message is received.
182
+ # The passed callback takes the following parameters:
183
+ # - [String] the received message (payload). Messages that are not JSON are discarded.
184
+ # - [Hash] the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
185
+ # - [*returns* Hash] The response sent back to the client that performed the request. Whatever is returned by the callback is marshaled into a JSON string and sent via MQTT.
186
+ def self.handle_requests_on_run( app_id, run_id, channel, callback )
187
+ Nutella::Net.handle_requests_on(channel, callback, app_id, run_id)
188
+ end
189
+
190
+ # @!endgroup
191
+
192
+ # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
193
+
194
+ # @!group Framework-level APIs to communicate at the run-level (broadcast)
195
+
196
+ # Allows framework-level APIs to subscribe to a run-level channel *for ALL runs*
197
+ #
198
+ # @param [String] channel the run-level channel we are subscribing to. Can be wildcard.
199
+ # @param [Proc] callback the callback that is fired whenever a message is received on the channel.
200
+ # The passed callback takes the following parameters:
201
+ # - [String] message: the received message. Messages that are not JSON are discarded.
202
+ # - [String] app_id: the app_id of the channel the message was sent on
203
+ # - [String] run_id: the run_id of the channel the message was sent on
204
+ # - [Hash] from: the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
205
+ def self.subscribe_to_all_runs( channel, callback )
206
+ # Check the passed callback has the right number of arguments
207
+ raise 'You need to pass a callback with 4 parameters (payload, app_id, run_id, from) when subscribing to all runs!' if callback.parameters.length!=4
208
+ # Pad channel
209
+ padded_channel = Nutella::Net.pad_channel(channel, '+', '+')
210
+ mqtt_cb = lambda do |mqtt_message, mqtt_channel|
211
+ begin
212
+ type, from, payload, _ = Nutella::Net.extract_fields_from_message mqtt_message
213
+ app_id, run_id = self.extract_run_id_and_app_id mqtt_channel
214
+ callback.call(payload, app_id, run_id, from) if type=='publish'
215
+ rescue JSON::ParserError
216
+ # Make sure the message is JSON, if not drop the message
217
+ return
218
+ rescue
219
+ # Check the passed callback has the right number of arguments
220
+ STDERR.puts "The callback you passed to subscribe has the #{$!}: it needs 'payload', 'app_id', 'run_id' and 'from'"
221
+ end
222
+ end
223
+ # Add to subscriptions, save mqtt callback and subscribe
224
+ Nutella::Net.subscriptions.push padded_channel
225
+ Nutella::Net.callbacks.push mqtt_cb
226
+ Nutella.mqtt.subscribe( padded_channel, mqtt_cb )
227
+ end
228
+
229
+
230
+ # Allows framework-level APIs to unsubscribe from a run-level channel *for ALL runs*
231
+ #
232
+ # @param [String] channel the run-level channel we want to unsubscribe from. Can contain wildcard(s).
233
+ def self.unsubscribe_from_all_runs( channel )
234
+ Nutella::Net.unsubscribe_to(channel, '+', '+')
235
+ end
236
+
237
+
238
+ # Allows framework-level APIs to publish a message to a run-level channel *for ALL runs*
239
+ #
240
+ # @param [String] channel the run-level channel we want to publish the message to. *CANNOT* contain wildcard(s)!
241
+ # @param [Object] message the message we are publishing. This can be,
242
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
243
+ def self.publish_to_all_runs( channel, message )
244
+ Nutella.runlist.all_runs.each do |app_id, _|
245
+ Nutella.runlist.runs_for_app(app_id).each do |run_id|
246
+ Nutella::Net.publish_to(channel, message, app_id, run_id)
247
+ end
248
+ end
249
+ end
250
+
251
+
252
+ # Allows framework-level APIs to send a request to a run-level channel *for ALL runs*
253
+ #
254
+ # @param [String] channel the run-level channel we want to make the request to. *CANNOT* contain wildcard(s)!
255
+ # @param [Object] request the body of request. This can be,
256
+ # nil/empty (default), a string, a hash and, in general, anything with a .to_json method.
257
+ # @param [Proc] callback the callback that is fired whenever a response is received. It takes one parameter (response).
258
+ def self.async_request_to_all_runs(channel, request, callback)
259
+ Nutella.runlist.all_runs.each do |app_id, _|
260
+ Nutella.runlist.runs_for_app(app_id).each do |run_id|
261
+ Nutella::Net.async_request_to(channel, request, callback, app_id, run_id)
262
+ end
263
+ end
264
+ end
265
+
266
+
267
+ # Allows framework-level APIs to handle requests to a run-level channel *for ALL runs*
268
+ #
269
+ # @param [String] channel tha run-level channel we want to listen for requests on. Can contain wildcard(s).
270
+ # @param [Proc] callback a lambda expression that is fired whenever a message is received.
271
+ # The passed callback takes the following parameters:
272
+ # - [String] the received message (request). Messages that are not JSON are discarded.
273
+ # - [String] app_id: the app_id of the channel the request was sent on
274
+ # - [String] run_id: the run_id of the channel the request was sent on
275
+ # - [Hash] the sender's identifiers (from containing, run_id, app_id, component_id and optionally resource_id)
276
+ # - [*returns* Hash] The response sent back to the client that performed the request. Whatever is returned by the callback is marshaled into a JSON string and sent via MQTT.
277
+ def self.handle_requests_on_all_runs(channel, callback)
278
+ # Check the passed callback has the right number of arguments
279
+ raise 'You need to pass a callback with 4 parameters (request, run_id, from) when handling requests!' if callback.parameters.length!=4
280
+ # Pad channel
281
+ padded_channel = Nutella::Net.pad_channel(channel, '+', '+')
282
+ mqtt_cb = lambda do |request, mqtt_channel|
283
+ begin
284
+ # Extract nutella fields
285
+ type, from, payload, id = Nutella::Net.extract_fields_from_message request
286
+ app_id, run_id = self.extract_run_id_and_app_id mqtt_channel
287
+ # Only handle requests that have proper id set
288
+ return if type!='request' || id.nil?
289
+ # Execute callback and send response
290
+ m = Net.prepare_message_for_response( callback.call( payload, app_id, run_id, from), id )
291
+ Nutella.mqtt.publish( mqtt_channel, m )
292
+ rescue JSON::ParserError
293
+ # Make sure that request contains JSON, if not drop the message
294
+ return
295
+ rescue
296
+ # Check the passed callback has the right number of arguments
297
+ STDERR.puts "The callback you passed to subscribe has the #{$!}: it needs 'request', 'app_id', 'run_id' and 'from'"
298
+ end
299
+ end
300
+ # Subscribe to the channel
301
+ Nutella.mqtt.subscribe( padded_channel, mqtt_cb )
302
+ end
303
+
304
+ # @!endgroup
305
+
306
+ # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
307
+
308
+ # @!group Framework-level APIs to communicate at the application-level
309
+
310
+ # TODO
311
+
312
+ # @!endgroup
313
+
314
+ # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
315
+
316
+ # @!group Framework-level APIs to communicate at the application-level (broadcast)
317
+
318
+ # TODO
319
+
320
+ # @!endgroup
321
+
322
+ private
323
+
324
+ def self.extract_run_id_and_app_id( mqtt_channel )
325
+ sp = mqtt_channel.sub('/nutella/apps/', '').split('/')
326
+ return sp[0], sp[2]
327
+ end
328
+
329
+
330
+ end
331
+
332
+ end
333
+ end
data/lib/tmux/tmux.rb ADDED
@@ -0,0 +1,76 @@
1
+ module Nutella
2
+
3
+ class Tmux
4
+
5
+ def initialize( app_id, run_id )
6
+ @app_id = app_id
7
+ @run_id = run_id
8
+ end
9
+
10
+ # Creates a new window (and session if necessary) to start a run-level bot
11
+ def new_bot_window( bot )
12
+ # Create session name
13
+ sn = Tmux.session_name(@app_id, @run_id)
14
+ # Create session
15
+ create_tmux_window(sn, bot)
16
+ # Start bot
17
+ `tmux send-keys "cd bots/#{bot};./startup #{Nutella.config['broker']} #{@app_id} #{@run_id}" C-m`
18
+ end
19
+
20
+ # Creates a new window (and session if necessary) to start an app-level bot
21
+ def new_app_bot_window( bot )
22
+ # Create session name
23
+ sn = Tmux.app_bot_session_name(@app_id)
24
+ # Create session
25
+ create_tmux_window(sn, bot)
26
+ # Start bot
27
+ `tmux send-keys "cd bots/#{bot};./startup #{Nutella.config['broker']} #{@app_id}" C-m`
28
+ end
29
+
30
+ # Removes a run-level session associated to a particular run
31
+ def self.kill_run_session( app_id, run_id )
32
+ `tmux kill-session -t #{session_name(app_id, run_id)} &> /dev/null`
33
+ end
34
+
35
+ # Removes the app-level session associated to a particular application
36
+ def self.kill_app_session( app_id )
37
+ `tmux kill-session -t #{app_bot_session_name( app_id )} &> /dev/null`
38
+ end
39
+
40
+ # Returns true if a tmux session with a certain id exists
41
+ def self.session_exist?( session_id )
42
+ system( "tmux has-session -t #{session_id} &> /dev/null" )
43
+ end
44
+
45
+ # Builds a session name for run-level session
46
+ def self.session_name( app_id, run_id )
47
+ "#{app_id}/#{run_id}"
48
+ end
49
+
50
+ # Builds a session name for an app-level session
51
+ def self.app_bot_session_name( app_id )
52
+ "#{app_id}-app-bots"
53
+ end
54
+
55
+
56
+ private
57
+
58
+ def create_tmux_window( session_name, bot )
59
+ # If a session already exists, simply create a new window (-n) for 'bot'.
60
+ # -k destroys the window if it can't be created
61
+ # -P prints info about creation of window
62
+ # If there is no sessions, let's create one (-s) and, at the same time, create a new window for the bot
63
+ if defined? @windows
64
+ `tmux new-window -kP -n #{bot} &> /dev/null`
65
+ @windows.push bot
66
+ else
67
+ `tmux new-session -d -s #{session_name} -n #{bot} &> /dev/null`
68
+ @windows = [bot]
69
+ end
70
+ # Select the last window we launched
71
+ `tmux select-window -t #{session_name}:#{@windows.length-1} &> /dev/null`
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: nutella_framework 0.3.1 ruby lib
5
+ # stub: nutella_framework 0.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "nutella_framework"
9
- s.version = "0.3.1"
9
+ s.version = "0.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Alessandro Gnoli"]
14
- s.date = "2015-02-26"
14
+ s.date = "2015-03-13"
15
15
  s.description = "Nutella is a framework to create and run classroom narratives"
16
16
  s.email = "tebemis@gmail.com"
17
17
  s.executables = ["nutella"]
@@ -27,46 +27,53 @@ Gem::Specification.new do |s|
27
27
  "README.md",
28
28
  "Rakefile",
29
29
  "VERSION",
30
- "actors/main_interface/main_interface_bot.rb",
31
- "actors/main_interface/public/index.html",
32
- "actors/main_interface/startup",
33
- "actors/main_interface/views/index.erb",
34
- "actors/main_interface/views/not_found_404.erb",
35
30
  "bin/nutella",
36
31
  "data/index.html",
37
32
  "data/startup",
38
- "lib/cli/nutella_cli.rb",
33
+ "framework_components/example_framework_interface/dandelion-flowers-card.jpg",
34
+ "framework_components/example_framework_interface/index.html",
35
+ "framework_components/main_interface/main_interface_bot.rb",
36
+ "framework_components/main_interface/public/index.html",
37
+ "framework_components/main_interface/startup",
38
+ "framework_components/main_interface/views/index.erb",
39
+ "framework_components/main_interface/views/not_found_404.erb",
40
+ "framework_components/order.json.example",
41
+ "framework_components/runs_list_bot/app_runs_list_bot.rb",
42
+ "lib/commands/broker.rb",
43
+ "lib/commands/checkup.rb",
44
+ "lib/commands/compile.rb",
45
+ "lib/commands/dependencies.rb",
46
+ "lib/commands/help.rb",
47
+ "lib/commands/install.rb",
48
+ "lib/commands/meta/command.rb",
49
+ "lib/commands/meta/run_command.rb",
50
+ "lib/commands/meta/template_command.rb",
51
+ "lib/commands/new.rb",
52
+ "lib/commands/runs.rb",
53
+ "lib/commands/start.rb",
54
+ "lib/commands/stop.rb",
55
+ "lib/commands/template.rb",
39
56
  "lib/config/config.rb",
40
- "lib/config/current_project.rb",
57
+ "lib/config/current_app_utils.rb",
41
58
  "lib/config/persisted_hash.rb",
42
59
  "lib/config/runlist.rb",
43
- "lib/core/command.rb",
44
- "lib/core/commands/broker.rb",
45
- "lib/core/commands/checkup.rb",
46
- "lib/core/commands/compile.rb",
47
- "lib/core/commands/dependencies.rb",
48
- "lib/core/commands/help.rb",
49
- "lib/core/commands/install.rb",
50
- "lib/core/commands/new.rb",
51
- "lib/core/commands/runs.rb",
52
- "lib/core/commands/start.rb",
53
- "lib/core/commands/stop.rb",
54
- "lib/core/commands/template.rb",
60
+ "lib/core/nutella_cli.rb",
55
61
  "lib/core/nutella_core.rb",
56
- "lib/core/run_command.rb",
57
- "lib/core/template_command.rb",
58
- "lib/core/tmux.rb",
59
62
  "lib/logging/nutella_logger-remote.rb",
60
63
  "lib/logging/nutella_logger.rb",
61
64
  "lib/logging/nutella_logging.rb",
62
65
  "lib/nutella_framework.rb",
66
+ "lib/nutella_lib_framework/api.rb",
67
+ "lib/tmux/tmux.rb",
63
68
  "nutella_framework.gemspec",
64
- "test/config/test_config.rb",
65
- "test/config/test_project.rb",
69
+ "test/commands/test_cmd_cli_params_parsing.rb",
70
+ "test/commands/test_command_template.rb",
71
+ "test/config/test_current_app_utils.rb",
72
+ "test/config/test_persisted_hash.rb",
66
73
  "test/config/test_runlist.rb",
74
+ "test/framework_apis/test_framework_api.rb",
67
75
  "test/helper.rb",
68
- "test/logging/test_logging.rb",
69
- "test/test_run_command.rb"
76
+ "test/logging/test_logging.rb"
70
77
  ]
71
78
  s.homepage = "https://github.com/nutella-framework/nutella_framework"
72
79
  s.licenses = ["MIT"]
@@ -82,8 +89,10 @@ Gem::Specification.new do |s|
82
89
  s.add_runtime_dependency(%q<logging>, [">= 1.8.2", "~> 1.8"])
83
90
  s.add_runtime_dependency(%q<git>, [">= 1.2.8", "~> 1.2"])
84
91
  s.add_runtime_dependency(%q<sinatra>, [">= 1.4.5", "~> 1.4.5"])
92
+ s.add_runtime_dependency(%q<thin>, [">= 1.6.3", "~> 1.6.3"])
85
93
  s.add_runtime_dependency(%q<nokogiri>, [">= 1.6.3", "~> 1.6.3"])
86
94
  s.add_runtime_dependency(%q<slop>, [">= 4.0.0", "~> 4.0.0"])
95
+ s.add_runtime_dependency(%q<nutella_lib>, [">= 0.4.0", "~> 0.4.0"])
87
96
  s.add_development_dependency(%q<shoulda>, [">= 3", "~> 3"])
88
97
  s.add_development_dependency(%q<yard>, [">= 0.8.7", "~> 0.8"])
89
98
  s.add_development_dependency(%q<rdoc>, [">= 4.0", "~> 4.0"])
@@ -96,8 +105,10 @@ Gem::Specification.new do |s|
96
105
  s.add_dependency(%q<logging>, [">= 1.8.2", "~> 1.8"])
97
106
  s.add_dependency(%q<git>, [">= 1.2.8", "~> 1.2"])
98
107
  s.add_dependency(%q<sinatra>, [">= 1.4.5", "~> 1.4.5"])
108
+ s.add_dependency(%q<thin>, [">= 1.6.3", "~> 1.6.3"])
99
109
  s.add_dependency(%q<nokogiri>, [">= 1.6.3", "~> 1.6.3"])
100
110
  s.add_dependency(%q<slop>, [">= 4.0.0", "~> 4.0.0"])
111
+ s.add_dependency(%q<nutella_lib>, [">= 0.4.0", "~> 0.4.0"])
101
112
  s.add_dependency(%q<shoulda>, [">= 3", "~> 3"])
102
113
  s.add_dependency(%q<yard>, [">= 0.8.7", "~> 0.8"])
103
114
  s.add_dependency(%q<rdoc>, [">= 4.0", "~> 4.0"])
@@ -111,8 +122,10 @@ Gem::Specification.new do |s|
111
122
  s.add_dependency(%q<logging>, [">= 1.8.2", "~> 1.8"])
112
123
  s.add_dependency(%q<git>, [">= 1.2.8", "~> 1.2"])
113
124
  s.add_dependency(%q<sinatra>, [">= 1.4.5", "~> 1.4.5"])
125
+ s.add_dependency(%q<thin>, [">= 1.6.3", "~> 1.6.3"])
114
126
  s.add_dependency(%q<nokogiri>, [">= 1.6.3", "~> 1.6.3"])
115
127
  s.add_dependency(%q<slop>, [">= 4.0.0", "~> 4.0.0"])
128
+ s.add_dependency(%q<nutella_lib>, [">= 0.4.0", "~> 0.4.0"])
116
129
  s.add_dependency(%q<shoulda>, [">= 3", "~> 3"])
117
130
  s.add_dependency(%q<yard>, [">= 0.8.7", "~> 0.8"])
118
131
  s.add_dependency(%q<rdoc>, [">= 4.0", "~> 4.0"])
@@ -0,0 +1,56 @@
1
+ require 'helper'
2
+
3
+ module Nutella
4
+
5
+ class TestCmdCLIParamsParsing < MiniTest::Test
6
+
7
+ def setup
8
+ @run_cmd = RunCommand.new
9
+ end
10
+
11
+
12
+ should 'parse app long argument' do
13
+ params = @run_cmd.parse_cli_parameters ['--with=bot1,bot2,bot3']
14
+ assert_equal %w(bot1 bot2 bot3), params[:with]
15
+ end
16
+
17
+ should 'parse without long argument' do
18
+ params = @run_cmd.parse_cli_parameters ['--without=botA,botB,botC']
19
+ assert_equal %w(botA botB botC), params[:without]
20
+ end
21
+
22
+ should 'parse with long argument' do
23
+ params = @run_cmd.parse_cli_parameters ['--with=botX,botY,botZ']
24
+ assert_equal %w(botX botY botZ), params[:with]
25
+ end
26
+
27
+ should 'parse one short argument' do
28
+ params = @run_cmd.parse_cli_parameters ['-w=bot1,bot2,bot3']
29
+ assert_equal %w(bot1 bot2 bot3), params[:with]
30
+ end
31
+
32
+ should 'parse two long arguments' do
33
+ params = @run_cmd.parse_cli_parameters %w(--with=bot1,bot2,bot3 --without=botA,botB,botC)
34
+ assert_equal %w(bot1 bot2 bot3), params[:with]
35
+ assert_equal %w(botA botB botC), params[:without]
36
+ end
37
+
38
+ should 'parse two short arguments' do
39
+ params = @run_cmd.parse_cli_parameters %w(-wo=bot1,bot2,bot3 -w=botA,botB,botC)
40
+ assert_equal %w(bot1 bot2 bot3), params[:without]
41
+ assert_equal %w(botA botB botC), params[:with]
42
+ end
43
+
44
+ should 'parse one short and one long argument' do
45
+ params = @run_cmd.parse_cli_parameters %w(--with=bot1,bot2,bot3 -wo=botA,botB,botC)
46
+ assert_equal %w(bot1 bot2 bot3), params[:with]
47
+ assert_equal %w(botA botB botC), params[:without]
48
+ end
49
+
50
+ should 'raise an exception when trying to parse params that do not exist' do
51
+ assert_raises (StandardError) { @run_cmd.parse_cli_parameters %w(--wit=bot1,bot2,bot3 -o=botA,botB,botC) }
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,31 @@
1
+ require 'helper'
2
+
3
+ module Nutella
4
+
5
+ class TestCommandTemplate < MiniTest::Test
6
+
7
+ # 1. Create a fake app
8
+ # New.new.run ['test_app']
9
+ # Dir.chdir 'test_app'
10
+ # Nutella::Install.new.run ['basic-ruby-bot', 'bot1']
11
+ # Dir.chdir '..'
12
+
13
+ # 2. Perform tests
14
+ # should 'this is my first test' do
15
+ # Dir.chdir 'test_app'
16
+ # # Test code here
17
+ # Dir.chdir '..'
18
+ # end
19
+ #
20
+ # should 'this is my second test' do
21
+ # Dir.chdir 'test_app'
22
+ # # Test code here
23
+ # Dir.chdir '..'
24
+ # end
25
+
26
+ # 3. Cleanup
27
+ # MiniTest.after_run { FileUtils.rm_r 'test_app' }
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'helper'
2
+
3
+ module Nutella
4
+
5
+ class TestCurrentAppUtils < MiniTest::Test
6
+
7
+ # def setup
8
+ # Dir.chdir NUTELLA_HOME
9
+ # Nutella.execute_command( 'new', ['test_app'] )
10
+ # Dir.chdir "#{NUTELLA_HOME}test_app"
11
+ # end
12
+ #
13
+ #
14
+ # should 'return true if the dir is a nutella app' do
15
+ # assert Nutella.current_app.exist?
16
+ # end
17
+ #
18
+ # should 'return false if the dir is not a nutella app' do
19
+ # Dir.chdir NUTELLA_HOME
20
+ # refute Nutella.current_app.exist?
21
+ # end
22
+ #
23
+ # should 'return the correct version of nutella as read from the app configuration file' do
24
+ # assert_equal File.open("#{NUTELLA_HOME}VERSION", "rb").read, Nutella.current_app.config['nutella_version']
25
+ # end
26
+ #
27
+ #
28
+ # def teardown
29
+ # FileUtils.rm_rf "#{NUTELLA_HOME}test_app"
30
+ # Dir.chdir NUTELLA_HOME
31
+ # end
32
+
33
+ end
34
+ end