rack-params 0.0.1.pre3 → 0.0.1.pre5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9639d1c1bf66f13870bb654b66e08daf47b83b0a
4
- data.tar.gz: a1f5b916ef01a61473ec7846d61bd2b81868ecb3
3
+ metadata.gz: 1007badc8d33a5465e1d7facda42c81901f4b5ad
4
+ data.tar.gz: a0d6fb178dc571d748ee5bb452db6a79502c8b15
5
5
  SHA512:
6
- metadata.gz: 9b760ac7d1b02b4f43c81af56220c503301eaf876a1fb0b7dc8f2dd6b21183042a6752c6c462dbfe48fc8a33b039fb872cc5bdbabd1047b5201ff807d600282e
7
- data.tar.gz: 75fb7462ecb7f70e145b422ea76b26f673f20f7543a7b31cbb444270b26332c6481b3e991e2905eda3fa18d98e679fd0657ef70ed25aab8dd504b977c8a2a3ad
6
+ metadata.gz: 6f9d9e7469c1855f94b40b151c27a1d07ea1872d1c1c0dbd81addd5ead29dfae38a91df31af3378498b15a78e2a94f2cbb3809c38059bbf0a0fb3ffe8a677cf2
7
+ data.tar.gz: ac8475ffbc12725fb09b60890a225baa00037d9a37ee8c77e6fb8b5e0fb110a8443d11c27c68e87b9bc324c00b759c9bc5bd4a7621965ba82c67ed6fe624f77a
data/.gitignore CHANGED
@@ -2,7 +2,7 @@
2
2
  /.yardoc
3
3
  /_yardoc/
4
4
  /coverage/
5
- /doc/
5
+ /docs/
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --no-private
2
+ --protected
3
+ --embed-mixins
@@ -0,0 +1,46 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ * Using welcoming and inclusive language
12
+ * Being respectful of differing viewpoints and experiences
13
+ * Gracefully accepting constructive criticism
14
+ * Focusing on what is best for the community
15
+ * Showing empathy towards other community members
16
+
17
+ Examples of unacceptable behavior by participants include:
18
+
19
+ * The use of sexualized language or imagery and unwelcome sexual attention or advances
20
+ * Trolling, insulting/derogatory comments, and personal or political attacks
21
+ * Public or private harassment
22
+ * Publishing others' private information, such as a physical or electronic address, without explicit permission
23
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
24
+
25
+ ## Our Responsibilities
26
+
27
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
+
29
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jon@accidental.cc. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
+
39
+ Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
+
41
+ ## Attribution
42
+
43
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
+
45
+ [homepage]: http://contributor-covenant.org
46
+ [version]: http://contributor-covenant.org/version/1/4/
data/README.md CHANGED
@@ -108,7 +108,7 @@ Or install it yourself as:
108
108
 
109
109
  ## Usage
110
110
 
111
- **[RDoc @ master - Rack::Params](http://www.rudydoc.info/github/lygaret/master)**
111
+ **[RDoc @ master - Rack::Params](http://www.rubydoc.info/github/lygaret/rack-params/master)**
112
112
 
113
113
  1. Include `Rack::Params` to get the `.validator`, `#validate` and `#validate!` methods.
114
114
  2. Call `.validator(name, options = {}, &code)` to register a named validator for use later.
data/Rakefile CHANGED
@@ -1,7 +1,16 @@
1
+ # drop the lib directory into the load path
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
1
5
  require "bundler/gem_tasks"
2
6
  require "rspec/core/rake_task"
3
7
  require "coveralls/rake/task"
4
8
 
9
+ import(*Dir.glob("./lib/rack/params/**/*.rake"))
10
+
11
+ CLOBBER << "docs"
12
+ CLOBBER << "coverage"
13
+
5
14
  RSpec::Core::RakeTask.new(:spec)
6
15
  Coveralls::RakeTask.new
7
16
 
@@ -3,11 +3,19 @@ require 'date'
3
3
  module Rack
4
4
  module Params
5
5
 
6
+ # the context in which to run validation.
7
+ # it contains the {#params} and {#result}, and provides methods to use in coercion.
8
+ # @abstract To subclass, provide a {Result} constant, and methods to do coercion/validation.
6
9
  class Context
7
10
  attr_reader :options
8
11
  attr_reader :params
9
12
  attr_reader :result
10
13
 
14
+ # the structure of the result - eg. {} or [].
15
+ # the actual {#result} will be this type extended by {Rack::Params::Result}
16
+ Result = nil
17
+
18
+ # create a context with a parameter hash and options.
11
19
  def initialize(params, options = {})
12
20
  @options = options
13
21
  @path = options[:path]
@@ -19,11 +27,35 @@ module Rack
19
27
  @result.errors = Hash.new { |h, k| h[k] = [] }
20
28
  end
21
29
 
30
+ # execute the given block, in this context
31
+ # @yield in the block, {self}'s methods are available.
32
+ # @return [Result] the result of this context's validation.
22
33
  def exec(&block)
23
34
  instance_exec(&block)
24
35
  @result
25
36
  end
26
37
 
38
+ protected
39
+
40
+ # return a correctly typed value, given a string and a type.
41
+ #
42
+ # == valid types
43
+ # :symbol :: convert value as a symbol
44
+ # :boolean :: parse the following strings: "0, 1, false, f, true, t, no, n, yes, y"
45
+ # Symbol ::
46
+ # Int ::
47
+ # Float ::
48
+ # Date ::
49
+ # Time ::
50
+ # DateTime :: parse as the given type.
51
+ # Array :: parse value as an array. default options { sep: ' ' }
52
+ # Hash :: parse value as a Hash, default options { esep: ',', fsep: ':' }
53
+ #
54
+ # @param value the value to coerce, likely a string, hash or array
55
+ # @param type the type to coerce into
56
+ # @param options [Hash]
57
+ # @return value the coerced value
58
+ # @raise [ArgumentError] if coercion fails
27
59
  def _coerce(value, type, options)
28
60
  return nil if value.nil?
29
61
  return value if value.is_a?(type) rescue false
@@ -57,17 +89,24 @@ module Rack
57
89
  return true if /^(true|t|yes|y|1)$/i === value
58
90
  raise ArgumentError # otherwise
59
91
  end
60
- rescue ArgumentError => ex
61
- fail InvalidParameterError, ex.message
62
- end
63
92
 
64
- def _validate(name, value, validation, options)
65
- options = {} if options == true
66
- # what to do...
93
+ # default failure
94
+ raise ArgumentError, "unknown type #{type}"
67
95
  end
68
96
 
69
- def _recurse(name, type, value, &block)
70
- path = [@path, name].reject(&:nil?).join(".")
97
+ # todo: figure this out
98
+ # def _validate(key, value, validation, options)
99
+ # options = {} if options == true
100
+ # end
101
+
102
+ # recursively process parameters, so we can support validating nested
103
+ # parameter hashes and arrays.
104
+ #
105
+ # @param path [String] the current path to the recursing object, used to provide error keys
106
+ # @param type must be {Array} or {Hash}
107
+ # @return [Result] with validation results and errors
108
+ def _recurse(path, type, value, &block)
109
+ path = [@path, path].reject(&:nil?).join(".")
71
110
 
72
111
  if type == Array
73
112
  ArrayContext.new(value, path: path).exec(&block)
@@ -79,65 +118,95 @@ module Rack
79
118
  end
80
119
  end
81
120
 
82
- # the DSL when validating a hash parameter (including the top-level params hash)
83
-
121
+ # the DSL for validating a hash parameter (including the top-level params hash)
84
122
  class HashContext < Context
85
123
  Result = Hash
86
124
 
87
- def param(name, type, options = {}, &block)
88
- name = name.to_s
125
+ # do type coercion and validation for a parameter with the given key.
126
+ # adds the coerced value to the result hash, or push an error.
127
+ #
128
+ # @see #_coerce #_coerce defines valid types for coercion.
129
+ # @param key the key in the hash of the parameter to validate
130
+ # @param type the type to coerce the value into
131
+ # @param options [Hash]
132
+ # @yield
133
+ # if type is {Hash} or {Array}, passing a block will recursively
134
+ # validate the coerced value, assuming the block is a new validation
135
+ # context.
136
+ # @return the coerced value
137
+ def param(key, type, options = {}, &block)
138
+ key = key.to_s
89
139
 
90
140
  # default and required
91
- value = params[name] || options[:default]
92
- raise InvalidParameterError, "is required" if options[:required] && value.nil?
141
+ value = params[key] || options[:default]
142
+ raise ArgumentError, "is required" if options[:required] && value.nil?
93
143
 
94
144
  # type cast
95
145
  value = _coerce(value, type, options)
96
146
 
97
147
  # validate against rules
98
- options.each { |v, vopts| _validate(name, value, v, vopts) }
148
+ # options.each { |v, vopts| _validate(key, value, v, vopts) }
99
149
 
100
150
  # recurse if we've got a block
101
151
  if block_given?
102
- value = _recurse(name, type, value, &block)
152
+ value = _recurse(key, type, value, &block)
103
153
  result.errors.merge! value.errors
104
154
  end
105
155
 
106
156
  # return - we're good
107
- result[name] = value
108
- rescue InvalidParameterError => ex
109
- path = [@path, name].reject(&:nil?).join(".")
157
+ result[key] = value
158
+ rescue ArgumentError => ex
159
+ path = [@path, key].reject(&:nil?).join(".")
110
160
  result.errors[path] << ex.message
161
+ nil
111
162
  end
112
163
 
113
- def splat(name, options = {}, &block)
114
- name = name.to_s
164
+ # collect uncoerced keys from the parameter hash into the results hash.
165
+ # collects keys not _yet_ coerced, so it should be last in the validation block.
166
+ #
167
+ # @param key the result key under which to place the collected parameters
168
+ # @param options [Hash]
169
+ # @return the collected keys as a hash
170
+ def splat(key, options = {})
171
+ key = key.to_s
115
172
 
116
173
  # every key in params that's not already in results
117
174
  value = params.reject { |k, _| result.keys.include? k }
118
- result[name] = value
175
+ result[key] = value
119
176
  end
120
177
  end
121
178
 
122
- # the DSL when validating an array parameter
179
+ # the DSL for validating an array parameter
123
180
  class ArrayContext < Context
124
181
  Result = Array
125
182
 
126
- # validate and coerce every element in the array to the type/options/block given
183
+ # validate and coerce every element in the array, using the same values.
184
+ # equivalent to {HashContext#param} over every element.
185
+ #
186
+ # @see HashContext#param
187
+ # @see #_coerce #_coerce defines valid types for coercion.
188
+ # @param type the type to use for coercion
189
+ # @param options [Hash]
190
+ # @yield
191
+ # if type is Hash or Array, passing a block will recursively
192
+ # validate the coerced value, assuming the block is a new validation
193
+ # context.
194
+ # @return the coerced value
127
195
  def every(type, options = {}, &block)
128
196
  params.each_with_index do |value, i|
129
197
  begin
130
198
  value = _coerce(value, type, options)
131
- options.each { |v, vopts| _validate(i.to_s, value, v, vopts) }
199
+ # options.each { |v, vopts| _validate(i.to_s, value, v, vopts) }
132
200
  if block_given?
133
201
  value = _recurse(i.to_s, type, value, &block)
134
202
  result.errors.merge! value.errors
135
203
  end
136
204
 
137
205
  result[i] = value
138
- rescue InvalidParameterError => ex
206
+ rescue ArgumentError => ex
139
207
  path = [@path, i].reject(&:nil?).join(".")
140
208
  result.errors[path] << ex.message
209
+ nil
141
210
  end
142
211
  end
143
212
  end
@@ -1,7 +1,13 @@
1
1
  module Rack
2
2
  module Params
3
3
 
4
+ # raised on {Rack::Params#validate!} failure
4
5
  class ParameterValidationError < StandardError
6
+
7
+ # @!attribute [r] errors
8
+ # a hash of errors discovered during parameter coercion and validation.
9
+ # keys are dotted paths from the parameter hash.
10
+ # @return [Hash] a hash of errors
5
11
  attr_accessor :errors
6
12
 
7
13
  def initialize(errors)
@@ -10,9 +16,5 @@ module Rack
10
16
  end
11
17
  end
12
18
 
13
- class InvalidParameterError < StandardError
14
- attr_accessor :name, :type, :options
15
- end
16
-
17
19
  end
18
20
  end
@@ -1,15 +1,20 @@
1
1
  module Rack
2
2
  module Params
3
+
4
+ # a mixin for validation results, to include errors
3
5
  module Result
4
6
  attr_accessor :errors
5
7
 
8
+ # is the result valid, meaning it has no errors?
6
9
  def valid?
7
10
  errors.length == 0
8
11
  end
9
12
 
13
+ # is the result invalid, meaning it has some errors?
10
14
  def invalid?
11
15
  not valid?
12
16
  end
17
+
13
18
  end
14
19
  end
15
20
  end
@@ -0,0 +1,28 @@
1
+ require 'tmpdir'
2
+ require 'yard'
3
+ require 'yard/rake/yardoc_task'
4
+
5
+ namespace :docs do
6
+ ROOT_DIR = `git rev-parse --show-toplevel`.strip
7
+ DOC_DIR = File.join(ROOT_DIR, 'docs')
8
+
9
+ YARD::Rake::YardocTask.new(:generate) do |yard|
10
+ yard.options = ["--out", DOC_DIR]
11
+ end
12
+
13
+ desc "publish documentation to gh-pages"
14
+ task :publish do
15
+ Dir.mktmpdir('docs-publish') do |tmpdir|
16
+ `git clone "#{ROOT_DIR}" "#{tmpdir}"`
17
+ Dir.chdir(tmpdir) do |cwd|
18
+ `git checkout gh-pages`
19
+ `rm -rf *`
20
+ `cp -R "#{DOC_DIR}"/* "#{tmpdir}/"`
21
+ `git add .`
22
+ `git commit -am 'published | #{Time.now}'`
23
+ `git push origin gh-pages`
24
+ end
25
+ end
26
+ `git push origin gh-pages`
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Params
3
- VERSION = "0.0.1.pre3"
3
+ VERSION = "0.0.1.pre5"
4
4
  end
5
5
  end
data/lib/rack/params.rb CHANGED
@@ -4,28 +4,52 @@ require 'rack/params/result'
4
4
  require 'rack/params/version'
5
5
 
6
6
  module Rack
7
+
8
+ # Rack::Params provides a lightweight DSL for type coercion and validation of request parameters.
9
+ # @!parse extend Rack::Params::ClassMethods
7
10
  module Params
11
+
12
+ # @private
8
13
  def self.included(base)
9
14
  base.extend(ClassMethods)
10
15
  end
11
16
 
12
17
  module ClassMethods
18
+ # holds options and a block when registering a validator.
19
+ # @private
13
20
  Validator = Struct.new(:options, :code) do
14
21
  def exec(values)
15
22
  HashContext.new(values, options).exec(&code)
16
23
  end
17
24
  end
18
25
 
26
+ # get the set of validators, keyed by name
27
+ # @private
19
28
  def validators
20
29
  @_rp_validators ||= {}
21
30
  end
22
31
 
32
+ # register a Validator with the given options and block.
33
+ # the validator can be used in #validate method by providing the name.
23
34
  def validator(name, options = {}, &code)
24
35
  validators[name] = Validator.new(options, code)
25
36
  end
26
37
  end
27
38
 
28
- # validate request.params
39
+ # validate the given parameters
40
+ # @overload validate(name, params, options = {})
41
+ # validates the given parameters against the named validator
42
+ # @param [Symbol] name the name of a registered validator.
43
+ # @param [Hash] params the parameter hash to validate
44
+ # @param [Hash] options
45
+ # @return [Result] a result hash containing the extracted keys, and errors.
46
+ # @overload validate(params, options = {}, &block)
47
+ # validates the given parameters against the given block
48
+ # @see Rack::Params::HashContext
49
+ # @param [Hash] params the parameter hash to validate
50
+ # @param [Hash] options
51
+ # @yield a code block that will run in the context of a {Rack::Params::HashContext} to validate the params
52
+ # @return [Result] a result hash containing the extracted keys, and errors.
29
53
  def validate(name = nil, params = nil, options = {}, &block)
30
54
  if params.nil? && (name.class <= Hash)
31
55
  params = name
@@ -42,14 +66,30 @@ module Rack
42
66
  end
43
67
  end
44
68
 
69
+ # {include:#validate}
70
+ # @overload validate!(name, params, options = {})
71
+ # @param [Symbol] name the name of a registered validator.
72
+ # @param [Hash] params the parameter hash to validate
73
+ # @param [Hash] options
74
+ # @return [Result] a valid result hash containing the extracted keys, and no errors.
75
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
76
+ # @overload validate!(params, options = {}, &block)
77
+ # validates the given parameters against the given block
78
+ # @param [Hash] params the parameter hash to validate
79
+ # @param [Hash] options
80
+ # @yield a code block that will run in the context of a {Rack::Params::HashContext} to validate the params
81
+ # @return [Result] a valid result hash containing the extracted keys, and no errors.
82
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
45
83
  def validate!(name = nil, params = nil, options = {}, &block)
46
84
  validate(name, params, options, &block).tap do |res|
47
85
  fail ParameterValidationError, res.errors if res.invalid?
48
86
  end
49
87
  end
50
88
 
51
- # secondary mixin for frameworks that put `request` in the scope
52
-
89
+ # mixin for frameworks that have a {#request} method in scope
90
+ # make sure you `include Rack::Params` before including
91
+ # @!attribute [r] params
92
+ # @return [Result] the validated params, including errors
53
93
  module Connector
54
94
  def self.included(base)
55
95
  base.class_eval do
@@ -57,9 +97,37 @@ module Rack
57
97
  end
58
98
  end
59
99
 
100
+ # validates {Rack::Request#params} against a validator.
101
+ # @overload validate(name, options = {})
102
+ # @param [Symbol] name the name of a registered validator.
103
+ # @param [Hash] options
104
+ # @return [Result] a result hash containing the extracted keys, and any errors.
105
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
106
+ # @overload validate(options = {}, &block)
107
+ # validates the given parameters against the given block
108
+ # @param [Hash] options
109
+ # @yield a code block that will run in the context of a {Rack::Params::HashContext} to validate the params
110
+ # @return [Result] a result hash containing the extracted keys, and any errors.
111
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
60
112
  def validate(name = nil, params = nil, options = {}, &block)
61
113
  super(name, params || request.params, options, &block)
62
114
  end
115
+
116
+ # validates {Rack::Request#params} against a validator, raising on errors.
117
+ # @overload validate!(name, options = {})
118
+ # @param [Symbol] name the name of a registered validator.
119
+ # @param [Hash] options
120
+ # @return [Result] a valid result hash containing the extracted keys, and no errors.
121
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
122
+ # @overload validate!(options = {}, &block)
123
+ # validates the given parameters against the given block
124
+ # @param [Hash] options
125
+ # @yield a code block that will run in the context of a {Rack::Params::HashContext} to validate the params
126
+ # @return [Result] a valid result hash containing the extracted keys, and no errors.
127
+ # @raise [ParameterValidationError] if the parameters are invalid after validation and coercion
128
+ def validate!(name = nil, params = nil, options = {}, &block)
129
+ super(name, params || request.params, options, &block)
130
+ end
63
131
  end
64
132
  end
65
133
  end
data/rack-params.gemspec CHANGED
@@ -24,11 +24,10 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.16"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
-
28
27
  spec.add_development_dependency "rspec", "~> 3.0"
29
- spec.add_development_dependency 'coveralls'
30
- spec.add_development_dependency 'simplecov'
31
- spec.add_development_dependency 'simplecov-console'
32
-
28
+ spec.add_development_dependency "yard"
29
+ spec.add_development_dependency "coveralls"
30
+ spec.add_development_dependency "simplecov"
31
+ spec.add_development_dependency "simplecov-console"
33
32
  spec.add_development_dependency "byebug", "~> 9.0"
34
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-params
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre3
4
+ version: 0.0.1.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Raphaelson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-23 00:00:00.000000000 Z
11
+ date: 2018-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: coveralls
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -132,6 +146,8 @@ files:
132
146
  - ".gitignore"
133
147
  - ".rspec"
134
148
  - ".travis.yml"
149
+ - ".yardopts"
150
+ - CODE_OF_CONDUCT.md
135
151
  - Gemfile
136
152
  - LICENSE.txt
137
153
  - README.md
@@ -143,6 +159,7 @@ files:
143
159
  - lib/rack/params/context.rb
144
160
  - lib/rack/params/errors.rb
145
161
  - lib/rack/params/result.rb
162
+ - lib/rack/params/tasks.rake
146
163
  - lib/rack/params/version.rb
147
164
  - rack-params.gemspec
148
165
  homepage: https://github.com/lygaret/rack-params