hammock 0.3.9 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,21 @@
1
+ == 0.3.10 2009-07-19
2
+ Updated to newgem v1.5.1.
3
+ Sort componenets before requiring, for consistent require order.
4
+ Added preliminary prefix and singleton support to RouteStep, renaming 'resource' to 'node' (since it's a RouteNode).
5
+ Added preliminary prefix and singleton resource support to RouteNode.
6
+ Redesigned scope lookups to choose verb-specific scopes whenever possible, defaulting to :read or :write depending whether the route is safe.
7
+ Added RouteStep#default_verb.
8
+ Cleaned up RouteNode#base_for, using Array#pick.
9
+ Added RouteNode#default_verb_for.
10
+ Added RouteNode#safe_for?.
11
+ Improved error message in RouteNode#for.
12
+ Added RouteNote#all_routes hash.
13
+ Added Array#pick - like #detect, but returns the result of the block instead of the original element.
14
+ Use #camelize instead of #classify in Hammock.load_models, to avoid changing the plurality.
15
+ Added block support to Array#discard[!].
16
+ Removed unneeded self. calls from ArrayPatches.
17
+
18
+
1
19
  == 0.3.9 2009-06-18
2
20
  Improved logging in find_record_on_create.
3
21
  Enabled :indicate_current support in #hamlink_to, using RouteStep#matches?.
data/Rakefile CHANGED
@@ -1,29 +1,21 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- %w[action_controller].each { |f| require f }
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require 'action_controller'
3
6
  require File.dirname(__FILE__) + '/lib/hammock'
4
7
 
5
- # Generate all the Rake tasks
6
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
- $hoe = Hoe.new('hammock', Hammock::VERSION) do |p|
8
- p.developer('Ben Hoskings', 'ben@hoskings.net')
9
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
- p.rubyforge_name = p.name
11
- p.extra_deps = [
8
+ Hoe.plugin :newgem
9
+ # Hoe.plugin :website
10
+ # Hoe.plugin :cucumberfeatures
11
+
12
+ $hoe = Hoe.spec 'hammock' do
13
+ self.developer 'Ben Hoskings', 'ben@hoskings.net'
14
+ self.extra_deps = [
12
15
  ['rails', '~> 2.2'],
13
16
  ['benhoskings-ambitious-activerecord', '~> 0.1.3.7'],
14
17
  ]
15
- p.extra_dev_deps = [
16
- ['newgem', ">= #{::Newgem::VERSION}"]
17
- ]
18
-
19
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
- p.rsync_args = '-av --delete --ignore-errors'
23
18
  end
24
19
 
25
- require 'newgem/tasks' # load /tasks/*.rake
20
+ require 'newgem/tasks'
26
21
  Dir['tasks/**/*.rake'].each { |t| load t }
27
-
28
- # TODO - want other tests/tasks run by default? Add them to the list
29
- # task :default => [:spec, :features]
data/hammock.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{hammock}
5
- s.version = "0.3.9"
5
+ s.version = "0.3.10"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ben Hoskings"]
9
- s.date = %q{2009-06-18}
9
+ s.date = %q{2009-07-19}
10
10
  s.description = %q{Hammock is a Rails plugin that eliminates redundant code in a very RESTful manner. It does this in lots in lots of different places, but in one manner: it encourages specification in place of implementation.
11
11
 
12
12
 
@@ -18,7 +18,7 @@ Hammock inspects your routes and resources to generate a routing tree for each r
18
18
 
19
19
  It makes more sense when you see how it works though. There's a screencast coming soon.}
20
20
  s.email = ["ben@hoskings.net"]
21
- s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc", "misc/scaffold.txt"]
21
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "misc/scaffold.txt"]
22
22
  s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "hammock.gemspec", "init.rb", "lib/hammock.rb", "lib/hammock/ajaxinate.rb", "lib/hammock/callback.rb", "lib/hammock/callbacks.rb", "lib/hammock/canned_scopes.rb", "lib/hammock/constants.rb", "lib/hammock/controller_attributes.rb", "lib/hammock/export_scope.rb", "lib/hammock/hamlink_to.rb", "lib/hammock/javascript_buffer.rb", "lib/hammock/lambda_alias.rb", "lib/hammock/lambda_composition.rb", "lib/hammock/logging.rb", "lib/hammock/model_attributes.rb", "lib/hammock/model_logging.rb", "lib/hammock/monkey_patches/action_pack.rb", "lib/hammock/monkey_patches/active_record.rb", "lib/hammock/monkey_patches/array.rb", "lib/hammock/monkey_patches/hash.rb", "lib/hammock/monkey_patches/logger.rb", "lib/hammock/monkey_patches/module.rb", "lib/hammock/monkey_patches/numeric.rb", "lib/hammock/monkey_patches/object.rb", "lib/hammock/monkey_patches/route_set.rb", "lib/hammock/monkey_patches/string.rb", "lib/hammock/mutex.rb", "lib/hammock/overrides.rb", "lib/hammock/resource_mapping_hooks.rb", "lib/hammock/resource_retrieval.rb", "lib/hammock/restful_actions.rb", "lib/hammock/restful_rendering.rb", "lib/hammock/restful_support.rb", "lib/hammock/route_drawing_hooks.rb", "lib/hammock/route_for.rb", "lib/hammock/route_node.rb", "lib/hammock/route_step.rb", "lib/hammock/scope.rb", "lib/hammock/suggest.rb", "lib/hammock/utils.rb", "misc/scaffold.txt", "misc/template.rb", "tasks/hammock_tasks.rake", "test/hammock_test.rb"]
23
23
  s.homepage = %q{http://github.com/benhoskings/hammock}
24
24
  s.rdoc_options = ["--main", "README.rdoc"]
@@ -34,18 +34,15 @@ It makes more sense when you see how it works though. There's a screencast comin
34
34
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
35
35
  s.add_runtime_dependency(%q<rails>, ["~> 2.2"])
36
36
  s.add_runtime_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
37
- s.add_development_dependency(%q<newgem>, [">= 1.4.1"])
38
- s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
37
+ s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
39
38
  else
40
39
  s.add_dependency(%q<rails>, ["~> 2.2"])
41
40
  s.add_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
42
- s.add_dependency(%q<newgem>, [">= 1.4.1"])
43
- s.add_dependency(%q<hoe>, [">= 1.8.0"])
41
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
44
42
  end
45
43
  else
46
44
  s.add_dependency(%q<rails>, ["~> 2.2"])
47
45
  s.add_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
48
- s.add_dependency(%q<newgem>, [">= 1.4.1"])
49
- s.add_dependency(%q<hoe>, [">= 1.8.0"])
46
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
50
47
  end
51
48
  end
@@ -9,12 +9,12 @@ module Hammock
9
9
 
10
10
  module ClassMethods
11
11
 
12
- def has_public_scope? scope_name
13
- "#{scope_name}able" if respond_to? "#{scope_name}_scope"
12
+ def public_scope_for verb
13
+ "#{verb}able" if respond_to? "#{verb}_scope"
14
14
  end
15
15
 
16
- def has_account_scope? scope_name
17
- "#{scope_name}able_by" if respond_to? "#{scope_name}_scope_for"
16
+ def user_scope_for verb
17
+ "#{verb}able_by" if respond_to? "#{verb}_scope_for"
18
18
  end
19
19
 
20
20
  def export_scopes *verbs
@@ -22,18 +22,25 @@ module Hammock
22
22
  self[-other.length, other.length] == other
23
23
  end
24
24
 
25
+ def pick &block
26
+ value = nil
27
+ detect {|i| value = yield(i) }
28
+ value
29
+ end
30
+
25
31
  def squash
26
- self.dup.squash!
32
+ dup.squash!
27
33
  end
28
34
  def squash!
29
- self.delete_if &:blank?
35
+ delete_if &:blank?
30
36
  end
31
37
 
32
- def discard *args
33
- self.dup.discard! *args
38
+ def discard *args, &block
39
+ dup.discard! *args, &block
34
40
  end
35
- def discard! *args
36
- args.each {|arg| self.delete arg }
41
+ def discard! *args, &block
42
+ args.each {|arg| delete arg }
43
+ each {|i| delete(i) if yield(i) } if block_given?
37
44
  self
38
45
  end
39
46
 
@@ -55,7 +62,7 @@ module Hammock
55
62
  this_method = methods.shift
56
63
 
57
64
  # First, hash this array into +hsh+.
58
- self.each {|i| hsh[i.send(this_method)] << i }
65
+ each {|i| hsh[i.send(this_method)] << i }
59
66
 
60
67
  if methods.empty?
61
68
  # If there are no methods remaining, yield this group to the block if required.
@@ -69,14 +69,14 @@ module Hammock
69
69
  elsif :readonly == reason
70
70
  escort_for_read_only
71
71
  elsif :unauthed == reason
72
- if current_user.nil? && request.get? && account_verb_scope?
72
+ if current_user.nil? && request.get? && current_user_scope
73
73
  # This request may be available after a login, and can be replayed
74
74
  redirect_to returning_login_path
75
75
  else
76
76
  # TODO Write a 403 partial.
77
77
  render_for_status 404
78
78
  end
79
- elsif current_user.nil? && account_verb_scope?
79
+ elsif current_user.nil? && current_user_scope
80
80
  escort_for_login
81
81
  else
82
82
  render_for_status 404
@@ -145,10 +145,6 @@ module Hammock
145
145
  end
146
146
  end
147
147
 
148
- def safe_verb_and_implication?
149
- request.get? && !action_name.to_sym.in?(Hammock::Constants::ImpliedUnsafeActions)
150
- end
151
-
152
148
  def set_editing
153
149
  @editing = @record
154
150
  end
@@ -15,11 +15,13 @@ module Hammock
15
15
  :create => :post
16
16
  }.freeze
17
17
 
18
- attr_reader :mdl, :resource, :parent, :children, :routing_parent, :record_routes, :resource_routes, :build_routes
18
+ attr_reader :mdl, :resource, :parent, :children, :prefix, :routing_parent, :record_routes, :resource_routes, :build_routes, :all_routes
19
19
 
20
20
  def initialize entity = nil, options = {}
21
21
  @parent = options[:parent]
22
22
  @children = {}
23
+ @options = options[:name_prefix]
24
+ @singleton = options[:singleton]
23
25
  unless root?
24
26
  @mdl = entity if entity.is_a?(Symbol)
25
27
  @routing_parent = determine_routing_parent
@@ -32,16 +34,28 @@ module Hammock
32
34
  Object.const_get mdl.to_s.classify rescue nil
33
35
  end
34
36
 
37
+ def default_verb_for verb
38
+ safe_for?(verb) ? :read : :write
39
+ end
40
+
35
41
  def root?
36
42
  parent.nil?
37
43
  end
38
44
 
45
+ def safe_for? verb
46
+ (:get == all_routes[verb]) && !verb.in?(Hammock::Constants::ImpliedUnsafeActions)
47
+ end
48
+
49
+ def singleton?
50
+ @singleton
51
+ end
52
+
39
53
  def ancestry
40
54
  root? ? [] : parent.ancestry.push(self)
41
55
  end
42
56
 
43
57
  def for verb, entities, options
44
- raise "Hammock::RouteNode#for requires an explicitly specified verb as its first argument." unless verb.is_a?(Symbol)
58
+ raise "Hammock::RouteNode#for requires a verb (as a symbol) as its first argument." unless verb.is_a?(Symbol)
45
59
  raise "Hammock::RouteNode#for requires an Array of at least one record or resource." if entities.empty? || !entities.is_a?(Array)
46
60
 
47
61
  entity = entities.shift
@@ -54,22 +68,16 @@ module Hammock
54
68
  end
55
69
 
56
70
  def base_for resources
57
- # puts "base_for<#{mdl}>: resources=#{resources.inspect}."
58
71
  if resources.empty?
59
- self
72
+ if root?
73
+ raise "You have to supply at least one valid resource to find its routing base."
74
+ else
75
+ self
76
+ end
60
77
  else
61
- match = nil
62
- children.values.detect {|child|
63
- # puts " Trying #{child.ancestry.map(&:mdl).inspect} for #{resources.inspect}"
64
- if !resources.include?(child.mdl)
65
- # puts " Can't match #{resources.inspect} against #{child.mdl}."
66
- nil
67
- else
68
- # puts " Matched #{child.mdl} from #{resources.inspect}."
69
- match = child.base_for resources.discard(child.mdl)
70
- end
71
- } #|| raise("There is no routing path for #{resources.map(&:inspect).inspect}.")
72
- match
78
+ children.values.pick {|child|
79
+ child.base_for resources.discard(child.mdl) if resources.include?(child.mdl)
80
+ }
73
81
  end
74
82
  end
75
83
 
@@ -89,13 +97,19 @@ module Hammock
89
97
  eval "resource.select {|r| r.#{resource.routing_attribute} == value }"
90
98
  end
91
99
 
92
- def add entity, options, steps = nil
93
- if steps.nil?
94
- add entity, options, (options[:name_prefix] || '').chomp('_').split('_').map {|i| i.pluralize.underscore.to_sym }
95
- elsif steps.empty?
100
+ def add_singleton entity, options, path_steps = nil
101
+ add entity, options.merge(:singleton => true), path_steps
102
+ end
103
+
104
+ def add entity, options, path_steps = nil
105
+ # puts "add(#{entity.inspect}, #{options.inspect}, #{path_steps.inspect})"
106
+ if path_steps.nil?
107
+ path_steps = (options[:path_prefix] || '').split('/').squash.discard {|i| i.starts_with? ':' }.map(&:to_sym)
108
+ add entity, options, path_steps
109
+ elsif path_steps.empty?
96
110
  add_child entity, options
97
111
  else
98
- children[steps.shift].add entity, options, steps
112
+ children[path_steps.shift].add entity, options, path_steps
99
113
  end
100
114
  end
101
115
 
@@ -115,6 +129,7 @@ module Hammock
115
129
  @record_routes = DefaultRecordVerbs.dup.update(options[:member] || {})
116
130
  @resource_routes = DefaultResourceVerbs.dup.update(options[:collection] || {})
117
131
  @build_routes = DefaultBuildVerbs.dup.update(options[:build] || {})
132
+ @all_routes = @record_routes.merge(@resource_routes).merge(@build_routes)
118
133
  end
119
134
 
120
135
  def determine_routing_parent
@@ -1,13 +1,13 @@
1
1
  module Hammock
2
2
  class RouteStep
3
- attr_reader :resource, :routeable_as, :verb, :entity, :parent
3
+ attr_reader :node, :routeable_as, :verb, :entity, :parent
4
4
 
5
- def initialize resource
6
- @resource = resource
5
+ def initialize node
6
+ @node = node
7
7
  end
8
8
 
9
9
  def for verb, entity
10
- routeable_as = resource.routeable_as(verb, entity)
10
+ routeable_as = node.routeable_as(verb, entity)
11
11
 
12
12
  if !routeable_as
13
13
  raise "The verb '#{verb}' can't be applied to " + (entity.record? ? "#{entity.resource} records" : "the #{entity.resource} resource") + "."
@@ -40,8 +40,15 @@ module Hammock
40
40
  raise_unless_setup_while_trying_to 'render a path'
41
41
 
42
42
  buf = '/'
43
- buf << entity.resource_name
44
- buf << '/' + entity.to_param if entity.record? && !entity.new_record?
43
+ buf << node.prefix unless node.prefix.nil?
44
+
45
+ if node.singleton?
46
+ buf << entity.resource_name.singularize
47
+ else
48
+ buf << entity.resource_name
49
+ buf << '/' + entity.to_param if entity.record? && !entity.new_record?
50
+ end
51
+
45
52
  buf << '/' + verb.to_s unless verb.nil? or implied_verb?(verb)
46
53
 
47
54
  buf = parent.path + buf unless parent.nil?
@@ -52,7 +59,7 @@ module Hammock
52
59
 
53
60
  def http_method
54
61
  raise_unless_setup_while_trying_to 'extract the HTTP method'
55
- resource.send("#{routeable_as}_routes")[verb]
62
+ node.send("#{routeable_as}_routes")[verb]
56
63
  end
57
64
 
58
65
  def fake_http_method
@@ -68,6 +75,10 @@ module Hammock
68
75
  get? && !verb.in?(Hammock::Constants::ImpliedUnsafeActions)
69
76
  end
70
77
 
78
+ def default_verb
79
+ safe? ? :read : :write
80
+ end
81
+
71
82
  private
72
83
 
73
84
  def implied_verb? verb
data/lib/hammock/scope.rb CHANGED
@@ -42,35 +42,25 @@ module Hammock
42
42
  raise "The verb at #{call_point} must be supplied as a Symbol." unless verb.nil? || verb.is_a?(Symbol)
43
43
  route = route_for verb, record
44
44
  if route.verb.in?(:save, :create) && record.new_record?
45
- if !record.createable_by?(current_user)
46
- dlog "#{requester_name} can't create a #{record.class} with #{record.attributes.inspect}. #{describe_call_point 4}"
47
- :unauthed
48
- else
49
- :ok
45
+ returning record.createable_by?(current_user) ? :ok : :unauthed do |result|
46
+ dlog "#{requester_name} can#{"'t" unless result == :ok} create a #{record.class} with #{record.attributes.inspect}. #{describe_call_point 4}"
50
47
  end
51
48
  else
52
- if !record.readable_by?(current_user)
53
- dlog "#{requester_name} can't see #{record.class}<#{record.id}>. #{describe_call_point 4}"
54
- :not_found
55
- elsif !route.safe? && !record.writeable_by?(current_user)
56
- dlog "#{requester_name} can't #{verb} #{record.class}<#{record.id}>. #{describe_call_point 4}"
57
- :read_only
58
- else
59
- # dlog "#{requester_name} can #{verb} #{record.class}<#{record.id}>."
60
- :ok
49
+ returning record.send("#{scope_for_route(route)}?", current_user) ? :ok : :not_found do |result|
50
+ dlog "#{requester_name} can#{"'t" unless result == :ok} #{verb} #{record.class}<#{record.id}>. #{describe_call_point 4}"
61
51
  end
62
52
  end
63
53
  end
64
54
 
65
55
  def current_verb_scope
66
- if current_user && (scope_name = account_verb_scope?)
67
- # dlog "got an account_verb_scope #{scope_name}."
56
+ if current_user && (scope_name = current_user_scope)
57
+ # dlog "current_user_scope is #{scope_name}."
68
58
  mdl.send scope_name, current_user
69
- elsif !(scope_name = public_verb_scope?)
70
- log "No #{current_user.nil? ? 'public' : 'account'} #{scope_name_for_action} scope available for #{mdl}.#{' May be available after login.' if account_verb_scope?}"
59
+ elsif !(scope_name = current_public_scope)
60
+ log "No #{current_user.nil? ? 'public' : 'account'} #{action_name} scope available for #{mdl}.#{' May be available after login.' if current_user_scope}"
71
61
  nil
72
62
  else
73
- # dlog "got a #{scope_name} public_verb_scope."
63
+ # dlog "current_public_scope is #{scope_name}."
74
64
  mdl.send scope_name
75
65
  end
76
66
  end
@@ -101,25 +91,20 @@ module Hammock
101
91
 
102
92
  private
103
93
 
104
- def scope_name_for_action
105
- if 'index' == action_name
106
- 'index'
107
- elsif safe_verb_and_implication?
108
- 'read'
109
- else
110
- 'write'
111
- end
112
- end
113
-
114
94
  def requester_name
115
95
  current_user.nil? ? 'Anonymous' : "#{current_user.class}<#{current_user.id}>"
116
96
  end
117
97
 
118
- def account_verb_scope?
119
- mdl.has_account_scope?(action_name) || mdl.has_account_scope?(scope_name_for_action)
98
+ def current_user_scope
99
+ mdl.user_scope_for(action_name) || mdl.user_scope_for(current_hammock_resource.default_verb_for(action_name))
100
+ end
101
+ def current_public_scope
102
+ mdl.public_scope_for(action_name) || mdl.public_scope_for(current_hammock_resource.default_verb_for(action_name))
120
103
  end
121
- def public_verb_scope?
122
- mdl.has_public_scope?(action_name) || mdl.has_public_scope?(scope_name_for_action)
104
+
105
+ def scope_for_route route
106
+ method_name = current_user.nil? ? :public_scope_for : :user_scope_for
107
+ mdl.send(method_name, route.verb) || mdl.send(method_name, route.default_verb)
123
108
  end
124
109
 
125
110
  end
data/lib/hammock.rb CHANGED
@@ -4,7 +4,7 @@ require 'ambition'
4
4
  require 'ambition/adapters/active_record'
5
5
 
6
6
  module Hammock
7
- VERSION = '0.3.9'
7
+ VERSION = '0.3.10'
8
8
  IncludeTarget = ActionController::Base
9
9
 
10
10
  def self.included base # :nodoc:
@@ -21,7 +21,7 @@ module Hammock
21
21
  # and related methods always return the full set of models they should.
22
22
  def self.load_models
23
23
  Dir.glob(RAILS_ROOT / 'app/models/**/*.rb').each {|model_file|
24
- klass = File.basename(model_file, '.rb').classify
24
+ klass = File.basename(model_file, '.rb').camelize
25
25
  begin
26
26
  Object.const_get klass
27
27
  rescue
@@ -39,7 +39,7 @@ module Hammock
39
39
  end
40
40
 
41
41
  def self.require_hammock_components
42
- Dir.glob("#{File.dirname __FILE__}/hammock/**/*.rb").each {|dep|
42
+ Dir.glob("#{File.dirname __FILE__}/hammock/**/*.rb").sort.each {|dep|
43
43
  require dep
44
44
  }
45
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hammock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Hoskings
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-18 00:00:00 +10:00
12
+ date: 2009-07-19 00:00:00 +10:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,16 +32,6 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.1.3.7
34
34
  version:
35
- - !ruby/object:Gem::Dependency
36
- name: newgem
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 1.4.1
44
- version:
45
35
  - !ruby/object:Gem::Dependency
46
36
  name: hoe
47
37
  type: :development
@@ -50,7 +40,7 @@ dependencies:
50
40
  requirements:
51
41
  - - ">="
52
42
  - !ruby/object:Gem::Version
53
- version: 1.8.0
43
+ version: 2.3.2
54
44
  version:
55
45
  description: |-
56
46
  Hammock is a Rails plugin that eliminates redundant code in a very RESTful manner. It does this in lots in lots of different places, but in one manner: it encourages specification in place of implementation.
@@ -72,7 +62,6 @@ extensions: []
72
62
  extra_rdoc_files:
73
63
  - History.txt
74
64
  - Manifest.txt
75
- - README.rdoc
76
65
  - misc/scaffold.txt
77
66
  files:
78
67
  - History.txt