wycats-merb-core 0.9.8

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 (98) hide show
  1. data/CHANGELOG +992 -0
  2. data/CONTRIBUTORS +94 -0
  3. data/LICENSE +20 -0
  4. data/PUBLIC_CHANGELOG +142 -0
  5. data/README +21 -0
  6. data/Rakefile +458 -0
  7. data/TODO +0 -0
  8. data/bin/merb +11 -0
  9. data/bin/merb-specs +5 -0
  10. data/lib/merb-core.rb +598 -0
  11. data/lib/merb-core/autoload.rb +31 -0
  12. data/lib/merb-core/bootloader.rb +717 -0
  13. data/lib/merb-core/config.rb +305 -0
  14. data/lib/merb-core/constants.rb +45 -0
  15. data/lib/merb-core/controller/abstract_controller.rb +568 -0
  16. data/lib/merb-core/controller/exceptions.rb +315 -0
  17. data/lib/merb-core/controller/merb_controller.rb +256 -0
  18. data/lib/merb-core/controller/mime.rb +107 -0
  19. data/lib/merb-core/controller/mixins/authentication.rb +123 -0
  20. data/lib/merb-core/controller/mixins/conditional_get.rb +83 -0
  21. data/lib/merb-core/controller/mixins/controller.rb +319 -0
  22. data/lib/merb-core/controller/mixins/render.rb +513 -0
  23. data/lib/merb-core/controller/mixins/responder.rb +469 -0
  24. data/lib/merb-core/controller/template.rb +254 -0
  25. data/lib/merb-core/core_ext.rb +9 -0
  26. data/lib/merb-core/core_ext/hash.rb +7 -0
  27. data/lib/merb-core/core_ext/kernel.rb +340 -0
  28. data/lib/merb-core/dispatch/cookies.rb +130 -0
  29. data/lib/merb-core/dispatch/default_exception/default_exception.rb +93 -0
  30. data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +198 -0
  31. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +73 -0
  32. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +94 -0
  33. data/lib/merb-core/dispatch/dispatcher.rb +176 -0
  34. data/lib/merb-core/dispatch/request.rb +729 -0
  35. data/lib/merb-core/dispatch/router.rb +151 -0
  36. data/lib/merb-core/dispatch/router/behavior.rb +566 -0
  37. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  38. data/lib/merb-core/dispatch/router/resources.rb +191 -0
  39. data/lib/merb-core/dispatch/router/route.rb +511 -0
  40. data/lib/merb-core/dispatch/session.rb +222 -0
  41. data/lib/merb-core/dispatch/session/container.rb +74 -0
  42. data/lib/merb-core/dispatch/session/cookie.rb +173 -0
  43. data/lib/merb-core/dispatch/session/memcached.rb +68 -0
  44. data/lib/merb-core/dispatch/session/memory.rb +99 -0
  45. data/lib/merb-core/dispatch/session/store_container.rb +150 -0
  46. data/lib/merb-core/dispatch/worker.rb +28 -0
  47. data/lib/merb-core/gem_ext/erubis.rb +77 -0
  48. data/lib/merb-core/logger.rb +203 -0
  49. data/lib/merb-core/plugins.rb +67 -0
  50. data/lib/merb-core/rack.rb +25 -0
  51. data/lib/merb-core/rack/adapter.rb +44 -0
  52. data/lib/merb-core/rack/adapter/ebb.rb +25 -0
  53. data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
  54. data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
  55. data/lib/merb-core/rack/adapter/irb.rb +118 -0
  56. data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
  57. data/lib/merb-core/rack/adapter/runner.rb +28 -0
  58. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
  59. data/lib/merb-core/rack/adapter/thin.rb +39 -0
  60. data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
  61. data/lib/merb-core/rack/adapter/webrick.rb +36 -0
  62. data/lib/merb-core/rack/application.rb +32 -0
  63. data/lib/merb-core/rack/handler/mongrel.rb +97 -0
  64. data/lib/merb-core/rack/middleware.rb +20 -0
  65. data/lib/merb-core/rack/middleware/conditional_get.rb +29 -0
  66. data/lib/merb-core/rack/middleware/content_length.rb +18 -0
  67. data/lib/merb-core/rack/middleware/csrf.rb +73 -0
  68. data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
  69. data/lib/merb-core/rack/middleware/profiler.rb +19 -0
  70. data/lib/merb-core/rack/middleware/static.rb +45 -0
  71. data/lib/merb-core/rack/middleware/tracer.rb +20 -0
  72. data/lib/merb-core/server.rb +284 -0
  73. data/lib/merb-core/tasks/audit.rake +68 -0
  74. data/lib/merb-core/tasks/gem_management.rb +229 -0
  75. data/lib/merb-core/tasks/merb.rb +1 -0
  76. data/lib/merb-core/tasks/merb_rake_helper.rb +80 -0
  77. data/lib/merb-core/tasks/stats.rake +71 -0
  78. data/lib/merb-core/test.rb +11 -0
  79. data/lib/merb-core/test/helpers.rb +9 -0
  80. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  81. data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
  82. data/lib/merb-core/test/helpers/request_helper.rb +393 -0
  83. data/lib/merb-core/test/helpers/route_helper.rb +39 -0
  84. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  85. data/lib/merb-core/test/matchers.rb +9 -0
  86. data/lib/merb-core/test/matchers/controller_matchers.rb +351 -0
  87. data/lib/merb-core/test/matchers/route_matchers.rb +137 -0
  88. data/lib/merb-core/test/matchers/view_matchers.rb +375 -0
  89. data/lib/merb-core/test/run_specs.rb +49 -0
  90. data/lib/merb-core/test/tasks/spectasks.rb +68 -0
  91. data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
  92. data/lib/merb-core/test/test_ext/object.rb +14 -0
  93. data/lib/merb-core/test/test_ext/string.rb +14 -0
  94. data/lib/merb-core/vendor/facets.rb +2 -0
  95. data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
  96. data/lib/merb-core/vendor/facets/inflect.rb +342 -0
  97. data/lib/merb-core/version.rb +3 -0
  98. metadata +253 -0
data/CONTRIBUTORS ADDED
@@ -0,0 +1,94 @@
1
+ Use merb? Say thanks the following people:
2
+
3
+ Aaron Wheeler
4
+ Abhay Kumar
5
+ Adam Jacob
6
+ Andy C
7
+ Antti Tarvainen
8
+ Ben Burkert
9
+ Ben Chiu
10
+ Ben Griffiths
11
+ Bradly Feeley
12
+ Brandon Dimcheff
13
+ Brian Mitchell
14
+ Bryan Ray
15
+ Carl Lerche
16
+ Charles Jolley
17
+ Coda Hale
18
+ Cory ODaniel
19
+ Daniel Neighman
20
+ Daniel Schierbeck
21
+ Daniel Siemssen
22
+ David James
23
+ Diego Scataglini
24
+ Dirkjan Bussink
25
+ Dudley Flanders
26
+ Ezra Zygmuntowicz
27
+ Fabien Franzen
28
+ Flea
29
+ Gabe
30
+ Geoffrey Grosenbach
31
+ Goh Toh Chye
32
+ Grant Hollingworth
33
+ Guillaume Maury
34
+ Hampton Catlin
35
+ Ho-Sheng Hsiao
36
+ Jack Dempsey
37
+ James Herdman
38
+ James Whiteman
39
+ Janne Asmala
40
+ Jaroslaw Zabiello
41
+ Jonas Nicklas
42
+ Jonathan Younger
43
+ Josh Nichols
44
+ Kyle Drake
45
+ Lance Carlson
46
+ Loren Segal
47
+ Lori Holden
48
+ Martin Grund
49
+ Mason Browne
50
+ Matt Aimonetti
51
+ Matt Todd
52
+ Matthew Ford
53
+ Matthew Windwer
54
+ Matthijs Langenberg
55
+ Max Aller
56
+ Max Lapshin
57
+ Michael D'Auria
58
+ Michael D. Ivey
59
+ Michael Holub
60
+ Michael Latta
61
+ Michael S. Klishin
62
+ Michael Sheakoski
63
+ Mirko Froehlich
64
+ Nathan Weizenbaum
65
+ Oliver Jakubiec
66
+ Paul Barry
67
+ Paul Boone
68
+ Paul Carey
69
+ Ray Morgan
70
+ Rich Cavanaugh
71
+ Ross Lawley
72
+ Shalon Wood
73
+ Shay Arnett
74
+ Simon Jefford
75
+ Sindre Aarsaether
76
+ StarTrader
77
+ Steve Tooke
78
+ Thomas Reynolds
79
+ Tim Kofol
80
+ Wayne E. Seguin
81
+ Wayne Larsen
82
+ Wesley Beary
83
+ Will Prater
84
+ William Smith
85
+ Wilson Bilkovich
86
+ Yehuda Katz
87
+ Zach Holt
88
+ brainopia
89
+ jonas
90
+ jonuts
91
+ macournoyer
92
+ mde
93
+ rick
94
+ wvl
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Engine Yard Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/PUBLIC_CHANGELOG ADDED
@@ -0,0 +1,142 @@
1
+ 9/26/2008:
2
+ * For Merb developers, Rakefile features a new implementation of the :install
3
+ and :uninstall tasks. These will work with Gems directly, without running
4
+ the intermediate commands on the shell. This means 'sudo' is now explicitly
5
+ needed when installing gems system-wide; implicit sudo (prompt) is considered
6
+ harmful. The new code will write appropriate executable wrappers that feature
7
+ local gem loading and minigems usage. All gems in -more and -core now use this
8
+ new (un)install procedure.
9
+
10
+ 9/25/2008:
11
+ * Merb::Config[:reload_templates] needs to be set explicitly in
12
+ config/environments/development.rb - which is true for newly generated apps.
13
+ Previously Merb.env?(:development) meant that reload_templates was enabled.
14
+ Since we don't want to depend on Merb.env like that, we're using Merb::Config.
15
+
16
+ 9/24/2008:
17
+ * Kernel#dependency and Kernel#load_dependency will now register the requested
18
+ dependency on Merb::BootLoader::Dependencies.dependencies. Doing so creates a
19
+ Gem::Dependency instance, which will be returned from these methods.
20
+ Before, an Array of [name, ver] was returned. Working with Gem::Dependency
21
+ makes the dependency information more uniform, regardless of the original
22
+ version requirements.
23
+
24
+ 9/13/2008:
25
+ * Merb apps will always give priority to gems that are available locally in
26
+ Merb.root / gems. Because of the specific load order, you will need to use
27
+ bin/merb to load merb-core from local gems, as detailed below. This is also
28
+ the case for bin/merb-gen, bin/rake and bin/spec for example. The added
29
+ advantage is that your app will be completely independent from system gems.
30
+
31
+ * Thor tasks 'merb.thor' have been added for newly generated apps; regenerate
32
+ your app to get them; alternatively these are available on merbivore.com:
33
+
34
+ http://merbivore.com/merb.thor
35
+
36
+ * Release 0.9.6 introduced 'merb-gen scripts' which added script/merb and
37
+ script/merb-gen. However, now that merb.thor provides tasks to manage
38
+ bundled gems, we can directly extract the correct executables. To follow the
39
+ standard convention, these will be installed in ./bin instead of ./script.
40
+
41
+ With merb.thor installed, run the following to get started:
42
+
43
+ $ thor merb:tasks:setup # adds bin/thor, bin/rake etc.
44
+
45
+ As soon as you install other gems using merb.thor you'll have the required
46
+ bin executables available; these are setup so that running them will load
47
+ merb-core from the local gems dir, not from the system-wide rubygems.
48
+
49
+ To get bin/merb and bin/merb-gen for a fresh application, you can use:
50
+
51
+ $ thor merb:stable -a mongrel # install a full merb stack from stable rubygems
52
+
53
+ Alternatively, you can install from the bleeding edge:
54
+
55
+ $ thor merb:edge --install # install a full merb stack from github
56
+ $ thor merb:gems:install mongrel # or ebb, thin...
57
+
58
+ 9/5/2008:
59
+ * Language::English::Inflector is now English::Inflect - be sure to change your
60
+ custom inflections in config/init.rb. Additionally, the merb-gen template
61
+ config/init.rb has been changed to document the features accordingly.
62
+
63
+ 9/2/2008:
64
+ * AbstractController now uniformly uses instance_eval for Procs where previously
65
+ the controller instance (self) was passed as an argument:
66
+ - Procs thrown during dispatch
67
+ - Procs used as before/after filters
68
+ - Procs used as conditions to before/after filters
69
+
70
+ This means that code like this:
71
+
72
+ proc { |c| c.a_controller_method }
73
+
74
+ Becomes the following for the cases mentioned:
75
+
76
+ proc { a_controller_method }
77
+
78
+ 8/29/2008:
79
+ * The directory Merb.root / 'framework' is now gone - framework gems are
80
+ expected to be installed as local gems in Merb.root / 'gems':
81
+ sudo gem install merb -i ./gems
82
+ * The notion of a frozen application setup (using bundled gems) is now known
83
+ as a bundled setup; Merb.frozen? => Merb.bundled? By default an app uses
84
+ bundled gems (the -B or --bundle options to merb), to disable this use
85
+ the option --no-bundle.
86
+
87
+ 8/27/2008:
88
+ * Merb::Request#protocol now returns valid protocol names: http, not http://.
89
+
90
+ 8/22/2008:
91
+ * controller.cookies['foo'] = { ... } (Hash with options) is now deprecated;
92
+ use controller.cookies['foo'] = 'bar' for simple cookies without options, or
93
+ use controller.cookies.set_cookie('foo', 'bar', options) for more control.
94
+
95
+ 8/21/2008:
96
+ * Memcached sessions are now configured by assignment to
97
+ Merb::MemcachedSession.store (previously the CACHE constant was used)
98
+ * Added Merb::Config[:ignore_tampered_cookies] option to skip cookie warnings
99
+ during development. This defaults to 'on' in the development environment.
100
+ * Merb::Config[:session_store] or Merb::Config[:session_stores] now accept an
101
+ Array (or String); when an Array is given, multiple session stores will be
102
+ available to the application.
103
+ * If you have custom session stores (that inherit from Merb::SessionContainer)
104
+ be sure to require them in your init.rb
105
+
106
+ 8/20/2008:
107
+ * Merb::Config[:session_cookie_domain] is now
108
+ Merb::Config[:default_cookie_domain]
109
+ * Merb.registered_session_types is now Merb::Request.registered_session_types
110
+ * When running in :development env, cookie-based sessions won't bother you
111
+ by raising TamperedWithCookie anymore.
112
+
113
+ 8/14/2008:
114
+ * Merb.orm_generator_scope and friends are renamed.
115
+ ** Merb.orm_generator_scope => Merb.orm
116
+ ** Merb.test_framework_generator_scope => Merb.test_framework
117
+ ** Added Merb.template_engine
118
+
119
+ Merb-gen is updated accordingly. This let us add --haml and similar
120
+ options to merb-gen and plugin generators.
121
+
122
+ 8/10/2008:
123
+ * Modified the way Exceptions are handled in the Dispatcher
124
+ ** To rescue all exceptions, supply Exceptions#exception
125
+ ** To rescue all Merb-generated exceptions, supply Exceptions#base
126
+ ** Exceptions#internal_server_error is no longer a catch-all and should
127
+ not be used as such.
128
+
129
+ 6/22/2008:
130
+
131
+ Erubis modified:
132
+ * <%= %> now can take a block, so <%= helper do %>Hello<% end %> now works
133
+ * Erubis buffer is now an ivar (@_erb_buf), which eliminates the need for
134
+ eval in capture helpers.
135
+
136
+ CONSEQUENCE:
137
+ Helpers that take a block should simply return a string, and should not
138
+ use concat. Example:
139
+
140
+ def my_helper(&blk)
141
+ "My helper says #{capture(&blk)}."
142
+ end
data/README ADDED
@@ -0,0 +1,21 @@
1
+ merb-core is a new branch of Merb (also referred to as merb-next or the 0.9 series) which aims to provide a stable, stripped down API for a future Merb 1.0 release.
2
+
3
+ This branch is based off the 0.5 release series but with significant rewrites.
4
+
5
+ Goals of this release:
6
+
7
+ * Stabilize the @public interface methods to provide for a more consistent application development experience.
8
+ * Remove features until nothing except a central application API is left
9
+ * Improve comments on methods using a standard documentation methodology as described in DOCUMENTATION_STANDARDS
10
+ * Separate the tests into two sections... "private" and "public"
11
+ * Public methods are methods tagged with @public that will be part of the standard, stable Merb API
12
+ * Private methods are implementation methods that might
13
+ * Implement a new render API
14
+ * Build more extensions to regain selected features when needed
15
+
16
+ To familiarize yourself with how a merb-core application might look,
17
+ use merb-gen (from merb-more) to generate a few apps:
18
+ $ merb-gen app myapp # a "normal" merb app
19
+ $ merb-gen app myapp --flat # a flattened app
20
+ $ merb-gen app myapp --very-flat # a single-file app
21
+
data/Rakefile ADDED
@@ -0,0 +1,458 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+ require "rake/gempackagetask"
4
+ require "rake/rdoctask"
5
+ require "rake/testtask"
6
+ require "spec/rake/spectask"
7
+ require "fileutils"
8
+ require "extlib"
9
+
10
+ def __DIR__
11
+ File.dirname(__FILE__)
12
+ end
13
+
14
+ require __DIR__ + "/tools/rakehelp"
15
+ require __DIR__ + "/tools/annotation_extract"
16
+
17
+ include FileUtils
18
+
19
+ require "lib/merb-core/version"
20
+ require "lib/merb-core/test/run_specs"
21
+ require 'lib/merb-core/tasks/merb_rake_helper'
22
+
23
+ ##############################################################################
24
+ # Package && release
25
+ ##############################################################################
26
+ RUBY_FORGE_PROJECT = "merb"
27
+ PROJECT_URL = "http://merbivore.com"
28
+ PROJECT_SUMMARY = "Merb. Pocket rocket web framework."
29
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY
30
+
31
+ AUTHOR = "Ezra Zygmuntowicz"
32
+ EMAIL = "ez@engineyard.com"
33
+
34
+ GEM_NAME = "merb-core"
35
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
36
+ GEM_VERSION = Merb::VERSION + PKG_BUILD
37
+
38
+ RELEASE_NAME = "REL #{GEM_VERSION}"
39
+
40
+ require "extlib/tasks/release"
41
+
42
+ spec = Gem::Specification.new do |s|
43
+ s.name = GEM_NAME
44
+ s.version = GEM_VERSION
45
+ s.platform = Gem::Platform::RUBY
46
+ s.author = AUTHOR
47
+ s.email = EMAIL
48
+ s.homepage = PROJECT_URL
49
+ s.summary = PROJECT_SUMMARY
50
+ s.bindir = "bin"
51
+ s.description = PROJECT_DESCRIPTION
52
+ s.executables = %w( merb )
53
+ s.require_path = "lib"
54
+ s.files = %w( LICENSE README Rakefile TODO CHANGELOG PUBLIC_CHANGELOG CONTRIBUTORS ) + Dir["{doc/rdoc,bin,lib}/**/*"]
55
+
56
+ # rdoc
57
+ s.has_rdoc = true
58
+ s.extra_rdoc_files = %w( README LICENSE TODO )
59
+
60
+ # Dependencies
61
+ s.add_dependency "extlib", ">= 0.9.6"
62
+ s.add_dependency "erubis"
63
+ s.add_dependency "rake"
64
+ s.add_dependency "json_pure"
65
+ s.add_dependency "rspec"
66
+ s.add_dependency "rack"
67
+ s.add_dependency "mime-types"
68
+ s.add_dependency "hpricot"
69
+ s.add_dependency "thor", ">= 0.9.6"
70
+ # this escalates to "regular" dependencies, comment it out
71
+ # for now. RubyGems need some love.
72
+ #s.add_development_dependency "libxml-ruby"
73
+ #s.add_development_dependency "memcache-client"
74
+ # Requirements
75
+ s.requirements << "install the json gem to get faster json parsing"
76
+ s.required_ruby_version = ">= 1.8.6"
77
+ end
78
+
79
+ Rake::GemPackageTask.new(spec) do |package|
80
+ package.gem_spec = spec
81
+ end
82
+
83
+ desc "Run :package and install the resulting .gem"
84
+ task :install => :clean do
85
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
86
+ end
87
+
88
+ desc "Install Merb with development dependencies"
89
+ task :dev_install => :clean do
90
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION, :development => true)
91
+ end
92
+
93
+ desc "Run :clean and uninstall the .gem"
94
+ task :uninstall => :clean do
95
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
96
+ end
97
+
98
+ desc "Create a gemspec file"
99
+ task :gemspec do
100
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
101
+ file.puts spec.to_ruby
102
+ end
103
+ end
104
+
105
+ CLEAN.include ["**/.*.sw?", "pkg", "lib/*.bundle", "lib/*.so", "*.gem", "doc/rdoc", ".config", "coverage", "cache", "spec/**/*.log"]
106
+
107
+ desc "Run the specs."
108
+ task :default => :specs
109
+
110
+ task :merb => [:clean, :rdoc, :package]
111
+
112
+ ##############################################################################
113
+ # Github
114
+ ##############################################################################
115
+ namespace :github do
116
+ desc "Update Github Gemspec"
117
+ task :update_gemspec do
118
+ skip_fields = %w(new_platform original_platform)
119
+ integer_fields = %w(specification_version)
120
+
121
+ result = "Gem::Specification.new do |s|\n"
122
+ spec.instance_variables.each do |ivar|
123
+ value = spec.instance_variable_get(ivar)
124
+ name = ivar.split("@").last
125
+ next if skip_fields.include?(name) || value.nil? || value == "" || (value.respond_to?(:empty?) && value.empty?)
126
+ if name == "dependencies"
127
+ value.each do |d|
128
+ dep, *ver = d.to_s.split(" ")
129
+ result << " s.add_dependency #{dep.inspect}, #{ver.join(" ").inspect.gsub(/[()]/, "")}\n"
130
+ end
131
+ else
132
+ case value
133
+ when Array
134
+ value = name != "files" ? value.inspect : value.inspect.split(",").join(",\n")
135
+ when String
136
+ value = value.to_i if integer_fields.include?(name)
137
+ value = value.inspect
138
+ else
139
+ value = value.to_s.inspect
140
+ end
141
+ result << " s.#{name} = #{value}\n"
142
+ end
143
+ end
144
+ result << "end"
145
+ File.open(File.join(File.dirname(__FILE__), "#{spec.name}.gemspec"), "w"){|f| f << result}
146
+ end
147
+ end
148
+
149
+ ##############################################################################
150
+ # Documentation
151
+ ##############################################################################
152
+ task :doc => [:rdoc]
153
+ namespace :doc do
154
+
155
+ Rake::RDocTask.new do |rdoc|
156
+ files = ["README", "LICENSE", "CHANGELOG", "lib/**/*.rb"]
157
+ rdoc.rdoc_files.add(files)
158
+ rdoc.main = "README"
159
+ rdoc.title = "Merb Docs"
160
+ rdoc.template = __DIR__ + "/tools/allison-2.0.2/lib/allison.rb"
161
+ rdoc.rdoc_dir = "doc/rdoc"
162
+ rdoc.options << "--line-numbers" << "--inline-source"
163
+ end
164
+
165
+ desc "run webgen"
166
+ task :webgen do
167
+ sh %{cd doc/site; webgen}
168
+ end
169
+
170
+ desc "rdoc to rubyforge"
171
+ task :rubyforge do
172
+ sh %{#{sudo} chmod -R 755 doc} unless windows?
173
+ sh %{/usr/bin/scp -r -p doc/rdoc/* ezmobius@rubyforge.org:/var/www/gforge-projects/merb}
174
+ end
175
+
176
+ end
177
+
178
+ ##############################################################################
179
+ # rSpec & rcov
180
+ ##############################################################################
181
+ desc "Run :specs, :rcov"
182
+ task :aok => [:specs, :rcov]
183
+
184
+ def setup_specs(name, spec_cmd='spec', run_opts = "-c")
185
+ except = []
186
+ except += Dir["spec/**/memcache*_spec.rb"] if ENV['MEMCACHED'] == 'no'
187
+
188
+ public_globs = ["abstract_controller", "boot_loader",
189
+ "controller/*_spec.rb", "core",
190
+ "core_ext", "directory_structure", "logger", "rack/*_spec.rb", "reloading",
191
+ "request", "router/*_spec.rb", "session/*_spec.rb", "template", "test"].map do |glob|
192
+ "spec/public/#{glob}"
193
+ end
194
+
195
+ private_globs = ["boot_loader", "config", "core_ext", "dispatch/**/*_spec.rb", "router/*_spec.rb", "vendor"].map do |glob|
196
+ "spec/private/#{glob}"
197
+ end
198
+
199
+ desc "Run all specs (#{name})"
200
+ task "specs:#{name}" do
201
+ globs = public_globs + private_globs
202
+ run_specs(globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts, except)
203
+ end
204
+
205
+ desc "Run private specs (#{name})"
206
+ task "specs:#{name}:private" do
207
+ run_specs(private_globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
208
+ end
209
+
210
+ desc "Run public specs (#{name})"
211
+ task "specs:#{name}:public" do
212
+ run_specs(public_globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
213
+ end
214
+
215
+ # With profiling formatter
216
+ desc "Run all specs (#{name}) with profiling formatter"
217
+ task "specs:#{name}_profiled" do
218
+ run_specs("spec/**/*_spec.rb", spec_cmd, "-c -f o")
219
+ end
220
+
221
+ desc "Run private specs (#{name}) with profiling formatter"
222
+ task "specs:#{name}_profiled:private" do
223
+ run_specs("spec/private/**/*_spec.rb", spec_cmd, "-c -f o")
224
+ end
225
+
226
+ desc "Run public specs (#{name}) with profiling formatter"
227
+ task "specs:#{name}_profiled:public" do
228
+ run_specs("spec/public/**/*_spec.rb", spec_cmd, "-c -f o")
229
+ end
230
+ end
231
+
232
+ setup_specs("mri", "spec")
233
+ setup_specs("jruby", "jruby -S spec")
234
+
235
+ task "specs" => ["specs:mri"]
236
+ task "specs:private" => ["specs:mri:private"]
237
+ task "specs:public" => ["specs:mri:public"]
238
+
239
+ desc "Run coverage suite"
240
+ task :rcov do
241
+ require 'fileutils'
242
+ FileUtils.rm_rf("coverage") if File.directory?("coverage")
243
+ FileUtils.mkdir("coverage")
244
+ path = File.expand_path(Dir.pwd)
245
+ files = Dir["spec/**/*_spec.rb"]
246
+ files.each do |spec|
247
+ puts "Getting coverage for #{File.expand_path(spec)}"
248
+ command = %{rcov #{File.expand_path(spec)} --aggregate #{path}/coverage/data.data --exclude ".*" --include-file "lib/merb-core(?!\/vendor)"}
249
+ command += " --no-html" unless spec == files.last
250
+ `#{command} 2>&1`
251
+ end
252
+ end
253
+
254
+ desc "Run a specific spec with TASK=xxxx"
255
+ Spec::Rake::SpecTask.new("spec") do |t|
256
+ t.spec_opts = ["--colour"]
257
+ t.libs = ["lib", "server/lib" ]
258
+ t.spec_files = (ENV["TASK"] || '').split(',').map do |task|
259
+ "spec/**/#{task}_spec.rb"
260
+ end
261
+ end
262
+
263
+ desc "Run all specs output html"
264
+ Spec::Rake::SpecTask.new("specs_html") do |t|
265
+ t.spec_opts = ["--format", "html"]
266
+ t.libs = ["lib", "server/lib" ]
267
+ t.spec_files = Dir["spec/**/*_spec.rb"].sort
268
+ end
269
+
270
+ STATS_DIRECTORIES = [
271
+ ['Code', 'lib/'],
272
+ ['Unit tests', 'spec']
273
+ ].collect { |name, dir| [ name, "./#{dir}" ] }.
274
+ select { |name, dir| File.directory?(dir) }
275
+
276
+ desc "Report code statistics (KLOCs, etc) from the application"
277
+ task :stats do
278
+ require __DIR__ + "/tools/code_statistics"
279
+ # require "extra/stats"
280
+ verbose = true
281
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
282
+ end
283
+
284
+ ##############################################################################
285
+ # SYNTAX CHECKING
286
+ ##############################################################################
287
+
288
+ task :check_syntax do
289
+ `find . -name "*.rb" |xargs -n1 ruby -c |grep -v "Syntax OK"`
290
+ puts "* Done"
291
+ end
292
+
293
+ ##############################################################################
294
+ # Git and SVN
295
+ ##############################################################################
296
+ namespace :repo do
297
+
298
+ desc "Add new files to repository"
299
+ task :add do
300
+ if File.directory?(".git")
301
+ system "git add *"
302
+ elsif File.directory?(".svn")
303
+ system "svn status | grep '^\?' | sed -e 's/? *//' | sed -e 's/ /\ /g' | xargs svn add"
304
+ end
305
+ end
306
+
307
+ desc "Fetch changes from master repository"
308
+ task :rebase do
309
+ if File.directory?(".git")
310
+ system "git stash ; git svn rebase ; git stash apply"
311
+ elsif File.directory?(".svn")
312
+ system "svn update"
313
+ end
314
+ end
315
+
316
+ desc "commit modified changes to the repository"
317
+ task :commit do
318
+ if File.directory?(".git")
319
+ system "git commit"
320
+ elsif File.directory?(".svn")
321
+ system "svn commit"
322
+ end
323
+ end
324
+
325
+ end
326
+
327
+ def git_log(since_release = nil, log_format = "%an")
328
+ git_log_query = "git log"
329
+ git_log_query << " v#{since_release}..HEAD" if since_release
330
+ git_log_query << " --pretty='format:#{log_format}' --no-merges"
331
+ puts
332
+ puts "Running #{git_log_query}"
333
+ puts
334
+ `#{git_log_query}`
335
+ end
336
+
337
+ def contributors(since_release = nil)
338
+ git_log(since_release).split("\n").uniq.sort
339
+ end
340
+
341
+ PREVIOUS_RELEASE = '0.9.7'
342
+ namespace :history do
343
+ namespace :update do
344
+ desc "updates contributors list"
345
+ task :contributors do
346
+ list = contributors.join "\n"
347
+
348
+ path = File.join(File.dirname(__FILE__), 'CONTRIBUTORS')
349
+
350
+ rm path if File.exists?(path)
351
+
352
+ puts "Writing contributors (#{contributors.size} entries)."
353
+ # windows needs wb
354
+ File.open(path, "wb") do |io|
355
+ io << "Use #{RUBY_FORGE_PROJECT}? Say thanks the following people:\n\n"
356
+ io << list
357
+ end
358
+ end
359
+ end
360
+
361
+
362
+ namespace :alltime do
363
+ desc 'shows all-time committers'
364
+ task :contributors do
365
+ puts 'All-time contributors (#{contributors.size} total): '
366
+ puts '=============================='
367
+ puts
368
+ puts contributors.join("\n")
369
+ end
370
+ end
371
+
372
+ namespace :current_release do
373
+ desc "show changes since previous release"
374
+ task :changes do
375
+ puts git_log(PREVIOUS_RELEASE, "* %s")
376
+ end
377
+
378
+
379
+ desc 'shows current release committers'
380
+ task :contributors do
381
+ puts "Current release contributors (#{contributors.size} total): "
382
+ puts '=============================='
383
+ puts
384
+ puts contributors(PREVIOUS_RELEASE).join("\n")
385
+ end
386
+ end
387
+ end
388
+
389
+
390
+ # Run specific tests or test files. Searches nested spec directories as well.
391
+ #
392
+ # Based on a technique popularized by Geoffrey Grosenbach
393
+ rule "" do |t|
394
+ spec_cmd = (RUBY_PLATFORM =~ /java/) ? "jruby -S spec" : "spec"
395
+ # spec:spec_file:spec_name
396
+ if /spec:(.*)$/.match(t.name)
397
+ arguments = t.name.split(':')
398
+
399
+ file_name = arguments[1]
400
+ spec_name = arguments[2..-1]
401
+
402
+ spec_filename = "#{file_name}_spec.rb"
403
+ specs = Dir["spec/**/#{spec_filename}"]
404
+
405
+ if path = specs.detect { |f| spec_filename == File.basename(f) }
406
+ run_file_name = path
407
+ else
408
+ puts "No specs found for #{t.name.inspect}"
409
+ exit
410
+ end
411
+
412
+ example = " -e '#{spec_name}'" unless spec_name.empty?
413
+
414
+ sh "#{spec_cmd} #{run_file_name} --colour #{example}"
415
+ end
416
+ end
417
+
418
+ ##############################################################################
419
+ # Flog
420
+ ##############################################################################
421
+
422
+ namespace :flog do
423
+ task :worst_methods do
424
+ require "flog"
425
+ flogger = Flog.new
426
+ flogger.flog_files Dir["lib/**/*.rb"]
427
+ totals = flogger.totals.sort_by {|k,v| v}.reverse[0..10]
428
+ totals.each do |meth, total|
429
+ puts "%50s: %s" % [meth, total]
430
+ end
431
+ end
432
+
433
+ task :total do
434
+ require "flog"
435
+ flogger = Flog.new
436
+ flogger.flog_files Dir["lib/**/*.rb"]
437
+ puts "Total: #{flogger.total}"
438
+ end
439
+
440
+ task :per_method do
441
+ require "flog"
442
+ flogger = Flog.new
443
+ flogger.flog_files Dir["lib/**/*.rb"]
444
+ methods = flogger.totals.reject { |k,v| k =~ /\#none$/ }.sort_by { |k,v| v }
445
+ puts "Total Flog: #{flogger.total}"
446
+ puts "Total Methods: #{flogger.totals.size}"
447
+ puts "Flog / Method: #{flogger.total / methods.size}"
448
+ end
449
+ end
450
+
451
+ namespace :tools do
452
+ namespace :tags do
453
+ desc "Generates Emacs tags using Exuberant Ctags."
454
+ task :emacs do
455
+ sh "ctags -e --Ruby-kinds=-f -o TAGS -R lib"
456
+ end
457
+ end
458
+ end