radiant 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (205) hide show
  1. data/CHANGELOG +1 -0
  2. data/CONTRIBUTORS +12 -0
  3. data/LICENSE +9 -0
  4. data/README +91 -0
  5. data/Rakefile +10 -0
  6. data/app/behaviors/archive_behavior.rb +42 -0
  7. data/app/behaviors/archive_day_index_behavior.rb +30 -0
  8. data/app/behaviors/archive_month_index_behavior.rb +30 -0
  9. data/app/behaviors/archive_year_index_behavior.rb +30 -0
  10. data/app/behaviors/env_behavior.rb +18 -0
  11. data/app/behaviors/page_missing_behavior.rb +31 -0
  12. data/app/controllers/admin/export_controller.rb +8 -0
  13. data/app/controllers/admin/layout_controller.rb +23 -0
  14. data/app/controllers/admin/model_controller.rb +119 -0
  15. data/app/controllers/admin/page_controller.rb +119 -0
  16. data/app/controllers/admin/snippet_controller.rb +6 -0
  17. data/app/controllers/admin/user_controller.rb +45 -0
  18. data/app/controllers/admin/welcome_controller.rb +39 -0
  19. data/app/controllers/application.rb +32 -0
  20. data/app/controllers/site_controller.rb +54 -0
  21. data/app/filters/markdown_filter.rb +9 -0
  22. data/app/filters/textile_filter.rb +9 -0
  23. data/app/helpers/admin/export_helper.rb +2 -0
  24. data/app/helpers/admin/layout_helper.rb +2 -0
  25. data/app/helpers/admin/page_helper.rb +10 -0
  26. data/app/helpers/admin/snippet_helper.rb +2 -0
  27. data/app/helpers/admin/user_helper.rb +2 -0
  28. data/app/helpers/admin/welcome_helper.rb +2 -0
  29. data/app/helpers/application_helper.rb +141 -0
  30. data/app/helpers/site_helper.rb +2 -0
  31. data/app/models/archive_finder.rb +66 -0
  32. data/app/models/behavior.rb +194 -0
  33. data/app/models/layout.rb +13 -0
  34. data/app/models/page.rb +91 -0
  35. data/app/models/page_context.rb +526 -0
  36. data/app/models/page_part.rb +13 -0
  37. data/app/models/radiant/config.rb +53 -0
  38. data/app/models/radiant/exporter.rb +11 -0
  39. data/app/models/response_cache.rb +112 -0
  40. data/app/models/snippet.rb +16 -0
  41. data/app/models/status.rb +31 -0
  42. data/app/models/text_filter.rb +11 -0
  43. data/app/models/user.rb +70 -0
  44. data/app/models/user_action_observer.rb +13 -0
  45. data/app/views/admin/layout/index.rhtml +38 -0
  46. data/app/views/admin/layout/new.rhtml +37 -0
  47. data/app/views/admin/layout/remove.rhtml +17 -0
  48. data/app/views/admin/page/_node.rhtml +51 -0
  49. data/app/views/admin/page/_part.rhtml +17 -0
  50. data/app/views/admin/page/children.rhtml +4 -0
  51. data/app/views/admin/page/index.rhtml +172 -0
  52. data/app/views/admin/page/new.rhtml +164 -0
  53. data/app/views/admin/page/remove.rhtml +14 -0
  54. data/app/views/admin/snippet/index.rhtml +36 -0
  55. data/app/views/admin/snippet/new.rhtml +28 -0
  56. data/app/views/admin/snippet/remove.rhtml +16 -0
  57. data/app/views/admin/user/index.rhtml +43 -0
  58. data/app/views/admin/user/new.rhtml +48 -0
  59. data/app/views/admin/user/preferences.rhtml +29 -0
  60. data/app/views/admin/user/remove.rhtml +16 -0
  61. data/app/views/admin/welcome/login.rhtml +51 -0
  62. data/app/views/layouts/application.rhtml +75 -0
  63. data/app/views/site/not_found.rhtml +3 -0
  64. data/bin/radiant +305 -0
  65. data/config/boot.rb +80 -0
  66. data/config/database.mysql.yml +20 -0
  67. data/config/database.postgresql.yml +20 -0
  68. data/config/database.sqlite.yml +20 -0
  69. data/config/environment.rb +76 -0
  70. data/config/environments/development.rb +20 -0
  71. data/config/environments/production.rb +22 -0
  72. data/config/environments/test.rb +20 -0
  73. data/config/locomotive.yml +6 -0
  74. data/config/routes.rb +64 -0
  75. data/db/development_structure.sql +80 -0
  76. data/db/migrate/001_create_radiant_tables.rb +73 -0
  77. data/db/migrate/002_insert_initial_data.rb +45 -0
  78. data/db/migrate/003_rename_behavior_column.rb +9 -0
  79. data/db/migrate/004_rename_filter_column.rb +11 -0
  80. data/db/migrate/005_add_virtual_column_to_page.rb +9 -0
  81. data/db/migrate/006_integer_columns_to_boolean.rb +11 -0
  82. data/db/migrate/007_remove_virtual_column_from_page.rb +9 -0
  83. data/db/migrate/008_add_virtual_column_to_page_again.rb +9 -0
  84. data/db/migrate/009_add_content_type_field_to_layout.rb +9 -0
  85. data/db/schema.rb +74 -0
  86. data/db/templates/empty.yml +2 -0
  87. data/db/templates/simple-blog.yml +197 -0
  88. data/db/templates/styled-blog.yml +472 -0
  89. data/lib/advanced_delegation.rb +21 -0
  90. data/lib/archive_index_behavior_tags_and_methods.rb +48 -0
  91. data/lib/generators/behavior/USAGE +16 -0
  92. data/lib/generators/behavior/behavior_generator.rb +22 -0
  93. data/lib/generators/behavior/templates/model.rb.template +9 -0
  94. data/lib/generators/behavior/templates/unit_test.rb.template +16 -0
  95. data/lib/generators/filter/USAGE +16 -0
  96. data/lib/generators/filter/filter_generator.rb +22 -0
  97. data/lib/generators/filter/templates/model.rb.template +8 -0
  98. data/lib/generators/filter/templates/unit_test.rb.template +7 -0
  99. data/lib/inheritable_class_attributes.rb +65 -0
  100. data/lib/login_system.rb +80 -0
  101. data/lib/plugins/index_quoting_fix/init.rb +32 -0
  102. data/lib/plugins/string_io/init.rb +2 -0
  103. data/lib/radiant.rb +5 -0
  104. data/lib/registerable.rb +70 -0
  105. data/lib/tasks/release.rake +84 -0
  106. data/public/404.html +8 -0
  107. data/public/500.html +8 -0
  108. data/public/dispatch.cgi +10 -0
  109. data/public/dispatch.fcgi +24 -0
  110. data/public/dispatch.rb +10 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/images/add-child.png +0 -0
  113. data/public/images/brown-bottom-line.gif +0 -0
  114. data/public/images/clear-page-cache.png +0 -0
  115. data/public/images/collapse.png +0 -0
  116. data/public/images/expand.png +0 -0
  117. data/public/images/minus.png +0 -0
  118. data/public/images/new-homepage.png +0 -0
  119. data/public/images/new-layout.png +0 -0
  120. data/public/images/new-snippet.png +0 -0
  121. data/public/images/new-user.png +0 -0
  122. data/public/images/page.png +0 -0
  123. data/public/images/plus.png +0 -0
  124. data/public/images/remove-disabled.png +0 -0
  125. data/public/images/remove.png +0 -0
  126. data/public/images/snippet.png +0 -0
  127. data/public/images/spinner.gif +0 -0
  128. data/public/images/view-site.gif +0 -0
  129. data/public/images/virtual-page.png +0 -0
  130. data/public/javascripts/application.js +2 -0
  131. data/public/javascripts/controls.js +815 -0
  132. data/public/javascripts/dragdrop.js +913 -0
  133. data/public/javascripts/effects.js +958 -0
  134. data/public/javascripts/pngfix.js +78 -0
  135. data/public/javascripts/prototype.js +2006 -0
  136. data/public/javascripts/ruledtable.js +28 -0
  137. data/public/javascripts/string.js +23 -0
  138. data/public/javascripts/tabcontrol.js +140 -0
  139. data/public/robots.txt +1 -0
  140. data/public/stylesheets/admin.css +464 -0
  141. data/script/about +3 -0
  142. data/script/breakpointer +3 -0
  143. data/script/console +3 -0
  144. data/script/destroy +3 -0
  145. data/script/generate +3 -0
  146. data/script/performance/benchmarker +3 -0
  147. data/script/performance/profiler +3 -0
  148. data/script/plugin +3 -0
  149. data/script/process/reaper +3 -0
  150. data/script/process/spawner +3 -0
  151. data/script/process/spinner +3 -0
  152. data/script/runner +3 -0
  153. data/script/server +3 -0
  154. data/script/setup_database +297 -0
  155. data/test/fixtures/layouts.yml +26 -0
  156. data/test/fixtures/page_parts.yml +99 -0
  157. data/test/fixtures/pages.yml +359 -0
  158. data/test/fixtures/pages.yml.rej +28 -0
  159. data/test/fixtures/snippets.yml +18 -0
  160. data/test/fixtures/users.yml +30 -0
  161. data/test/functional/admin/export_controller_test.rb +22 -0
  162. data/test/functional/admin/layout_controller_test.rb +40 -0
  163. data/test/functional/admin/model_controller_test.rb +152 -0
  164. data/test/functional/admin/page_controller_test.rb +179 -0
  165. data/test/functional/admin/snippet_controller_test.rb +11 -0
  166. data/test/functional/admin/user_controller_test.rb +71 -0
  167. data/test/functional/admin/welcome_controller_test.rb +48 -0
  168. data/test/functional/application_controller_test.rb +44 -0
  169. data/test/functional/login_system_test.rb +155 -0
  170. data/test/functional/site_controller_test.rb +172 -0
  171. data/test/helpers/archive_index_test_helper.rb +35 -0
  172. data/test/helpers/behavior_render_test_helper.rb +34 -0
  173. data/test/helpers/behavior_test_helper.rb +47 -0
  174. data/test/helpers/caching_test_helper.rb +41 -0
  175. data/test/helpers/layout_test_helper.rb +35 -0
  176. data/test/helpers/page_part_test_helper.rb +49 -0
  177. data/test/helpers/page_test_helper.rb +36 -0
  178. data/test/helpers/snippet_test_helper.rb +32 -0
  179. data/test/helpers/user_test_helper.rb +34 -0
  180. data/test/helpers/validation_test_helper.rb +42 -0
  181. data/test/test_helper.rb +54 -0
  182. data/test/unit/behavior_test.rb +196 -0
  183. data/test/unit/behaviors/archive_behavior_test.rb +33 -0
  184. data/test/unit/behaviors/archive_day_index_behavior_test.rb +21 -0
  185. data/test/unit/behaviors/archive_month_index_behavior_test.rb +21 -0
  186. data/test/unit/behaviors/archive_year_index_behavior_test.rb +21 -0
  187. data/test/unit/behaviors/page_missing_behavior_test.rb +27 -0
  188. data/test/unit/filters/markdown_filter_test.rb +14 -0
  189. data/test/unit/filters/textile_filter_test.rb +14 -0
  190. data/test/unit/inheritable_class_attributes_test.rb +47 -0
  191. data/test/unit/layout_test.rb +29 -0
  192. data/test/unit/page_context_test.rb +375 -0
  193. data/test/unit/page_context_test.rb.rej +26 -0
  194. data/test/unit/page_part_test.rb +44 -0
  195. data/test/unit/page_test.rb +224 -0
  196. data/test/unit/radiant/config_test.rb +46 -0
  197. data/test/unit/radiant/exporter_test.rb +26 -0
  198. data/test/unit/registerable_test.rb +68 -0
  199. data/test/unit/response_cache_test.rb +133 -0
  200. data/test/unit/snippet_test.rb +47 -0
  201. data/test/unit/status_test.rb +43 -0
  202. data/test/unit/text_filter_test.rb +14 -0
  203. data/test/unit/user_action_observer_test.rb +40 -0
  204. data/test/unit/user_test.rb +138 -0
  205. metadata +355 -0
@@ -0,0 +1,43 @@
1
+ <h1>Users</h1>
2
+
3
+ <table id="users" class="index" cellpadding="0" cellspacing="0" border="0">
4
+ <thead>
5
+ <tr>
6
+ <th class="user">Name / Login</th>
7
+ <th class="roles">Roles</th>
8
+ <th class="modify">Modify</th>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <% unless @users.empty? -%>
13
+ <% for user in @users -%>
14
+ <tr class="node level-1">
15
+ <td class="user">
16
+ <%= link_to user.name, user_edit_url(:id => user) %>
17
+ <small class="login"><%= user.login %></small>
18
+ </td>
19
+ <td class="roles">
20
+ <%=
21
+ roles = []
22
+ roles << 'Administrator' if user.admin?
23
+ roles << 'Developer' if user.developer?
24
+ roles.join(', ')
25
+ %>
26
+ </td>
27
+ <td class="remove"><%= user.id != session[:user].id ? link_to(image_tag('remove', :alt => 'Remove User'), user_remove_url(:id => user)) : image_tag('remove-disabled', :alt => 'Remove') %></td>
28
+ </tr>
29
+ <% end -%>
30
+ <% else -%>
31
+ <tr>
32
+ <td colspan="3" class="note">No Users</td>
33
+ </tr>
34
+ <% end -%>
35
+ </tbody>
36
+ </table>
37
+ <script type="text/javascript">
38
+ // <![CDATA[
39
+ new RuledTable('users');
40
+ // ]]>
41
+ </script>
42
+
43
+ <p><%= link_to image_tag('new-user', :alt => 'New User'), user_new_url %></p>
@@ -0,0 +1,48 @@
1
+ <% if @user.new_record? -%>
2
+ <h1>New User</h1>
3
+ <% else -%>
4
+ <h1>Edit User</h1>
5
+ <% end -%>
6
+
7
+ <form method="post">
8
+ <table class="fieldset" cellpadding="0" cellspacing="0" border="0">
9
+ <tr>
10
+ <td class="label"><label for="user_name">Name</label></td>
11
+ <td class="field"><%= text_field "user", "name", :class => 'textbox', :maxlength => 100 %></td>
12
+ <td class="help">Required.</td>
13
+ </tr>
14
+ <tr>
15
+ <td class="label"><label class="optional" for="user_email">E-mail</label></td>
16
+ <td class="field"><%= text_field "user", "email", :class => 'textbox', :maxlength => 255 %></td>
17
+ <td class="help">Optional. Please use a valid e-mail address.</td>
18
+ </tr>
19
+ <tr>
20
+ <td class="label"><label for="user_login">Username</label></td>
21
+ <td class="field"><%= text_field "user", "login", :class => 'textbox', :maxlength => 40 %></td>
22
+ <td class="help">At least 3 characters. Must be unique.</td>
23
+ </tr>
24
+ <tr>
25
+ <td class="label"><label for="user_password">Password</label></td>
26
+ <td class="field"><%= password_field "user", "password", :class => 'textbox', :value => '', :maxlength => 40 %></td>
27
+ <td class="help" rowspan="2">At least 5 characters. <% unless @user.new_record? %>Leave password blank for it to remain unchanged.<% end %></td>
28
+ </tr>
29
+ <tr>
30
+ <td class="label"><label for="user_password_confirmation">Confirm Password</label></td>
31
+ <td class="field"><%= password_field "user", "password_confirmation", :class => 'textbox', :value => '', :maxlength => 40 %></td>
32
+ </tr>
33
+ <tr>
34
+ <td class="label"><label for="user_admin">Roles</label></td>
35
+ <td class="field">
36
+ <span class="checkbox"><%= check_box "user", "admin" %>&nbsp;Administrator</span>
37
+ <span class="checkbox"><%= check_box "user", "developer" %>&nbsp;Developer</span>
38
+ </td>
39
+ <td class="help">Roles restrict user privileges and turn parts of the administrative interface on or off.</td>
40
+ </tr>
41
+ </table>
42
+ <%= updated_stamp @user %>
43
+ <p class="buttons">
44
+ <%= save_model_button(@user) %> <%= save_model_and_continue_editing_button(@user) %> or <%= link_to "Cancel", user_index_url %>
45
+ </p>
46
+ </form>
47
+
48
+ <%= focus 'user_name' %>
@@ -0,0 +1,29 @@
1
+ <h1>User Preferences</h1>
2
+
3
+ <form method="post">
4
+ <table class="fieldset" cellpadding="0" cellspacing="0" border="0">
5
+ <tr>
6
+ <td class="label"><label for="user_password">Password</label></td>
7
+ <td class="field"><%= password_field "user", "password", :class => 'textbox', :value => '', :maxlength => 40 %></td>
8
+ <td class="help" rowspan="2">At least 5 characters. <% unless @user.new_record? %>Leave password blank for it to remain unchanged.<% end %></td>
9
+ </tr>
10
+ <tr>
11
+ <td class="label"><label for="user_password_confirmation">Confirm Password</label></td>
12
+ <td class="field"><%= password_field "user", "password_confirmation", :class => 'textbox', :value => '', :maxlength => 40 %></td>
13
+ </tr>
14
+ <tr>
15
+ <td class="label"><label for="user_email">E-mail</label></td>
16
+ <td class="field"><%= text_field "user", "email", :class => 'textbox', :maxlength => 255 %></td>
17
+ <td class="help">Optional.</td>
18
+ </tr>
19
+ </table>
20
+ <p class="buttons">
21
+ <%= submit_tag 'Save Changes' %> or <%= link_to "Cancel", admin_url %>
22
+ </p>
23
+ </form>
24
+
25
+ <script type="text/javascript">
26
+ // <![CDATA[
27
+ Field.focus('user_password');
28
+ // ]]>
29
+ </script>
@@ -0,0 +1,16 @@
1
+ <h1>Remove User</h1>
2
+ <p>Are you sure you want to <strong class="warning">permanently remove</strong> the following user?</p>
3
+
4
+ <table id="users" class="index" cellpadding="0" cellspacing="0" border="0">
5
+ <tbody>
6
+ <tr class="node level-1" onmouseover="Element.addClassName(this, 'highlight');" onmouseout="Element.removeClassName(this, 'highlight');">
7
+ <td class="user">
8
+ <%= @user.name %>
9
+ </td>
10
+ </tr>
11
+ </tbody>
12
+ </table>
13
+
14
+ <form method="post">
15
+ <p class="buttons"><%= submit_tag "Delete User", :class => 'button' %> or <%= link_to 'Cancel', user_index_url %></p>
16
+ </form>
@@ -0,0 +1,51 @@
1
+ <% content_for 'page_css' do -%>
2
+ #content {
3
+ text-align: center;
4
+ }
5
+ #content #login {
6
+ background-color: #F5F1E2;
7
+ border: 5px solid #EFEAD3;
8
+ text-align: left;
9
+ margin: 2em;
10
+ margin-left: auto;
11
+ margin-right: auto;
12
+ padding-left: 20px;
13
+ width: 23.5em;
14
+ }
15
+ #content #login h1 {
16
+ font-size: 140%;
17
+ margin: 0;
18
+ margin-top: 18px;
19
+ margin-bottom: 18px;
20
+ }
21
+ #content #login label {
22
+ float: left;
23
+ clear: left;
24
+ margin-top: 4px;
25
+ width: 6em;
26
+ }
27
+ #content #login .textbox {
28
+ font-size: 100%;
29
+ width: 16em;
30
+ }
31
+ #content #login .buttons {
32
+ margin-top: 15px;
33
+ margin-bottom: 20px;
34
+ }
35
+ <% end -%>
36
+
37
+ <div id="login">
38
+ <h1>Please Login</h1>
39
+
40
+ <form method="post">
41
+ <p><label for="user_login">Username</label>
42
+ <%= text_field "user", "login", :class => 'textbox', :value => '', :maxlength => 40 %></p>
43
+ <p><label for="user_password">Password</label>
44
+ <%= password_field "user", "password", :class => 'textbox', :value => '', :maxlength => 40 %></p>
45
+ <p class="buttons">
46
+ <%= submit_tag 'Login', :class => 'button' %>
47
+ </p>
48
+ </form>
49
+ </div>
50
+
51
+ <%= focus 'user_login' %>
@@ -0,0 +1,75 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
6
+ <title><%= @page_title || default_page_title %></title>
7
+ <%= stylesheet_link_tag 'admin' %>
8
+ <%= javascript_include_tag 'prototype' %>
9
+ <%= javascript_include_tag 'string' %>
10
+ <%= javascript_include_tag 'effects' %>
11
+ <%= javascript_include_tag 'dragdrop' %>
12
+ <%= javascript_include_tag 'controls' %>
13
+ <%= javascript_include_tag 'tabcontrol' %>
14
+ <%= javascript_include_tag 'ruledtable' %>
15
+ <!--[if lt IE 7]>
16
+ <script defer type="text/javascript" src="/javascripts/pngfix.js"></script>
17
+ <![endif]-->
18
+ <% if @content_for_page_scripts -%>
19
+ <script type="text/javascript">
20
+ // <![CDATA[
21
+ <%= @content_for_page_scripts %>
22
+ // ]]>
23
+ </script>
24
+ <% end -%>
25
+ <% if @content_for_page_css -%>
26
+ <style type="text/css" media="screen">
27
+ <%= @content_for_page_css -%>
28
+ </style>
29
+ <% end -%>
30
+ </head>
31
+ <body>
32
+ <div id="header">
33
+ <div id="site-title"><%= link_to_unless_current title, admin_url %></div>
34
+ <div id="site-subtitle"><%= subtitle %></div>
35
+ <% if logged_in? -%>
36
+ <div id="navigation">
37
+ <%= links_for_navigation %>
38
+ </div>
39
+ <% end -%>
40
+ </div>
41
+ <hr class="hidden" />
42
+ <div id="main">
43
+ <% if flash[:notice] -%>
44
+ <div id="notice">
45
+ <p><%= flash[:notice] %></p>
46
+ </div>
47
+ <% end -%>
48
+ <% if flash[:error] -%>
49
+ <div id="error">
50
+ <p><%= flash[:error] %></p>
51
+ </div>
52
+ <% end -%>
53
+ <div id="content">
54
+ <%= yield%>
55
+ </div>
56
+ </div>
57
+ <hr class="hidden" />
58
+ <div id="footer">
59
+ <p>This site was made with Ruby and is powered by <a href="http://radiantcms.org">Radiant CMS</a>.</p>
60
+ <p id="site-links">
61
+ <% if logged_in? -%>
62
+ <% if admin? -%>
63
+ <%= nav_link_to 'Users', user_index_url %>
64
+ <% else -%>
65
+ <%= nav_link_to 'Preferences', user_preferences_url %>
66
+ <% end -%>
67
+ <span class="separator"> | </span>
68
+ <%= nav_link_to 'Log Out', logout_url %>
69
+ <span class="separator"> | </span>
70
+ <% end -%>
71
+ <%= link_to image_tag('view-site.gif', :alt => 'View Site', :title => '', :align => 'center'), homepage_url %>
72
+ </p>
73
+ </div>
74
+ </body>
75
+ </html>
@@ -0,0 +1,3 @@
1
+ <% @page_title = 'Page Not Found' -%>
2
+ <h1><%= @page_title %></h1>
3
+ <p>The page you were looking for could not be located on this site.</p>
@@ -0,0 +1,305 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ autoload 'OptionParser', 'optparse'
4
+ autoload 'FileUtils', 'fileutils'
5
+ autoload 'Pathname', 'pathname'
6
+ autoload 'Radiant', File.join(File.dirname(__FILE__), "..", "lib", "radiant")
7
+
8
+ class RadiantCommandApplication
9
+ def self.run(args = ARGV)
10
+ new.run(args)
11
+ end
12
+
13
+ def initialize
14
+ @indent = 0
15
+ @out = $stdout
16
+ @in = $stdin
17
+ @ignore = %w( . .. .svn )
18
+ @radiant_root = File.expand_path(clean_path(File.join(File.dirname(__FILE__), '..')))
19
+ end
20
+
21
+ def run(args = [])
22
+ parse_args(args)
23
+ if @help
24
+ puts
25
+ puts @opts
26
+ else
27
+ announce "Unpacking Radiant #{@type}..." do
28
+ case @type
29
+ when :application
30
+ unpack_radiant_application
31
+ when :instance
32
+ unpack_radiant_instance
33
+ end
34
+ make_scripts_executable
35
+ end
36
+ puts "Done."
37
+ output_additional_instructions
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def parse_args(args)
44
+ args = args.dup
45
+
46
+ @type = :instance
47
+ @overwrite = false
48
+ @dirname = args.pop unless args.last =~ /^-/
49
+ @dirname = clean_path(@dirname) unless @dirname.nil?
50
+ @help = @dirname.nil?
51
+
52
+ @opts = OptionParser.new do |opts|
53
+ opts.banner = "Usage: #{File.basename($0)} [options] path"
54
+ opts.separator "Create a Radiant application at path."
55
+ opts.separator ""
56
+
57
+ opts.separator "Options:\n"
58
+
59
+ opts.on(
60
+ "-u", "--unpack",
61
+ "Completely unpack Radiant in the current directory and cause it to ",
62
+ "run in 'application' mode. Without this flag Radiant is unpacked in ",
63
+ "'instance' mode, which basically means that the `radiant` command ",
64
+ "only unpacks the files necessary to run the application and all ",
65
+ "other files are 'linked' in at run time. Where the files are linked ",
66
+ "in from depends on whether you run the `radiant` command from a gem ",
67
+ "or another unpacked Radiant install.\n"
68
+ ) do |type|
69
+ @type = :application
70
+ end
71
+
72
+ opts.on("-f", "--force", "Overwrite files in path without prompting.\n") do |type|
73
+ @overwrite = true
74
+ end
75
+
76
+ opts.on("-?", "--help", "Display this message.\n") do
77
+ @help = true
78
+ end
79
+ end
80
+
81
+ begin
82
+ @opts.parse(args)
83
+ rescue OptionParser::ParseError => e
84
+ puts e.message.capitalize
85
+ @help = true
86
+ end
87
+ end
88
+
89
+ def unpack_radiant_application
90
+ %w( cache log vendor/plugins ).each do |path|
91
+ make_path(File.join(@dirname, path))
92
+ end
93
+ remove_instance_config
94
+ remove_config_stub('routes')
95
+ copy_files @radiant_root, @dirname
96
+ end
97
+
98
+ def unpack_radiant_instance
99
+ %w( cache config db log public script vendor/plugins ).each do |path|
100
+ make_path(File.join(@dirname, path))
101
+ end
102
+ %w(
103
+ config/boot.rb
104
+ config/database.mysql.yml
105
+ config/database.sqlite.yml
106
+ config/database.postgresql.yml
107
+ config/environment.rb
108
+ config/environments/development.rb
109
+ config/environments/production.rb
110
+ config/environments/test.rb
111
+ script/server
112
+ script/setup_database
113
+ script/about
114
+ script/plugin
115
+ script/process/reaper
116
+ script/process/spawner
117
+ script/process/spinner
118
+ script/runner
119
+ README
120
+ CHANGELOG
121
+ CONTRIBUTORS
122
+ LICENSE
123
+ ).each do |file|
124
+ copy_file File.join(@radiant_root, file), File.join(@dirname, file)
125
+ end
126
+ %w( public ).each do |path|
127
+ copy_files File.join(@radiant_root, path), File.join(@dirname, path)
128
+ end
129
+ create_instance_config
130
+ create_config_stub('routes')
131
+ end
132
+
133
+ def make_scripts_executable
134
+ (
135
+ Dir[File.join(@dirname, 'script', '**/*')] +
136
+ Dir[File.join(@dirname, 'public', 'dispatch.*')]
137
+ ).each do |filename|
138
+ make_executable(filename)
139
+ end
140
+ end
141
+
142
+ def output_additional_instructions
143
+ puts
144
+ puts "Now, if this is a new install:"
145
+ puts
146
+ puts " 1. Create a MySQL/PostgreSQL/SQLite database for your Web site."
147
+ puts
148
+ puts " 2. Create config/database.yml for your database setup. (There are"
149
+ puts " several examples in the config directory.)"
150
+ puts
151
+ puts " 3. Run the database setup script:"
152
+ puts
153
+ puts " % script/setup_database production"
154
+ puts
155
+ puts " 4. Start it like a normal Rails application. To test execute:"
156
+ puts
157
+ puts " % script/server production"
158
+ puts
159
+ puts " And open your Web browser on port 3000 (http://localhost:3000)."
160
+ puts
161
+ puts "See the README for more details."
162
+ end
163
+
164
+ def instance_config_filename
165
+ File.join(@dirname, 'config', 'instance.yml')
166
+ end
167
+
168
+ def create_instance_config
169
+ text = gem? ? "Gem Version: #{ Radiant::Version }" : "Radiant Root: #{@radiant_root}"
170
+ create_file instance_config_filename, text
171
+ end
172
+
173
+ def remove_instance_config
174
+ remove_file instance_config_filename
175
+ end
176
+
177
+ def config_stub_filename(filename)
178
+ File.join(@dirname, 'config', filename + '.rb')
179
+ end
180
+
181
+ def create_config_stub(filename)
182
+ make_path File.join(@dirname, 'config', File.dirname(filename))
183
+ create_file config_stub_filename(filename), %{require File.join(RADIANT_ROOT, "config", "#{filename}") }
184
+ end
185
+
186
+ def remove_config_stub(filename)
187
+ remove_file config_stub_filename(filename)
188
+ end
189
+
190
+ def announce(text)
191
+ puts text
192
+ @indent += 1
193
+ yield
194
+ @indent -= 1
195
+ end
196
+
197
+ def copy_files(from, to)
198
+ make_path(to)
199
+ Dir.foreach(from) do |file|
200
+ unless @ignore.include?(file)
201
+ full_name = File.join(from, file)
202
+ if File.directory?(full_name)
203
+ copy_files full_name, File.join(to, file)
204
+ else
205
+ copy_file full_name, File.join(to, file)
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ def copy_file(from, to)
212
+ return if not @overwrite and (File.file?(to) and not ask_yes_or_no("overwrite #{to}"))
213
+ make_path(File.dirname(to))
214
+ FileUtils.cp from, to
215
+ puts "created #{to}"
216
+ end
217
+
218
+ def make_dir(dir)
219
+ unless File.directory?(dir)
220
+ FileUtils.mkdir dir
221
+ puts "created #{dir}"
222
+ end
223
+ end
224
+
225
+ def make_path(path)
226
+ unless File.directory?(path)
227
+ parts = path.split(%r{\\|/})
228
+ if parts.size > 1
229
+ parts.pop
230
+ make_path File.join(*parts)
231
+ end
232
+ make_dir path
233
+ end
234
+ end
235
+
236
+ def create_file(filename, text)
237
+ open(filename, 'w+') do |file|
238
+ file.puts text
239
+ end
240
+ puts "created #{filename}"
241
+ end
242
+
243
+ def remove_file(file)
244
+ if File.file?(file)
245
+ FileUtils.rm file
246
+ puts "removed #{file}"
247
+ end
248
+ end
249
+
250
+ def make_executable(filename)
251
+ FileUtils.chmod(0775, filename)
252
+ puts "made #{filename} executable"
253
+ end
254
+
255
+ def clean_path(path)
256
+ Pathname.new(path).cleanpath(true).to_s unless path.nil?
257
+ end
258
+
259
+ def print(*args)
260
+ @out << args
261
+ @out.flush
262
+ end
263
+
264
+ def puts(*args)
265
+ args << '' if args.size == 0
266
+ print *(args.map { |a| "#{' ' * @indent}#{a}\n" })
267
+ end
268
+
269
+ def gets
270
+ @in.gets
271
+ end
272
+
273
+ def ask_yes_or_no(question, default = :yes)
274
+ prompt = (default == :yes) ? "[Yn]" : "[yN]"
275
+ loop do
276
+ print "#{question}? #{prompt} "
277
+ case gets.strip.downcase
278
+ when "yes", "y"
279
+ break true
280
+ when "no", "n"
281
+ break false
282
+ when ""
283
+ break default == :yes
284
+ else
285
+ invalid_option
286
+ end
287
+ end
288
+ end
289
+
290
+ def invalid_option
291
+ puts "Invalid option."
292
+ end
293
+
294
+ def gem?
295
+ parent_dir = File.expand_path(File.join(@radiant_root, '..'))
296
+ last_part = parent_dir.split(%r{\\|/}).pop
297
+ last_part.downcase == 'gems'
298
+ end
299
+ end
300
+
301
+ trap('INT') do
302
+ puts
303
+ exit
304
+ end
305
+ RadiantCommandApplication.run