Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
Brakeman
提交
f746d34b
B
Brakeman
项目概览
李少辉-开发者
/
Brakeman
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
B
Brakeman
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f746d34b
编写于
4月 26, 2011
作者:
J
Justin Collins
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'rails3'
-Add experimental support for Rails 3
上级
7ab13735
11428fa2
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
524 addition
and
333 deletion
+524
-333
bin/brakeman
bin/brakeman
+4
-0
lib/processors/lib/find_model_call.rb
lib/processors/lib/find_model_call.rb
+5
-1
lib/processors/lib/rails2_route_processor.rb
lib/processors/lib/rails2_route_processor.rb
+304
-0
lib/processors/lib/rails3_route_processor.rb
lib/processors/lib/rails3_route_processor.rb
+172
-0
lib/processors/lib/route_helper.rb
lib/processors/lib/route_helper.rb
+34
-0
lib/processors/route_processor.rb
lib/processors/route_processor.rb
+5
-332
未找到文件。
bin/brakeman
浏览文件 @
f746d34b
...
...
@@ -27,6 +27,10 @@ OptionParser.new do |opts|
$VERBOSE
=
nil
end
opts
.
on
"-3"
,
"--rails3"
,
"[Experimental] Rails 3 support"
do
options
[
:rails3
]
=
true
end
opts
.
separator
""
opts
.
separator
"Scanning options:"
...
...
lib/processors/lib/find_model_call.rb
浏览文件 @
f746d34b
...
...
@@ -6,7 +6,11 @@ class FindModelCall < FindCall
#Passes +targets+ to FindCall
def
initialize
targets
super
(
targets
,
/^(find.*|first|last|all|count|sum|average|minumum|maximum|count_by_sql)$/
,
true
)
if
OPTIONS
[
:rails3
]
super
(
targets
,
/^(find.*|first|last|all|where|order|group|having)$/
,
true
)
else
super
(
targets
,
/^(find.*|first|last|all)$/
,
true
)
end
end
#Matches entire method chain as a target. This differs from
...
...
lib/processors/lib/rails2_route_processor.rb
0 → 100644
浏览文件 @
f746d34b
require
'processors/base_processor'
#Processes the Sexp from routes.rb. Stores results in tracker.routes.
#
#Note that it is only interested in determining what methods on which
#controllers are used as routes, not the generated URLs for routes.
class
RoutesProcessor
<
BaseProcessor
include
RouteHelper
attr_reader
:map
,
:nested
,
:current_controller
def
initialize
tracker
super
@map
=
Sexp
.
new
(
:lvar
,
:map
)
@nested
=
nil
#used for identifying nested targets
@prefix
=
[]
#Controller name prefix (a module name, usually)
@current_controller
=
nil
@with_options
=
nil
#For use inside map.with_options
end
#Call this with parsed route file information.
#
#This method first calls RouteAliasProcessor#process_safely on the +exp+,
#so it does not modify the +exp+.
def
process_routes
exp
process
RouteAliasProcessor
.
new
.
process_safely
(
exp
)
end
#Looking for mapping of routes
def
process_call
exp
target
=
exp
[
1
]
if
target
==
map
or
target
==
nested
process_map
exp
else
process_default
exp
end
exp
end
#Process a map.something call
#based on the method used
def
process_map
exp
args
=
exp
[
3
][
1
..-
1
]
case
exp
[
2
]
when
:resource
process_resource
args
when
:resources
process_resources
args
when
:connect
,
:root
process_connect
args
else
process_named_route
args
end
exp
end
#Look for map calls that take a block.
#Otherwise, just do the default processing.
def
process_iter
exp
if
exp
[
1
][
1
]
==
map
or
exp
[
1
][
1
]
==
nested
method
=
exp
[
1
][
2
]
case
method
when
:namespace
process_namespace
exp
when
:resources
,
:resource
process_resources
exp
[
1
][
3
][
1
..-
1
]
process_default
exp
[
3
]
when
:with_options
process_with_options
exp
end
exp
else
super
end
end
#Process
# map.resources :x, :controller => :y, :member => ...
#etc.
def
process_resources
exp
controller
=
check_for_controller_name
exp
if
controller
self
.
current_controller
=
controller
process_resource_options
exp
[
-
1
]
else
exp
.
each
do
|
argument
|
if
sexp?
argument
and
argument
.
node_type
==
:lit
self
.
current_controller
=
exp
[
0
][
1
]
add_resources_routes
process_resource_options
exp
[
-
1
]
end
end
end
end
#Process all the options that might be in the hash passed to
#map.resource, et al.
def
process_resource_options
exp
if
exp
.
nil?
and
@with_options
exp
=
@with_options
elsif
@with_options
exp
=
exp
.
concat
@with_options
[
1
..-
1
]
end
return
unless
exp
.
node_type
==
:hash
hash_iterate
(
exp
)
do
|
option
,
value
|
case
option
[
1
]
when
:controller
,
:requirements
,
:singular
,
:path_prefix
,
:as
,
:path_names
,
:shallow
,
:name_prefix
#should be able to skip
when
:collection
,
:member
,
:new
process_collection
value
when
:has_one
save_controller
=
current_controller
process_resource
value
[
1
..-
1
]
self
.
current_controller
=
save_controller
when
:has_many
save_controller
=
current_controller
process_resources
value
[
1
..-
1
]
self
.
current_controller
=
save_controller
when
:only
process_option_only
value
when
:except
process_option_except
value
else
raise
"Unhandled resource option:
#{
option
}
"
end
end
end
#Process route option :only => ...
def
process_option_only
exp
routes
=
@tracker
.
routes
[
@current_controller
]
[
:index
,
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
].
each
do
|
r
|
routes
.
delete
r
end
if
exp
.
node_type
==
:array
exp
[
1
..-
1
].
each
do
|
e
|
routes
<<
e
[
1
]
end
end
end
#Process route option :except => ...
def
process_option_except
exp
return
unless
exp
.
node_type
==
:array
routes
=
@tracker
.
routes
[
@current_controller
]
exp
[
1
..-
1
].
each
do
|
e
|
routes
.
delete
e
[
1
]
end
end
# map.resource :x, ..
def
process_resource
exp
controller
=
check_for_controller_name
exp
if
controller
self
.
current_controller
=
controller
process_resource_options
exp
[
-
1
]
else
exp
.
each
do
|
argument
|
if
argument
.
node_type
==
:lit
self
.
current_controller
=
pluralize
(
exp
[
0
][
1
].
to_s
)
add_resource_routes
process_resource_options
exp
[
-
1
]
end
end
end
end
#Process
# map.connect '/something', :controller => 'blah', :action => 'whatever'
def
process_connect
exp
controller
=
check_for_controller_name
exp
self
.
current_controller
=
controller
if
controller
#Check for default route
if
string?
exp
[
0
]
if
exp
[
0
][
1
]
==
":controller/:action/:id"
@tracker
.
routes
[
:allow_all_actions
]
=
exp
[
0
]
elsif
exp
[
0
][
1
].
include?
":action"
@tracker
.
routes
[
@current_controller
]
=
:allow_all_actions
return
end
end
#This -seems- redundant, but people might connect actions
#to a controller which already allows them all
return
if
@tracker
.
routes
[
@current_controller
]
==
:allow_all_actions
exp
[
-
1
].
each_with_index
do
|
e
,
i
|
if
symbol?
e
and
e
[
1
]
==
:action
@tracker
.
routes
[
@current_controller
]
<<
exp
[
-
1
][
i
+
1
][
1
].
to_sym
return
end
end
end
# map.with_options :controller => 'something' do |something|
# something.resources :blah
# end
def
process_with_options
exp
@with_options
=
exp
[
1
][
3
][
-
1
]
@nested
=
Sexp
.
new
(
:lvar
,
exp
[
2
][
1
])
self
.
current_controller
=
check_for_controller_name
exp
[
1
][
3
]
#process block
process
exp
[
3
]
@with_options
=
nil
@nested
=
nil
end
# map.namespace :something do |something|
# something.resources :blah
# end
def
process_namespace
exp
call
=
exp
[
1
]
formal_args
=
exp
[
2
]
block
=
exp
[
3
]
@prefix
<<
camelize
(
call
[
3
][
1
][
1
])
@nested
=
Sexp
.
new
(
:lvar
,
formal_args
[
1
])
process
block
@prefix
.
pop
end
# map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'
def
process_named_route
exp
process_connect
exp
end
#Process collection option
# :collection => { :some_action => :http_actions }
def
process_collection
exp
return
unless
exp
.
node_type
==
:hash
routes
=
@tracker
.
routes
[
@current_controller
]
hash_iterate
(
exp
)
do
|
action
,
type
|
routes
<<
action
[
1
]
end
end
private
#Checks an argument list for a hash that has a key :controller.
#If it does, returns the value.
#
#Otherwise, returns nil.
def
check_for_controller_name
args
args
.
each
do
|
a
|
if
hash
?
a
hash_iterate
(
a
)
do
|
k
,
v
|
if
k
[
1
]
==
:
controller
return
v
[
1
]
end
end
end
end
nil
end
end
#This is for a really specific case where a hash is used as arguments
#to one of the map methods.
class
RouteAliasProcessor
<
AliasProcessor
#This replaces
# { :some => :hash }.keys
#with
# [:some]
def
process_call
exp
process_default
exp
if
hash
?
exp
[
1
]
and
exp
[
2
]
==
:
keys
keys
=
get_keys
exp
[
1
]
exp
.
clear
keys
.
each_with_index
do
|
e
,
i
|
exp
[
i
]
=
e
end
end
exp
end
#Returns an array Sexp containing the keys from the hash
def
get_keys
hash
keys
=
Sexp
.
new
(
:array
)
hash_iterate
(
hash
)
do
|
key
,
value
|
keys
<<
key
end
keys
end
end
lib/processors/lib/rails3_route_processor.rb
0 → 100644
浏览文件 @
f746d34b
#Processes the Sexp from routes.rb. Stores results in tracker.routes.
#
#Note that it is only interested in determining what methods on which
#controllers are used as routes, not the generated URLs for routes.
class
RoutesProcessor
<
BaseProcessor
include
RouteHelper
attr_reader
:map
,
:nested
,
:current_controller
def
initialize
tracker
super
@map
=
Sexp
.
new
(
:lvar
,
:map
)
@nested
=
nil
#used for identifying nested targets
@prefix
=
[]
#Controller name prefix (a module name, usually)
@current_controller
=
nil
@with_options
=
nil
#For use inside map.with_options
end
def
process_routes
exp
process
exp
.
dup
end
def
process_call
exp
case
exp
[
2
]
when
:resources
process_resources
exp
when
:resource
process_resource
exp
when
:root
process_root
exp
when
:member
process_default
exp
when
:get
,
:put
,
:post
,
:delete
process_verb
exp
when
:match
process_match
exp
else
exp
end
end
def
process_iter
exp
case
exp
[
1
][
2
]
when
:namespace
process_namespace
exp
when
:resource
process_resource_block
exp
when
:resources
process_resources_block
exp
when
:scope
process_scope_block
exp
else
super
end
end
def
process_namespace
exp
name
=
exp
[
1
][
3
][
1
][
1
]
block
=
exp
[
3
]
@prefix
<<
camelize
(
name
)
process
block
@prefix
.
pop
exp
end
def
process_root
exp
args
=
exp
[
3
][
1
..-
1
]
hash_iterate
args
[
0
]
do
|
k
,
v
|
if
symbol?
k
and
k
[
1
]
==
:to
controller
,
action
=
extract_action
v
[
1
]
self
.
current_controller
=
controller
@tracker
.
routes
[
@current_controller
]
<<
action
.
to_sym
break
end
end
exp
end
def
process_match
exp
args
=
exp
[
3
][
1
..-
1
]
hash_iterate
args
[
0
]
do
|
k
,
v
|
if
string?
k
and
string?
v
controller
,
action
=
extract_action
v
[
1
]
self
.
current_controller
=
controller
@tracker
.
routes
[
@current_controller
]
<<
action
.
to_sym
if
action
elsif
symbol?
k
and
k
[
1
]
==
:action
@tracker
.
routes
[
@current_controller
]
<<
v
[
1
].
to_sym
end
end
exp
end
def
process_verb
exp
args
=
exp
[
3
][
1
..-
1
]
if
symbol?
args
[
0
]
@tracker
.
routes
[
@current_controller
]
<<
args
[
0
][
1
]
elsif
string?
args
[
0
]
route
=
args
[
0
][
1
].
split
"/"
if
route
.
length
!=
2
@tracker
.
routes
[
@current_controller
]
<<
route
[
0
].
to_sym
else
self
.
current_controller
=
route
[
0
]
@tracker
.
routes
[
@current_controller
]
<<
route
[
1
].
to_sym
@current_controller
=
nil
end
else
hash
?
args
[
0
]
hash_iterate
args
[
0
]
do
|
k
,
v
|
if
string?
v
controller
,
action
=
extract_action
v
[
1
]
self
.
current_controller
=
controller
@tracker
.
routes
[
@current_controller
]
<<
action
.
to_sym
end
end
end
exp
end
def
process_resources
exp
if
exp
[
3
]
and
exp
[
3
][
2
]
and
exp
[
3
][
2
][
0
]
==
:
hash
#handle hash
elsif
exp
[
3
][
1
..-
1
].
all?
{
|
s
|
symbol?
s
}
exp
[
3
][
1
..-
1
].
each
do
|
s
|
self
.
current_controller
=
s
[
1
]
add_resources_routes
end
end
exp
end
def
process_resource
exp
exp
[
3
][
1
..-
1
].
each
do
|
s
|
self
.
current_controller
=
s
[
1
]
add_resource_routes
end
exp
end
def
process_resources_block
exp
process_resources
exp
[
1
]
process
exp
[
3
]
end
def
process_resource_block
exp
process_resource
exp
[
1
]
process
exp
[
3
]
end
def
process_scope_block
exp
#How to deal with options?
process
exp
[
3
]
end
def
extract_action
str
str
.
split
"#"
end
end
lib/processors/lib/route_helper.rb
0 → 100644
浏览文件 @
f746d34b
module
RouteHelper
#Manage Controller prefixes
#@prefix is an Array, but this method returns a string
#suitable for prefixing onto a controller name.
def
prefix
if
@prefix
.
length
>
0
@prefix
.
join
(
"::"
)
<<
"::"
else
''
end
end
#Sets the controller name to a proper class name.
#For example
# self.current_controller = :session
# @controller == :SessionController #true
#
#Also prepends the prefix if there is one set.
def
current_controller
=
name
@current_controller
=
(
prefix
+
camelize
(
name
)
+
"Controller"
).
to_sym
@tracker
.
routes
[
@current_controller
]
||=
Set
.
new
end
#Add default routes
def
add_resources_routes
@tracker
.
routes
[
@current_controller
].
merge
[
:index
,
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
]
end
#Add default routes minus :index
def
add_resource_routes
@tracker
.
routes
[
@current_controller
].
merge
[
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
]
end
end
lib/processors/route_processor.rb
浏览文件 @
f746d34b
require
'processors/base_processor'
require
'processors/alias_processor'
require
'processors/lib/route_helper'
require
'util'
require
'set'
#Processes the Sexp from routes.rb. Stores results in tracker.routes.
#
#Note that it is only interested in determining what methods on which
#controllers are used as routes, not the generated URLs for routes.
class
RoutesProcessor
<
BaseProcessor
attr_reader
:map
,
:nested
,
:current_controller
def
initialize
tracker
super
@map
=
Sexp
.
new
(
:lvar
,
:map
)
@nested
=
nil
#used for identifying nested targets
@prefix
=
[]
#Controller name prefix (a module name, usually)
@current_controller
=
nil
@with_options
=
nil
#For use inside map.with_options
end
#Call this with parsed route file information.
#
#This method first calls RouteAliasProcessor#process_safely on the +exp+,
#so it does not modify the +exp+.
def
process_routes
exp
process
RouteAliasProcessor
.
new
.
process_safely
(
exp
)
end
#Looking for mapping of routes
def
process_call
exp
target
=
exp
[
1
]
if
target
==
map
or
target
==
nested
process_map
exp
else
process_default
exp
end
exp
end
#Process a map.something call
#based on the method used
def
process_map
exp
args
=
exp
[
3
][
1
..-
1
]
case
exp
[
2
]
when
:resource
process_resource
args
when
:resources
process_resources
args
when
:connect
,
:root
process_connect
args
else
process_named_route
args
end
exp
end
#Look for map calls that take a block.
#Otherwise, just do the default processing.
def
process_iter
exp
if
exp
[
1
][
1
]
==
map
or
exp
[
1
][
1
]
==
nested
method
=
exp
[
1
][
2
]
case
method
when
:namespace
process_namespace
exp
when
:resources
,
:resource
process_resources
exp
[
1
][
3
][
1
..-
1
]
process_default
exp
[
3
]
when
:with_options
process_with_options
exp
end
exp
else
super
end
end
#Process
# map.resources :x, :controller => :y, :member => ...
#etc.
def
process_resources
exp
controller
=
check_for_controller_name
exp
if
controller
self
.
current_controller
=
controller
process_resource_options
exp
[
-
1
]
else
exp
.
each
do
|
argument
|
if
sexp?
argument
and
argument
.
node_type
==
:lit
self
.
current_controller
=
exp
[
0
][
1
]
add_resources_routes
process_resource_options
exp
[
-
1
]
end
end
end
end
#Add default routes
def
add_resources_routes
@tracker
.
routes
[
@current_controller
].
merge
[
:index
,
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
]
end
#Process all the options that might be in the hash passed to
#map.resource, et al.
def
process_resource_options
exp
if
exp
.
nil?
and
@with_options
exp
=
@with_options
elsif
@with_options
exp
=
exp
.
concat
@with_options
[
1
..-
1
]
end
return
unless
exp
.
node_type
==
:hash
hash_iterate
(
exp
)
do
|
option
,
value
|
case
option
[
1
]
when
:controller
,
:requirements
,
:singular
,
:path_prefix
,
:as
,
:path_names
,
:shallow
,
:name_prefix
#should be able to skip
when
:collection
,
:member
,
:new
process_collection
value
when
:has_one
save_controller
=
current_controller
process_resource
value
[
1
..-
1
]
self
.
current_controller
=
save_controller
when
:has_many
save_controller
=
current_controller
process_resources
value
[
1
..-
1
]
self
.
current_controller
=
save_controller
when
:only
process_option_only
value
when
:except
process_option_except
value
else
raise
"Unhandled resource option:
#{
option
}
"
end
end
end
#Process route option :only => ...
def
process_option_only
exp
routes
=
@tracker
.
routes
[
@current_controller
]
[
:index
,
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
].
each
do
|
r
|
routes
.
delete
r
end
if
exp
.
node_type
==
:array
exp
[
1
..-
1
].
each
do
|
e
|
routes
<<
e
[
1
]
end
end
end
#Process route option :except => ...
def
process_option_except
exp
return
unless
exp
.
node_type
==
:array
routes
=
@tracker
.
routes
[
@current_controller
]
exp
[
1
..-
1
].
each
do
|
e
|
routes
.
delete
e
[
1
]
end
end
# map.resource :x, ..
def
process_resource
exp
controller
=
check_for_controller_name
exp
if
controller
self
.
current_controller
=
controller
process_resource_options
exp
[
-
1
]
else
exp
.
each
do
|
argument
|
if
argument
.
node_type
==
:lit
self
.
current_controller
=
pluralize
(
exp
[
0
][
1
].
to_s
)
add_resource_routes
process_resource_options
exp
[
-
1
]
end
end
end
end
#Add default routes minus :index
def
add_resource_routes
@tracker
.
routes
[
@current_controller
].
merge
[
:new
,
:create
,
:show
,
:edit
,
:update
,
:destroy
]
end
#Process
# map.connect '/something', :controller => 'blah', :action => 'whatever'
def
process_connect
exp
controller
=
check_for_controller_name
exp
self
.
current_controller
=
controller
if
controller
#Check for default route
if
string?
exp
[
0
]
if
exp
[
0
][
1
]
==
":controller/:action/:id"
@tracker
.
routes
[
:allow_all_actions
]
=
exp
[
0
]
elsif
exp
[
0
][
1
].
include?
":action"
@tracker
.
routes
[
@current_controller
]
=
:allow_all_actions
return
end
end
#This -seems- redundant, but people might connect actions
#to a controller which already allows them all
return
if
@tracker
.
routes
[
@current_controller
]
==
:allow_all_actions
exp
[
-
1
].
each_with_index
do
|
e
,
i
|
if
symbol?
e
and
e
[
1
]
==
:action
@tracker
.
routes
[
@current_controller
]
<<
exp
[
-
1
][
i
+
1
][
1
].
to_sym
return
end
end
end
# map.with_options :controller => 'something' do |something|
# something.resources :blah
# end
def
process_with_options
exp
@with_options
=
exp
[
1
][
3
][
-
1
]
@nested
=
Sexp
.
new
(
:lvar
,
exp
[
2
][
1
])
self
.
current_controller
=
check_for_controller_name
exp
[
1
][
3
]
#process block
process
exp
[
3
]
@with_options
=
nil
@nested
=
nil
end
# map.namespace :something do |something|
# something.resources :blah
# end
def
process_namespace
exp
call
=
exp
[
1
]
formal_args
=
exp
[
2
]
block
=
exp
[
3
]
@prefix
<<
camelize
(
call
[
3
][
1
][
1
])
@nested
=
Sexp
.
new
(
:lvar
,
formal_args
[
1
])
process
block
@prefix
.
pop
end
# map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'
def
process_named_route
exp
process_connect
exp
end
#Process collection option
# :collection => { :some_action => :http_actions }
def
process_collection
exp
return
unless
exp
.
node_type
==
:hash
routes
=
@tracker
.
routes
[
@current_controller
]
hash_iterate
(
exp
)
do
|
action
,
type
|
routes
<<
action
[
1
]
end
end
#Manage Controller prefixes
#@prefix is an Array, but this method returns a string
#suitable for prefixing onto a controller name.
def
prefix
if
@prefix
.
length
>
0
@prefix
.
join
(
"::"
)
<<
"::"
else
''
end
end
#Sets the controller name to a proper class name.
#For example
# self.current_controller = :session
# @controller == :SessionController #true
#
#Also prepends the prefix if there is one set.
def
current_controller
=
name
@current_controller
=
(
prefix
+
camelize
(
name
)
+
"Controller"
).
to_sym
@tracker
.
routes
[
@current_controller
]
||=
Set
.
new
end
private
#Checks an argument list for a hash that has a key :controller.
#If it does, returns the value.
#
#Otherwise, returns nil.
def
check_for_controller_name
args
args
.
each
do
|
a
|
if
hash
?
a
hash_iterate
(
a
)
do
|
k
,
v
|
if
k
[
1
]
==
:
controller
return
v
[
1
]
end
end
end
end
nil
end
end
#This is for a really specific case where a hash is used as arguments
#to one of the map methods.
class
RouteAliasProcessor
<
AliasProcessor
#This replaces
# { :some => :hash }.keys
#with
# [:some]
def
process_call
exp
process_default
exp
if
hash
?
exp
[
1
]
and
exp
[
2
]
==
:
keys
keys
=
get_keys
exp
[
1
]
exp
.
clear
keys
.
each_with_index
do
|
e
,
i
|
exp
[
i
]
=
e
end
end
exp
end
#Returns an array Sexp containing the keys from the hash
def
get_keys
hash
keys
=
Sexp
.
new
(
:array
)
hash_iterate
(
hash
)
do
|
key
,
value
|
keys
<<
key
end
keys
end
if
OPTIONS
[
:rails3
]
require
'processors/lib/rails3_route_processor'
else
require
'processors/lib/rails2_route_processor'
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录