PageRenderTime 47ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/r2check.rb

https://bitbucket.org/kapilnakhwa/demo-teachme
Ruby | 275 lines | 244 code | 14 blank | 17 comment | 6 complexity | fbba5cc000f7698364faa9884ff4b6b6 MD5 | raw file
  1. ## Checks pre-Rails 2.0 apps for compatibility (v1.0)
  2. # Usage - download and run while in your application root directory:
  3. #
  4. # ruby r2check.rb
  5. #
  6. # Alternative - run straight from Pastie:
  7. #
  8. # wget http://pastie.caboo.se/99900.txt?key=krcevozww61drdeza13e3a -q -O- | ruby -
  9. # (or:)
  10. # curl http://pastie.caboo.se/99900.txt?key=krcevozww61drdeza13e3a -s | ruby -
  11. #
  12. #
  13. # NOTE: this script does simple, regular expression searches. It might *not* be right at all times.
  14. # Consider this script just for informative purposes.
  15. #
  16. # Author: Mislav Marohnić
  17. # More info: http://mislav.caboo.se/rails/rails-2-0-taking-the-plunge/
  18. require 'yaml'
  19. specs = YAML::load <<YML
  20. breakpoint server:
  21. pattern: '\\bbreakpoint_server\\b'
  22. where: config
  23. info: 'The configuration option has been removed in favor of the better ruby-debug library.'
  24. gem: ruby-debug
  25. solution: 'Remove the line(s) from configuration since the setting has no effect anymore. Instead, start `script/server` with the "-u" or "--debugger" option (or "-h" to see all the options).'
  26. changeset: 6627
  27. with_scope:
  28. pattern: '[A-Z]\\w+\\.with_scope\\b'
  29. info: 'This class method has been declared private to model classes.'
  30. solution: "Don't use it directly. You can only use it internally from the model class itself."
  31. changeset: 6909
  32. singular resources:
  33. pattern: "\\\\.resource\\\\s+[:\\"'](\\w+)"
  34. eval: "File.exist?('app/controllers/' + $1 + '_controller.rb') and line !~ /:controller\\\\b/"
  35. where: routes
  36. info: "Singular resources map to pluralized controllers now (ie. map_resource(:post) maps to PostsController)."
  37. solution: "Rename your singular controller(s) to plural or use the :controller option in `map.resource` to override the controller name it maps to."
  38. changeset: 6922
  39. pagination:
  40. pattern: '[^.\\w](paginate|(?:find|count)_collection_for_pagination|pagination_links(?:_each)?)\\b'
  41. where: controllers, views
  42. changeset: 6992
  43. info: "Pagination has been extracted from Rails core."
  44. solution: "Alternative: you can replace your pagination calls with will_paginate (find it on http://rock.errtheblog.com/)."
  45. plugin: svn://errtheblog.com/svn/plugins/classic_pagination
  46. push_with_attributes:
  47. pattern: '\\.push_with_attributes\\b'
  48. info: This method on associations has been removed from Rails.
  49. solution: "If you need attributes on associations, use has_many :through."
  50. changeset: 6997
  51. find_first or find_all:
  52. pattern: '\\b(find_first|[A-Z]\\w+\\.find_all)\\b'
  53. where: models, controllers
  54. info: "AR::Base `find_first` and `find_all` class methods have been removed. (If you're in fact using `find_all` method of Enumerable, ignore this warning.)"
  55. solution: "Use `find(:first)` or `find(:all)`."
  56. changeset: 6998
  57. Hash.create_from_xml:
  58. pattern: '\\bHash.create_from_xml\\b'
  59. info: "`Hash.create_from_xml` has been renamed to `from_xml`."
  60. changeset: 7085
  61. nested resource named routes:
  62. pattern: '\\b\\w+_(new|edit)_\\w+_(url|path)\\b'
  63. where: controllers, views
  64. info: "Nested resource named routes are now prefixed by their action name."
  65. solution: "Rename your calls to such named routes from ie. 'group_new_user_path' to 'new_group_user_path'. Same applies for 'edit' paths."
  66. changeset: 7138
  67. belongs_to foreign key assumption:
  68. pattern: '\\bbelongs_to\\b.+:class_name\\b'
  69. eval: 'line !~ /:foreign_key\\b/'
  70. where: models
  71. info: "The foreign key name is no longer inferred from the explicit class name, but from the association name."
  72. solution: "Make sure the foreign key for your association is in the form of '{association_name}_id'. (See the changeset for an example)."
  73. changeset: 7188
  74. old association dependencies:
  75. pattern: ':dependent\\s*=>\\s*true|:exclusively_dependent\\b'
  76. where: models
  77. info: "Specifying dependencies in associations has a new form and the old API has been removed."
  78. solution: "Change ':dependent => true' to ':dependent => :destroy' and ':exclusively_dependent' to ':dependent => :delete_all'."
  79. changeset: 7402
  80. old render methods:
  81. pattern: '\\brender_(action|with(out)?_layout|file|text|template)\\b'
  82. where: controllers
  83. info: "The old `render_{something}` API has been removed."
  84. solution: "Change `render_action` to `render :action`, `render_text` to `render :text` (and so on) in your controllers."
  85. changeset: 7403
  86. template root:
  87. pattern: '\\btemplate_root\\b'
  88. info: "`template_root` has been dropped in favor of `view_paths` array."
  89. solution: 'Replace `template_root = "some/dir"` with `view_paths = "some/dir"`.'
  90. changeset: 7426
  91. expire matched fragments:
  92. pattern: '\\bexpire_matched_fragments\\b'
  93. where: controllers
  94. info: "`expire_matched_fragments` has been superseded by `expire_fragment`."
  95. solution: "Simply call `expire_fragment` with a regular expression."
  96. changeset: 7427
  97. expire matched fragments:
  98. pattern: '\\bkeep_flash\\b'
  99. where: controllers
  100. info: "`keep flash` has been superseded by `flash.keep`."
  101. changeset: 7428
  102. dynamic scaffold:
  103. pattern: '\\bscaffold\\b'
  104. where: controllers
  105. plugin: scaffolding
  106. info: "Dynamic scaffolding has gone the way of the dinosaurs."
  107. solution: "Don't use it. Use the 'scaffold' generator to generate scaffolding for RESTful resources."
  108. changeset: 7429
  109. image tag without extension:
  110. pattern: "\\\\bimage_tag\\s*(\\(\\s*)?('[^'.]+'|\\"[^\\".]+\\")"
  111. where: views
  112. info: ".png is no longer the default extension for images."
  113. solution: "Explicitly set the image extension when using `image_tag`: instead of just `image_tag 'logo'`, use 'logo.png'."
  114. changeset: 7432
  115. cookie:
  116. pattern: ^\\s*cookie\\b
  117. where: controllers
  118. info: "The `cookie` writer method was removed from controllers."
  119. solution: "Use `cookies[name] = value` instead."
  120. changeset: 7434
  121. javascript in-place editor:
  122. pattern: \\b(in_place_editor_field|in_place_edit_for)\\b
  123. where: views, controllers
  124. plugin: in_place_editing
  125. info: "The in-place editor has been extracted from Rails core."
  126. changeset: 7442
  127. javascript autocompleter:
  128. pattern: \\b(auto_complete_field|auto_complete_for)\\b
  129. where: views, controllers
  130. plugin: auto_complete
  131. info: "The autocompleter has been extracted from Rails core."
  132. changeset: 7450
  133. acts_as_list:
  134. pattern: \\bacts_as_list\\b
  135. where: models
  136. plugin: acts_as_list
  137. info: "acts_as_list has been extracted from Rails core."
  138. changeset: 7444
  139. acts_as_nested_set:
  140. pattern: \\bacts_as_nested_set\\b
  141. where: models
  142. plugin: acts_as_nested_set
  143. info: "acts_as_nested_set has been extracted from Rails core."
  144. changeset: 7453
  145. acts_as_tree:
  146. pattern: \\bacts_as_tree\\b
  147. where: models
  148. plugin: acts_as_tree
  149. info: "acts_as_tree has been extracted from Rails core."
  150. changeset: 7454
  151. reloadable:
  152. pattern: \\binclude\\s+Reloadable\\b
  153. info: "Reloadable module is removed from Rails."
  154. solution: "Don't include the module anymore. Dependencies code is smart enough to reload classes if they're not in 'load_once' paths."
  155. changeset: 7473
  156. YML
  157. for props in specs.values
  158. next unless props['pattern']
  159. props['pattern'] = Regexp.new props['pattern']
  160. props['found'] = []
  161. end
  162. class String
  163. def word_wrap(line_width = 78)
  164. self.split("\n").collect do |line|
  165. line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
  166. end * "\n"
  167. end
  168. def camelize
  169. self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
  170. end
  171. end
  172. files = (Dir["{app,config,db/migrate,lib,test}/**/*.rb"] + Dir['app/views/**/*.{rhtml,rxml,erb,builder,haml}']).sort
  173. files -= ['config/boot.rb']
  174. plugins = Dir['vendor/plugins/*'].map{ |p| File.basename p }.sort
  175. files.each do |filename|
  176. File.open(filename).each_with_index do |line, ln|
  177. next if line =~ /^\s*#/ # skip commented lines
  178. for props in specs.values
  179. if props['where']
  180. where = props['where'].scan /\w+/
  181. next unless where.any? do |place|
  182. case place
  183. when 'controllers', 'models'
  184. filename.index("app/#{place}/") == 0
  185. when 'views'
  186. filename =~ %r[^app/(views|helpers)/]
  187. when 'routes'
  188. filename == 'config/routes.rb'
  189. else
  190. filename.index("#{place}/") == 0
  191. end
  192. end
  193. end
  194. if line =~ props['pattern'] and (props['eval'].nil? or eval(props['eval']))
  195. props['found'] << "#{filename}:#{ln + 1}: #{line.strip}"
  196. end
  197. end
  198. end
  199. end
  200. found = false
  201. for name, props in specs
  202. unless props['found'].empty?
  203. plugin = (props['plugin'] and File.basename(props['plugin']))
  204. next if plugin and (plugins.include?(plugin) or (plugin == 'classic_pagination' and plugins.include? 'will_paginate'))
  205. unless found
  206. puts(("Your application doesn't seem ready to upgrade to Rails 2.0." +
  207. " Please take a moment to review the following:").word_wrap(80))
  208. end
  209. found = true
  210. title = "-- #{name} "
  211. puts "\n" + title.ljust(80, '-')
  212. text = []
  213. text << (props['info'] + " (changeset #{props['changeset']})").word_wrap
  214. if props['gem']
  215. text << ''
  216. text << " gem install #{props['gem']}"
  217. end
  218. if props['plugin']
  219. text << ''
  220. text << " script/plugin install #{props['plugin']}"
  221. end
  222. if props['solution']
  223. text << ''
  224. text << props['solution'].word_wrap
  225. end
  226. text << ''
  227. text << "files:"
  228. text << props['found'].join("\n")
  229. puts "\n " + text.join("\n").gsub("\n", "\n ")
  230. end
  231. end
  232. unless found
  233. puts "Congratulations! Your application seems ready for Rails 2.0"
  234. end