Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Public Api for Register New Extensions for Rake Notes #14379

Merged
merged 8 commits into from Mar 17, 2014
8 changes: 7 additions & 1 deletion guides/source/command_line.md
Expand Up @@ -411,7 +411,7 @@ The `doc:` namespace has the tools to generate documentation for your app, API d

### `notes`

`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.erb`, `.haml`, `.slim`, `.css`, `.scss`, `.js`, `.coffee`, `.rake`, `.sass` and `.less` for both default and custom annotations.
`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.rake`, `.yml`, `.yaml`, `.ruby`, `.css`, `.js` and `.erb` for both default and custom annotations.

```bash
$ rake notes
Expand All @@ -425,6 +425,12 @@ app/models/school.rb:
* [ 17] [FIXME]
```

You can add support for new file extensions using `config.annotations.register_extensions` option, which receives a list of the extensions with its corresponding regex to match it up.

```ruby
config.annotations.register_extensions("scss", "sass", "less") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ }
```

If you are looking for a specific annotation, say FIXME, you can use `rake notes:fixme`. Note that you have to lower case the annotation's name.

```bash
Expand Down
8 changes: 8 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,11 @@
* Add public API to register new extensions for `rake notes`.

Example:

config.annotations.register_extensions("scss", "sass") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }

*Roberto Miranda*

* Removed unnecessary `rails application` command.

*Arun Agrawal*
Expand Down
4 changes: 4 additions & 0 deletions railties/lib/rails/application/configuration.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/kernel/reporting'
require 'active_support/file_update_checker'
require 'rails/engine/configuration'
require 'rails/source_annotation_extractor'

module Rails
class Application
Expand Down Expand Up @@ -149,6 +150,9 @@ def session_store(*args)
end
end

def annotations
SourceAnnotationExtractor::Annotation
end
end
end
end
37 changes: 22 additions & 15 deletions railties/lib/rails/source_annotation_extractor.rb
Expand Up @@ -18,6 +18,20 @@ def self.directories
@@directories ||= %w(app config db lib test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',')
end

def self.extensions
@@extensions ||= {}
end

# Registers new Annotations File Extensions
# SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
def self.register_extensions(*exts, &block)
extensions[/\.(#{exts.join("|")})$/] = block
end

register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }

# Returns a representation of the annotation that looks like this:
#
# [126] [TODO] This algorithm is simple and clearly correct, make it faster.
Expand Down Expand Up @@ -78,21 +92,14 @@ def find_in(dir)
if File.directory?(item)
results.update(find_in(item))
else
pattern =
case item
when /\.(builder|rb|coffee|rake)$/
/#\s*(#{tag}):?\s*(.*)$/
when /\.(css|scss|sass|less|js)$/
/\/\/\s*(#{tag}):?\s*(.*)$/
when /\.erb$/
/<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/
when /\.haml$/
/-\s*#\s*(#{tag}):?\s*(.*)$/
when /\.slim$/
/\/\s*\s*(#{tag}):?\s*(.*)$/
else nil
end
results.update(extract_annotations_from(item, pattern)) if pattern
extension = Annotation.extensions.detect do |regexp, _block|
regexp.match(item)
end

if extension
pattern = extension.last.call(tag)
results.update(extract_annotations_from(item, pattern)) if pattern
end
end
end

Expand Down
10 changes: 10 additions & 0 deletions railties/test/application/configuration_test.rb
Expand Up @@ -793,5 +793,15 @@ def index

assert ActiveRecord::Base.dump_schema_after_migration
end

test "config.annotations wrapping SourceAnnotationExtractor::Annotation class" do
make_basic_app do |app|
app.config.annotations.register_extensions("coffee") do |tag|
/#\s*(#{tag}):?\s*(.*)$/
end
end

assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/]
end
end
end
44 changes: 30 additions & 14 deletions railties/test/application/rake/notes_test.rb
@@ -1,4 +1,5 @@
require "isolation/abstract_unit"
require 'rails/source_annotation_extractor'

module ApplicationTests
module RakeTests
Expand All @@ -18,17 +19,14 @@ def teardown

test 'notes finds notes for certain file_types' do
app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>"
app_file "app/views/home/index.html.haml", "-# TODO: note in haml"
app_file "app/views/home/index.html.slim", "/ TODO: note in slim"
app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee"
app_file "app/assets/javascripts/application.js", "// TODO: note in js"
app_file "app/assets/stylesheets/application.css", "// TODO: note in css"
app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss"
app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass"
app_file "app/assets/stylesheets/application.css.less", "// TODO: note in less"
app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby"
app_file "lib/tasks/task.rake", "# TODO: note in rake"
app_file 'app/views/home/index.html.builder', '# TODO: note in builder'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep scss and sass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, this will be sass-rails job.

app_file 'config/locales/en.yml', '# TODO: note in yml'
app_file 'config/locales/en.yaml', '# TODO: note in yaml'
app_file "app/views/home/index.ruby", "# TODO: note in ruby"

boot_rails
require 'rake'
Expand All @@ -42,19 +40,15 @@ def teardown
lines = output.scan(/\[([0-9\s]+)\](\s)/)

assert_match(/note in erb/, output)
assert_match(/note in haml/, output)
assert_match(/note in slim/, output)
assert_match(/note in ruby/, output)
assert_match(/note in coffee/, output)
assert_match(/note in js/, output)
assert_match(/note in css/, output)
assert_match(/note in scss/, output)
assert_match(/note in sass/, output)
assert_match(/note in less/, output)
assert_match(/note in rake/, output)
assert_match(/note in builder/, output)
assert_match(/note in yml/, output)
assert_match(/note in yaml/, output)
assert_match(/note in ruby/, output)

assert_equal 12, lines.size
assert_equal 9, lines.size

lines.each do |line|
assert_equal 4, line[0].size
Expand Down Expand Up @@ -175,6 +169,28 @@ def teardown
end
end

test 'register a new extension' do
add_to_config %q{ config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } }
app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss"
app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass"

boot_rails

require 'rake'
require 'rdoc/task'
require 'rake/testtask'

Rails.application.load_tasks

Dir.chdir(app_path) do
output = `bundle exec rake notes`
lines = output.scan(/\[([0-9\s]+)\]/).flatten
assert_match(/note in scss/, output)
assert_match(/note in sass/, output)
assert_equal 2, lines.size
end
end

private
def boot_rails
super
Expand Down