authorails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (347) hide show
  1. data/AUTHORAILS_README +20 -0
  2. data/CHANGELOG +1366 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README +182 -0
  5. data/Rakefile +334 -0
  6. data/bin/about +3 -0
  7. data/bin/authorails +19 -0
  8. data/bin/breakpointer +3 -0
  9. data/bin/console +3 -0
  10. data/bin/destroy +3 -0
  11. data/bin/generate +3 -0
  12. data/bin/performance/benchmarker +3 -0
  13. data/bin/performance/profiler +3 -0
  14. data/bin/plugin +3 -0
  15. data/bin/process/inspector +3 -0
  16. data/bin/process/reaper +3 -0
  17. data/bin/process/spawner +3 -0
  18. data/bin/runner +3 -0
  19. data/bin/server +3 -0
  20. data/builtin/rails_info/rails/info.rb +123 -0
  21. data/builtin/rails_info/rails/info_controller.rb +9 -0
  22. data/builtin/rails_info/rails/info_helper.rb +2 -0
  23. data/builtin/rails_info/rails_info_controller.rb +2 -0
  24. data/configs/apache.conf +40 -0
  25. data/configs/databases/frontbase.yml +28 -0
  26. data/configs/databases/mysql.yml +48 -0
  27. data/configs/databases/oracle.yml +39 -0
  28. data/configs/databases/postgresql.yml +44 -0
  29. data/configs/databases/sqlite2.yml +16 -0
  30. data/configs/databases/sqlite3.yml +19 -0
  31. data/configs/empty.log +0 -0
  32. data/configs/lighttpd.conf +54 -0
  33. data/configs/routes.rb +23 -0
  34. data/controllers/accounts_controller.rb +11 -0
  35. data/controllers/admin_controller.rb +76 -0
  36. data/controllers/begin_controller.rb +5 -0
  37. data/controllers/login_controller.rb +101 -0
  38. data/controllers/permission_controller.rb +91 -0
  39. data/controllers/roles_controller.rb +58 -0
  40. data/controllers/tables_controller.rb +714 -0
  41. data/dispatches/dispatch.fcgi +24 -0
  42. data/dispatches/dispatch.rb +10 -0
  43. data/dispatches/gateway.cgi +97 -0
  44. data/doc/README_FOR_APP +2 -0
  45. data/environments/boot.rb +45 -0
  46. data/environments/development.rb +21 -0
  47. data/environments/environment.rb +63 -0
  48. data/environments/production.rb +18 -0
  49. data/environments/test.rb +19 -0
  50. data/fresh_rakefile +10 -0
  51. data/helpers/application.rb +607 -0
  52. data/helpers/application_helper.rb +315 -0
  53. data/helpers/permission_helper.rb +27 -0
  54. data/helpers/test_helper.rb +28 -0
  55. data/html/404.html +30 -0
  56. data/html/500.html +30 -0
  57. data/html/favicon.ico +0 -0
  58. data/html/images/ArrowDn.png +0 -0
  59. data/html/images/ArrowUp.png +0 -0
  60. data/html/images/arrow.gif +0 -0
  61. data/html/images/authorails_logo.gif +0 -0
  62. data/html/images/delete.png +0 -0
  63. data/html/images/edit.png +0 -0
  64. data/html/images/minus.gif +0 -0
  65. data/html/images/plus.gif +0 -0
  66. data/html/images/rails.png +0 -0
  67. data/html/images/show.png +0 -0
  68. data/html/images/spinner.gif +0 -0
  69. data/html/index.html +273 -0
  70. data/html/javascripts/application.js +2 -0
  71. data/html/javascripts/controls.js +833 -0
  72. data/html/javascripts/dragdrop.js +942 -0
  73. data/html/javascripts/effects.js +1088 -0
  74. data/html/javascripts/live_validation.js +4 -0
  75. data/html/javascripts/prototype.js +2515 -0
  76. data/html/robots.txt +1 -0
  77. data/lib/authorails/version.rb +9 -0
  78. data/lib/binding_of_caller.rb +85 -0
  79. data/lib/breakpoint.rb +553 -0
  80. data/lib/breakpoint_client.rb +196 -0
  81. data/lib/code_statistics.rb +107 -0
  82. data/lib/commands.rb +17 -0
  83. data/lib/commands/about.rb +2 -0
  84. data/lib/commands/breakpointer.rb +1 -0
  85. data/lib/commands/console.rb +25 -0
  86. data/lib/commands/destroy.rb +6 -0
  87. data/lib/commands/generate.rb +6 -0
  88. data/lib/commands/ncgi/listener +86 -0
  89. data/lib/commands/ncgi/tracker +69 -0
  90. data/lib/commands/performance/benchmarker.rb +24 -0
  91. data/lib/commands/performance/profiler.rb +50 -0
  92. data/lib/commands/plugin.rb +918 -0
  93. data/lib/commands/process/inspector.rb +68 -0
  94. data/lib/commands/process/reaper.rb +149 -0
  95. data/lib/commands/process/spawner.rb +209 -0
  96. data/lib/commands/process/spinner.rb +57 -0
  97. data/lib/commands/runner.rb +48 -0
  98. data/lib/commands/server.rb +39 -0
  99. data/lib/commands/servers/base.rb +19 -0
  100. data/lib/commands/servers/lighttpd.rb +94 -0
  101. data/lib/commands/servers/mongrel.rb +65 -0
  102. data/lib/commands/servers/webrick.rb +59 -0
  103. data/lib/commands/update.rb +4 -0
  104. data/lib/console_app.rb +27 -0
  105. data/lib/console_sandbox.rb +6 -0
  106. data/lib/console_with_helpers.rb +23 -0
  107. data/lib/dispatcher.rb +173 -0
  108. data/lib/fcgi_handler.rb +225 -0
  109. data/lib/initializer.rb +702 -0
  110. data/lib/rails_generator.rb +43 -0
  111. data/lib/rails_generator/base.rb +261 -0
  112. data/lib/rails_generator/commands.rb +581 -0
  113. data/lib/rails_generator/generated_attribute.rb +42 -0
  114. data/lib/rails_generator/generators/applications/app/USAGE +16 -0
  115. data/lib/rails_generator/generators/applications/app/app_generator.rb +341 -0
  116. data/lib/rails_generator/generators/components/controller/USAGE +30 -0
  117. data/lib/rails_generator/generators/components/controller/controller_generator.rb +37 -0
  118. data/lib/rails_generator/generators/components/controller/templates/controller.rb +10 -0
  119. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
  120. data/lib/rails_generator/generators/components/controller/templates/helper.rb +2 -0
  121. data/lib/rails_generator/generators/components/controller/templates/view.rhtml +2 -0
  122. data/lib/rails_generator/generators/components/integration_test/USAGE +14 -0
  123. data/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb +16 -0
  124. data/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb +10 -0
  125. data/lib/rails_generator/generators/components/mailer/USAGE +18 -0
  126. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +34 -0
  127. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +3 -0
  128. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +13 -0
  129. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +37 -0
  130. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +3 -0
  131. data/lib/rails_generator/generators/components/migration/USAGE +14 -0
  132. data/lib/rails_generator/generators/components/migration/migration_generator.rb +7 -0
  133. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -0
  134. data/lib/rails_generator/generators/components/model/USAGE +26 -0
  135. data/lib/rails_generator/generators/components/model/model_generator.rb +38 -0
  136. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +11 -0
  137. data/lib/rails_generator/generators/components/model/templates/migration.rb +13 -0
  138. data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
  139. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +10 -0
  140. data/lib/rails_generator/generators/components/observer/USAGE +15 -0
  141. data/lib/rails_generator/generators/components/observer/observer_generator.rb +16 -0
  142. data/lib/rails_generator/generators/components/observer/templates/observer.rb +2 -0
  143. data/lib/rails_generator/generators/components/observer/templates/unit_test.rb +10 -0
  144. data/lib/rails_generator/generators/components/plugin/USAGE +35 -0
  145. data/lib/rails_generator/generators/components/plugin/plugin_generator.rb +38 -0
  146. data/lib/rails_generator/generators/components/plugin/templates/README +4 -0
  147. data/lib/rails_generator/generators/components/plugin/templates/Rakefile +22 -0
  148. data/lib/rails_generator/generators/components/plugin/templates/USAGE +8 -0
  149. data/lib/rails_generator/generators/components/plugin/templates/generator.rb +8 -0
  150. data/lib/rails_generator/generators/components/plugin/templates/init.rb +1 -0
  151. data/lib/rails_generator/generators/components/plugin/templates/install.rb +1 -0
  152. data/lib/rails_generator/generators/components/plugin/templates/plugin.rb +1 -0
  153. data/lib/rails_generator/generators/components/plugin/templates/tasks.rake +4 -0
  154. data/lib/rails_generator/generators/components/plugin/templates/uninstall.rb +1 -0
  155. data/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +8 -0
  156. data/lib/rails_generator/generators/components/resource/resource_generator.rb +76 -0
  157. data/lib/rails_generator/generators/components/resource/templates/USAGE +18 -0
  158. data/lib/rails_generator/generators/components/resource/templates/controller.rb +2 -0
  159. data/lib/rails_generator/generators/components/resource/templates/fixtures.yml +11 -0
  160. data/lib/rails_generator/generators/components/resource/templates/functional_test.rb +20 -0
  161. data/lib/rails_generator/generators/components/resource/templates/helper.rb +2 -0
  162. data/lib/rails_generator/generators/components/resource/templates/migration.rb +13 -0
  163. data/lib/rails_generator/generators/components/resource/templates/model.rb +2 -0
  164. data/lib/rails_generator/generators/components/resource/templates/unit_test.rb +10 -0
  165. data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
  166. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +208 -0
  167. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +134 -0
  168. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +3 -0
  169. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +35 -0
  170. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +102 -0
  171. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  172. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +17 -0
  173. data/lib/rails_generator/generators/components/scaffold/templates/partial_list_elements.rhtml +127 -0
  174. data/lib/rails_generator/generators/components/scaffold/templates/style.css +74 -0
  175. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +75 -0
  176. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +30 -0
  177. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +8 -0
  178. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +37 -0
  179. data/lib/rails_generator/generators/components/scaffold_resource/USAGE +29 -0
  180. data/lib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb +92 -0
  181. data/lib/rails_generator/generators/components/scaffold_resource/templates/controller.rb +79 -0
  182. data/lib/rails_generator/generators/components/scaffold_resource/templates/fixtures.yml +11 -0
  183. data/lib/rails_generator/generators/components/scaffold_resource/templates/functional_test.rb +57 -0
  184. data/lib/rails_generator/generators/components/scaffold_resource/templates/helper.rb +2 -0
  185. data/lib/rails_generator/generators/components/scaffold_resource/templates/layout.rhtml +17 -0
  186. data/lib/rails_generator/generators/components/scaffold_resource/templates/migration.rb +13 -0
  187. data/lib/rails_generator/generators/components/scaffold_resource/templates/model.rb +2 -0
  188. data/lib/rails_generator/generators/components/scaffold_resource/templates/style.css +74 -0
  189. data/lib/rails_generator/generators/components/scaffold_resource/templates/unit_test.rb +10 -0
  190. data/lib/rails_generator/generators/components/scaffold_resource/templates/view_edit.rhtml +19 -0
  191. data/lib/rails_generator/generators/components/scaffold_resource/templates/view_index.rhtml +24 -0
  192. data/lib/rails_generator/generators/components/scaffold_resource/templates/view_new.rhtml +18 -0
  193. data/lib/rails_generator/generators/components/scaffold_resource/templates/view_show.rhtml +10 -0
  194. data/lib/rails_generator/generators/components/session_migration/USAGE +15 -0
  195. data/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +18 -0
  196. data/lib/rails_generator/generators/components/session_migration/templates/migration.rb +16 -0
  197. data/lib/rails_generator/generators/components/web_service/USAGE +28 -0
  198. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +5 -0
  199. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +8 -0
  200. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +19 -0
  201. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +29 -0
  202. data/lib/rails_generator/lookup.rb +209 -0
  203. data/lib/rails_generator/manifest.rb +53 -0
  204. data/lib/rails_generator/options.rb +143 -0
  205. data/lib/rails_generator/scripts.rb +83 -0
  206. data/lib/rails_generator/scripts/destroy.rb +7 -0
  207. data/lib/rails_generator/scripts/generate.rb +7 -0
  208. data/lib/rails_generator/scripts/update.rb +12 -0
  209. data/lib/rails_generator/simple_logger.rb +46 -0
  210. data/lib/rails_generator/spec.rb +44 -0
  211. data/lib/railties_path.rb +1 -0
  212. data/lib/ruby_version_check.rb +17 -0
  213. data/lib/rubyprof_ext.rb +35 -0
  214. data/lib/tasks/databases.rake +187 -0
  215. data/lib/tasks/documentation.rake +82 -0
  216. data/lib/tasks/framework.rake +112 -0
  217. data/lib/tasks/log.rake +9 -0
  218. data/lib/tasks/misc.rake +4 -0
  219. data/lib/tasks/pre_namespace_aliases.rake +53 -0
  220. data/lib/tasks/rails.rb +8 -0
  221. data/lib/tasks/statistics.rake +18 -0
  222. data/lib/tasks/testing.rake +120 -0
  223. data/lib/tasks/tmp.rake +37 -0
  224. data/lib/test_help.rb +19 -0
  225. data/lib/webrick_server.rb +166 -0
  226. data/libs/migration_helper.rb +11 -0
  227. data/migrations/001_create_logins.rb +22 -0
  228. data/migrations/002_create_admins.rb +16 -0
  229. data/migrations/003_create_roles.rb +13 -0
  230. data/migrations/004_create_tables.rb +11 -0
  231. data/migrations/005_create_attr_types.rb +13 -0
  232. data/migrations/006_create_table_fields.rb +22 -0
  233. data/migrations/007_create_tab_operations.rb +13 -0
  234. data/migrations/008_create_attr_operations.rb +13 -0
  235. data/migrations/009_create_tab_permissions.rb +21 -0
  236. data/migrations/010_create_attr_permissions.rb +21 -0
  237. data/migrations/011_create_relations.rb +23 -0
  238. data/migrations/012_create_scaffolds.rb +11 -0
  239. data/migrations/013_create_relation_permissions.rb +20 -0
  240. data/models/admin.rb +38 -0
  241. data/models/attr_operation.rb +3 -0
  242. data/models/attr_permission.rb +5 -0
  243. data/models/attr_type.rb +3 -0
  244. data/models/login.rb +51 -0
  245. data/models/relation.rb +5 -0
  246. data/models/relation_permission.rb +4 -0
  247. data/models/role.rb +13 -0
  248. data/models/scaffold.rb +2 -0
  249. data/models/tab_operation.rb +3 -0
  250. data/models/tab_permission.rb +5 -0
  251. data/models/table.rb +18 -0
  252. data/models/table_field.rb +6 -0
  253. data/plugins/redhillonrails_core/CHANGELOG +186 -0
  254. data/plugins/redhillonrails_core/MIT-LICENSE +20 -0
  255. data/plugins/redhillonrails_core/README +152 -0
  256. data/plugins/redhillonrails_core/init.rb +1 -0
  257. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/base.rb +54 -0
  258. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb +46 -0
  259. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/column.rb +21 -0
  260. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb +26 -0
  261. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb +11 -0
  262. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb +94 -0
  263. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb +8 -0
  264. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb +131 -0
  265. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb +23 -0
  266. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb +9 -0
  267. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb +27 -0
  268. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema.rb +25 -0
  269. data/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema_dumper.rb +58 -0
  270. data/plugins/redhillonrails_core/lib/redhillonrails_core.rb +19 -0
  271. data/plugins/redhillonrails_core/tasks/db/comments.rake +9 -0
  272. data/plugins/schema_validations/CHANGELOG +149 -0
  273. data/plugins/schema_validations/MIT-LICENSE +20 -0
  274. data/plugins/schema_validations/README +54 -0
  275. data/plugins/schema_validations/about.yml +5 -0
  276. data/plugins/schema_validations/init.rb +1 -0
  277. data/plugins/schema_validations/install.rb +1 -0
  278. data/plugins/schema_validations/lib/red_hill_consulting/schema_validations/active_record/base.rb +108 -0
  279. data/plugins/schema_validations/lib/schema_validations.rb +1 -0
  280. data/plugins/svn/README +69 -0
  281. data/plugins/svn/Rakefile +22 -0
  282. data/plugins/svn/assets/javascripts/live_validation.js +4 -0
  283. data/plugins/svn/assets/stylesheets/live_validation.css +28 -0
  284. data/plugins/svn/init.rb +2 -0
  285. data/plugins/svn/install.rb +1 -0
  286. data/plugins/svn/lib/form_helpers.rb +49 -0
  287. data/plugins/svn/lib/live_validations.rb +73 -0
  288. data/plugins/svn/tasks/live_validation_tasks.rake +17 -0
  289. data/plugins/svn/test/form_helpers_test.rb +214 -0
  290. data/plugins/svn/test/live_validations_test.rb +124 -0
  291. data/plugins/svn/test/resource.rb +17 -0
  292. data/plugins/svn/uninstall.rb +1 -0
  293. data/stylesheets/live_validation.css +28 -0
  294. data/stylesheets/print.css +72 -0
  295. data/stylesheets/scaffold.css +175 -0
  296. data/views/accounts/index.rhtml +12 -0
  297. data/views/accounts/show.rhtml +5 -0
  298. data/views/admin/_form.rhtml +15 -0
  299. data/views/admin/add_user.rhtml +21 -0
  300. data/views/admin/change_pwd.rhtml +23 -0
  301. data/views/admin/edit_user.rhtml +12 -0
  302. data/views/admin/index.rhtml +19 -0
  303. data/views/begin/index.rhtml +0 -0
  304. data/views/layouts/general.rhtml +59 -0
  305. data/views/layouts/login.rhtml +18 -0
  306. data/views/login/change_pwd.rhtml +21 -0
  307. data/views/login/expired_pwd.rhtml +19 -0
  308. data/views/login/index.rhtml +15 -0
  309. data/views/permission/index.rhtml +17 -0
  310. data/views/permission/relations.rhtml +28 -0
  311. data/views/permission/roles.rhtml +45 -0
  312. data/views/permission/tables.rhtml +53 -0
  313. data/views/roles/_form.rhtml +8 -0
  314. data/views/roles/edit.rhtml +11 -0
  315. data/views/roles/list.rhtml +28 -0
  316. data/views/roles/new.rhtml +8 -0
  317. data/views/roles/show.rhtml +14 -0
  318. data/views/shared_views/_advanced_search.rhtml +35 -0
  319. data/views/shared_views/_child_elements.rhtml +30 -0
  320. data/views/shared_views/_childs.rhtml +20 -0
  321. data/views/shared_views/_father_elements.rhtml +27 -0
  322. data/views/shared_views/_fathers.rhtml +21 -0
  323. data/views/shared_views/_fathers_header.rhtml +58 -0
  324. data/views/shared_views/_many_to_many_elements.rhtml +50 -0
  325. data/views/shared_views/_many_to_manys.rhtml +18 -0
  326. data/views/shared_views/_one_to_one_elements.rhtml +24 -0
  327. data/views/shared_views/_one_to_one_father_elements.rhtml +26 -0
  328. data/views/shared_views/_one_to_ones.rhtml +42 -0
  329. data/views/shared_views/_one_to_ones_header.rhtml +117 -0
  330. data/views/shared_views/edit_child.rhtml +89 -0
  331. data/views/shared_views/edit_many.rhtml +75 -0
  332. data/views/tables/_cascade.rhtml +10 -0
  333. data/views/tables/_field.rhtml +10 -0
  334. data/views/tables/_fk.rhtml +9 -0
  335. data/views/tables/_form.rhtml +9 -0
  336. data/views/tables/_join_table_name.rhtml +16 -0
  337. data/views/tables/_relation_types.rhtml +5 -0
  338. data/views/tables/_tables.rhtml +15 -0
  339. data/views/tables/attributes.rhtml +15 -0
  340. data/views/tables/edit.rhtml +11 -0
  341. data/views/tables/edit_field.rhtml +18 -0
  342. data/views/tables/list.rhtml +39 -0
  343. data/views/tables/new.rhtml +8 -0
  344. data/views/tables/new_field.rhtml +25 -0
  345. data/views/tables/relations.rhtml +24 -0
  346. data/views/tables/show.rhtml +24 -0
  347. metadata +518 -0
@@ -0,0 +1,69 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'drb'
4
+ require 'thread'
5
+
6
+ def message(s)
7
+ $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
8
+ end
9
+
10
+ class Tracker
11
+ include DRbUndumped
12
+
13
+ def initialize(instances, socket_path)
14
+ @instances = instances
15
+ @socket = File.expand_path(socket_path)
16
+ @active = false
17
+
18
+ @listeners = []
19
+ @instances.times { @listeners << Mutex.new }
20
+
21
+ message "using #{@listeners.length} listeners"
22
+ message "opening socket at #{@socket}"
23
+
24
+ @service = DRb.start_service("drbunix://#{@socket}", self)
25
+ end
26
+
27
+ def with_listener
28
+ message "listener requested"
29
+
30
+ mutex = has_lock = index = nil
31
+ 3.times do
32
+ @listeners.each_with_index do |mutex, index|
33
+ has_lock = mutex.try_lock
34
+ break if has_lock
35
+ end
36
+ break if has_lock
37
+ sleep 0.05
38
+ end
39
+
40
+ if has_lock
41
+ message "obtained listener #{index}"
42
+ @active = true
43
+ begin yield index
44
+ ensure
45
+ mutex.unlock
46
+ message "released listener #{index}"
47
+ end
48
+ else
49
+ message "dropping request because no listeners are available!"
50
+ end
51
+ end
52
+
53
+ def background(check_interval = nil)
54
+ if check_interval
55
+ loop do
56
+ sleep check_interval
57
+ message "Idle for #{check_interval}, shutting down" unless @active
58
+ @active = false
59
+ Kernel.exit 0
60
+ end
61
+ else DRb.thread.join
62
+ end
63
+ end
64
+ end
65
+
66
+ socket_path = ARGV.shift
67
+ instances = ARGV.shift.to_i
68
+ t = Tracker.new(instances, socket_path)
69
+ t.background(ARGV.first ? ARGV.shift.to_i : 90)
@@ -0,0 +1,24 @@
1
+ if ARGV.empty?
2
+ puts "Usage: ./script/performance/benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..."
3
+ exit 1
4
+ end
5
+
6
+ begin
7
+ N = Integer(ARGV.first)
8
+ ARGV.shift
9
+ rescue ArgumentError
10
+ N = 1
11
+ end
12
+
13
+ require RAILS_ROOT + '/config/environment'
14
+ require 'benchmark'
15
+ include Benchmark
16
+
17
+ # Don't include compilation in the benchmark
18
+ ARGV.each { |expression| eval(expression) }
19
+
20
+ bm(6) do |x|
21
+ ARGV.each_with_index do |expression, idx|
22
+ x.report("##{idx + 1}") { N.times { eval(expression) } }
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ if ARGV.empty?
2
+ $stderr.puts "Usage: ./script/performance/profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]"
3
+ exit(1)
4
+ end
5
+
6
+ # Keep the expensive require out of the profile.
7
+ $stderr.puts 'Loading Rails...'
8
+ require RAILS_ROOT + '/config/environment'
9
+
10
+ # Define a method to profile.
11
+ if ARGV[1] and ARGV[1].to_i > 1
12
+ eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end"
13
+ else
14
+ eval "def profile_me() #{ARGV[0]} end"
15
+ end
16
+
17
+ # Use the ruby-prof extension if available. Fall back to stdlib profiler.
18
+ begin
19
+ begin
20
+ require "ruby-prof"
21
+ $stderr.puts 'Using the ruby-prof extension.'
22
+ RubyProf.clock_mode = RubyProf::WALL_TIME
23
+ RubyProf.start
24
+ profile_me
25
+ results = RubyProf.stop
26
+ if ARGV[2]
27
+ printer_class = RubyProf.const_get((ARGV[2] + "_printer").classify)
28
+ else
29
+ printer_class = RubyProf::FlatPrinter
30
+ end
31
+ printer = printer_class.new(results)
32
+ printer.print($stderr, 0)
33
+ rescue LoadError
34
+ require "prof"
35
+ $stderr.puts 'Using the old ruby-prof extension.'
36
+ Prof.clock_mode = Prof::GETTIMEOFDAY
37
+ Prof.start
38
+ profile_me
39
+ results = Prof.stop
40
+ require 'rubyprof_ext'
41
+ Prof.print_profile(results, $stderr)
42
+ end
43
+ rescue LoadError
44
+ require 'profiler'
45
+ $stderr.puts 'Using the standard Ruby profiler.'
46
+ Profiler__.start_profile
47
+ profile_me
48
+ Profiler__.stop_profile
49
+ Profiler__.print_profile($stderr)
50
+ end
@@ -0,0 +1,918 @@
1
+ # Rails Plugin Manager.
2
+ #
3
+ # Listing available plugins:
4
+ #
5
+ # $ ./script/plugin list
6
+ # continuous_builder http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder
7
+ # asset_timestamping http://svn.aviditybytes.com/rails/plugins/asset_timestamping
8
+ # enumerations_mixin http://svn.protocool.com/rails/plugins/enumerations_mixin/trunk
9
+ # calculations http://techno-weenie.net/svn/projects/calculations/
10
+ # ...
11
+ #
12
+ # Installing plugins:
13
+ #
14
+ # $ ./script/plugin install continuous_builder asset_timestamping
15
+ #
16
+ # Finding Repositories:
17
+ #
18
+ # $ ./script/plugin discover
19
+ #
20
+ # Adding Repositories:
21
+ #
22
+ # $ ./script/plugin source http://svn.protocool.com/rails/plugins/
23
+ #
24
+ # How it works:
25
+ #
26
+ # * Maintains a list of subversion repositories that are assumed to have
27
+ # a plugin directory structure. Manage them with the (source, unsource,
28
+ # and sources commands)
29
+ #
30
+ # * The discover command scrapes the following page for things that
31
+ # look like subversion repositories with plugins:
32
+ # http://wiki.rubyonrails.org/rails/pages/Plugins
33
+ #
34
+ # * Unless you specify that you want to use svn, script/plugin uses plain old
35
+ # HTTP for downloads. The following bullets are true if you specify
36
+ # that you want to use svn.
37
+ #
38
+ # * If `vendor/plugins` is under subversion control, the script will
39
+ # modify the svn:externals property and perform an update. You can
40
+ # use normal subversion commands to keep the plugins up to date.
41
+ #
42
+ # * Or, if `vendor/plugins` is not under subversion control, the
43
+ # plugin is pulled via `svn checkout` or `svn export` but looks
44
+ # exactly the same.
45
+ #
46
+ # This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com)
47
+ # and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php)
48
+
49
+ $verbose = false
50
+
51
+
52
+ require 'open-uri'
53
+ require 'fileutils'
54
+ require 'tempfile'
55
+
56
+ include FileUtils
57
+
58
+ class RailsEnvironment
59
+ attr_reader :root
60
+
61
+ def initialize(dir)
62
+ @root = dir
63
+ end
64
+
65
+ def self.find(dir=nil)
66
+ dir ||= pwd
67
+ while dir.length > 1
68
+ return new(dir) if File.exist?(File.join(dir, 'config', 'environment.rb'))
69
+ dir = File.dirname(dir)
70
+ end
71
+ end
72
+
73
+ def self.default
74
+ @default ||= find
75
+ end
76
+
77
+ def self.default=(rails_env)
78
+ @default = rails_env
79
+ end
80
+
81
+ def install(name_uri_or_plugin)
82
+ if name_uri_or_plugin.is_a? String
83
+ if name_uri_or_plugin =~ /:\/\//
84
+ plugin = Plugin.new(name_uri_or_plugin)
85
+ else
86
+ plugin = Plugins[name_uri_or_plugin]
87
+ end
88
+ else
89
+ plugin = name_uri_or_plugin
90
+ end
91
+ unless plugin.nil?
92
+ plugin.install
93
+ else
94
+ puts "plugin not found: #{name_uri_or_plugin}"
95
+ end
96
+ end
97
+
98
+ def use_svn?
99
+ require 'active_support/core_ext/kernel'
100
+ silence_stderr {`svn --version` rescue nil}
101
+ !$?.nil? && $?.success?
102
+ end
103
+
104
+ def use_externals?
105
+ use_svn? && File.directory?("#{root}/vendor/plugins/.svn")
106
+ end
107
+
108
+ def use_checkout?
109
+ # this is a bit of a guess. we assume that if the rails environment
110
+ # is under subversion then they probably want the plugin checked out
111
+ # instead of exported. This can be overridden on the command line
112
+ File.directory?("#{root}/.svn")
113
+ end
114
+
115
+ def best_install_method
116
+ return :http unless use_svn?
117
+ case
118
+ when use_externals? then :externals
119
+ when use_checkout? then :checkout
120
+ else :export
121
+ end
122
+ end
123
+
124
+ def externals
125
+ return [] unless use_externals?
126
+ ext = `svn propget svn:externals "#{root}/vendor/plugins"`
127
+ ext.reject{ |line| line.strip == '' }.map do |line|
128
+ line.strip.split(/\s+/, 2)
129
+ end
130
+ end
131
+
132
+ def externals=(items)
133
+ unless items.is_a? String
134
+ items = items.map{|name,uri| "#{name.ljust(29)} #{uri.chomp('/')}"}.join("\n")
135
+ end
136
+ Tempfile.open("svn-set-prop") do |file|
137
+ file.write(items)
138
+ file.flush
139
+ system("svn propset -q svn:externals -F \"#{file.path}\" \"#{root}/vendor/plugins\"")
140
+ end
141
+ end
142
+
143
+ end
144
+
145
+ class Plugin
146
+ attr_reader :name, :uri
147
+
148
+ def initialize(uri, name=nil)
149
+ @uri = uri
150
+ guess_name(uri)
151
+ end
152
+
153
+ def self.find(name)
154
+ name =~ /\// ? new(name) : Repositories.instance.find_plugin(name)
155
+ end
156
+
157
+ def to_s
158
+ "#{@name.ljust(30)}#{@uri}"
159
+ end
160
+
161
+ def svn_url?
162
+ @uri =~ /svn(?:\+ssh)?:\/\/*/
163
+ end
164
+
165
+ def installed?
166
+ File.directory?("#{rails_env.root}/vendor/plugins/#{name}") \
167
+ or rails_env.externals.detect{ |name, repo| self.uri == repo }
168
+ end
169
+
170
+ def install(method=nil, options = {})
171
+ method ||= rails_env.best_install_method?
172
+ method = :export if method == :http and svn_url?
173
+
174
+ uninstall if installed? and options[:force]
175
+
176
+ unless installed?
177
+ send("install_using_#{method}", options)
178
+ run_install_hook
179
+ else
180
+ puts "already installed: #{name} (#{uri}). pass --force to reinstall"
181
+ end
182
+ end
183
+
184
+ def uninstall
185
+ path = "#{rails_env.root}/vendor/plugins/#{name}"
186
+ if File.directory?(path)
187
+ puts "Removing 'vendor/plugins/#{name}'" if $verbose
188
+ run_uninstall_hook
189
+ rm_r path
190
+ else
191
+ puts "Plugin doesn't exist: #{path}"
192
+ end
193
+ # clean up svn:externals
194
+ externals = rails_env.externals
195
+ externals.reject!{|n,u| name == n or name == u}
196
+ rails_env.externals = externals
197
+ end
198
+
199
+ def info
200
+ tmp = "#{rails_env.root}/_tmp_about.yml"
201
+ if svn_url?
202
+ cmd = "svn export #{@uri} \"#{rails_env.root}/#{tmp}\""
203
+ puts cmd if $verbose
204
+ system(cmd)
205
+ end
206
+ open(svn_url? ? tmp : File.join(@uri, 'about.yml')) do |stream|
207
+ stream.read
208
+ end rescue "No about.yml found in #{uri}"
209
+ ensure
210
+ FileUtils.rm_rf tmp if svn_url?
211
+ end
212
+
213
+ private
214
+
215
+ def run_install_hook
216
+ install_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/install.rb"
217
+ load install_hook_file if File.exists? install_hook_file
218
+ end
219
+
220
+ def run_uninstall_hook
221
+ uninstall_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/uninstall.rb"
222
+ load uninstall_hook_file if File.exists? uninstall_hook_file
223
+ end
224
+
225
+ def install_using_export(options = {})
226
+ svn_command :export, options
227
+ end
228
+
229
+ def install_using_checkout(options = {})
230
+ svn_command :checkout, options
231
+ end
232
+
233
+ def install_using_externals(options = {})
234
+ externals = rails_env.externals
235
+ externals.push([@name, uri])
236
+ rails_env.externals = externals
237
+ install_using_checkout(options)
238
+ end
239
+
240
+ def install_using_http(options = {})
241
+ root = rails_env.root
242
+ mkdir_p "#{root}/vendor/plugins"
243
+ Dir.chdir "#{root}/vendor/plugins" do
244
+ puts "fetching from '#{uri}'" if $verbose
245
+ fetcher = RecursiveHTTPFetcher.new(uri)
246
+ fetcher.quiet = true if options[:quiet]
247
+ fetcher.fetch
248
+ end
249
+ end
250
+
251
+ def svn_command(cmd, options = {})
252
+ root = rails_env.root
253
+ mkdir_p "#{root}/vendor/plugins"
254
+ base_cmd = "svn #{cmd} #{uri} \"#{root}/vendor/plugins/#{name}\""
255
+ base_cmd += ' -q' if options[:quiet] and not $verbose
256
+ base_cmd += " -r #{options[:revision]}" if options[:revision]
257
+ puts base_cmd if $verbose
258
+ system(base_cmd)
259
+ end
260
+
261
+ def guess_name(url)
262
+ @name = File.basename(url)
263
+ if @name == 'trunk' || @name.empty?
264
+ @name = File.basename(File.dirname(url))
265
+ end
266
+ end
267
+
268
+ def rails_env
269
+ @rails_env || RailsEnvironment.default
270
+ end
271
+ end
272
+
273
+ class Repositories
274
+ include Enumerable
275
+
276
+ def initialize(cache_file = File.join(find_home, ".rails-plugin-sources"))
277
+ @cache_file = File.expand_path(cache_file)
278
+ load!
279
+ end
280
+
281
+ def each(&block)
282
+ @repositories.each(&block)
283
+ end
284
+
285
+ def add(uri)
286
+ unless find{|repo| repo.uri == uri }
287
+ @repositories.push(Repository.new(uri)).last
288
+ end
289
+ end
290
+
291
+ def remove(uri)
292
+ @repositories.reject!{|repo| repo.uri == uri}
293
+ end
294
+
295
+ def exist?(uri)
296
+ @repositories.detect{|repo| repo.uri == uri }
297
+ end
298
+
299
+ def all
300
+ @repositories
301
+ end
302
+
303
+ def find_plugin(name)
304
+ @repositories.each do |repo|
305
+ repo.each do |plugin|
306
+ return plugin if plugin.name == name
307
+ end
308
+ end
309
+ return nil
310
+ end
311
+
312
+ def load!
313
+ contents = File.exist?(@cache_file) ? File.read(@cache_file) : defaults
314
+ contents = defaults if contents.empty?
315
+ @repositories = contents.split(/\n/).reject do |line|
316
+ line =~ /^\s*#/ or line =~ /^\s*$/
317
+ end.map { |source| Repository.new(source.strip) }
318
+ end
319
+
320
+ def save
321
+ File.open(@cache_file, 'w') do |f|
322
+ each do |repo|
323
+ f.write(repo.uri)
324
+ f.write("\n")
325
+ end
326
+ end
327
+ end
328
+
329
+ def defaults
330
+ <<-DEFAULTS
331
+ http://dev.rubyonrails.com/svn/rails/plugins/
332
+ DEFAULTS
333
+ end
334
+
335
+ def find_home
336
+ ['HOME', 'USERPROFILE'].each do |homekey|
337
+ return ENV[homekey] if ENV[homekey]
338
+ end
339
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
340
+ return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
341
+ end
342
+ begin
343
+ File.expand_path("~")
344
+ rescue StandardError => ex
345
+ if File::ALT_SEPARATOR
346
+ "C:/"
347
+ else
348
+ "/"
349
+ end
350
+ end
351
+ end
352
+
353
+ def self.instance
354
+ @instance ||= Repositories.new
355
+ end
356
+
357
+ def self.each(&block)
358
+ self.instance.each(&block)
359
+ end
360
+ end
361
+
362
+ class Repository
363
+ include Enumerable
364
+ attr_reader :uri, :plugins
365
+
366
+ def initialize(uri)
367
+ @uri = uri.chomp('/') << "/"
368
+ @plugins = nil
369
+ end
370
+
371
+ def plugins
372
+ unless @plugins
373
+ if $verbose
374
+ puts "Discovering plugins in #{@uri}"
375
+ puts index
376
+ end
377
+
378
+ @plugins = index.reject{ |line| line !~ /\/$/ }
379
+ @plugins.map! { |name| Plugin.new(File.join(@uri, name), name) }
380
+ end
381
+
382
+ @plugins
383
+ end
384
+
385
+ def each(&block)
386
+ plugins.each(&block)
387
+ end
388
+
389
+ private
390
+ def index
391
+ @index ||= RecursiveHTTPFetcher.new(@uri).ls
392
+ end
393
+ end
394
+
395
+
396
+ # load default environment and parse arguments
397
+ require 'optparse'
398
+ module Commands
399
+
400
+ class Plugin
401
+ attr_reader :environment, :script_name, :sources
402
+ def initialize
403
+ @environment = RailsEnvironment.default
404
+ @rails_root = RailsEnvironment.default.root
405
+ @script_name = File.basename($0)
406
+ @sources = []
407
+ end
408
+
409
+ def environment=(value)
410
+ @environment = value
411
+ RailsEnvironment.default = value
412
+ end
413
+
414
+ def options
415
+ OptionParser.new do |o|
416
+ o.set_summary_indent(' ')
417
+ o.banner = "Usage: #{@script_name} [OPTIONS] command"
418
+ o.define_head "Rails plugin manager."
419
+
420
+ o.separator ""
421
+ o.separator "GENERAL OPTIONS"
422
+
423
+ o.on("-r", "--root=DIR", String,
424
+ "Set an explicit rails app directory.",
425
+ "Default: #{@rails_root}") { |@rails_root| self.environment = RailsEnvironment.new(@rails_root) }
426
+ o.on("-s", "--source=URL1,URL2", Array,
427
+ "Use the specified plugin repositories instead of the defaults.") { |@sources|}
428
+
429
+ o.on("-v", "--verbose", "Turn on verbose output.") { |$verbose| }
430
+ o.on("-h", "--help", "Show this help message.") { puts o; exit }
431
+
432
+ o.separator ""
433
+ o.separator "COMMANDS"
434
+
435
+ o.separator " discover Discover plugin repositories."
436
+ o.separator " list List available plugins."
437
+ o.separator " install Install plugin(s) from known repositories or URLs."
438
+ o.separator " update Update installed plugins."
439
+ o.separator " remove Uninstall plugins."
440
+ o.separator " source Add a plugin source repository."
441
+ o.separator " unsource Remove a plugin repository."
442
+ o.separator " sources List currently configured plugin repositories."
443
+
444
+ o.separator ""
445
+ o.separator "EXAMPLES"
446
+ o.separator " Install a plugin:"
447
+ o.separator " #{@script_name} install continuous_builder\n"
448
+ o.separator " Install a plugin from a subversion URL:"
449
+ o.separator " #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
450
+ o.separator " Install a plugin and add a svn:externals entry to vendor/plugins"
451
+ o.separator " #{@script_name} install -x continuous_builder\n"
452
+ o.separator " List all available plugins:"
453
+ o.separator " #{@script_name} list\n"
454
+ o.separator " List plugins in the specified repository:"
455
+ o.separator " #{@script_name} list --source=http://dev.rubyonrails.com/svn/rails/plugins/\n"
456
+ o.separator " Discover and prompt to add new repositories:"
457
+ o.separator " #{@script_name} discover\n"
458
+ o.separator " Discover new repositories but just list them, don't add anything:"
459
+ o.separator " #{@script_name} discover -l\n"
460
+ o.separator " Add a new repository to the source list:"
461
+ o.separator " #{@script_name} source http://dev.rubyonrails.com/svn/rails/plugins/\n"
462
+ o.separator " Remove a repository from the source list:"
463
+ o.separator " #{@script_name} unsource http://dev.rubyonrails.com/svn/rails/plugins/\n"
464
+ o.separator " Show currently configured repositories:"
465
+ o.separator " #{@script_name} sources\n"
466
+ end
467
+ end
468
+
469
+ def parse!(args=ARGV)
470
+ general, sub = split_args(args)
471
+ options.parse!(general)
472
+
473
+ command = general.shift
474
+ if command =~ /^(list|discover|install|source|unsource|sources|remove|update|info)$/
475
+ command = Commands.const_get(command.capitalize).new(self)
476
+ command.parse!(sub)
477
+ else
478
+ puts "Unknown command: #{command}"
479
+ puts options
480
+ exit 1
481
+ end
482
+ end
483
+
484
+ def split_args(args)
485
+ left = []
486
+ left << args.shift while args[0] and args[0] =~ /^-/
487
+ left << args.shift if args[0]
488
+ return [left, args]
489
+ end
490
+
491
+ def self.parse!(args=ARGV)
492
+ Plugin.new.parse!(args)
493
+ end
494
+ end
495
+
496
+
497
+ class List
498
+ def initialize(base_command)
499
+ @base_command = base_command
500
+ @sources = []
501
+ @local = false
502
+ @remote = true
503
+ end
504
+
505
+ def options
506
+ OptionParser.new do |o|
507
+ o.set_summary_indent(' ')
508
+ o.banner = "Usage: #{@base_command.script_name} list [OPTIONS] [PATTERN]"
509
+ o.define_head "List available plugins."
510
+ o.separator ""
511
+ o.separator "Options:"
512
+ o.separator ""
513
+ o.on( "-s", "--source=URL1,URL2", Array,
514
+ "Use the specified plugin repositories.") {|@sources|}
515
+ o.on( "--local",
516
+ "List locally installed plugins.") {|@local| @remote = false}
517
+ o.on( "--remote",
518
+ "List remotely availabled plugins. This is the default behavior",
519
+ "unless --local is provided.") {|@remote|}
520
+ end
521
+ end
522
+
523
+ def parse!(args)
524
+ options.order!(args)
525
+ unless @sources.empty?
526
+ @sources.map!{ |uri| Repository.new(uri) }
527
+ else
528
+ @sources = Repositories.instance.all
529
+ end
530
+ if @remote
531
+ @sources.map{|r| r.plugins}.flatten.each do |plugin|
532
+ if @local or !plugin.installed?
533
+ puts plugin.to_s
534
+ end
535
+ end
536
+ else
537
+ cd "#{@base_command.environment.root}/vendor/plugins"
538
+ Dir["*"].select{|p| File.directory?(p)}.each do |name|
539
+ puts name
540
+ end
541
+ end
542
+ end
543
+ end
544
+
545
+
546
+ class Sources
547
+ def initialize(base_command)
548
+ @base_command = base_command
549
+ end
550
+
551
+ def options
552
+ OptionParser.new do |o|
553
+ o.set_summary_indent(' ')
554
+ o.banner = "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]"
555
+ o.define_head "List configured plugin repositories."
556
+ o.separator ""
557
+ o.separator "Options:"
558
+ o.separator ""
559
+ o.on( "-c", "--check",
560
+ "Report status of repository.") { |@sources|}
561
+ end
562
+ end
563
+
564
+ def parse!(args)
565
+ options.parse!(args)
566
+ Repositories.each do |repo|
567
+ puts repo.uri
568
+ end
569
+ end
570
+ end
571
+
572
+
573
+ class Source
574
+ def initialize(base_command)
575
+ @base_command = base_command
576
+ end
577
+
578
+ def options
579
+ OptionParser.new do |o|
580
+ o.set_summary_indent(' ')
581
+ o.banner = "Usage: #{@base_command.script_name} source REPOSITORY [REPOSITORY [REPOSITORY]...]"
582
+ o.define_head "Add new repositories to the default search list."
583
+ end
584
+ end
585
+
586
+ def parse!(args)
587
+ options.parse!(args)
588
+ count = 0
589
+ args.each do |uri|
590
+ if Repositories.instance.add(uri)
591
+ puts "added: #{uri.ljust(50)}" if $verbose
592
+ count += 1
593
+ else
594
+ puts "failed: #{uri.ljust(50)}"
595
+ end
596
+ end
597
+ Repositories.instance.save
598
+ puts "Added #{count} repositories."
599
+ end
600
+ end
601
+
602
+
603
+ class Unsource
604
+ def initialize(base_command)
605
+ @base_command = base_command
606
+ end
607
+
608
+ def options
609
+ OptionParser.new do |o|
610
+ o.set_summary_indent(' ')
611
+ o.banner = "Usage: #{@base_command.script_name} source URI [URI [URI]...]"
612
+ o.define_head "Remove repositories from the default search list."
613
+ o.separator ""
614
+ o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
615
+ end
616
+ end
617
+
618
+ def parse!(args)
619
+ options.parse!(args)
620
+ count = 0
621
+ args.each do |uri|
622
+ if Repositories.instance.remove(uri)
623
+ count += 1
624
+ puts "removed: #{uri.ljust(50)}"
625
+ else
626
+ puts "failed: #{uri.ljust(50)}"
627
+ end
628
+ end
629
+ Repositories.instance.save
630
+ puts "Removed #{count} repositories."
631
+ end
632
+ end
633
+
634
+
635
+ class Discover
636
+ def initialize(base_command)
637
+ @base_command = base_command
638
+ @list = false
639
+ @prompt = true
640
+ end
641
+
642
+ def options
643
+ OptionParser.new do |o|
644
+ o.set_summary_indent(' ')
645
+ o.banner = "Usage: #{@base_command.script_name} discover URI [URI [URI]...]"
646
+ o.define_head "Discover repositories referenced on a page."
647
+ o.separator ""
648
+ o.separator "Options:"
649
+ o.separator ""
650
+ o.on( "-l", "--list",
651
+ "List but don't prompt or add discovered repositories.") { |@list| @prompt = !@list }
652
+ o.on( "-n", "--no-prompt",
653
+ "Add all new repositories without prompting.") { |v| @prompt = !v }
654
+ end
655
+ end
656
+
657
+ def parse!(args)
658
+ options.parse!(args)
659
+ args = ['http://wiki.rubyonrails.org/rails/pages/Plugins'] if args.empty?
660
+ args.each do |uri|
661
+ scrape(uri) do |repo_uri|
662
+ catch(:next_uri) do
663
+ if @prompt
664
+ begin
665
+ $stdout.print "Add #{repo_uri}? [Y/n] "
666
+ throw :next_uri if $stdin.gets !~ /^y?$/i
667
+ rescue Interrupt
668
+ $stdout.puts
669
+ exit 1
670
+ end
671
+ elsif @list
672
+ puts repo_uri
673
+ throw :next_uri
674
+ end
675
+ Repositories.instance.add(repo_uri)
676
+ puts "discovered: #{repo_uri}" if $verbose or !@prompt
677
+ end
678
+ end
679
+ end
680
+ Repositories.instance.save
681
+ end
682
+
683
+ def scrape(uri)
684
+ require 'open-uri'
685
+ puts "Scraping #{uri}" if $verbose
686
+ dupes = []
687
+ content = open(uri).each do |line|
688
+ begin
689
+ if line =~ /<a[^>]*href=['"]([^'"]*)['"]/ || line =~ /(svn:\/\/[^<|\n]*)/
690
+ uri = $1
691
+ if uri =~ /^\w+:\/\// && uri =~ /\/plugins\// && uri !~ /\/browser\// && uri !~ /^http:\/\/wiki\.rubyonrails/ && uri !~ /http:\/\/instiki/
692
+ uri = extract_repository_uri(uri)
693
+ yield uri unless dupes.include?(uri) || Repositories.instance.exist?(uri)
694
+ dupes << uri
695
+ end
696
+ end
697
+ rescue
698
+ puts "Problems scraping '#{uri}': #{$!.to_s}"
699
+ end
700
+ end
701
+ end
702
+
703
+ def extract_repository_uri(uri)
704
+ uri.match(/(svn|https?):.*\/plugins\//i)[0]
705
+ end
706
+ end
707
+
708
+ class Install
709
+ def initialize(base_command)
710
+ @base_command = base_command
711
+ @method = :http
712
+ @options = { :quiet => false, :revision => nil, :force => false }
713
+ end
714
+
715
+ def options
716
+ OptionParser.new do |o|
717
+ o.set_summary_indent(' ')
718
+ o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]"
719
+ o.define_head "Install one or more plugins."
720
+ o.separator ""
721
+ o.separator "Options:"
722
+ o.on( "-x", "--externals",
723
+ "Use svn:externals to grab the plugin.",
724
+ "Enables plugin updates and plugin versioning.") { |v| @method = :externals }
725
+ o.on( "-o", "--checkout",
726
+ "Use svn checkout to grab the plugin.",
727
+ "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout }
728
+ o.on( "-q", "--quiet",
729
+ "Suppresses the output from installation.",
730
+ "Ignored if -v is passed (./script/plugin -v install ...)") { |v| @options[:quiet] = true }
731
+ o.on( "-r REVISION", "--revision REVISION",
732
+ "Checks out the given revision from subversion.",
733
+ "Ignored if subversion is not used.") { |v| @options[:revision] = v }
734
+ o.on( "-f", "--force",
735
+ "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true }
736
+ o.separator ""
737
+ o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to "
738
+ o.separator "a plugin repository."
739
+ end
740
+ end
741
+
742
+ def determine_install_method
743
+ best = @base_command.environment.best_install_method
744
+ @method = :http if best == :http and @method == :export
745
+ case
746
+ when (best == :http and @method != :http)
747
+ msg = "Cannot install using subversion because `svn' cannot be found in your PATH"
748
+ when (best == :export and (@method != :export and @method != :http))
749
+ msg = "Cannot install using #{@method} because this project is not under subversion."
750
+ when (best != :externals and @method == :externals)
751
+ msg = "Cannot install using externals because vendor/plugins is not under subversion."
752
+ end
753
+ if msg
754
+ puts msg
755
+ exit 1
756
+ end
757
+ @method
758
+ end
759
+
760
+ def parse!(args)
761
+ options.parse!(args)
762
+ environment = @base_command.environment
763
+ install_method = determine_install_method
764
+ puts "Plugins will be installed using #{install_method}" if $verbose
765
+ args.each do |name|
766
+ ::Plugin.find(name).install(install_method, @options)
767
+ end
768
+ rescue
769
+ puts "Plugin not found: #{args.inspect}"
770
+ exit 1
771
+ end
772
+ end
773
+
774
+ class Update
775
+ def initialize(base_command)
776
+ @base_command = base_command
777
+ end
778
+
779
+ def options
780
+ OptionParser.new do |o|
781
+ o.set_summary_indent(' ')
782
+ o.banner = "Usage: #{@base_command.script_name} update [name [name]...]"
783
+ o.on( "-r REVISION", "--revision REVISION",
784
+ "Checks out the given revision from subversion.",
785
+ "Ignored if subversion is not used.") { |v| @revision = v }
786
+ o.define_head "Update plugins."
787
+ end
788
+ end
789
+
790
+ def parse!(args)
791
+ options.parse!(args)
792
+ root = @base_command.environment.root
793
+ cd root
794
+ args = Dir["vendor/plugins/*"].map do |f|
795
+ File.directory?("#{f}/.svn") ? File.basename(f) : nil
796
+ end.compact if args.empty?
797
+ cd "vendor/plugins"
798
+ args.each do |name|
799
+ if File.directory?(name)
800
+ puts "Updating plugin: #{name}"
801
+ system("svn #{$verbose ? '' : '-q'} up \"#{name}\" #{@revision ? "-r #{@revision}" : ''}")
802
+ else
803
+ puts "Plugin doesn't exist: #{name}"
804
+ end
805
+ end
806
+ end
807
+ end
808
+
809
+ class Remove
810
+ def initialize(base_command)
811
+ @base_command = base_command
812
+ end
813
+
814
+ def options
815
+ OptionParser.new do |o|
816
+ o.set_summary_indent(' ')
817
+ o.banner = "Usage: #{@base_command.script_name} remove name [name]..."
818
+ o.define_head "Remove plugins."
819
+ end
820
+ end
821
+
822
+ def parse!(args)
823
+ options.parse!(args)
824
+ root = @base_command.environment.root
825
+ args.each do |name|
826
+ ::Plugin.new(name).uninstall
827
+ end
828
+ end
829
+ end
830
+
831
+ class Info
832
+ def initialize(base_command)
833
+ @base_command = base_command
834
+ end
835
+
836
+ def options
837
+ OptionParser.new do |o|
838
+ o.set_summary_indent(' ')
839
+ o.banner = "Usage: #{@base_command.script_name} info name [name]..."
840
+ o.define_head "Shows plugin info at {url}/about.yml."
841
+ end
842
+ end
843
+
844
+ def parse!(args)
845
+ options.parse!(args)
846
+ args.each do |name|
847
+ puts ::Plugin.find(name).info
848
+ puts
849
+ end
850
+ end
851
+ end
852
+ end
853
+
854
+ class RecursiveHTTPFetcher
855
+ attr_accessor :quiet
856
+ def initialize(urls_to_fetch, cwd = ".")
857
+ @cwd = cwd
858
+ @urls_to_fetch = urls_to_fetch.to_a
859
+ @quiet = false
860
+ end
861
+
862
+ def ls
863
+ @urls_to_fetch.collect do |url|
864
+ if url =~ /^svn:\/\/.*/
865
+ `svn ls #{url}`.split("\n").map {|entry| "/#{entry}"} rescue nil
866
+ else
867
+ open(url) do |stream|
868
+ links("", stream.read)
869
+ end rescue nil
870
+ end
871
+ end.flatten
872
+ end
873
+
874
+ def push_d(dir)
875
+ @cwd = File.join(@cwd, dir)
876
+ FileUtils.mkdir_p(@cwd)
877
+ end
878
+
879
+ def pop_d
880
+ @cwd = File.dirname(@cwd)
881
+ end
882
+
883
+ def links(base_url, contents)
884
+ links = []
885
+ contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link|
886
+ link = link.sub(/href="/i, "")
887
+ next if link =~ /^http/i || link =~ /^\./
888
+ links << File.join(base_url, link)
889
+ end
890
+ links
891
+ end
892
+
893
+ def download(link)
894
+ puts "+ #{File.join(@cwd, File.basename(link))}" unless @quiet
895
+ open(link) do |stream|
896
+ File.open(File.join(@cwd, File.basename(link)), "wb") do |file|
897
+ file.write(stream.read)
898
+ end
899
+ end
900
+ end
901
+
902
+ def fetch(links = @urls_to_fetch)
903
+ links.each do |l|
904
+ (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l)
905
+ end
906
+ end
907
+
908
+ def fetch_dir(url)
909
+ push_d(File.basename(url))
910
+ open(url) do |stream|
911
+ contents = stream.read
912
+ fetch(links(url, contents))
913
+ end
914
+ pop_d
915
+ end
916
+ end
917
+
918
+ Commands::Plugin.parse!