rack-rewrite 1.0.2 → 1.1.0
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.
- data/Gemfile +3 -0
- data/Gemfile.lock +21 -0
- data/History.rdoc +7 -0
- data/README.rdoc +19 -0
- data/VERSION +1 -0
- data/lib/rack/rewrite.rb +3 -2
- data/lib/rack/rewrite/rule.rb +53 -28
- data/lib/rack/rewrite/version.rb +5 -0
- data/rack-rewrite.gemspec +16 -7
- data/test/rule_test.rb +43 -3
- data/test/test_helper.rb +4 -8
- metadata +75 -44
- data/.document +0 -5
- data/.gitignore +0 -5
- data/RELEASING +0 -4
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rack-rewrite (1.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
mocha (0.9.12)
|
10
|
+
rack (1.2.1)
|
11
|
+
shoulda (2.10.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler (~> 1.0.10)
|
18
|
+
mocha (~> 0.9.7)
|
19
|
+
rack
|
20
|
+
rack-rewrite!
|
21
|
+
shoulda (~> 2.10.2)
|
data/History.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 1.1.0 / 2011-08-15
|
2
|
+
* API
|
3
|
+
* :host and :method option to match SERVER_NAME and REQUEST_METHOD env params.
|
4
|
+
* :not option to negative match against path.
|
5
|
+
* Maintenance
|
6
|
+
* Refactored internals a bit.
|
7
|
+
|
1
8
|
=== 1.0.2 / 2010-10-01
|
2
9
|
* Maintenance
|
3
10
|
* :send_file rules return content in an Array for Ruby 1.9.2 compatibility
|
data/README.rdoc
CHANGED
@@ -169,6 +169,25 @@ capture group and substitution pattern in your rewrite rule to achieve this.
|
|
169
169
|
This rule will store the querystring in a capture group (via '(?.*)' ) and
|
170
170
|
will substitute the querystring back into the rewritten URL (via $1).
|
171
171
|
|
172
|
+
=== Matching on a host
|
173
|
+
|
174
|
+
Using the :host option you can match requests to a specific hostname.
|
175
|
+
|
176
|
+
r301 "/features", "/facial_features", :host => "facerecognizer.com"
|
177
|
+
|
178
|
+
This rule will only match when the hostname is "facerecognizer.com"
|
179
|
+
|
180
|
+
=== Restrict rule to HTTP methods (GET, POST, PUT, DELETE, etc)
|
181
|
+
|
182
|
+
In certain scenarios you will want to restrict your rules by the HTTP method
|
183
|
+
of a given request. rack-rewrite exposes the :method option for this purpose.
|
184
|
+
|
185
|
+
# redirect GET's one way
|
186
|
+
r301 "/players", "/current_players", :method => :get
|
187
|
+
|
188
|
+
# and redirect POST's another way
|
189
|
+
r302 "/players", "/no_longer_available.html?message=No&longer&supported", :method => :post
|
190
|
+
|
172
191
|
=== Rule Guards
|
173
192
|
|
174
193
|
All rules support passing guards as Procs/lambdas. Guards simply return
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
data/lib/rack/rewrite.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
require 'rack/rewrite/rule'
|
2
|
-
|
3
1
|
module Rack
|
2
|
+
autoload :RuleSet, 'rack/rewrite/rule'
|
3
|
+
autoload :VERSION, 'rack/rewrite/version'
|
4
|
+
|
4
5
|
# A rack middleware for defining and applying rewrite rules. In many cases you
|
5
6
|
# can get away with rack-rewrite instead of writing Apache mod_rewrite rules.
|
6
7
|
class Rewrite
|
data/lib/rack/rewrite/rule.rb
CHANGED
@@ -19,36 +19,32 @@ module Rack
|
|
19
19
|
# rewrite '/wiki/John_Trupiano', '/john'
|
20
20
|
# rewrite %r{/wiki/(\w+)_\w+}, '/$1'
|
21
21
|
# rewrite %r{(.*)}, '/maintenance.html', :if => lambda { File.exists?('maintenance.html') }
|
22
|
-
def rewrite(
|
23
|
-
|
24
|
-
@rules << Rule.new(:rewrite, from, to, options[:if])
|
22
|
+
def rewrite(*args)
|
23
|
+
add_rule :rewrite, *args
|
25
24
|
end
|
26
25
|
|
27
26
|
# Creates a redirect rule that will send a 301 when matching.
|
28
27
|
#
|
29
28
|
# r301 '/wiki/John_Trupiano', '/john'
|
30
29
|
# r301 '/contact-us.php', '/contact-us'
|
31
|
-
def r301(
|
32
|
-
|
33
|
-
@rules << Rule.new(:r301, from, to, options[:if])
|
30
|
+
def r301(*args)
|
31
|
+
add_rule :r301, *args
|
34
32
|
end
|
35
33
|
|
36
34
|
# Creates a redirect rule that will send a 302 when matching.
|
37
35
|
#
|
38
36
|
# r302 '/wiki/John_Trupiano', '/john'
|
39
37
|
# r302 '/wiki/(.*)', 'http://www.google.com/?q=$1'
|
40
|
-
def r302(
|
41
|
-
|
42
|
-
@rules << Rule.new(:r302, from, to, options[:if])
|
38
|
+
def r302(*args)
|
39
|
+
add_rule :r302, *args
|
43
40
|
end
|
44
41
|
|
45
42
|
# Creates a rule that will render a file if matched.
|
46
43
|
#
|
47
44
|
# send_file /*/, 'public/system/maintenance.html',
|
48
45
|
# :if => Proc.new { File.exists?('public/system/maintenance.html') }
|
49
|
-
def send_file(
|
50
|
-
|
51
|
-
@rules << Rule.new(:send_file, from, to, options[:if])
|
46
|
+
def send_file(*args)
|
47
|
+
add_rule :send_file, *args
|
52
48
|
end
|
53
49
|
|
54
50
|
# Creates a rule that will render a file using x-send-file
|
@@ -56,29 +52,29 @@ module Rack
|
|
56
52
|
#
|
57
53
|
# x_send_file /*/, 'public/system/maintenance.html',
|
58
54
|
# :if => Proc.new { File.exists?('public/system/maintenance.html') }
|
59
|
-
def x_send_file(
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
def x_send_file(*args)
|
56
|
+
add_rule :x_send_file, *args
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def add_rule(method, from, to, options = {}) #:nodoc:
|
61
|
+
@rules << Rule.new(method.to_sym, from, to, options)
|
62
|
+
end
|
63
|
+
|
63
64
|
end
|
64
65
|
|
65
66
|
# TODO: Break rules into subclasses
|
66
67
|
class Rule #:nodoc:
|
67
|
-
attr_reader :rule_type, :from, :to, :
|
68
|
-
def initialize(rule_type, from, to,
|
69
|
-
@rule_type, @from, @to, @
|
68
|
+
attr_reader :rule_type, :from, :to, :options
|
69
|
+
def initialize(rule_type, from, to, options={}) #:nodoc:
|
70
|
+
@rule_type, @from, @to, @options = rule_type, from, to, normalize_options(options)
|
70
71
|
end
|
71
72
|
|
72
73
|
def matches?(rack_env) #:nodoc:
|
73
|
-
return false if
|
74
|
+
return false if options[:if].respond_to?(:call) && !options[:if].call(rack_env)
|
74
75
|
path = build_path_from_env(rack_env)
|
75
|
-
|
76
|
-
|
77
|
-
elsif self.from.is_a?(String)
|
78
|
-
path == self.from
|
79
|
-
else
|
80
|
-
false
|
81
|
-
end
|
76
|
+
|
77
|
+
self.match_options?(rack_env) && string_matches?(path, self.from)
|
82
78
|
end
|
83
79
|
|
84
80
|
# Either (a) return a Rack response (short-circuiting the Rack stack), or
|
@@ -128,8 +124,27 @@ module Rack
|
|
128
124
|
def is_a_regexp?(obj)
|
129
125
|
obj.is_a?(Regexp) || (Object.const_defined?(:Oniguruma) && obj.is_a?(Oniguruma::ORegexp))
|
130
126
|
end
|
131
|
-
|
127
|
+
|
128
|
+
def match_options?(env, path = build_path_from_env(env))
|
129
|
+
matches = []
|
130
|
+
|
131
|
+
# negative matches
|
132
|
+
matches << !string_matches?(path, options[:not]) if options[:not]
|
133
|
+
|
134
|
+
# possitive matches
|
135
|
+
matches << string_matches?(env['REQUEST_METHOD'], options[:method]) if options[:method]
|
136
|
+
matches << string_matches?(env['SERVER_NAME'], options[:host]) if options[:host]
|
137
|
+
|
138
|
+
matches.all?
|
139
|
+
end
|
140
|
+
|
132
141
|
private
|
142
|
+
def normalize_options(arg)
|
143
|
+
options = arg.respond_to?(:call) ? {:if => arg} : arg
|
144
|
+
options.symbolize_keys! if options.respond_to? :symbolize_keys!
|
145
|
+
options.freeze
|
146
|
+
end
|
147
|
+
|
133
148
|
def interpret_to_proc(path, env)
|
134
149
|
return self.to.call(match(path), env) if self.from.is_a?(Regexp)
|
135
150
|
self.to.call(self.from, env)
|
@@ -142,6 +157,16 @@ module Rack
|
|
142
157
|
def match(path)
|
143
158
|
self.from.match(path)
|
144
159
|
end
|
160
|
+
|
161
|
+
def string_matches?(string, matcher)
|
162
|
+
if self.is_a_regexp?(matcher)
|
163
|
+
string =~ matcher
|
164
|
+
elsif matcher.is_a?(String)
|
165
|
+
string == matcher
|
166
|
+
else
|
167
|
+
false
|
168
|
+
end
|
169
|
+
end
|
145
170
|
|
146
171
|
def computed_to(path)
|
147
172
|
# is there a better way to do this?
|
data/rack-rewrite.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name =
|
3
|
-
s.version =
|
2
|
+
s.name = 'rack-rewrite'
|
3
|
+
s.version = File.read('VERSION')
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.authors = ["John Trupiano"]
|
7
|
-
s.date =
|
7
|
+
s.date = Date.today.to_s
|
8
8
|
s.description = %q{A rack middleware for enforcing rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules.}
|
9
9
|
s.email = %q{jtrupiano@gmail.com}
|
10
10
|
s.extra_rdoc_files = [
|
@@ -13,16 +13,17 @@ Gem::Specification.new do |s|
|
|
13
13
|
"README.rdoc"
|
14
14
|
]
|
15
15
|
s.files = [
|
16
|
-
".document",
|
17
|
-
".gitignore",
|
18
16
|
"History.rdoc",
|
19
17
|
"LICENSE",
|
20
18
|
"README.rdoc",
|
21
19
|
"Rakefile",
|
22
|
-
"
|
20
|
+
"VERSION",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
23
|
"lib/rack-rewrite.rb",
|
24
24
|
"lib/rack/rewrite.rb",
|
25
25
|
"lib/rack/rewrite/rule.rb",
|
26
|
+
"lib/rack/rewrite/version.rb",
|
26
27
|
"rack-rewrite.gemspec",
|
27
28
|
"test/geminstaller.yml",
|
28
29
|
"test/rack-rewrite_test.rb",
|
@@ -36,11 +37,19 @@ Gem::Specification.new do |s|
|
|
36
37
|
s.rubygems_version = %q{1.3.7}
|
37
38
|
s.summary = %q{A rack middleware for enforcing rewrite rules}
|
38
39
|
s.test_files = [
|
40
|
+
"test/rack-rewrite_test.rb",
|
41
|
+
"test/geminstaller.yml",
|
39
42
|
"test/rack-rewrite_test.rb",
|
40
43
|
"test/rule_test.rb",
|
41
44
|
"test/test_helper.rb"
|
42
45
|
]
|
43
|
-
|
46
|
+
#s.add_dependency 'rack'
|
47
|
+
|
48
|
+
s.add_development_dependency 'bundler', '~> 1.0.10'
|
49
|
+
s.add_development_dependency 'shoulda', '~> 2.10.2'
|
50
|
+
s.add_development_dependency 'mocha', '~> 0.9.7'
|
51
|
+
s.add_development_dependency 'rack'
|
52
|
+
|
44
53
|
if s.respond_to? :specification_version then
|
45
54
|
s.specification_version = 3
|
46
55
|
end
|
data/test/rule_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'test_helper'
|
2
2
|
|
3
3
|
class RuleTest < Test::Unit::TestCase
|
4
4
|
|
@@ -146,6 +146,46 @@ class RuleTest < Test::Unit::TestCase
|
|
146
146
|
end
|
147
147
|
|
148
148
|
context 'Rule#matches' do
|
149
|
+
context 'Given rule with :not option which matches "from" string' do
|
150
|
+
setup do
|
151
|
+
@rule = Rack::Rewrite::Rule.new(:rewrite, /^\/features/, '/facial_features', :not => '/features')
|
152
|
+
end
|
153
|
+
should 'not match PATH_INFO of /features' do
|
154
|
+
assert !@rule.matches?(rack_env_for("/features"))
|
155
|
+
end
|
156
|
+
should 'match PATH_INFO of /features.xml' do
|
157
|
+
assert @rule.matches?(rack_env_for("/features.xml"))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'Given rule with :host option of testapp.com' do
|
162
|
+
setup do
|
163
|
+
@rule = Rack::Rewrite::Rule.new(:rewrite, /^\/features/, '/facial_features', :host => 'testapp.com')
|
164
|
+
end
|
165
|
+
|
166
|
+
should 'match PATH_INFO of /features and HOST of testapp.com' do
|
167
|
+
assert @rule.matches?(rack_env_for("/features", 'SERVER_NAME' => 'testapp.com'))
|
168
|
+
end
|
169
|
+
|
170
|
+
should 'not match PATH_INFO of /features and HOST of nottestapp.com' do
|
171
|
+
assert ! @rule.matches?(rack_env_for("/features", 'SERVER_NAME' => 'nottestapp.com'))
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'Given rule with :method option of POST' do
|
176
|
+
setup do
|
177
|
+
@rule = Rack::Rewrite::Rule.new(:rewrite, '/features', '/facial_features', :method => 'POST')
|
178
|
+
end
|
179
|
+
|
180
|
+
should 'match PATH_INFO of /features and REQUEST_METHOD of POST' do
|
181
|
+
assert @rule.matches?(rack_env_for("/features", 'REQUEST_METHOD' => 'POST'))
|
182
|
+
end
|
183
|
+
|
184
|
+
should 'not match PATH_INFO of /features and REQUEST_METHOD of DELETE' do
|
185
|
+
assert ! @rule.matches?(rack_env_for("/features", 'REQUEST_METHOD' => 'DELETE'))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
149
189
|
context 'Given any rule with a "from" string of /features' do
|
150
190
|
setup do
|
151
191
|
@rule = Rack::Rewrite::Rule.new(:rewrite, '/features', '/facial_features')
|
@@ -307,8 +347,8 @@ class RuleTest < Test::Unit::TestCase
|
|
307
347
|
end
|
308
348
|
end
|
309
349
|
|
310
|
-
def rack_env_for(url)
|
350
|
+
def rack_env_for(url, options = {})
|
311
351
|
components = url.split('?')
|
312
|
-
{'PATH_INFO' => components[0], 'QUERY_STRING' => components[1] || ''}
|
352
|
+
{'PATH_INFO' => components[0], 'QUERY_STRING' => components[1] || ''}.merge(options)
|
313
353
|
end
|
314
354
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
3
|
-
|
4
|
-
require
|
5
|
-
gem 'mocha', '~> 0.9.7'
|
6
|
-
require 'mocha'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
Bundler.require :default, :development
|
7
5
|
|
8
|
-
|
9
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
|
-
require 'rack/rewrite'
|
6
|
+
require 'test/unit'
|
11
7
|
|
12
8
|
class Test::Unit::TestCase
|
13
9
|
end
|
metadata
CHANGED
@@ -1,45 +1,82 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-rewrite
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 2
|
10
|
-
version: 1.0.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- John Trupiano
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2010-10-01 00:00:00 -04:00
|
12
|
+
date: 2011-08-15 00:00:00.000000000 -04:00
|
19
13
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
22
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bundler
|
17
|
+
requirement: &2152850260 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.10
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2152850260
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: shoulda
|
28
|
+
requirement: &2152849800 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.10.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2152849800
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: mocha
|
39
|
+
requirement: &2152849340 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 0.9.7
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2152849340
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rack
|
50
|
+
requirement: &2152848960 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2152848960
|
59
|
+
description: A rack middleware for enforcing rewrite rules. In many cases you can
|
60
|
+
get away with rack-rewrite instead of writing Apache mod_rewrite rules.
|
23
61
|
email: jtrupiano@gmail.com
|
24
62
|
executables: []
|
25
|
-
|
26
63
|
extensions: []
|
27
|
-
|
28
|
-
extra_rdoc_files:
|
64
|
+
extra_rdoc_files:
|
29
65
|
- LICENSE
|
30
66
|
- History.rdoc
|
31
67
|
- README.rdoc
|
32
|
-
files:
|
33
|
-
- .document
|
34
|
-
- .gitignore
|
68
|
+
files:
|
35
69
|
- History.rdoc
|
36
70
|
- LICENSE
|
37
71
|
- README.rdoc
|
38
72
|
- Rakefile
|
39
|
-
-
|
73
|
+
- VERSION
|
74
|
+
- Gemfile
|
75
|
+
- Gemfile.lock
|
40
76
|
- lib/rack-rewrite.rb
|
41
77
|
- lib/rack/rewrite.rb
|
42
78
|
- lib/rack/rewrite/rule.rb
|
79
|
+
- lib/rack/rewrite/version.rb
|
43
80
|
- rack-rewrite.gemspec
|
44
81
|
- test/geminstaller.yml
|
45
82
|
- test/rack-rewrite_test.rb
|
@@ -48,38 +85,32 @@ files:
|
|
48
85
|
has_rdoc: true
|
49
86
|
homepage: http://github.com/jtrupiano/rack-rewrite
|
50
87
|
licenses: []
|
51
|
-
|
52
88
|
post_install_message:
|
53
|
-
rdoc_options:
|
89
|
+
rdoc_options:
|
54
90
|
- --charset=UTF-8
|
55
|
-
require_paths:
|
91
|
+
require_paths:
|
56
92
|
- lib
|
57
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
94
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
|
64
|
-
- 0
|
65
|
-
version: "0"
|
66
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
100
|
none: false
|
68
|
-
requirements:
|
69
|
-
- -
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
|
72
|
-
segments:
|
73
|
-
- 0
|
74
|
-
version: "0"
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
75
105
|
requirements: []
|
76
|
-
|
77
106
|
rubyforge_project: johntrupiano
|
78
|
-
rubygems_version: 1.
|
107
|
+
rubygems_version: 1.6.2
|
79
108
|
signing_key:
|
80
109
|
specification_version: 3
|
81
110
|
summary: A rack middleware for enforcing rewrite rules
|
82
|
-
test_files:
|
111
|
+
test_files:
|
112
|
+
- test/rack-rewrite_test.rb
|
113
|
+
- test/geminstaller.yml
|
83
114
|
- test/rack-rewrite_test.rb
|
84
115
|
- test/rule_test.rb
|
85
116
|
- test/test_helper.rb
|
data/.document
DELETED
data/RELEASING
DELETED