joe-merb-core 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
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 +456 -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 +648 -0
  11. data/lib/merb-core/autoload.rb +31 -0
  12. data/lib/merb-core/bootloader.rb +889 -0
  13. data/lib/merb-core/config.rb +380 -0
  14. data/lib/merb-core/constants.rb +45 -0
  15. data/lib/merb-core/controller/abstract_controller.rb +620 -0
  16. data/lib/merb-core/controller/exceptions.rb +302 -0
  17. data/lib/merb-core/controller/merb_controller.rb +283 -0
  18. data/lib/merb-core/controller/mime.rb +111 -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 +316 -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 +345 -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 +200 -0
  31. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +77 -0
  32. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +98 -0
  33. data/lib/merb-core/dispatch/dispatcher.rb +172 -0
  34. data/lib/merb-core/dispatch/request.rb +718 -0
  35. data/lib/merb-core/dispatch/router.rb +228 -0
  36. data/lib/merb-core/dispatch/router/behavior.rb +610 -0
  37. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  38. data/lib/merb-core/dispatch/router/resources.rb +220 -0
  39. data/lib/merb-core/dispatch/router/route.rb +560 -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 +215 -0
  49. data/lib/merb-core/plugins.rb +67 -0
  50. data/lib/merb-core/rack.rb +27 -0
  51. data/lib/merb-core/rack/adapter.rb +47 -0
  52. data/lib/merb-core/rack/adapter/ebb.rb +24 -0
  53. data/lib/merb-core/rack/adapter/evented_mongrel.rb +13 -0
  54. data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
  55. data/lib/merb-core/rack/adapter/irb.rb +119 -0
  56. data/lib/merb-core/rack/adapter/mongrel.rb +33 -0
  57. data/lib/merb-core/rack/adapter/runner.rb +28 -0
  58. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +14 -0
  59. data/lib/merb-core/rack/adapter/thin.rb +40 -0
  60. data/lib/merb-core/rack/adapter/thin_turbo.rb +17 -0
  61. data/lib/merb-core/rack/adapter/webrick.rb +72 -0
  62. data/lib/merb-core/rack/application.rb +32 -0
  63. data/lib/merb-core/rack/handler/mongrel.rb +96 -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 +321 -0
  73. data/lib/merb-core/tasks/audit.rake +68 -0
  74. data/lib/merb-core/tasks/gem_management.rb +252 -0
  75. data/lib/merb-core/tasks/merb.rb +2 -0
  76. data/lib/merb-core/tasks/merb_rake_helper.rb +51 -0
  77. data/lib/merb-core/tasks/stats.rake +71 -0
  78. data/lib/merb-core/test.rb +17 -0
  79. data/lib/merb-core/test/helpers.rb +10 -0
  80. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  81. data/lib/merb-core/test/helpers/multipart_request_helper.rb +176 -0
  82. data/lib/merb-core/test/helpers/request_helper.rb +61 -0
  83. data/lib/merb-core/test/helpers/route_helper.rb +47 -0
  84. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  85. data/lib/merb-core/test/matchers.rb +10 -0
  86. data/lib/merb-core/test/matchers/controller_matchers.rb +108 -0
  87. data/lib/merb-core/test/matchers/route_matchers.rb +137 -0
  88. data/lib/merb-core/test/matchers/view_matchers.rb +393 -0
  89. data/lib/merb-core/test/run_specs.rb +141 -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,456 @@
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/tasks/merb_rake_helper'
21
+
22
+ ##############################################################################
23
+ # Package && release
24
+ ##############################################################################
25
+ RUBY_FORGE_PROJECT = "merb"
26
+ PROJECT_URL = "http://merbivore.com"
27
+ PROJECT_SUMMARY = "Merb. Pocket rocket web framework."
28
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY
29
+
30
+ AUTHOR = "Ezra Zygmuntowicz"
31
+ EMAIL = "ez@engineyard.com"
32
+
33
+ GEM_NAME = "merb-core"
34
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
35
+ GEM_VERSION = Merb::VERSION + PKG_BUILD
36
+
37
+ RELEASE_NAME = "REL #{GEM_VERSION}"
38
+
39
+ require "extlib/tasks/release"
40
+
41
+ spec = Gem::Specification.new do |s|
42
+ s.name = GEM_NAME
43
+ s.version = GEM_VERSION
44
+ s.platform = Gem::Platform::RUBY
45
+ s.author = AUTHOR
46
+ s.email = EMAIL
47
+ s.homepage = PROJECT_URL
48
+ s.summary = PROJECT_SUMMARY
49
+ s.bindir = "bin"
50
+ s.description = PROJECT_DESCRIPTION
51
+ s.executables = %w( merb )
52
+ s.require_path = "lib"
53
+ s.files = %w( LICENSE README Rakefile TODO CHANGELOG PUBLIC_CHANGELOG CONTRIBUTORS ) + Dir["{doc/rdoc,bin,lib}/**/*"]
54
+
55
+ # rdoc
56
+ s.has_rdoc = true
57
+ s.extra_rdoc_files = %w( README LICENSE TODO )
58
+
59
+ # Dependencies
60
+ s.add_dependency "extlib", ">= 0.9.6"
61
+ s.add_dependency "erubis"
62
+ s.add_dependency "rake"
63
+ s.add_dependency "json_pure"
64
+ s.add_dependency "rspec"
65
+ s.add_dependency "rack"
66
+ s.add_dependency "mime-types"
67
+ s.add_dependency "hpricot"
68
+ s.add_dependency "thor", ">= 0.9.6"
69
+ # this escalates to "regular" dependencies, comment it out
70
+ # for now. RubyGems need some love.
71
+ #s.add_development_dependency "libxml-ruby"
72
+ #s.add_development_dependency "memcache-client"
73
+ # Requirements
74
+ s.requirements << "install the json gem to get faster json parsing"
75
+ s.required_ruby_version = ">= 1.8.6"
76
+ end
77
+
78
+ Rake::GemPackageTask.new(spec) do |package|
79
+ package.gem_spec = spec
80
+ end
81
+
82
+ desc "Run :package and install the resulting .gem"
83
+ task :install => :clean do
84
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
85
+ end
86
+
87
+ desc "Install Merb with development dependencies"
88
+ task :dev_install => :clean do
89
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION, :development => true)
90
+ end
91
+
92
+ desc "Run :clean and uninstall the .gem"
93
+ task :uninstall => :clean do
94
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
95
+ end
96
+
97
+ desc "Create a gemspec file"
98
+ task :gemspec do
99
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
100
+ file.puts spec.to_ruby
101
+ end
102
+ end
103
+
104
+ CLEAN.include ["**/.*.sw?", "pkg", "lib/*.bundle", "lib/*.so", "*.gem", "doc/rdoc", ".config", "coverage", "cache", "spec/**/*.log"]
105
+
106
+ desc "Run the specs."
107
+ task :default => :specs
108
+
109
+ task :merb => [:clean, :rdoc, :package]
110
+
111
+ ##############################################################################
112
+ # Github
113
+ ##############################################################################
114
+ namespace :github do
115
+ desc "Update Github Gemspec"
116
+ task :update_gemspec do
117
+ skip_fields = %w(new_platform original_platform)
118
+ integer_fields = %w(specification_version)
119
+
120
+ result = "Gem::Specification.new do |s|\n"
121
+ spec.instance_variables.each do |ivar|
122
+ value = spec.instance_variable_get(ivar)
123
+ name = ivar.split("@").last
124
+ next if skip_fields.include?(name) || value.nil? || value == "" || (value.respond_to?(:empty?) && value.empty?)
125
+ if name == "dependencies"
126
+ value.each do |d|
127
+ dep, *ver = d.to_s.split(" ")
128
+ result << " s.add_dependency #{dep.inspect}, #{ver.join(" ").inspect.gsub(/[()]/, "")}\n"
129
+ end
130
+ else
131
+ case value
132
+ when Array
133
+ value = name != "files" ? value.inspect : value.inspect.split(",").join(",\n")
134
+ when String
135
+ value = value.to_i if integer_fields.include?(name)
136
+ value = value.inspect
137
+ else
138
+ value = value.to_s.inspect
139
+ end
140
+ result << " s.#{name} = #{value}\n"
141
+ end
142
+ end
143
+ result << "end"
144
+ File.open(File.join(File.dirname(__FILE__), "#{spec.name}.gemspec"), "w"){|f| f << result}
145
+ end
146
+ end
147
+
148
+ ##############################################################################
149
+ # Documentation
150
+ ##############################################################################
151
+ task :doc => [:rdoc]
152
+ namespace :doc do
153
+
154
+ Rake::RDocTask.new do |rdoc|
155
+ files = ["README", "LICENSE", "CHANGELOG", "lib/**/*.rb"]
156
+ rdoc.rdoc_files.add(files)
157
+ rdoc.main = "README"
158
+ rdoc.title = "Merb Docs"
159
+ rdoc.template = __DIR__ + "/tools/allison-2.0.2/lib/allison.rb"
160
+ rdoc.rdoc_dir = "doc/rdoc"
161
+ rdoc.options << "--line-numbers" << "--inline-source"
162
+ end
163
+
164
+ desc "run webgen"
165
+ task :webgen do
166
+ sh %{cd doc/site; webgen}
167
+ end
168
+
169
+ desc "rdoc to rubyforge"
170
+ task :rubyforge do
171
+ sh %{#{Merb::RakeHelper.sudo} chmod -R 755 doc} unless Merb::RakeHelper.windows?
172
+ sh %{/usr/bin/scp -r -p doc/rdoc/* ezmobius@rubyforge.org:/var/www/gforge-projects/merb}
173
+ end
174
+
175
+ end
176
+
177
+ ##############################################################################
178
+ # rSpec & rcov
179
+ ##############################################################################
180
+ desc "Run :specs, :rcov"
181
+ task :aok => [:specs, :rcov]
182
+
183
+ def setup_specs(name, spec_cmd='spec', run_opts = "-c")
184
+ except = []
185
+ except += Dir["spec/**/memcache*_spec.rb"] if ENV['MEMCACHED'] == 'no'
186
+
187
+ public_globs = Dir["#{Dir.pwd}/spec/public/**/*_spec.rb"]
188
+
189
+ private_globs = Dir["#{Dir.pwd}/spec/private/**/*_spec.rb"]
190
+
191
+ desc "Run all specs (#{name})"
192
+ task "specs:#{name}" do
193
+ require "lib/merb-core/test/run_specs"
194
+ globs = public_globs + private_globs
195
+ run_specs(globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts, except)
196
+ end
197
+
198
+ desc "Run private specs (#{name})"
199
+ task "specs:#{name}:private" do
200
+ require "lib/merb-core/test/run_specs"
201
+ run_specs(private_globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
202
+ end
203
+
204
+ desc "Run public specs (#{name})"
205
+ task "specs:#{name}:public" do
206
+ require "lib/merb-core/test/run_specs"
207
+ run_specs(public_globs, spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
208
+ end
209
+
210
+ # With profiling formatter
211
+ desc "Run all specs (#{name}) with profiling formatter"
212
+ task "specs:#{name}_profiled" do
213
+ require "lib/merb-core/test/run_specs"
214
+ run_specs("spec/**/*_spec.rb", spec_cmd, "-c -f o")
215
+ end
216
+
217
+ desc "Run private specs (#{name}) with profiling formatter"
218
+ task "specs:#{name}_profiled:private" do
219
+ require "lib/merb-core/test/run_specs"
220
+ run_specs("spec/private/**/*_spec.rb", spec_cmd, "-c -f o")
221
+ end
222
+
223
+ desc "Run public specs (#{name}) with profiling formatter"
224
+ task "specs:#{name}_profiled:public" do
225
+ require "lib/merb-core/test/run_specs"
226
+ run_specs("spec/public/**/*_spec.rb", spec_cmd, "-c -f o")
227
+ end
228
+ end
229
+
230
+ setup_specs("mri", "spec")
231
+ setup_specs("jruby", "jruby -S spec")
232
+
233
+ task "specs" => ["specs:mri"]
234
+ task "specs:private" => ["specs:mri:private"]
235
+ task "specs:public" => ["specs:mri:public"]
236
+
237
+ desc "Run coverage suite"
238
+ task :rcov do
239
+ require 'fileutils'
240
+ FileUtils.rm_rf("coverage") if File.directory?("coverage")
241
+ FileUtils.mkdir("coverage")
242
+ path = File.expand_path(Dir.pwd)
243
+ files = Dir["spec/**/*_spec.rb"]
244
+ files.each do |spec|
245
+ puts "Getting coverage for #{File.expand_path(spec)}"
246
+ command = %{rcov #{File.expand_path(spec)} --aggregate #{path}/coverage/data.data --exclude ".*" --include-file "lib/merb-core(?!\/vendor)"}
247
+ command += " --no-html" unless spec == files.last
248
+ `#{command} 2>&1`
249
+ end
250
+ end
251
+
252
+ desc "Run a specific spec with TASK=xxxx"
253
+ Spec::Rake::SpecTask.new("spec") do |t|
254
+ t.spec_opts = ["--colour"]
255
+ t.libs = ["lib", "server/lib" ]
256
+ t.spec_files = (ENV["TASK"] || '').split(',').map do |task|
257
+ "spec/**/#{task}_spec.rb"
258
+ end
259
+ end
260
+
261
+ desc "Run all specs output html"
262
+ Spec::Rake::SpecTask.new("specs_html") do |t|
263
+ t.spec_opts = ["--format", "html"]
264
+ t.libs = ["lib", "server/lib" ]
265
+ t.spec_files = Dir["spec/**/*_spec.rb"].sort
266
+ end
267
+
268
+ STATS_DIRECTORIES = [
269
+ ['Code', 'lib/'],
270
+ ['Unit tests', 'spec']
271
+ ].collect { |name, dir| [ name, "./#{dir}" ] }.
272
+ select { |name, dir| File.directory?(dir) }
273
+
274
+ desc "Report code statistics (KLOCs, etc) from the application"
275
+ task :stats do
276
+ require __DIR__ + "/tools/code_statistics"
277
+ # require "extra/stats"
278
+ verbose = true
279
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
280
+ end
281
+
282
+ ##############################################################################
283
+ # SYNTAX CHECKING
284
+ ##############################################################################
285
+
286
+ task :check_syntax do
287
+ `find . -name "*.rb" |xargs -n1 ruby -c |grep -v "Syntax OK"`
288
+ puts "* Done"
289
+ end
290
+
291
+ ##############################################################################
292
+ # Git and SVN
293
+ ##############################################################################
294
+ namespace :repo do
295
+
296
+ desc "Add new files to repository"
297
+ task :add do
298
+ if File.directory?(".git")
299
+ system "git add *"
300
+ elsif File.directory?(".svn")
301
+ system "svn status | grep '^\?' | sed -e 's/? *//' | sed -e 's/ /\ /g' | xargs svn add"
302
+ end
303
+ end
304
+
305
+ desc "Fetch changes from master repository"
306
+ task :rebase do
307
+ if File.directory?(".git")
308
+ system "git stash ; git svn rebase ; git stash apply"
309
+ elsif File.directory?(".svn")
310
+ system "svn update"
311
+ end
312
+ end
313
+
314
+ desc "commit modified changes to the repository"
315
+ task :commit do
316
+ if File.directory?(".git")
317
+ system "git commit"
318
+ elsif File.directory?(".svn")
319
+ system "svn commit"
320
+ end
321
+ end
322
+
323
+ end
324
+
325
+ def git_log(since_release = nil, log_format = "%an")
326
+ git_log_query = "git log"
327
+ git_log_query << " v#{since_release}..HEAD" if since_release
328
+ git_log_query << " --pretty='format:#{log_format}' --no-merges"
329
+ puts
330
+ puts "Running #{git_log_query}"
331
+ puts
332
+ `#{git_log_query}`
333
+ end
334
+
335
+ def contributors(since_release = nil)
336
+ git_log(since_release).split("\n").uniq.sort
337
+ end
338
+
339
+ PREVIOUS_RELEASE = '0.9.7'
340
+ namespace :history do
341
+ namespace :update do
342
+ desc "updates contributors list"
343
+ task :contributors do
344
+ list = contributors.join "\n"
345
+
346
+ path = File.join(File.dirname(__FILE__), 'CONTRIBUTORS')
347
+
348
+ rm path if File.exists?(path)
349
+
350
+ puts "Writing contributors (#{contributors.size} entries)."
351
+ # windows needs wb
352
+ File.open(path, "wb") do |io|
353
+ io << "Use #{RUBY_FORGE_PROJECT}? Say thanks the following people:\n\n"
354
+ io << list
355
+ end
356
+ end
357
+ end
358
+
359
+
360
+ namespace :alltime do
361
+ desc 'shows all-time committers'
362
+ task :contributors do
363
+ puts 'All-time contributors (#{contributors.size} total): '
364
+ puts '=============================='
365
+ puts
366
+ puts contributors.join("\n")
367
+ end
368
+ end
369
+
370
+ namespace :current_release do
371
+ desc "show changes since previous release"
372
+ task :changes do
373
+ puts git_log(PREVIOUS_RELEASE, "* %s")
374
+ end
375
+
376
+
377
+ desc 'shows current release committers'
378
+ task :contributors do
379
+ puts "Current release contributors (#{contributors.size} total): "
380
+ puts '=============================='
381
+ puts
382
+ puts contributors(PREVIOUS_RELEASE).join("\n")
383
+ end
384
+ end
385
+ end
386
+
387
+
388
+ # Run specific tests or test files. Searches nested spec directories as well.
389
+ #
390
+ # Based on a technique popularized by Geoffrey Grosenbach
391
+ rule "" do |t|
392
+ spec_cmd = (RUBY_PLATFORM =~ /java/) ? "jruby -S spec" : "spec"
393
+ # spec:spec_file:spec_name
394
+ if /spec:(.*)$/.match(t.name)
395
+ arguments = t.name.split(':')
396
+
397
+ file_name = arguments[1]
398
+ spec_name = arguments[2..-1]
399
+
400
+ spec_filename = "#{file_name}_spec.rb"
401
+ specs = Dir["spec/**/#{spec_filename}"]
402
+
403
+ if path = specs.detect { |f| spec_filename == File.basename(f) }
404
+ run_file_name = path
405
+ else
406
+ puts "No specs found for #{t.name.inspect}"
407
+ exit
408
+ end
409
+
410
+ example = " -e '#{spec_name}'" unless spec_name.empty?
411
+
412
+ sh "#{spec_cmd} #{run_file_name} --colour #{example}"
413
+ end
414
+ end
415
+
416
+ ##############################################################################
417
+ # Flog
418
+ ##############################################################################
419
+
420
+ namespace :flog do
421
+ task :worst_methods do
422
+ require "flog"
423
+ flogger = Flog.new
424
+ flogger.flog_files Dir["lib/**/*.rb"]
425
+ totals = flogger.totals.sort_by {|k,v| v}.reverse[0..10]
426
+ totals.each do |meth, total|
427
+ puts "%50s: %s" % [meth, total]
428
+ end
429
+ end
430
+
431
+ task :total do
432
+ require "flog"
433
+ flogger = Flog.new
434
+ flogger.flog_files Dir["lib/**/*.rb"]
435
+ puts "Total: #{flogger.total}"
436
+ end
437
+
438
+ task :per_method do
439
+ require "flog"
440
+ flogger = Flog.new
441
+ flogger.flog_files Dir["lib/**/*.rb"]
442
+ methods = flogger.totals.reject { |k,v| k =~ /\#none$/ }.sort_by { |k,v| v }
443
+ puts "Total Flog: #{flogger.total}"
444
+ puts "Total Methods: #{flogger.totals.size}"
445
+ puts "Flog / Method: #{flogger.total / methods.size}"
446
+ end
447
+ end
448
+
449
+ namespace :tools do
450
+ namespace :tags do
451
+ desc "Generates Emacs tags using Exuberant Ctags."
452
+ task :emacs do
453
+ sh "ctags -e --Ruby-kinds=-f -o TAGS -R lib"
454
+ end
455
+ end
456
+ end