rake-notes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake-notes.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Fabio Rehm
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,36 @@
1
+ # rake-notes
2
+
3
+ `rake notes` task for non-Rails' projects (heavily based on Rails' one ;)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rake-notes'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rake-notes
18
+
19
+ And add this line to your project's Rakefile:
20
+
21
+ require 'rake/notes/rake_task'
22
+
23
+
24
+ ## Acknowledgement
25
+
26
+ Special thanks to everyone that contributed to the original
27
+ [Rails' code](https://github.com/rails/rails/blob/master/railties/lib/rails/source_annotation_extractor.rb)
28
+
29
+
30
+ ## Contributing
31
+
32
+ 1. Fork it
33
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
34
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
35
+ 4. Push to the branch (`git push origin my-new-feature`)
36
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:test)
5
+
6
+ task :default => [:test]
@@ -0,0 +1,3 @@
1
+ require 'rake/notes/version'
2
+
3
+ # Nothing to see here, see rake_task.rb
@@ -0,0 +1,37 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ require 'rake/notes/source_annotation_extractor'
5
+
6
+ module Rake
7
+ module Notes
8
+ class RakeTask < ::Rake::TaskLib
9
+ include ::Rake::DSL if defined?(::Rake::DSL)
10
+
11
+ def initialize(*args)
12
+ yield self if block_given?
13
+
14
+ desc "Enumerate all annotations (use notes:optimize, :fixme, :todo for focus)"
15
+ task :notes do
16
+ SourceAnnotationExtractor.enumerate "OPTIMIZE|FIXME|TODO", :tag => true
17
+ end
18
+
19
+ namespace :notes do
20
+ ["OPTIMIZE", "FIXME", "TODO"].each do |annotation|
21
+ desc "Enumerate all #{annotation} annotations"
22
+ task annotation.downcase.intern do
23
+ SourceAnnotationExtractor.enumerate annotation
24
+ end
25
+ end
26
+
27
+ desc "Enumerate a custom annotation, specify with ANNOTATION=CUSTOM"
28
+ task :custom do
29
+ SourceAnnotationExtractor.enumerate ENV['ANNOTATION']
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ Rake::Notes::RakeTask.new
@@ -0,0 +1,113 @@
1
+ module Rake
2
+ module Notes
3
+ # From:
4
+ # https://github.com/rails/rails/blob/master/railties/lib/rails/source_annotation_extractor.rb
5
+ #
6
+ # Implements the logic behind the rake tasks for annotations like
7
+ #
8
+ # rake notes
9
+ # rake notes:optimize
10
+ #
11
+ # and friends. See <tt>rake -T notes</tt>.
12
+ #
13
+ # Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
14
+ # represent the line where the annotation lives, its tag, and its text. Note
15
+ # the filename is not stored.
16
+ #
17
+ # Annotations are looked for in comments and modulus whitespace they have to
18
+ # start with the tag optionally followed by a colon. Everything up to the end
19
+ # of the line (or closing ERB comment tag) is considered to be their text.
20
+ class SourceAnnotationExtractor
21
+ RUBYFILES = %w( Vagrantfile Rakefile Puppetfile Gemfile )
22
+
23
+ class Annotation < Struct.new(:line, :tag, :text)
24
+ # Returns a representation of the annotation that looks like this:
25
+ #
26
+ # [126] [TODO] This algorithm is simple and clearly correct, make it faster.
27
+ #
28
+ # If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above.
29
+ # Otherwise the string contains just line and text.
30
+ def to_s(options={})
31
+ s = "[#{line.to_s.rjust(options[:indent])}] "
32
+ s << "[#{tag}] " if options[:tag]
33
+ s << text
34
+ end
35
+ end
36
+
37
+ # Prints all annotations with tag +tag+ under the current directory. Only
38
+ # known file types are taken into account. The +options+ hash is passed
39
+ # to each annotation's +to_s+.
40
+ #
41
+ # This class method is the single entry point for the rake tasks.
42
+ def self.enumerate(tag, options={})
43
+ extractor = new(tag)
44
+ extractor.display(extractor.find, options)
45
+ end
46
+
47
+ attr_reader :tag
48
+
49
+ def initialize(tag)
50
+ @tag = tag
51
+ end
52
+
53
+ # Returns a hash that maps filenames to arrays with their annotations.
54
+ def find
55
+ find_in('.')
56
+ end
57
+
58
+ # Returns a hash that maps filenames under +dir+ (recursively) to arrays
59
+ # with their annotations. Only files with annotations are included, and only
60
+ # known file types are taken into account.
61
+ def find_in(dir)
62
+ results = {}
63
+
64
+ Dir.glob("#{dir}/*") do |item|
65
+ next if File.basename(item)[0] == ?.
66
+
67
+ if File.directory?(item)
68
+ results.update(find_in(item))
69
+ elsif item =~ /\.(builder|rb|coffee|rake|pp|ya?ml|gemspec)$/ || RUBYFILES.include?(File.basename(item))
70
+ results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/))
71
+ elsif item =~ /\.(css|scss|js)$/
72
+ results.update(extract_annotations_from(item, /\/\/\s*(#{tag}):?\s*(.*)$/))
73
+ elsif item =~ /\.erb$/
74
+ results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/))
75
+ elsif item =~ /\.haml$/
76
+ results.update(extract_annotations_from(item, /-\s*#\s*(#{tag}):?\s*(.*)$/))
77
+ elsif item =~ /\.slim$/
78
+ results.update(extract_annotations_from(item, /\/\s*\s*(#{tag}):?\s*(.*)$/))
79
+ end
80
+ end
81
+
82
+ results
83
+ end
84
+
85
+ # If +file+ is the filename of a file that contains annotations this method returns
86
+ # a hash with a single entry that maps +file+ to an array of its annotations.
87
+ # Otherwise it returns an empty hash.
88
+ def extract_annotations_from(file, pattern)
89
+ lineno = 0
90
+ result = File.readlines(file).inject([]) do |list, line|
91
+ lineno += 1
92
+ next list unless line =~ pattern
93
+ list << Annotation.new(lineno, $1, $2)
94
+ end
95
+ result.empty? ? {} : { file => result }
96
+ end
97
+
98
+ # Prints the mapping from filenames to annotations in +results+ ordered by filename.
99
+ # The +options+ hash is passed to each annotation's +to_s+.
100
+ def display(results, options={})
101
+ options[:indent] = results.map { |f, a| a.map(&:line) }.flatten.max.to_s.size
102
+ out = options.delete(:out) || $stdout
103
+ results.keys.sort.each do |file|
104
+ out.puts "#{file[2..-1]}:"
105
+ results[file].each do |note|
106
+ out.puts " * #{note.to_s(options)}"
107
+ end
108
+ out.puts
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,5 @@
1
+ module Rake
2
+ module Notes
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rake/notes/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "rake-notes"
8
+ gem.version = Rake::Notes::VERSION
9
+ gem.authors = ["Fabio Rehm"]
10
+ gem.email = ["fgrehm@gmail.com"]
11
+ gem.description = "rake notes task for non-Rails' projects"
12
+ gem.summary = "rake notes task for non-Rails' projects"
13
+ gem.homepage = "https://github.com/fgrehm/rake-notes"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'rake'
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rake/notes/source_annotation_extractor'
4
+
5
+ describe Rake::Notes::SourceAnnotationExtractor do
6
+ let(:fixture_path) { "#{Dir.pwd}/.tmp" }
7
+
8
+ before do
9
+ @current_path = Dir.pwd
10
+ Dir.mkdir(fixture_path) unless Dir.exist?(fixture_path)
11
+ Dir.chdir(fixture_path)
12
+ end
13
+
14
+ after do
15
+ Dir.chdir(@current_path)
16
+ end
17
+
18
+ context 'extracting notes based on file type' do
19
+ subject do
20
+ subj = StringIO.new
21
+ described_class.enumerate('TODO', :out => subj)
22
+ subj.string
23
+ end
24
+
25
+ before(:all) do
26
+ fixture_file "index.html.erb", "<% # TODO: note in erb %>"
27
+ fixture_file "index.html.haml", "- # TODO: note in haml"
28
+ fixture_file "index.html.slim", "/ TODO: note in slim"
29
+ fixture_file "application.js.coffee", "# TODO: note in coffee"
30
+ fixture_file "application.js", "// TODO: note in js"
31
+ fixture_file "application.css", "// TODO: note in css"
32
+ fixture_file "application.css.scss", "// TODO: note in scss"
33
+ fixture_file "application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby"
34
+ fixture_file "task.rake", "# TODO: note in rake"
35
+ fixture_file "init.pp", "# TODO: note in puppet"
36
+ fixture_file "config.yml", "# TODO: note in yml"
37
+ fixture_file "config.yaml", "# TODO: note in yaml"
38
+ fixture_file "gem.gemspec", "# TODO: note in gemspec"
39
+ fixture_file "Vagrantfile", "# TODO: note in vagrantfile"
40
+ fixture_file "Rakefile", "# TODO: note in rakefile"
41
+ fixture_file "Puppetfile", "# TODO: note in puppetfile"
42
+ fixture_file "Gemfile", "# TODO: note in gemfile"
43
+ end
44
+
45
+ it { should match(/note in erb/) }
46
+ it { should match(/note in haml/) }
47
+ it { should match(/note in slim/) }
48
+ it { should match(/note in ruby/) }
49
+ it { should match(/note in coffee/) }
50
+ it { should match(/note in js/) }
51
+ it { should match(/note in css/) }
52
+ it { should match(/note in scss/) }
53
+ it { should match(/note in rake/) }
54
+ it { should match(/note in puppet/) }
55
+ it { should match(/note in yml/) }
56
+ it { should match(/note in yaml/) }
57
+ it { should match(/note in gemspec/) }
58
+ it { should match(/note in vagrantfile/) }
59
+ it { should match(/note in rakefile/) }
60
+ it { should match(/note in puppetfile/) }
61
+ it { should match(/note in gemfile/) }
62
+ end
63
+
64
+ def fixture_file(path, contents)
65
+ FileUtils.mkdir_p File.dirname("#{fixture_path}/#{path}")
66
+ File.open("#{fixture_path}/#{path}", 'w') do |f|
67
+ f.puts contents
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,14 @@
1
+ require 'bundler/setup'
2
+ Bundler.require(:default)
3
+
4
+ RSpec.configure do |config|
5
+ config.treat_symbols_as_metadata_keys_with_true_values = true
6
+ config.run_all_when_everything_filtered = true
7
+ config.filter_run :focus
8
+
9
+ # Run specs in random order to surface order dependencies. If you find an
10
+ # order dependency and want to debug it, you can fix the order by providing
11
+ # the seed, which is printed after each run.
12
+ # --seed 1234
13
+ config.order = 'random'
14
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-notes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fabio Rehm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: rake notes task for non-Rails' projects
47
+ email:
48
+ - fgrehm@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - lib/rake/notes.rb
60
+ - lib/rake/notes/rake_task.rb
61
+ - lib/rake/notes/source_annotation_extractor.rb
62
+ - lib/rake/notes/version.rb
63
+ - rake-notes.gemspec
64
+ - spec/rake/notes/source_annotation_extractor_spec.rb
65
+ - spec/spec_helper.rb
66
+ homepage: https://github.com/fgrehm/rake-notes
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ segments:
79
+ - 0
80
+ hash: -2814637587116714080
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ segments:
88
+ - 0
89
+ hash: -2814637587116714080
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 1.8.23
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: rake notes task for non-Rails' projects
96
+ test_files:
97
+ - spec/rake/notes/source_annotation_extractor_spec.rb
98
+ - spec/spec_helper.rb