rails_product 0.5

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 (114) hide show
  1. data/CHANGELOG +619 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +195 -0
  4. data/Rakefile +413 -0
  5. data/bin/benchmarker +19 -0
  6. data/bin/breakpointer +3 -0
  7. data/bin/breakpointer_for_gem +4 -0
  8. data/bin/console +23 -0
  9. data/bin/console_sandbox +0 -0
  10. data/bin/destroy +7 -0
  11. data/bin/generate +7 -0
  12. data/bin/listener +86 -0
  13. data/bin/process/reaper +123 -0
  14. data/bin/process/spawner +54 -0
  15. data/bin/process/spinner +60 -0
  16. data/bin/profiler +34 -0
  17. data/bin/rails +17 -0
  18. data/bin/rails_product +17 -0
  19. data/bin/runner +28 -0
  20. data/bin/server +125 -0
  21. data/bin/tracker +69 -0
  22. data/bin/update +5 -0
  23. data/configs/apache/vhost.example.conf +42 -0
  24. data/configs/apache.conf +40 -0
  25. data/configs/database.yml +23 -0
  26. data/configs/empty.log +0 -0
  27. data/configs/routes.rb +19 -0
  28. data/dispatches/dispatch.fcgi +24 -0
  29. data/dispatches/dispatch.rb +10 -0
  30. data/dispatches/gateway.cgi +97 -0
  31. data/doc/README_FOR_APP +2 -0
  32. data/environments/development.rb +14 -0
  33. data/environments/environment.rb +101 -0
  34. data/environments/production.rb +8 -0
  35. data/environments/test.rb +17 -0
  36. data/fresh_rakefile +223 -0
  37. data/helpers/application.rb +4 -0
  38. data/helpers/application_helper.rb +3 -0
  39. data/helpers/test_helper.rb +26 -0
  40. data/html/404.html +8 -0
  41. data/html/500.html +8 -0
  42. data/html/favicon.ico +0 -0
  43. data/html/index.html +78 -0
  44. data/html/javascripts/controls.js +446 -0
  45. data/html/javascripts/dragdrop.js +537 -0
  46. data/html/javascripts/effects.js +612 -0
  47. data/html/javascripts/prototype.js +1038 -0
  48. data/html/robots.txt +1 -0
  49. data/lib/binding_of_caller.rb +83 -0
  50. data/lib/breakpoint.rb +523 -0
  51. data/lib/breakpoint_client.rb +196 -0
  52. data/lib/code_statistics.rb +104 -0
  53. data/lib/console_sandbox.rb +6 -0
  54. data/lib/dispatcher.rb +59 -0
  55. data/lib/fcgi_handler.rb +156 -0
  56. data/lib/productize.rb +116 -0
  57. data/lib/rails_generator/base.rb +203 -0
  58. data/lib/rails_generator/commands.rb +409 -0
  59. data/lib/rails_generator/generators/applications/app/USAGE +16 -0
  60. data/lib/rails_generator/generators/applications/app/app_generator.rb +126 -0
  61. data/lib/rails_generator/generators/applications/productized_app/USAGE +16 -0
  62. data/lib/rails_generator/generators/applications/productized_app/productized_app_generator.rb +133 -0
  63. data/lib/rails_generator/generators/components/controller/USAGE +30 -0
  64. data/lib/rails_generator/generators/components/controller/controller_generator.rb +38 -0
  65. data/lib/rails_generator/generators/components/controller/templates/controller.rb +10 -0
  66. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
  67. data/lib/rails_generator/generators/components/controller/templates/helper.rb +2 -0
  68. data/lib/rails_generator/generators/components/controller/templates/view.rhtml +2 -0
  69. data/lib/rails_generator/generators/components/mailer/USAGE +19 -0
  70. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +32 -0
  71. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +3 -0
  72. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +13 -0
  73. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +37 -0
  74. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +3 -0
  75. data/lib/rails_generator/generators/components/migration/USAGE +14 -0
  76. data/lib/rails_generator/generators/components/migration/migration_generator.rb +9 -0
  77. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -0
  78. data/lib/rails_generator/generators/components/model/USAGE +17 -0
  79. data/lib/rails_generator/generators/components/model/model_generator.rb +18 -0
  80. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +5 -0
  81. data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
  82. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +14 -0
  83. data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
  84. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +178 -0
  85. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +54 -0
  86. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +3 -0
  87. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +1 -0
  88. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +98 -0
  89. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  90. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +13 -0
  91. data/lib/rails_generator/generators/components/scaffold/templates/style.css +74 -0
  92. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +9 -0
  93. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +27 -0
  94. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +8 -0
  95. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +8 -0
  96. data/lib/rails_generator/generators/components/web_service/USAGE +28 -0
  97. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +5 -0
  98. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +8 -0
  99. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +19 -0
  100. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +29 -0
  101. data/lib/rails_generator/lookup.rb +206 -0
  102. data/lib/rails_generator/manifest.rb +53 -0
  103. data/lib/rails_generator/options.rb +134 -0
  104. data/lib/rails_generator/scripts/destroy.rb +7 -0
  105. data/lib/rails_generator/scripts/generate.rb +7 -0
  106. data/lib/rails_generator/scripts/update.rb +12 -0
  107. data/lib/rails_generator/scripts.rb +83 -0
  108. data/lib/rails_generator/simple_logger.rb +46 -0
  109. data/lib/rails_generator/spec.rb +44 -0
  110. data/lib/rails_generator.rb +43 -0
  111. data/lib/rubyprof_ext.rb +35 -0
  112. data/lib/webrick_server.rb +148 -0
  113. data/sites/fresh_rakefile +176 -0
  114. metadata +250 -0
data/README ADDED
@@ -0,0 +1,195 @@
1
+ == Welcome to the Productized Rails Application generator
2
+ Author: Duane Johnson (canadaduane)
3
+ Email: duane.johnson@gmail.com
4
+ Project Website: http://inquirylabs.com/productize/
5
+
6
+ = What is a 'Productized Rails Application' ?
7
+
8
+ At MyTechSupport, we often have clients who pay a few thousand dollars for
9
+ a web site, but in order to make a profit, we need to re-sell our work to
10
+ other companies with similar business needs. For example, we are currently
11
+ working on an adoption site (Jul 2005). Adoption sites, in general, have
12
+ some generic needs (e.g. a "Birth Mother" login and a "Waiting Family"
13
+ login), but our client has some particular needs as well.
14
+
15
+ Using the following code, you can create a single generic application which
16
+ uses a separate database for each client. In addition, you will have a
17
+ hierarchical application structure wherein add-ons and tweaks for specific
18
+ customers are possible without affecting the core "generic" site code base
19
+ (neither will you have to copy that code base for each application). In
20
+ this way, you can maintain a core application code base that every client
21
+ uses, while still providing flexibility for paid add-ons or site-specific
22
+ needs.
23
+
24
+ = Installation
25
+
26
+ To install the rails_product generator, simply run:
27
+
28
+ $ gem install rails_product
29
+
30
+ (This assumes you have the prerequisites to Rails already installed, e.g.
31
+ Ruby 1.8.2 2004-12-25 and the 'gem' shell command from rubyforge.org).
32
+
33
+ Next, you'll want to make sure you have the site generator as well:
34
+
35
+ $ gem install site_generator
36
+
37
+ The site generator will create a hollow directory structure for each site
38
+ that you add to your base application.
39
+
40
+ So, now that you've got the gems installed, here's how you'd create your
41
+ very first Rails product:
42
+
43
+ $ cd ~/Projects
44
+ $ rails_product shopping_cart
45
+ create
46
+ create app/apis
47
+ <snip>
48
+ create sites
49
+ create Rakefile
50
+ create README
51
+ create CHANGELOG
52
+ create app/controllers/application.rb
53
+ create app/helpers/application_helper.rb
54
+ create test/test_helper.rb
55
+ create config/database.yml
56
+ create config/routes.rb
57
+ create public/.htaccess
58
+ create sites/Rakefile
59
+ <snip>
60
+ $ cd shopping_cart
61
+ $ ./script/generate site my_first_cart_client
62
+ create sites/my_first_cart_client/app/controllers
63
+ create sites/my_first_cart_client/app/helpers
64
+ create sites/my_first_cart_client/app/models
65
+ create sites/my_first_cart_client/app/views/layouts
66
+ create sites/my_first_cart_client/db/migrate
67
+ create sites/my_first_cart_client/log
68
+ create sites/my_first_cart_client/public
69
+ create sites/my_first_cart_client/config
70
+ create sites/my_first_cart_client/test/fixtures
71
+ create sites/my_first_cart_client/test/functional
72
+ create sites/my_first_cart_client/test/unit
73
+ create sites/my_first_cart_client/public/.htaccess
74
+ create sites/my_first_cart_client/public/dispatch.fcgi
75
+ create sites/my_first_cart_client/config/routes.rb
76
+ $ ./script/server -s my_first_cart_client
77
+ => Productized Rails application started on http://0.0.0.0:3000
78
+ ...
79
+
80
+ At this point, assuming your application is going to be using a
81
+ database, you'll want to go make your first site's database. Depending on
82
+ how you do things, you'll want to make one, two, or possibly all three of
83
+ these databases:
84
+ my_first_cart_client_dev
85
+ my_first_cart_client_test
86
+ my_first_cart_client
87
+
88
+ The last database in that list is the production database.
89
+
90
+
91
+ = How Does The Directory Structure Differ From a Regular Rails Application?
92
+
93
+ The directory structure of the Generic application is just like a normal
94
+ Rails application, with one additional directory: the "sites" directory. So
95
+ it looks something like this:
96
+
97
+ RAILS_ROOT/
98
+ app/
99
+ controllers/
100
+ helpers/
101
+ models/
102
+ views/
103
+ public/
104
+ sites/
105
+ best_ever_adoptions_co_inc/ # <-- Site #1
106
+ app/
107
+ controllers/
108
+ helpers/
109
+ models/
110
+ views/
111
+ config/
112
+ db/
113
+ migrate/
114
+ public/
115
+ test/
116
+ fixtures/
117
+ functional/
118
+ unit/
119
+ yet_another_adoption_co/ # <-- Site #2
120
+ app/
121
+ controllers/
122
+ helpers/
123
+ models/
124
+ views/
125
+ (etc.)
126
+
127
+ Note that although the directory structure of each individual site is
128
+ almost identical to a regular Rails application, you need not have ANY
129
+ files in these directories. In fact, you can omit any directory (except
130
+ the SITE_ROOT, e.g. sites/best_ever_adoptions_co_inc/) if it does not
131
+ contain files. So how does it work?
132
+
133
+ Well, if you put a file called, for example, welcome_controller.rb in
134
+ RAILS_ROOT/app/controllers, then all of your sites will access that
135
+ controller as normal UNLESS you put a file with the same name in the
136
+ site-specific controllers folder. In that case, the RAILS_ROOT
137
+ welcome_controller.rb will be loaded, and then the WelcomeController class
138
+ will be reopened (yay for Ruby!) by the site-specific welcome_controller.rb
139
+ (say, for example, in
140
+ RAILS_ROOT/sites/yet_another_adoption_co/app/controllers/) and modified as
141
+ needed. For example, you could override the "index" method to do a
142
+ redirect, or you could add a before_filter to make the controller require a
143
+ login.
144
+
145
+ Views, layouts and partials act similarly--however, they simply override
146
+ their generic counterparts. For example, if you have an index.rhtml and a
147
+ _title.rhtml in RAILS_ROOT/app/views/welcome/ and supposing this
148
+ index.rhtml has a <%= render :partial => "title" %> in its code, then the
149
+ _title partial will be rendered in place. Now, however, let's say that we
150
+ put a _title.rhtml file in
151
+ RAILS_ROOT/sites/yet_another_adoption_co/app/views/welcome/. In that case,
152
+ our generic index.rhtml will load the site-specific _title partial in
153
+ place. Hierarchical customizations in a jiffy.
154
+
155
+ = Implementation Details
156
+
157
+ If you would like to understand how all of the pieces work together to
158
+ accomplish this feat, read on.
159
+
160
+ Here is what the rails_product generator will do:
161
+
162
+ 1. Create the RAILS_ROOT directory structure as usual, with the addition
163
+ of a /sites folder.
164
+
165
+ 2. Create a productize.rb file in your application's lib/ folder (open it
166
+ and read the comments to see what it does exactly. This is where the core
167
+ magic happens since we can re-open the Rails classes as necessary to allow
168
+ for our productization approach.)
169
+
170
+ 3. Create a slightly modified environment.rb file in your config/ folder.
171
+ The following three lines are different from the regular environment.rb:
172
+
173
+ a. SITE = ENV['SITE'] || ENV['site']
174
+ Sets a constant for the rest of the application so it can know where
175
+ to find your site's stuff.
176
+
177
+ b. require 'productize'
178
+ Modifies the core Rails classes as necessary to load both the base
179
+ application's code and the site-specific code.
180
+
181
+ c. File.join(SITE_ROOT, 'app', 'controllers'),
182
+ Lets the Dependencies::LoadingModules class know where to find site-
183
+ specific controllers if the base controller doesn't exist.
184
+
185
+ 4. Create a modified database.yml file that will dynamically load the
186
+ correct database when the server starts up.
187
+
188
+ 5. Create an 'apache' directory in your config/ folder with a sample Apache
189
+ VirtualHost configuration file. This sample file will show you what you'll
190
+ need to do to get Apache to behave like WEBrick below (shares resources).
191
+
192
+ 6. Create a modified script/server file that will let your WEBrick server
193
+ share the resources in your base application's public folder (e.g. images,
194
+ javascripts etc.) without having to copy them to each site's individual
195
+ public folder (Hurray for the DRY principle!) (DRY=Don't Repeat Yourself).
data/Rakefile ADDED
@@ -0,0 +1,413 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/contrib/rubyforgepublisher'
6
+
7
+ require 'date'
8
+ require 'rbconfig'
9
+
10
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
11
+ PKG_NAME = 'rails_product'
12
+ PKG_VERSION = '0.5' + PKG_BUILD
13
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
14
+ PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
15
+
16
+ RELEASE_NAME = "REL #{PKG_VERSION}"
17
+
18
+ RUBY_FORGE_PROJECT = "rails"
19
+ RUBY_FORGE_USER = "webster132"
20
+
21
+
22
+ # Rake::TestTask.new("test") do |t|
23
+ # t.libs << 'test'
24
+ # t.pattern = 'test/*_test.rb'
25
+ # t.verbose = true
26
+ # end
27
+
28
+
29
+ BASE_DIRS = %w( app config/environments components db doc log lib public script script/process test vendor )
30
+ APP_DIRS = %w( apis models controllers helpers views views/layouts )
31
+ PUBLIC_DIRS = %w( images javascripts stylesheets )
32
+ TEST_DIRS = %w( fixtures unit functional mocks mocks/development mocks/test )
33
+
34
+ BASE_DIRS << "sites"
35
+ SITE_BASE_DIRS = %w( app db db/migrate public test )
36
+ SITE_APP_DIRS = %w( models controllers helpers views views/layouts )
37
+ SITE_TEST_DIRS = %w( fixtures unit functional )
38
+
39
+ LOG_FILES = %w( server.log development.log test.log production.log )
40
+ HTML_FILES = %w( 404.html 500.html index.html robots.txt favicon.ico javascripts/prototype.js javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js )
41
+ BIN_FILES = %w( generate destroy breakpointer console server update runner profiler benchmarker process/reaper process/spinner process/spawner )
42
+
43
+ VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport actionwebservice railties )
44
+
45
+
46
+ desc "Generates a fresh Rails package with documentation"
47
+ task :fresh_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content, :generate_documentation ]
48
+
49
+ desc "Generates a fresh Rails package using GEMs with documentation"
50
+ task :fresh_gem_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_ties_content, :copy_gem_environment ]
51
+
52
+ desc "Generates a fresh Rails package without documentation (faster)"
53
+ task :fresh_rails_without_docs => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content ]
54
+
55
+ desc "Generates a fresh Rails package without documentation (faster)"
56
+ task :fresh_rails_without_docs_using_links => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ]
57
+
58
+ desc "Generates minimal Rails package using symlinks"
59
+ task :dev => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ]
60
+
61
+ desc "Packages the fresh Rails package with documentation"
62
+ task :package => [ :clean, :fresh_rails ] do
63
+ system %{cd ..; tar -czvf #{PKG_NAME}-#{PKG_VERSION}.tgz #{PKG_NAME}}
64
+ system %{cd ..; zip -r #{PKG_NAME}-#{PKG_VERSION}.zip #{PKG_NAME}}
65
+ end
66
+
67
+ task :clean do
68
+ rm_rf PKG_DESTINATION
69
+ end
70
+
71
+ # Get external spinoffs -------------------------------------------------------------------
72
+
73
+ desc "Updates railties to the latest version of the javascript spinoffs"
74
+ task :update_js do
75
+ for js in %w( prototype controls dragdrop effects )
76
+ rm "html/javascripts/#{js}.js"
77
+ cp "./../actionpack/lib/action_view/helpers/javascripts/#{js}.js", "html/javascripts"
78
+ end
79
+ end
80
+
81
+ # Make directory structure ----------------------------------------------------------------
82
+
83
+ def make_dest_dirs(dirs, path = nil)
84
+ mkdir_p dirs.map { |dir| File.join(PKG_DESTINATION, path, dir) }
85
+ end
86
+
87
+ desc "Make the directory structure for the new Rails application"
88
+ task :make_dir_structure => [ :make_base_dirs, :make_app_dirs, :make_public_dirs, :make_test_dirs ]
89
+
90
+ task(:make_base_dirs) { make_dest_dirs BASE_DIRS }
91
+ task(:make_app_dirs) { make_dest_dirs APP_DIRS, 'app' }
92
+ task(:make_public_dirs) { make_dest_dirs PUBLIC_DIRS, 'public' }
93
+ task(:make_test_dirs) { make_dest_dirs TEST_DIRS, 'test' }
94
+
95
+
96
+ # Initialize file stubs -------------------------------------------------------------------
97
+
98
+ desc "Initialize empty file stubs (such as for logging)"
99
+ task :initialize_file_stubs => [ :initialize_log_files ]
100
+
101
+ task :initialize_log_files do
102
+ log_dir = File.join(PKG_DESTINATION, 'log')
103
+ chmod 0777, log_dir
104
+ LOG_FILES.each do |log_file|
105
+ log_path = File.join(log_dir, log_file)
106
+ touch log_path
107
+ chmod 0666, log_path
108
+ end
109
+ end
110
+
111
+
112
+ # Copy Vendors ----------------------------------------------------------------------------
113
+
114
+ desc "Copy in all the Rails packages to vendor"
115
+ task :copy_vendor_libraries do
116
+ mkdir File.join(PKG_DESTINATION, 'vendor', 'rails')
117
+ VENDOR_LIBS.each { |dir| cp_r File.join('..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) }
118
+ end
119
+
120
+ desc "Link in all the Rails packages to vendor"
121
+ task :link_vendor_libraries do
122
+ mkdir File.join(PKG_DESTINATION, 'vendor', 'rails')
123
+ VENDOR_LIBS.each { |dir| ln_s File.join('..', '..', '..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) }
124
+ end
125
+
126
+
127
+ # Copy Ties Content -----------------------------------------------------------------------
128
+
129
+ # :link_apache_config
130
+ desc "Make copies of all the default content of ties"
131
+ task :copy_ties_content => [
132
+ :copy_rootfiles, :copy_dispatches, :copy_html_files, :copy_application,
133
+ :copy_configs, :copy_binfiles, :copy_test_helpers, :copy_app_doc_readme ]
134
+
135
+ task :copy_dispatches do
136
+ copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.rb")
137
+ chmod 0755, "#{PKG_DESTINATION}/public/dispatch.rb"
138
+
139
+ copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.cgi")
140
+ chmod 0755, "#{PKG_DESTINATION}/public/dispatch.cgi"
141
+
142
+ copy_with_rewritten_ruby_path("dispatches/dispatch.fcgi", "#{PKG_DESTINATION}/public/dispatch.fcgi")
143
+ chmod 0755, "#{PKG_DESTINATION}/public/dispatch.fcgi"
144
+
145
+ # copy_with_rewritten_ruby_path("dispatches/gateway.cgi", "#{PKG_DESTINATION}/public/gateway.cgi")
146
+ # chmod 0755, "#{PKG_DESTINATION}/public/gateway.cgi"
147
+ end
148
+
149
+ task :copy_html_files do
150
+ HTML_FILES.each { |file| cp File.join('html', file), File.join(PKG_DESTINATION, 'public', file) }
151
+ end
152
+
153
+ task :copy_application do
154
+ cp "helpers/application.rb", "#{PKG_DESTINATION}/app/controllers/application.rb"
155
+ cp "helpers/application_helper.rb", "#{PKG_DESTINATION}/app/helpers/application_helper.rb"
156
+ end
157
+
158
+ task :copy_configs do
159
+ cp "configs/database.yml", "#{PKG_DESTINATION}/config/database.yml"
160
+ cp "configs/routes.rb", "#{PKG_DESTINATION}/config/routes.rb"
161
+
162
+ cp "configs/apache.conf", "#{PKG_DESTINATION}/public/.htaccess"
163
+
164
+ cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
165
+ cp "environments/production.rb", "#{PKG_DESTINATION}/config/environments/production.rb"
166
+ cp "environments/development.rb", "#{PKG_DESTINATION}/config/environments/development.rb"
167
+ cp "environments/test.rb", "#{PKG_DESTINATION}/config/environments/test.rb"
168
+ end
169
+
170
+ task :copy_binfiles do
171
+ BIN_FILES.each do |file|
172
+ dest_file = File.join(PKG_DESTINATION, 'script', file)
173
+ copy_with_rewritten_ruby_path(File.join('bin', file), dest_file)
174
+ chmod 0755, dest_file
175
+ end
176
+ end
177
+
178
+ task :copy_rootfiles do
179
+ cp "fresh_rakefile", "#{PKG_DESTINATION}/Rakefile"
180
+ cp "README", "#{PKG_DESTINATION}/README"
181
+ cp "CHANGELOG", "#{PKG_DESTINATION}/CHANGELOG"
182
+ end
183
+
184
+ task :copy_test_helpers do
185
+ cp "helpers/test_helper.rb", "#{PKG_DESTINATION}/test/test_helper.rb"
186
+ end
187
+
188
+ task :copy_app_doc_readme do
189
+ cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
190
+ end
191
+
192
+ task :link_apache_config do
193
+ chdir(File.join(PKG_DESTINATION, 'config')) {
194
+ ln_s "../public/.htaccess", "apache.conf"
195
+ }
196
+ end
197
+
198
+ def copy_with_rewritten_ruby_path(src_file, dest_file)
199
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
200
+
201
+ File.open(dest_file, 'w') do |df|
202
+ File.open(src_file) do |sf|
203
+ line = sf.gets
204
+ if (line =~ /#!.+ruby\s*/) != nil
205
+ df.puts("#!#{ruby}")
206
+ else
207
+ df.puts(line)
208
+ end
209
+ df.write(sf.read)
210
+ end
211
+ end
212
+ end
213
+
214
+
215
+ # Generate documentation ------------------------------------------------------------------
216
+
217
+ desc "Generate documentation for the framework and for the empty application"
218
+ task :generate_documentation => [ :generate_app_doc, :generate_rails_framework_doc ]
219
+
220
+ task :generate_rails_framework_doc do
221
+ system %{cd #{PKG_DESTINATION}; rake apidoc}
222
+ end
223
+
224
+ task :generate_app_doc do
225
+ File.cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
226
+ system %{cd #{PKG_DESTINATION}; rake appdoc}
227
+ end
228
+
229
+
230
+ # Generate GEM ----------------------------------------------------------------------------
231
+
232
+ task :copy_gem_environment do
233
+ cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
234
+ dest_file = File.join(PKG_DESTINATION, 'script', 'breakpointer')
235
+ copy_with_rewritten_ruby_path(File.join('bin', 'breakpointer_for_gem'), dest_file)
236
+ chmod 0755, dest_file
237
+ end
238
+
239
+
240
+ PKG_FILES = FileList[
241
+ '[a-zA-Z]*',
242
+ 'bin/**/*',
243
+ 'configs/**/*',
244
+ 'doc/**/*',
245
+ 'dispatches/**/*',
246
+ 'environments/**/*',
247
+ 'helpers/**/*',
248
+ 'generators/**/*',
249
+ 'html/**/*',
250
+ 'lib/**/*',
251
+ 'sites/**/*'
252
+ ]
253
+
254
+ spec = Gem::Specification.new do |s|
255
+ s.name = 'rails_product'
256
+ s.version = PKG_VERSION
257
+ s.summary = "Creates a ready-to-go productized Ruby on Rails application from a single command ('rails_product')."
258
+ s.description = <<-EOF
259
+ A "Productized Rails Application" is a single generic application having a hierarchical structure
260
+ wherein add-ons and tweaks for concurrent versions of the application are possible without affecting
261
+ the core "generic" code base. You might use this, for example, if you want to maintain a common
262
+ shopping cart code base that all of your clients use, while still providing flexibility for paid
263
+ add-ons or site-specific needs.
264
+ EOF
265
+
266
+ s.add_dependency('rake', '>= 0.5.3')
267
+ s.add_dependency('activesupport', '= 1.1.1' + PKG_BUILD)
268
+ s.add_dependency('activerecord', '= 1.11.1' + PKG_BUILD)
269
+ s.add_dependency('actionpack', '= 1.9.1' + PKG_BUILD)
270
+ s.add_dependency('actionmailer', '= 1.0.1' + PKG_BUILD)
271
+ s.add_dependency('actionwebservice', '= 0.8.1' + PKG_BUILD)
272
+
273
+ s.rdoc_options << '--exclude' << '.'
274
+ s.has_rdoc = false
275
+
276
+ s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
277
+ s.require_path = 'lib'
278
+
279
+ s.bindir = "bin" # Use these for applications.
280
+ s.executables = ["rails_product"]
281
+ s.default_executable = "rails_product"
282
+
283
+ s.author = "Duane Johnson"
284
+ s.email = "duane.johnson@gmail.com"
285
+ s.homepage = "http://inquirylabs.com/productize/"
286
+ s.rubyforge_project = "rails_product"
287
+ end
288
+
289
+ Rake::GemPackageTask.new(spec) do |pkg|
290
+ end
291
+
292
+
293
+ # Publishing -------------------------------------------------------
294
+ desc "Publish the API documentation"
295
+ task :pgem => [:gem] do
296
+ Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
297
+ `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
298
+ end
299
+
300
+ desc "Publish the release files to RubyForge."
301
+ task :release => [:gem] do
302
+ files = ["gem"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
303
+
304
+ if RUBY_FORGE_PROJECT then
305
+ require 'net/http'
306
+ require 'open-uri'
307
+
308
+ project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
309
+ project_data = open(project_uri) { |data| data.read }
310
+ group_id = project_data[/[?&]group_id=(\d+)/, 1]
311
+ raise "Couldn't get group id" unless group_id
312
+
313
+ # This echos password to shell which is a bit sucky
314
+ if ENV["RUBY_FORGE_PASSWORD"]
315
+ password = ENV["RUBY_FORGE_PASSWORD"]
316
+ else
317
+ print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
318
+ password = STDIN.gets.chomp
319
+ end
320
+
321
+ login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
322
+ data = [
323
+ "login=1",
324
+ "form_loginname=#{RUBY_FORGE_USER}",
325
+ "form_pw=#{password}"
326
+ ].join("&")
327
+ http.post("/account/login.php", data)
328
+ end
329
+
330
+ cookie = login_response["set-cookie"]
331
+ raise "Login failed" unless cookie
332
+ headers = { "Cookie" => cookie }
333
+
334
+ release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
335
+ release_data = open(release_uri, headers) { |data| data.read }
336
+ package_id = release_data[/[?&]package_id=(\d+)/, 1]
337
+ raise "Couldn't get package id" unless package_id
338
+
339
+ first_file = true
340
+ release_id = ""
341
+
342
+ files.each do |filename|
343
+ basename = File.basename(filename)
344
+ file_ext = File.extname(filename)
345
+ file_data = File.open(filename, "rb") { |file| file.read }
346
+
347
+ puts "Releasing #{basename}..."
348
+
349
+ release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
350
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
351
+ type_map = {
352
+ ".zip" => "3000",
353
+ ".tgz" => "3110",
354
+ ".gz" => "3110",
355
+ ".gem" => "1400"
356
+ }; type_map.default = "9999"
357
+ type = type_map[file_ext]
358
+ boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
359
+
360
+ query_hash = if first_file then
361
+ {
362
+ "group_id" => group_id,
363
+ "package_id" => package_id,
364
+ "release_name" => RELEASE_NAME,
365
+ "release_date" => release_date,
366
+ "type_id" => type,
367
+ "processor_id" => "8000", # Any
368
+ "release_notes" => "",
369
+ "release_changes" => "",
370
+ "preformatted" => "1",
371
+ "submit" => "1"
372
+ }
373
+ else
374
+ {
375
+ "group_id" => group_id,
376
+ "release_id" => release_id,
377
+ "package_id" => package_id,
378
+ "step2" => "1",
379
+ "type_id" => type,
380
+ "processor_id" => "8000", # Any
381
+ "submit" => "Add This File"
382
+ }
383
+ end
384
+
385
+ query = "?" + query_hash.map do |(name, value)|
386
+ [name, URI.encode(value)].join("=")
387
+ end.join("&")
388
+
389
+ data = [
390
+ "--" + boundary,
391
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
392
+ "Content-Type: application/octet-stream",
393
+ "Content-Transfer-Encoding: binary",
394
+ "", file_data, ""
395
+ ].join("\x0D\x0A")
396
+
397
+ release_headers = headers.merge(
398
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
399
+ )
400
+
401
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
402
+ http.post(target + query, data, release_headers)
403
+ end
404
+
405
+ if first_file then
406
+ release_id = release_response.body[/release_id=(\d+)/, 1]
407
+ raise("Couldn't get release id") unless release_id
408
+ end
409
+
410
+ first_file = false
411
+ end
412
+ end
413
+ end
data/bin/benchmarker ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ if ARGV.empty?
4
+ puts "Usage: benchmarker times 'Person.expensive_way' 'Person.another_expensive_way' ..."
5
+ exit
6
+ end
7
+
8
+ require File.dirname(__FILE__) + '/../config/environment'
9
+ require 'benchmark'
10
+ include Benchmark
11
+
12
+ # Don't include compilation in the benchmark
13
+ ARGV[1..-1].each { |expression| eval(expression) }
14
+
15
+ bm(6) do |x|
16
+ ARGV[1..-1].each_with_index do |expression, idx|
17
+ x.report("##{idx + 1}") { ARGV[0].to_i.times { eval(expression) } }
18
+ end
19
+ end
data/bin/breakpointer ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/local/bin/ruby
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/../vendor/railties/lib'
3
+ require 'breakpoint_client'
@@ -0,0 +1,4 @@
1
+ #!/usr/local/bin/ruby
2
+ require 'rubygems'
3
+ require_gem 'rails'
4
+ require 'breakpoint_client'
data/bin/console ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/local/bin/ruby
2
+ irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
3
+
4
+ require 'optparse'
5
+ options = { :sandbox => false, :irb => irb }
6
+ OptionParser.new do |opt|
7
+ opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |options[:sandbox]| }
8
+ opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |options[:irb]| }
9
+ opt.parse!(ARGV)
10
+ end
11
+
12
+ libs = " -r irb/completion"
13
+ libs << " -r #{File.dirname(__FILE__)}/../config/environment"
14
+ libs << " -r console_sandbox" if options[:sandbox]
15
+
16
+ ENV['RAILS_ENV'] = ARGV.first || 'development'
17
+ if options[:sandbox]
18
+ puts "Loading #{ENV['RAILS_ENV']} environment in sandbox."
19
+ puts "Any modifications you make will be rolled back on exit."
20
+ else
21
+ puts "Loading #{ENV['RAILS_ENV']} environment."
22
+ end
23
+ exec "#{options[:irb]} #{libs} --prompt-mode simple"
File without changes
data/bin/destroy ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.dirname(__FILE__) + '/../config/environment'
3
+ require 'rails_generator'
4
+ require 'rails_generator/scripts/destroy'
5
+
6
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
7
+ Rails::Generator::Scripts::Destroy.new.run(ARGV)
data/bin/generate ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/local/bin/ruby
2
+ require File.dirname(__FILE__) + '/../config/environment'
3
+ require 'rails_generator'
4
+ require 'rails_generator/scripts/generate'
5
+
6
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
7
+ Rails::Generator::Scripts::Generate.new.run(ARGV)