roby 0.8.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (644) hide show
  1. checksums.yaml +7 -0
  2. data/.deep-cover.rb +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +24 -0
  5. data/.simplecov +10 -0
  6. data/.travis.yml +17 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +15 -0
  9. data/README.md +11 -0
  10. data/Rakefile +47 -177
  11. data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
  12. data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
  13. data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
  14. data/benchmark/{genom.rb → attic/genom.rb} +0 -0
  15. data/benchmark/attic/transactions.rb +62 -0
  16. data/benchmark/plan_basic_operations.rb +28 -0
  17. data/benchmark/relations/graph.rb +63 -0
  18. data/benchmark/ruby/identity.rb +18 -0
  19. data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
  20. data/benchmark/ruby/yield_vs_block.rb +35 -0
  21. data/benchmark/run +5 -0
  22. data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
  23. data/benchmark/transactions.rb +99 -51
  24. data/bin/roby +38 -197
  25. data/bin/roby-display +14 -0
  26. data/bin/roby-log +3 -176
  27. data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
  28. data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
  29. data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
  30. data/doc/guide/{src → attic}/abstraction/index.page +1 -1
  31. data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
  32. data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
  33. data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
  34. data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
  35. data/doc/guide/attic/cycle/error_handling.page +98 -0
  36. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
  37. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
  38. data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
  39. data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
  40. data/doc/guide/{src → attic}/cycle/index.page +1 -1
  41. data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
  42. data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
  43. data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
  44. data/doc/guide/attic/plans/building_plans.page +89 -0
  45. data/doc/guide/attic/plans/code.page +192 -0
  46. data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
  47. data/doc/guide/attic/plans/index.page +7 -0
  48. data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
  49. data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
  50. data/doc/guide/attic/plans/querying_plans.page +5 -0
  51. data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
  52. data/doc/guide/config.yaml +7 -4
  53. data/doc/guide/ext/extended_menu.rb +29 -0
  54. data/doc/guide/ext/init.rb +6 -0
  55. data/doc/guide/ext/rdoc_links.rb +7 -6
  56. data/doc/guide/src/advanced_concepts/history.page +5 -0
  57. data/doc/guide/src/advanced_concepts/index.page +11 -0
  58. data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
  59. data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
  60. data/doc/guide/src/advanced_concepts/transactions.page +5 -0
  61. data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
  62. data/doc/guide/src/base.template +96 -0
  63. data/doc/guide/src/basics_shell_header.txt +5 -7
  64. data/doc/guide/src/building/action_coordination.page +96 -0
  65. data/doc/guide/src/building/actions.page +124 -0
  66. data/doc/guide/src/building/file_layout.page +71 -0
  67. data/doc/guide/src/building/index.page +50 -0
  68. data/doc/guide/src/building/patterns.page +86 -0
  69. data/doc/guide/src/building/patterns_forwarding.png +0 -0
  70. data/doc/guide/src/building/patterns_forwarding.svg +277 -0
  71. data/doc/guide/src/building/runtime.page +95 -0
  72. data/doc/guide/src/building/task_models.page +94 -0
  73. data/doc/guide/src/building/tasks.page +284 -0
  74. data/doc/guide/src/concepts/error_handling.page +100 -0
  75. data/doc/guide/src/concepts/exception_propagation.png +0 -0
  76. data/doc/guide/src/concepts/exception_propagation.svg +445 -0
  77. data/doc/guide/src/concepts/execution.page +85 -0
  78. data/doc/guide/src/concepts/execution.png +0 -0
  79. data/doc/guide/src/concepts/execution.svg +573 -0
  80. data/doc/guide/src/concepts/execution_cycle.png +0 -0
  81. data/doc/guide/src/concepts/garbage_collection.page +57 -0
  82. data/doc/guide/src/concepts/index.page +27 -0
  83. data/doc/guide/src/concepts/plans.page +101 -0
  84. data/doc/guide/src/concepts/policy.page +31 -0
  85. data/doc/guide/src/concepts/reactor.page +61 -0
  86. data/doc/guide/src/concepts/simple_plan_example.png +0 -0
  87. data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
  88. data/doc/guide/src/default.template +9 -74
  89. data/doc/guide/src/event_relations/forward.page +71 -0
  90. data/doc/guide/src/event_relations/index.page +12 -0
  91. data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
  92. data/doc/guide/src/event_relations/signal.page +55 -0
  93. data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
  94. data/doc/guide/src/htmldoc.metainfo +21 -8
  95. data/doc/guide/src/index.page +8 -3
  96. data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
  97. data/doc/guide/src/installation/publications.page +14 -0
  98. data/doc/guide/src/{introduction → installation}/videos.page +14 -7
  99. data/doc/guide/src/interacting/index.page +16 -0
  100. data/doc/guide/src/interacting/run.page +33 -0
  101. data/doc/guide/src/interacting/shell.page +95 -0
  102. data/doc/guide/src/plugins/creating_plugins.page +72 -0
  103. data/doc/guide/src/plugins/index.page +27 -5
  104. data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
  105. data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
  106. data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
  107. data/doc/guide/src/style_screen.css +687 -0
  108. data/doc/guide/src/task_relations/dependency.page +107 -0
  109. data/doc/guide/src/task_relations/executed_by.page +77 -0
  110. data/doc/guide/src/task_relations/index.page +12 -0
  111. data/doc/guide/src/task_relations/new_relations.page +119 -0
  112. data/doc/guide/src/task_relations/planned_by.page +46 -0
  113. data/doc/guide/src/tutorial/app.page +117 -0
  114. data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
  115. data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
  116. data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
  117. data/doc/guide/src/tutorial/events.page +195 -0
  118. data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
  119. data/doc/guide/src/tutorial/index.page +13 -0
  120. data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
  121. data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
  122. data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
  123. data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
  124. data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
  125. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
  126. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
  127. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
  128. data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
  129. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
  130. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
  131. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
  132. data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
  133. data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
  134. data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
  135. data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
  136. data/doc/guide/src/tutorial/relations_display.page +153 -0
  137. data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
  138. data/doc/guide/src/tutorial/shell.page +121 -0
  139. data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
  140. data/doc/guide/src/tutorial/tasks.page +374 -0
  141. data/lib/roby.rb +102 -47
  142. data/lib/roby/actions.rb +17 -0
  143. data/lib/roby/actions/action.rb +80 -0
  144. data/lib/roby/actions/interface.rb +45 -0
  145. data/lib/roby/actions/library.rb +23 -0
  146. data/lib/roby/actions/models/action.rb +224 -0
  147. data/lib/roby/actions/models/coordination_action.rb +58 -0
  148. data/lib/roby/actions/models/interface.rb +22 -0
  149. data/lib/roby/actions/models/interface_base.rb +294 -0
  150. data/lib/roby/actions/models/library.rb +12 -0
  151. data/lib/roby/actions/models/method_action.rb +90 -0
  152. data/lib/roby/actions/task.rb +114 -0
  153. data/lib/roby/and_generator.rb +125 -0
  154. data/lib/roby/app.rb +2795 -829
  155. data/lib/roby/app/autotest_console_reporter.rb +138 -0
  156. data/lib/roby/app/base.rb +21 -0
  157. data/lib/roby/app/cucumber.rb +2 -0
  158. data/lib/roby/app/cucumber/controller.rb +439 -0
  159. data/lib/roby/app/cucumber/helpers.rb +280 -0
  160. data/lib/roby/app/cucumber/world.rb +32 -0
  161. data/lib/roby/app/debug.rb +136 -0
  162. data/lib/roby/app/gen.rb +2 -0
  163. data/lib/roby/app/rake.rb +178 -38
  164. data/lib/roby/app/robot_config.rb +9 -0
  165. data/lib/roby/app/robot_names.rb +115 -0
  166. data/lib/roby/app/run.rb +3 -2
  167. data/lib/roby/app/scripts.rb +72 -0
  168. data/lib/roby/app/scripts/autotest.rb +173 -0
  169. data/lib/roby/app/scripts/display.rb +2 -0
  170. data/lib/roby/app/scripts/restart.rb +52 -0
  171. data/lib/roby/app/scripts/results.rb +17 -8
  172. data/lib/roby/app/scripts/run.rb +155 -24
  173. data/lib/roby/app/scripts/shell.rb +147 -62
  174. data/lib/roby/app/scripts/test.rb +107 -22
  175. data/lib/roby/app/test_reporter.rb +74 -0
  176. data/lib/roby/app/test_server.rb +159 -0
  177. data/lib/roby/app/vagrant.rb +47 -0
  178. data/lib/roby/backports.rb +16 -0
  179. data/lib/roby/cli/display.rb +190 -0
  180. data/lib/roby/cli/exceptions.rb +17 -0
  181. data/lib/roby/cli/gen/actions/class.rb +5 -0
  182. data/lib/roby/cli/gen/actions/test.rb +6 -0
  183. data/lib/roby/cli/gen/app/.yardopts +6 -0
  184. data/lib/roby/cli/gen/app/README.md +28 -0
  185. data/lib/roby/cli/gen/app/Rakefile +15 -0
  186. data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
  187. data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
  188. data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
  189. data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
  190. data/lib/roby/cli/gen/class/class.rb +6 -0
  191. data/lib/roby/cli/gen/class/test.rb +7 -0
  192. data/lib/roby/cli/gen/helpers.rb +203 -0
  193. data/lib/roby/cli/gen/module/module.rb +5 -0
  194. data/lib/roby/cli/gen/module/test.rb +6 -0
  195. data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
  196. data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
  197. data/lib/roby/cli/gen/task/class.rb +44 -0
  198. data/lib/roby/cli/gen/task/test.rb +6 -0
  199. data/lib/roby/cli/gen_main.rb +120 -0
  200. data/lib/roby/cli/log.rb +276 -0
  201. data/lib/roby/cli/log/flamegraph.html +499 -0
  202. data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
  203. data/lib/roby/cli/main.rb +153 -0
  204. data/lib/roby/coordination.rb +60 -0
  205. data/lib/roby/coordination/action_script.rb +25 -0
  206. data/lib/roby/coordination/action_state_machine.rb +125 -0
  207. data/lib/roby/coordination/actions.rb +106 -0
  208. data/lib/roby/coordination/base.rb +145 -0
  209. data/lib/roby/coordination/calculus.rb +40 -0
  210. data/lib/roby/coordination/child.rb +28 -0
  211. data/lib/roby/coordination/event.rb +29 -0
  212. data/lib/roby/coordination/fault_handler.rb +25 -0
  213. data/lib/roby/coordination/fault_handling_task.rb +13 -0
  214. data/lib/roby/coordination/fault_response_table.rb +110 -0
  215. data/lib/roby/coordination/models/action_script.rb +64 -0
  216. data/lib/roby/coordination/models/action_state_machine.rb +224 -0
  217. data/lib/roby/coordination/models/actions.rb +191 -0
  218. data/lib/roby/coordination/models/arguments.rb +55 -0
  219. data/lib/roby/coordination/models/base.rb +176 -0
  220. data/lib/roby/coordination/models/capture.rb +86 -0
  221. data/lib/roby/coordination/models/child.rb +35 -0
  222. data/lib/roby/coordination/models/event.rb +41 -0
  223. data/lib/roby/coordination/models/exceptions.rb +42 -0
  224. data/lib/roby/coordination/models/fault_handler.rb +219 -0
  225. data/lib/roby/coordination/models/fault_response_table.rb +77 -0
  226. data/lib/roby/coordination/models/root.rb +22 -0
  227. data/lib/roby/coordination/models/script.rb +283 -0
  228. data/lib/roby/coordination/models/task.rb +184 -0
  229. data/lib/roby/coordination/models/task_from_action.rb +50 -0
  230. data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
  231. data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
  232. data/lib/roby/coordination/models/task_from_variable.rb +27 -0
  233. data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
  234. data/lib/roby/coordination/models/variable.rb +32 -0
  235. data/lib/roby/coordination/script.rb +200 -0
  236. data/lib/roby/coordination/script_instruction.rb +12 -0
  237. data/lib/roby/coordination/task.rb +45 -0
  238. data/lib/roby/coordination/task_base.rb +69 -0
  239. data/lib/roby/coordination/task_script.rb +293 -0
  240. data/lib/roby/coordination/task_state_machine.rb +308 -0
  241. data/lib/roby/decision_control.rb +33 -21
  242. data/lib/roby/distributed_object.rb +76 -0
  243. data/lib/roby/droby.rb +17 -0
  244. data/lib/roby/droby/droby_id.rb +6 -0
  245. data/lib/roby/droby/enable.rb +153 -0
  246. data/lib/roby/droby/event_logger.rb +189 -0
  247. data/lib/roby/droby/event_logging.rb +57 -0
  248. data/lib/roby/droby/exceptions.rb +14 -0
  249. data/lib/roby/droby/identifiable.rb +22 -0
  250. data/lib/roby/droby/logfile.rb +141 -0
  251. data/lib/roby/droby/logfile/client.rb +176 -0
  252. data/lib/roby/droby/logfile/file_format.md +97 -0
  253. data/lib/roby/droby/logfile/index.rb +117 -0
  254. data/lib/roby/droby/logfile/reader.rb +139 -0
  255. data/lib/roby/droby/logfile/server.rb +199 -0
  256. data/lib/roby/droby/logfile/writer.rb +114 -0
  257. data/lib/roby/droby/marshal.rb +264 -0
  258. data/lib/roby/droby/marshallable.rb +12 -0
  259. data/lib/roby/droby/null_event_logger.rb +25 -0
  260. data/lib/roby/droby/object_manager.rb +205 -0
  261. data/lib/roby/droby/peer_id.rb +6 -0
  262. data/lib/roby/droby/plan_rebuilder.rb +373 -0
  263. data/lib/roby/droby/rebuilt_plan.rb +160 -0
  264. data/lib/roby/droby/remote_droby_id.rb +6 -0
  265. data/lib/roby/droby/timepoints.rb +205 -0
  266. data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
  267. data/lib/roby/droby/timepoints_ctf.rb +125 -0
  268. data/lib/roby/droby/v5.rb +14 -0
  269. data/lib/roby/droby/v5/builtin.rb +120 -0
  270. data/lib/roby/droby/v5/droby_class.rb +45 -0
  271. data/lib/roby/droby/v5/droby_constant.rb +81 -0
  272. data/lib/roby/droby/v5/droby_dump.rb +1026 -0
  273. data/lib/roby/droby/v5/droby_id.rb +44 -0
  274. data/lib/roby/droby/v5/droby_model.rb +82 -0
  275. data/lib/roby/droby/v5/peer_id.rb +10 -0
  276. data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
  277. data/lib/roby/event.rb +79 -957
  278. data/lib/roby/event_constraints.rb +835 -0
  279. data/lib/roby/event_generator.rb +1047 -0
  280. data/lib/roby/event_structure/causal_link.rb +6 -0
  281. data/lib/roby/event_structure/forwarding.rb +6 -0
  282. data/lib/roby/event_structure/precedence.rb +7 -0
  283. data/lib/roby/event_structure/signal.rb +8 -0
  284. data/lib/roby/event_structure/temporal_constraints.rb +640 -0
  285. data/lib/roby/exceptions.rb +446 -152
  286. data/lib/roby/executable_plan.rb +549 -0
  287. data/lib/roby/execution_engine.rb +1997 -950
  288. data/lib/roby/filter_generator.rb +26 -0
  289. data/lib/roby/gui/chronicle_view.rb +225 -0
  290. data/lib/roby/gui/chronicle_widget.rb +925 -0
  291. data/lib/roby/gui/dot_id.rb +11 -0
  292. data/lib/roby/gui/exception_view.rb +44 -0
  293. data/lib/roby/gui/log_display.rb +273 -0
  294. data/lib/roby/gui/model_views.rb +2 -0
  295. data/lib/roby/gui/model_views/action_interface.rb +53 -0
  296. data/lib/roby/gui/model_views/task.rb +47 -0
  297. data/lib/roby/gui/model_views/task.rhtml +41 -0
  298. data/lib/roby/gui/object_info_view.rb +89 -0
  299. data/lib/roby/gui/plan_dot_layout.rb +427 -0
  300. data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
  301. data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
  302. data/lib/roby/gui/relations_view.rb +278 -0
  303. data/lib/roby/gui/relations_view/relations.ui +139 -0
  304. data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
  305. data/lib/roby/gui/relations_view/relations_config.rb +292 -0
  306. data/lib/roby/gui/relations_view/relations_view.ui +53 -0
  307. data/lib/roby/gui/scheduler_view.css +24 -0
  308. data/lib/roby/gui/scheduler_view.rb +46 -0
  309. data/lib/roby/gui/scheduler_view.rhtml +53 -0
  310. data/lib/roby/gui/stepping.rb +93 -0
  311. data/lib/roby/gui/stepping.ui +181 -0
  312. data/lib/roby/gui/styles.rb +81 -0
  313. data/lib/roby/gui/task_display_configuration.rb +42 -0
  314. data/lib/roby/gui/task_state_at.rb +38 -0
  315. data/lib/roby/hooks.rb +26 -0
  316. data/lib/roby/interface.rb +136 -469
  317. data/lib/roby/interface/async.rb +20 -0
  318. data/lib/roby/interface/async/action_monitor.rb +188 -0
  319. data/lib/roby/interface/async/interface.rb +498 -0
  320. data/lib/roby/interface/async/job_monitor.rb +213 -0
  321. data/lib/roby/interface/async/log.rb +238 -0
  322. data/lib/roby/interface/async/new_job_listener.rb +79 -0
  323. data/lib/roby/interface/async/ui_connector.rb +183 -0
  324. data/lib/roby/interface/client.rb +553 -0
  325. data/lib/roby/interface/command.rb +24 -0
  326. data/lib/roby/interface/command_argument.rb +16 -0
  327. data/lib/roby/interface/command_library.rb +92 -0
  328. data/lib/roby/interface/droby_channel.rb +174 -0
  329. data/lib/roby/interface/exceptions.rb +22 -0
  330. data/lib/roby/interface/interface.rb +655 -0
  331. data/lib/roby/interface/job.rb +47 -0
  332. data/lib/roby/interface/rest.rb +10 -0
  333. data/lib/roby/interface/rest/api.rb +29 -0
  334. data/lib/roby/interface/rest/helpers.rb +24 -0
  335. data/lib/roby/interface/rest/server.rb +212 -0
  336. data/lib/roby/interface/server.rb +154 -0
  337. data/lib/roby/interface/shell_client.rb +468 -0
  338. data/lib/roby/interface/shell_subcommand.rb +24 -0
  339. data/lib/roby/interface/subcommand_client.rb +35 -0
  340. data/lib/roby/interface/tcp.rb +168 -0
  341. data/lib/roby/models/arguments.rb +112 -0
  342. data/lib/roby/models/plan_object.rb +83 -0
  343. data/lib/roby/models/task.rb +835 -0
  344. data/lib/roby/models/task_event.rb +62 -0
  345. data/lib/roby/models/task_service.rb +78 -0
  346. data/lib/roby/or_generator.rb +88 -0
  347. data/lib/roby/plan.rb +1751 -864
  348. data/lib/roby/plan_object.rb +611 -0
  349. data/lib/roby/plan_service.rb +200 -0
  350. data/lib/roby/promise.rb +332 -0
  351. data/lib/roby/queries.rb +23 -0
  352. data/lib/roby/queries/and_matcher.rb +32 -0
  353. data/lib/roby/queries/any.rb +27 -0
  354. data/lib/roby/queries/code_error_matcher.rb +58 -0
  355. data/lib/roby/queries/event_generator_matcher.rb +9 -0
  356. data/lib/roby/queries/execution_exception_matcher.rb +165 -0
  357. data/lib/roby/queries/index.rb +165 -0
  358. data/lib/roby/queries/localized_error_matcher.rb +149 -0
  359. data/lib/roby/queries/matcher_base.rb +107 -0
  360. data/lib/roby/queries/none.rb +27 -0
  361. data/lib/roby/queries/not_matcher.rb +30 -0
  362. data/lib/roby/queries/op_matcher.rb +8 -0
  363. data/lib/roby/queries/or_matcher.rb +30 -0
  364. data/lib/roby/queries/plan_object_matcher.rb +363 -0
  365. data/lib/roby/queries/query.rb +188 -0
  366. data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
  367. data/lib/roby/queries/task_matcher.rb +344 -0
  368. data/lib/roby/relations.rb +42 -678
  369. data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
  370. data/lib/roby/relations/directed_relation_support.rb +268 -0
  371. data/lib/roby/relations/event_relation_graph.rb +19 -0
  372. data/lib/roby/relations/fork_merge_visitor.rb +154 -0
  373. data/lib/roby/relations/graph.rb +533 -0
  374. data/lib/roby/relations/models/directed_relation_support.rb +11 -0
  375. data/lib/roby/relations/models/graph.rb +75 -0
  376. data/lib/roby/relations/models/task_relation_graph.rb +18 -0
  377. data/lib/roby/relations/space.rb +380 -0
  378. data/lib/roby/relations/task_relation_graph.rb +20 -0
  379. data/lib/roby/robot.rb +85 -38
  380. data/lib/roby/schedulers/basic.rb +155 -25
  381. data/lib/roby/schedulers/null.rb +20 -0
  382. data/lib/roby/schedulers/reporting.rb +31 -0
  383. data/lib/roby/schedulers/state.rb +129 -0
  384. data/lib/roby/schedulers/temporal.rb +91 -0
  385. data/lib/roby/singletons.rb +87 -0
  386. data/lib/roby/standalone.rb +4 -2
  387. data/lib/roby/standard_errors.rb +405 -82
  388. data/lib/roby/state.rb +6 -3
  389. data/lib/roby/state/conf_model.rb +5 -0
  390. data/lib/roby/state/events.rb +181 -95
  391. data/lib/roby/state/goal_model.rb +77 -0
  392. data/lib/roby/state/open_struct.rb +591 -0
  393. data/lib/roby/state/open_struct_model.rb +68 -0
  394. data/lib/roby/state/pos.rb +45 -45
  395. data/lib/roby/state/shapes.rb +11 -11
  396. data/lib/roby/state/state_model.rb +303 -0
  397. data/lib/roby/state/task.rb +43 -0
  398. data/lib/roby/support.rb +88 -148
  399. data/lib/roby/task.rb +1361 -1750
  400. data/lib/roby/task_arguments.rb +428 -0
  401. data/lib/roby/task_event.rb +127 -0
  402. data/lib/roby/task_event_generator.rb +337 -0
  403. data/lib/roby/task_service.rb +6 -0
  404. data/lib/roby/task_structure/conflicts.rb +104 -0
  405. data/lib/roby/task_structure/dependency.rb +932 -0
  406. data/lib/roby/task_structure/error_handling.rb +118 -0
  407. data/lib/roby/task_structure/executed_by.rb +234 -0
  408. data/lib/roby/task_structure/planned_by.rb +90 -0
  409. data/lib/roby/tasks/aggregator.rb +37 -0
  410. data/lib/roby/tasks/external_process.rb +275 -0
  411. data/lib/roby/tasks/group.rb +27 -0
  412. data/lib/roby/tasks/null.rb +19 -0
  413. data/lib/roby/tasks/parallel.rb +43 -0
  414. data/lib/roby/tasks/sequence.rb +88 -0
  415. data/lib/roby/tasks/simple.rb +21 -0
  416. data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
  417. data/lib/roby/tasks/timeout.rb +17 -0
  418. data/lib/roby/tasks/virtual.rb +55 -0
  419. data/lib/roby/template_plan.rb +7 -0
  420. data/lib/roby/test/aruba_minitest.rb +74 -0
  421. data/lib/roby/test/assertion.rb +16 -0
  422. data/lib/roby/test/assertions.rb +490 -0
  423. data/lib/roby/test/common.rb +368 -591
  424. data/lib/roby/test/dsl.rb +149 -0
  425. data/lib/roby/test/error.rb +18 -0
  426. data/lib/roby/test/event_reporter.rb +83 -0
  427. data/lib/roby/test/execution_expectations.rb +1134 -0
  428. data/lib/roby/test/expect_execution.rb +151 -0
  429. data/lib/roby/test/minitest_helpers.rb +166 -0
  430. data/lib/roby/test/roby_app_helpers.rb +200 -0
  431. data/lib/roby/test/run_planners.rb +155 -0
  432. data/lib/roby/test/self.rb +112 -0
  433. data/lib/roby/test/spec.rb +198 -0
  434. data/lib/roby/test/tasks/empty_task.rb +4 -4
  435. data/lib/roby/test/tasks/goto.rb +28 -27
  436. data/lib/roby/test/teardown_plans.rb +100 -0
  437. data/lib/roby/test/testcase.rb +239 -307
  438. data/lib/roby/test/tools.rb +159 -155
  439. data/lib/roby/test/validate_state_machine.rb +75 -0
  440. data/lib/roby/transaction.rb +1125 -0
  441. data/lib/roby/transaction/event_generator_proxy.rb +63 -0
  442. data/lib/roby/transaction/plan_object_proxy.rb +99 -0
  443. data/lib/roby/transaction/plan_service_proxy.rb +43 -0
  444. data/lib/roby/transaction/proxying.rb +120 -0
  445. data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
  446. data/lib/roby/transaction/task_proxy.rb +135 -0
  447. data/lib/roby/until_generator.rb +30 -0
  448. data/lib/roby/version.rb +5 -0
  449. data/lib/roby/yard.rb +169 -0
  450. data/lib/yard-roby.rb +1 -0
  451. data/manifest.xml +32 -6
  452. data/roby.gemspec +59 -0
  453. metadata +788 -587
  454. data/Manifest.txt +0 -321
  455. data/NOTES +0 -4
  456. data/README.txt +0 -166
  457. data/TODO.txt +0 -146
  458. data/app/README.txt +0 -24
  459. data/app/Rakefile +0 -8
  460. data/app/config/ROBOT.rb +0 -5
  461. data/app/config/init.rb +0 -33
  462. data/app/config/roby.yml +0 -3
  463. data/app/controllers/ROBOT.rb +0 -2
  464. data/app/planners/ROBOT/main.rb +0 -6
  465. data/app/planners/main.rb +0 -5
  466. data/app/scripts/distributed +0 -3
  467. data/app/scripts/generate/bookmarks +0 -3
  468. data/app/scripts/replay +0 -3
  469. data/app/scripts/results +0 -3
  470. data/app/scripts/run +0 -3
  471. data/app/scripts/server +0 -3
  472. data/app/scripts/shell +0 -3
  473. data/app/scripts/test +0 -3
  474. data/app/tasks/.gitattributes +0 -0
  475. data/app/tasks/ROBOT/.gitattributes +0 -0
  476. data/bin/roby-shell +0 -25
  477. data/doc/guide/src/basics/app.page +0 -139
  478. data/doc/guide/src/basics/index.page +0 -11
  479. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  480. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  481. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  482. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  483. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  484. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  485. data/doc/guide/src/basics/relations_display.page +0 -203
  486. data/doc/guide/src/basics/shell.page +0 -102
  487. data/doc/guide/src/default.css +0 -319
  488. data/doc/guide/src/introduction/index.page +0 -29
  489. data/doc/guide/src/introduction/publications.page +0 -14
  490. data/doc/guide/src/relations/dependency.page +0 -89
  491. data/doc/guide/src/relations/index.page +0 -12
  492. data/ext/droby/dump.cc +0 -175
  493. data/ext/droby/extconf.rb +0 -3
  494. data/ext/graph/algorithm.cc +0 -746
  495. data/ext/graph/extconf.rb +0 -7
  496. data/ext/graph/graph.cc +0 -575
  497. data/ext/graph/graph.hh +0 -183
  498. data/ext/graph/iterator_sequence.hh +0 -102
  499. data/ext/graph/undirected_dfs.hh +0 -226
  500. data/ext/graph/undirected_graph.hh +0 -421
  501. data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
  502. data/lib/roby/app/scripts/replay.rb +0 -31
  503. data/lib/roby/app/scripts/server.rb +0 -18
  504. data/lib/roby/basic_object.rb +0 -151
  505. data/lib/roby/config.rb +0 -14
  506. data/lib/roby/distributed.rb +0 -36
  507. data/lib/roby/distributed/base.rb +0 -448
  508. data/lib/roby/distributed/communication.rb +0 -875
  509. data/lib/roby/distributed/connection_space.rb +0 -616
  510. data/lib/roby/distributed/distributed_object.rb +0 -206
  511. data/lib/roby/distributed/drb.rb +0 -62
  512. data/lib/roby/distributed/notifications.rb +0 -531
  513. data/lib/roby/distributed/peer.rb +0 -555
  514. data/lib/roby/distributed/protocol.rb +0 -529
  515. data/lib/roby/distributed/proxy.rb +0 -343
  516. data/lib/roby/distributed/subscription.rb +0 -311
  517. data/lib/roby/distributed/transaction.rb +0 -498
  518. data/lib/roby/external_process_task.rb +0 -225
  519. data/lib/roby/graph.rb +0 -160
  520. data/lib/roby/log.rb +0 -3
  521. data/lib/roby/log/chronicle.rb +0 -303
  522. data/lib/roby/log/console.rb +0 -74
  523. data/lib/roby/log/data_stream.rb +0 -275
  524. data/lib/roby/log/dot.rb +0 -279
  525. data/lib/roby/log/event_stream.rb +0 -161
  526. data/lib/roby/log/file.rb +0 -396
  527. data/lib/roby/log/gui/basic_display.ui +0 -83
  528. data/lib/roby/log/gui/basic_display_ui.rb +0 -89
  529. data/lib/roby/log/gui/chronicle.rb +0 -26
  530. data/lib/roby/log/gui/chronicle_view.rb +0 -40
  531. data/lib/roby/log/gui/chronicle_view.ui +0 -70
  532. data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
  533. data/lib/roby/log/gui/data_displays.rb +0 -171
  534. data/lib/roby/log/gui/data_displays.ui +0 -155
  535. data/lib/roby/log/gui/data_displays_ui.rb +0 -146
  536. data/lib/roby/log/gui/notifications.rb +0 -26
  537. data/lib/roby/log/gui/relations.rb +0 -269
  538. data/lib/roby/log/gui/relations.ui +0 -123
  539. data/lib/roby/log/gui/relations_ui.rb +0 -120
  540. data/lib/roby/log/gui/relations_view.rb +0 -185
  541. data/lib/roby/log/gui/relations_view.ui +0 -149
  542. data/lib/roby/log/gui/relations_view_ui.rb +0 -144
  543. data/lib/roby/log/gui/replay.rb +0 -366
  544. data/lib/roby/log/gui/replay_controls.rb +0 -206
  545. data/lib/roby/log/gui/replay_controls.ui +0 -282
  546. data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
  547. data/lib/roby/log/gui/runtime.rb +0 -130
  548. data/lib/roby/log/hooks.rb +0 -186
  549. data/lib/roby/log/logger.rb +0 -203
  550. data/lib/roby/log/notifications.rb +0 -244
  551. data/lib/roby/log/plan_rebuilder.rb +0 -468
  552. data/lib/roby/log/relations.rb +0 -1084
  553. data/lib/roby/log/server.rb +0 -547
  554. data/lib/roby/log/sqlite.rb +0 -47
  555. data/lib/roby/log/timings.rb +0 -233
  556. data/lib/roby/plan-object.rb +0 -371
  557. data/lib/roby/planning.rb +0 -13
  558. data/lib/roby/planning/loops.rb +0 -309
  559. data/lib/roby/planning/model.rb +0 -1012
  560. data/lib/roby/planning/task.rb +0 -180
  561. data/lib/roby/query.rb +0 -655
  562. data/lib/roby/relations/conflicts.rb +0 -67
  563. data/lib/roby/relations/dependency.rb +0 -358
  564. data/lib/roby/relations/ensured.rb +0 -19
  565. data/lib/roby/relations/error_handling.rb +0 -22
  566. data/lib/roby/relations/events.rb +0 -7
  567. data/lib/roby/relations/executed_by.rb +0 -208
  568. data/lib/roby/relations/influence.rb +0 -10
  569. data/lib/roby/relations/planned_by.rb +0 -63
  570. data/lib/roby/state/information.rb +0 -55
  571. data/lib/roby/state/state.rb +0 -367
  572. data/lib/roby/task-operations.rb +0 -186
  573. data/lib/roby/task_index.rb +0 -80
  574. data/lib/roby/test/distributed.rb +0 -230
  575. data/lib/roby/test/tasks/simple_task.rb +0 -23
  576. data/lib/roby/transactions.rb +0 -507
  577. data/lib/roby/transactions/proxy.rb +0 -325
  578. data/plugins/fault_injection/History.txt +0 -4
  579. data/plugins/fault_injection/README.txt +0 -34
  580. data/plugins/fault_injection/Rakefile +0 -12
  581. data/plugins/fault_injection/TODO.txt +0 -0
  582. data/plugins/fault_injection/app.rb +0 -52
  583. data/plugins/fault_injection/fault_injection.rb +0 -89
  584. data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
  585. data/plugins/subsystems/README.txt +0 -37
  586. data/plugins/subsystems/Rakefile +0 -13
  587. data/plugins/subsystems/app.rb +0 -182
  588. data/plugins/subsystems/test/app/README +0 -24
  589. data/plugins/subsystems/test/app/Rakefile +0 -8
  590. data/plugins/subsystems/test/app/config/app.yml +0 -71
  591. data/plugins/subsystems/test/app/config/init.rb +0 -12
  592. data/plugins/subsystems/test/app/config/roby.yml +0 -3
  593. data/plugins/subsystems/test/app/planners/main.rb +0 -20
  594. data/plugins/subsystems/test/app/scripts/distributed +0 -3
  595. data/plugins/subsystems/test/app/scripts/replay +0 -3
  596. data/plugins/subsystems/test/app/scripts/results +0 -3
  597. data/plugins/subsystems/test/app/scripts/run +0 -3
  598. data/plugins/subsystems/test/app/scripts/server +0 -3
  599. data/plugins/subsystems/test/app/scripts/shell +0 -3
  600. data/plugins/subsystems/test/app/scripts/test +0 -3
  601. data/plugins/subsystems/test/app/tasks/services.rb +0 -15
  602. data/plugins/subsystems/test/test_subsystems.rb +0 -78
  603. data/test/distributed/test_communication.rb +0 -195
  604. data/test/distributed/test_connection.rb +0 -284
  605. data/test/distributed/test_execution.rb +0 -378
  606. data/test/distributed/test_mixed_plan.rb +0 -341
  607. data/test/distributed/test_plan_notifications.rb +0 -238
  608. data/test/distributed/test_protocol.rb +0 -525
  609. data/test/distributed/test_query.rb +0 -106
  610. data/test/distributed/test_remote_plan.rb +0 -491
  611. data/test/distributed/test_transaction.rb +0 -466
  612. data/test/mockups/external_process +0 -28
  613. data/test/mockups/tasks.rb +0 -27
  614. data/test/planning/test_loops.rb +0 -432
  615. data/test/planning/test_model.rb +0 -427
  616. data/test/planning/test_task.rb +0 -126
  617. data/test/relations/test_conflicts.rb +0 -42
  618. data/test/relations/test_dependency.rb +0 -324
  619. data/test/relations/test_ensured.rb +0 -38
  620. data/test/relations/test_executed_by.rb +0 -224
  621. data/test/relations/test_planned_by.rb +0 -56
  622. data/test/suite_core.rb +0 -29
  623. data/test/suite_distributed.rb +0 -10
  624. data/test/suite_planning.rb +0 -4
  625. data/test/suite_relations.rb +0 -8
  626. data/test/tasks/test_external_process.rb +0 -126
  627. data/test/tasks/test_thread_task.rb +0 -70
  628. data/test/test_bgl.rb +0 -528
  629. data/test/test_event.rb +0 -969
  630. data/test/test_exceptions.rb +0 -591
  631. data/test/test_execution_engine.rb +0 -987
  632. data/test/test_gui.rb +0 -20
  633. data/test/test_interface.rb +0 -43
  634. data/test/test_log.rb +0 -125
  635. data/test/test_log_server.rb +0 -133
  636. data/test/test_plan.rb +0 -418
  637. data/test/test_query.rb +0 -424
  638. data/test/test_relations.rb +0 -260
  639. data/test/test_state.rb +0 -432
  640. data/test/test_support.rb +0 -16
  641. data/test/test_task.rb +0 -1181
  642. data/test/test_testcase.rb +0 -138
  643. data/test/test_transactions.rb +0 -610
  644. data/test/test_transactions_proxy.rb +0 -216
@@ -1,19 +1,31 @@
1
- class Exception
2
- def pretty_print(pp)
3
- pp.text "#{message} (#{self.class.name})"
4
- pp.breakable
5
- Roby.pretty_print_backtrace(pp, backtrace)
6
- end
7
-
8
- # True if +obj+ is involved in this error
9
- def involved_plan_object?(obj)
10
- false
11
- end
12
- end
13
1
 
14
2
  module Roby
3
+ class UserError < RuntimeError
4
+ def user_error?; true end
5
+ end
15
6
  class ConfigError < RuntimeError; end
16
7
  class ModelViolation < RuntimeError; end
8
+ class InternalError < RuntimeError; end
9
+
10
+ class << self
11
+ attr_reader :colorizer
12
+ end
13
+ @colorizer = Pastel.new
14
+ def self.color(string, *colors)
15
+ colorizer.decorate(string, *colors)
16
+ end
17
+
18
+ def self.disable_colors
19
+ @colorizer = Pastel.new(enabled: false)
20
+ end
21
+
22
+ def self.enable_colors_if_available
23
+ @colorizer = Pastel.new
24
+ end
25
+
26
+ def self.enable_colors
27
+ @colorizer = Pastel.new(enabled: true)
28
+ end
17
29
 
18
30
  # ExecutionException objects are used during the exception handling stage
19
31
  # to keep information about the propagation.
@@ -24,88 +36,124 @@ class ModelViolation < RuntimeError; end
24
36
  # different children, then they are merged with #merge to from one single
25
37
  # ExecutionException object.
26
38
  class ExecutionException
27
- # The propagation trace. Because of forks and merges, this should be a
28
- # graph. We don't use graph properties (at least not yet), so consider
29
- # this as the list of objects which did not handle the exeption. Only
30
- # trace.last and trace.first have a definite meaning: the former
31
- # is the last object(s) that handled the propagation and the latter
32
- # is the object from which the exception originated. They can be
33
- # accessed through #task and #origin.
34
- attr_reader :trace
35
- # The last object(s) that handled the exception. This is either a
36
- # single object or an array
37
- def task; trace.last end
38
- # The object from which the exception originates
39
- def origin; trace.first end
39
+ # The trace of how this exception has been propagated in the plan so far
40
+ #
41
+ # @return [Relations::BidirectionalDirectedAdjacencyGraph]
42
+ attr_reader :trace
43
+
44
+ # The last object(s) that handled the exception. This is either a
45
+ # single object or an array
46
+ def propagation_leafs; trace.each_vertex.find_all { |v| trace.leaf?(v) } end
47
+ # The object from which the exception originates
48
+ def origin; @origin end
49
+ # If true, the underlying exception is a fatal error, i.e. should cause
50
+ # parent tasks to be stopped if unhandled.
51
+ def fatal?; exception.fatal? end
40
52
 
41
- # The exception siblings (the ExecutionException objects
42
- # that come from the same exception object)
43
- attr_reader :siblings
44
- # The origin EventGenerator if there is one
45
- attr_reader :generator
46
- # The exception object
47
- attr_reader :exception
48
-
49
- # If this specific exception has been marked has handled
50
- attr_accessor :handled
51
- # If this exception or one of its siblings has been marked as handled
52
- def handled?
53
- siblings.find { |s| s.handled }
54
- end
55
- # Enumerates this exception's siblings
56
- def each_sibling
57
- for e in siblings
58
- yield(e) unless e == self
59
- end
60
- end
61
-
62
- # Creates a new execution exception object with the specified source
63
- # If +source+ is nil, tries to guess the source from +exception+: if
64
- # +exception+ responds to #task or #generator we use either #task or
65
- # call #generator.task
66
- def initialize(exception)
67
- @exception = exception
68
- @trace = Array.new
69
- @siblings = [self]
70
-
71
- if task = exception.failed_task
72
- @trace << exception.failed_task
73
- end
74
- if generator = exception.failed_generator
75
- @generator = exception.failed_generator
76
- end
77
-
78
- if !task && !generator
79
- raise ArgumentError, "invalid exception specification: cannot get the exception source"
80
- end
81
- end
82
-
83
- # Create a sibling from this exception
84
- def fork
85
- sibling = dup
86
- self.siblings << sibling
87
- sibling
88
- end
89
-
90
- # Merges +sibling+ into this object
91
- def merge(sibling)
92
- siblings.delete(sibling)
93
-
94
- topstack = trace.pop
95
- s_topstack = sibling.trace.pop
96
-
97
- origin = trace.shift
98
- s_origin = sibling.trace.shift
99
- origin = origin || s_origin || topstack
100
-
101
- new_top = *(Array[*topstack] | Array[*s_topstack])
102
- @trace = [origin] + (trace | sibling.trace) << new_top
103
- end
104
-
105
- def initialize_copy(from)
106
- super
107
- @trace = from.trace.dup
108
- end
53
+ # The origin EventGenerator if there is one
54
+ attr_reader :generator
55
+ # The exception object
56
+ attr_reader :exception
57
+
58
+ # If this specific exception has been marked has handled
59
+ attr_accessor :handled
60
+ # If this exception has been marked as handled
61
+ def handled?
62
+ handled
63
+ end
64
+ # Enumerates all tasks that are involved in this exception (either
65
+ # origin or in the trace)
66
+ def each_involved_task(&block)
67
+ return enum_for(__method__) if !block_given?
68
+ trace.each_vertex(&block)
69
+ end
70
+
71
+ def involved_task?(task)
72
+ trace.has_vertex?(task)
73
+ end
74
+
75
+ # Resets the trace to [origin]
76
+ def reset_trace
77
+ @trace = Relations::BidirectionalDirectedAdjacencyGraph.new
78
+ @trace.add_vertex(@origin)
79
+ end
80
+
81
+ # True if this exception originates from the given task or generator
82
+ def originates_from?(object)
83
+ generator == object || origin == object
84
+ end
85
+
86
+ # Creates a new execution exception object with the specified source
87
+ # If +source+ is nil, tries to guess the source from +exception+: if
88
+ # +exception+ responds to #task or #generator we use either #task or
89
+ # call #generator.task
90
+ def initialize(exception)
91
+ @exception = exception
92
+ @trace = Relations::BidirectionalDirectedAdjacencyGraph.new
93
+
94
+ if task = exception.failed_task
95
+ @origin = task
96
+ @trace.add_vertex(task)
97
+ end
98
+ if generator = exception.failed_generator
99
+ @generator = exception.failed_generator
100
+ end
101
+
102
+ if !task && !generator
103
+ raise ArgumentError, "invalid exception specification: cannot get the exception source"
104
+ end
105
+ end
106
+
107
+ # Create a sibling from this exception
108
+ def fork
109
+ dup
110
+ end
111
+
112
+ def propagate(from, to)
113
+ trace.add_edge(from, to)
114
+ end
115
+
116
+ # Merges +sibling+ into this object
117
+ #
118
+ # @param [Roby::Task] edge_source the source of the edge in sibling that
119
+ # led to this merge
120
+ # @param [Roby::Task] edge_target the target of the edge in sibling that
121
+ # led to this merge
122
+ def merge(sibling)
123
+ @trace.merge(sibling.trace)
124
+ self
125
+ end
126
+
127
+ def initialize_copy(from)
128
+ super
129
+ @trace = from.trace.dup
130
+ end
131
+
132
+ def to_execution_exception
133
+ self
134
+ end
135
+
136
+ def to_s
137
+ PP.pp(self, '')
138
+ end
139
+
140
+ def pretty_print(pp)
141
+ pp.text "from #{origin} with trace "
142
+ pp.nest(2) do
143
+ pp.nest(2) do
144
+ trace.each_edge do |a, b, _|
145
+ pp.breakable
146
+ pp.text "#{a} => #{b}"
147
+ end
148
+ end
149
+ pp.breakable
150
+ pp.text "Exception:"
151
+ pp.nest(2) do
152
+ pp.breakable
153
+ exception.pretty_print(pp)
154
+ end
155
+ end
156
+ end
109
157
  end
110
158
 
111
159
  # This module is to be included in all objects that are
@@ -114,62 +162,87 @@ def initialize_copy(from)
114
162
  #
115
163
  # See Task::on_exception and Task#on_exception
116
164
  module ExceptionHandlingObject
165
+ module ClassExtension
166
+ extend MetaRuby::Attributes
167
+ inherited_attribute('exception_handler', 'exception_handlers') { Array.new }
168
+ end
169
+
117
170
  # To be used in exception handlers themselves. Passes the exception to
118
171
  # the next matching exception handler
119
- def pass_exception
120
- throw :next_exception_handler
121
- end
122
-
123
- # Calls the exception handlers defined in this task for +exception_object.exception+
124
- # Returns true if the exception has been handled, false otherwise
125
- def handle_exception(exception_object)
126
- each_exception_handler do |matchers, handler|
127
- if matchers.find { |m| m === exception_object.exception }
128
- catch(:next_exception_handler) do
129
- begin
130
- handler.call(self, exception_object)
131
- return true
132
- rescue Exception => e
133
- if !kind_of?(PlanObject)
134
- engine.add_framework_error(e, 'global exception handling')
135
- else
136
- engine.add_error(FailedExceptionHandler.new(e, self, exception_object))
137
- end
138
- end
139
- end
140
- end
141
- end
142
- return false
143
- end
144
- end
145
-
146
- RX_IN_FRAMEWORK = /^((?:\s*\(druby:\/\/.+\)\s*)?#{Regexp.quote(ROBY_LIB_DIR)}\/)/
147
- def self.filter_backtrace(original_backtrace = nil)
172
+ def pass_exception
173
+ throw :next_exception_handler
174
+ end
175
+
176
+ def add_error(error, propagate_through: nil)
177
+ execution_engine.add_error(error, propagate_through: propagate_through)
178
+ end
179
+
180
+ # Calls the exception handlers defined in this task for +exception_object.exception+
181
+ # Returns true if the exception has been handled, false otherwise
182
+ def handle_exception(exception_object)
183
+ each_exception_handler do |matcher, handler|
184
+ if exception_object.exception.kind_of?(FailedExceptionHandler)
185
+ # Do not handle a failed exception handler by itself
186
+ next if exception_object.exception.handler == handler
187
+ end
188
+
189
+ if matcher === exception_object
190
+ catch(:next_exception_handler) do
191
+ begin
192
+ handler.call(self, exception_object)
193
+ return true
194
+ rescue Exception => e
195
+ if !kind_of?(PlanObject)
196
+ execution_engine.add_framework_error(e, 'global exception handling')
197
+ else
198
+ add_error(FailedExceptionHandler.new(e, self, exception_object, handler))
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ return false
205
+ end
206
+ end
207
+
208
+ def self.filter_backtrace(original_backtrace = nil, force: false, display_full_framework_backtraces: false)
209
+ filter_out = Roby.app.filter_out_patterns
210
+
148
211
  if !original_backtrace && block_given?
149
212
  begin
150
213
  return yield
151
214
  rescue Exception => e
152
- raise e, e.message, filter_backtrace(e.backtrace)
215
+ filtered = filter_backtrace(
216
+ e.backtrace, force: force,
217
+ display_full_framework_backtraces: display_full_framework_backtraces)
218
+ raise e, e.message, filtered
153
219
  end
154
220
  end
155
221
 
156
- if Roby.app.filter_backtraces? && original_backtrace
157
- app_dir = if defined? APP_DIR then Regexp.quote(APP_DIR) end
222
+ if (Roby.app.filter_backtraces? || force) && original_backtrace
223
+ app_dir = Roby.app.app_dir
158
224
 
159
225
  original_backtrace = original_backtrace.dup
226
+
227
+ # First, read out the "bottom" of the backtrace: search for the
228
+ # first backtrace line that is within the framework
160
229
  backtrace_bottom = []
161
- while !original_backtrace.empty? && original_backtrace.last !~ RX_IN_FRAMEWORK
230
+ while !original_backtrace.empty? && !filter_out.any? { |rx| rx =~ original_backtrace.last }
162
231
  backtrace_bottom.unshift original_backtrace.pop
163
232
  end
164
233
 
234
+ got_user_line = false
165
235
  backtrace = original_backtrace.enum_for(:each_with_index).map do |line, idx|
166
236
  case line
167
237
  when /in `poll_handler'$/
168
- line.gsub /:in.*/, ':in the polling handler'
238
+ got_user_line = true
239
+ line.gsub(/:in.*/, ':in the polling handler')
169
240
  when /in `event_command_(\w+)'$/
170
- line.gsub /:in.*/, ":in command for '#{$1}'"
241
+ got_user_line = true
242
+ line.gsub(/:in.*/, ":in command for '#{$1}'")
171
243
  when /in `event_handler_(\w+)_(?:[a-f0-9]+)'$/
172
- line.gsub /:in.*/, ":in event handler for '#{$1}'"
244
+ got_user_line = true
245
+ line.gsub(/:in.*/, ":in event handler for '#{$1}'")
173
246
  else
174
247
  if original_backtrace.size > idx + 4 &&
175
248
  original_backtrace[idx + 1] =~ /in `call'$/ &&
@@ -177,46 +250,50 @@ def self.filter_backtrace(original_backtrace = nil)
177
250
  original_backtrace[idx + 3] =~ /`each'$/ &&
178
251
  original_backtrace[idx + 4] =~ /`each_handler'$/
179
252
 
180
- line.gsub /:in /, ":in event handler, "
253
+ got_user_line = true
254
+ line.gsub(/:in /, ":in event handler, ")
181
255
  else
182
- case line
183
- when /in `(gem_original_)?require'$/
184
- when /^((?:\s*\(druby:\/\/.+\)\s*)?#{Regexp.quote(ROBY_LIB_DIR)}\/)/
185
- when /^(#{app_dir}\/)?scripts\//
186
- when /^\(eval\):\d+:in `each(?:_handler)?'/
187
- else
188
- line
256
+ is_user = !filter_out.any? { |rx| rx =~ line }
257
+ got_user_line ||= is_user
258
+ if !got_user_line || is_user
259
+ case line
260
+ when /^\(eval\):\d+:in `each(?:_handler)?'/
261
+ else
262
+ line
263
+ end
189
264
  end
190
265
  end
191
266
  end
192
267
  end
193
268
 
194
- while !backtrace.empty? && !backtrace.last
195
- backtrace.pop
196
- end
197
- backtrace.each_with_index do |line, i|
198
- backtrace[i] = line || original_backtrace[i]
199
- end
269
+ backtrace.compact!
200
270
 
201
271
  if app_dir
202
272
  backtrace = backtrace.map do |line|
203
- line.gsub /^#{app_dir}\/?/, './'
273
+ line.gsub(/^#{app_dir}\/?/, './')
204
274
  end
205
275
  end
206
276
  backtrace.concat backtrace_bottom
207
- end
208
- backtrace || original_backtrace || []
277
+ if original_backtrace.size == backtrace.size && !display_full_framework_backtraces
278
+ # The backtrace is only within the framework, make it empty
279
+ backtrace = []
280
+ end
281
+ end
282
+ backtrace || original_backtrace || []
209
283
  end
210
284
 
211
- def self.pretty_print_backtrace(pp, backtrace)
285
+ def self.pretty_print_backtrace(pp, backtrace, **options)
212
286
  if backtrace && !backtrace.empty?
213
- pp.group(2) do
214
- pp.seplist(filter_backtrace(backtrace)) { |line| pp.text line }
287
+ pp.nest(2) do
288
+ filter_backtrace(backtrace, **options).each do |line|
289
+ pp.breakable
290
+ pp.text line
291
+ end
215
292
  end
216
293
  end
217
294
  end
218
295
 
219
- def self.format_exception(exception)
296
+ def self.format_one_exception(exception)
220
297
  message = begin
221
298
  PP.pp(exception, "")
222
299
  rescue Exception => formatting_error
@@ -230,13 +307,230 @@ def self.format_exception(exception)
230
307
  formatting_error.full_message
231
308
  end
232
309
  end
310
+
233
311
  message.split("\n")
234
312
  end
235
313
 
236
- def self.log_exception(e, logger, level)
237
- format_exception(e).each do |line|
314
+ def self.format_exception(exception, with_original_exceptions: true)
315
+ message = format_one_exception(exception)
316
+ if with_original_exceptions && exception.respond_to?(:original_exceptions)
317
+ exception.original_exceptions.each do |original_e|
318
+ message.concat(format_exception(original_e, with_original_exceptions: true))
319
+ end
320
+ end
321
+ message
322
+ end
323
+
324
+ LOG_SYMBOLIC_TO_NUMERIC = Array[
325
+ :debug,
326
+ :info,
327
+ :warn,
328
+ :error,
329
+ :fatal,
330
+ :unknown]
331
+
332
+ def self.log_level_enabled?(logger, level)
333
+ logger_level = if logger.respond_to?(:log_level)
334
+ logger.log_level
335
+ else logger.level
336
+ end
337
+
338
+ if numeric_level = LOG_SYMBOLIC_TO_NUMERIC.index(level.to_sym)
339
+ logger_level <= numeric_level
340
+ else
341
+ raise ArgumentError, "#{level} is not a valid log level, log levels are #{LOG_SYMBOLIC_TO_NUMERIC.map(&:inspect).join(", ")}"
342
+ end
343
+ end
344
+
345
+ def self.log_pp(obj, logger, level)
346
+ return if !log_level_enabled?(logger, level)
347
+
348
+ message = begin
349
+ PP.pp(obj, "")
350
+ rescue Exception => formatting_error
351
+ begin
352
+ "error formatting object\n" +
353
+ obj + "\nplease report the formatting error: \n" +
354
+ formatting_error.full_message
355
+ rescue Exception => formatting_error
356
+ "\nerror formatting object\n" +
357
+ formatting_error.full_message
358
+ end
359
+ end
360
+
361
+ message.split("\n").each do |line|
362
+ logger.send(level, line)
363
+ end
364
+ end
365
+
366
+ def self.log_exception(e, logger, level, with_original_exceptions: true)
367
+ return if !log_level_enabled?(logger, level)
368
+
369
+ first_line = true
370
+ format_exception(e, with_original_exceptions: with_original_exceptions).each do |line|
371
+ if first_line
372
+ line = color(line, :bold, :red)
373
+ first_line = false
374
+ end
238
375
  logger.send(level, line)
239
376
  end
240
377
  end
378
+
379
+ def self.format_backtrace(e, filter: Roby.app.filter_backtraces?)
380
+ backtrace = e.backtrace
381
+ if filter
382
+ backtrace = filter_backtrace(backtrace)
383
+ end
384
+
385
+ format_exception(BacktraceFormatter.new(e, backtrace))
386
+ end
387
+
388
+ def self.log_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?)
389
+ format_backtrace(e, filter: filter).each do |line|
390
+ logger.send(level, line)
391
+ end
392
+ end
393
+
394
+ def self.log_exception_with_backtrace(e, logger, level, filter: Roby.app.filter_backtraces?, with_original_exceptions: true)
395
+ log_exception(e, logger, level, with_original_exceptions: false)
396
+ logger.send level, color("= Backtrace", :bold, :red)
397
+
398
+ backtrace = e.backtrace
399
+ if filter
400
+ backtrace = filter_backtrace(backtrace)
401
+ end
402
+ if !backtrace || backtrace.empty?
403
+ logger.send level, color("= No backtrace", :bold, :red)
404
+ else
405
+ logger.send level, color("= ", :bold, :red)
406
+ log_backtrace(e, logger, level)
407
+ logger.send level, color("= ", :bold, :red)
408
+ end
409
+
410
+ if with_original_exceptions && e.respond_to?(:original_exceptions)
411
+ e.original_exceptions.each do |orig_e|
412
+ log_exception_with_backtrace(orig_e, logger, level, with_original_exceptions: true)
413
+ end
414
+ end
415
+ end
416
+
417
+ def self.log_error(e, logger, level, with_backtrace: true)
418
+ if e.respond_to?(:backtrace) && with_backtrace
419
+ log_exception_with_backtrace(e, logger, level)
420
+ else
421
+ log_exception(e, logger, level)
422
+ end
423
+ end
424
+
425
+ class BacktraceFormatter
426
+ attr_reader :backtrace
427
+ def initialize(exception, backtrace = exception.backtrace)
428
+ @exception = exception
429
+ @backtrace = backtrace
430
+ end
431
+ def full_message
432
+ @exception.full_message
433
+ end
434
+
435
+ def pretty_print(pp)
436
+ Roby.pretty_print_backtrace(pp, backtrace)
437
+ end
438
+ end
439
+ def self.do_display_exception(io, e)
440
+ if colorizer.enabled?
441
+ do_display_exception_formatted(io, e)
442
+ else
443
+ do_display_exception_raw(io, e)
444
+ end
445
+
446
+ if e.respond_to?(:original_exceptions)
447
+ e.original_exceptions.each do |original_e|
448
+ do_display_exception(io, original_e)
449
+ end
450
+ end
451
+ end
452
+
453
+ def self.do_display_exception_raw(io, e)
454
+ first_line = true
455
+ io.puts
456
+ format_exception(e).each do |line|
457
+ if first_line
458
+ io.puts line
459
+ first_line = false
460
+ else
461
+ io.puts " #{line}"
462
+ end
463
+ end
464
+ format_exception(BacktraceFormatter.new(e)).each do |line|
465
+ io.puts line
466
+ end
467
+ true
468
+ end
469
+
470
+ def self.do_display_exception_formatted(io, e)
471
+ first_line = true
472
+ io.puts ""
473
+ format_exception(e).each do |line|
474
+ if first_line
475
+ io.print color("= ", :bold, :red)
476
+ io.puts color(line, :bold, :red)
477
+ first_line = false
478
+ else
479
+ io.print color("| ", :bold, :red)
480
+ io.puts line
481
+ end
482
+ end
483
+ io.puts color("= Backtrace", :bold, :red)
484
+ format_exception(BacktraceFormatter.new(e)).each do |line|
485
+ io.print color("| ", :bold, :red)
486
+ io.puts line
487
+ end
488
+ io.puts color("= ", :bold, :red)
489
+ true
490
+ end
491
+
492
+
493
+ def self.display_exception(io = STDOUT, e = nil, filter_backtraces = nil)
494
+ if !filter_backtraces.nil?
495
+ old_filter_backtraces = Roby.app.filter_backtraces?
496
+ Roby.app.filter_backtraces = filter_backtraces
497
+ end
498
+
499
+ if !block_given?
500
+ if !e
501
+ raise ArgumentError, "expected an exception object as no block was given"
502
+ end
503
+ do_display_exception(io, e)
504
+ e
505
+ else
506
+ yield
507
+ false
508
+ end
509
+
510
+ rescue Interrupt, SystemExit
511
+ raise
512
+ rescue Exception => e
513
+ if e.user_error?
514
+ io.print color(e.message, :bold, :red)
515
+ else
516
+ do_display_exception(io, e)
517
+ end
518
+ e
519
+
520
+ ensure
521
+ if !filter_backtraces.nil?
522
+ Roby.app.filter_backtraces = old_filter_backtraces
523
+ end
524
+ end
525
+
526
+ def self.flatten_exception(e)
527
+ result = [e].to_set
528
+ if e.respond_to?(:original_exceptions)
529
+ e.original_exceptions.each do |orig_e|
530
+ result.merge(flatten_exception(orig_e))
531
+ end
532
+ end
533
+ result
534
+ end
241
535
  end
242
536