notes 0.1.0.pre → 0.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.
@@ -1,4 +1,10 @@
1
- == 0.1.0-pre1
1
+ == 0.1.0
2
+
3
+ * improve scanner and executable
4
+ * some compatibility fixes
5
+ * change -t option into -a
6
+
7
+ == 0.1.0-pre
2
8
 
3
9
  Complete refactoring of Notes: LESS IS MORE!
4
10
 
data/LICENSE CHANGED
@@ -1,6 +1,4 @@
1
- ----------------------------------------------------------------------------
2
1
  "THE BEER-WARE LICENSE" (Revision 42):
3
2
  <vivien@didelot.org> wrote this code. As long as you retain this notice you
4
3
  can do whatever you want with this stuff. If we meet some day, and you think
5
4
  this stuff is worth it, you can buy me a beer in return Vivien Didelot
6
- ----------------------------------------------------------------------------
@@ -0,0 +1,92 @@
1
+ = Notes
2
+
3
+ <b>Stupidly grep tags in source code.</b>
4
+
5
+ This gem provides a command line tool and a Ruby library to find tags in
6
+ source code. Defaults tags are *TODO*, *FIXME*, and *XXX*.
7
+ Custom tags can be found as well.
8
+
9
+ It's kind of a generic version of the Ruby on Rails <tt>rake notes</tt> command,
10
+ for any project/source.
11
+
12
+ == Command line tool
13
+
14
+ Usage:
15
+
16
+ $ notes [options] [file...]
17
+
18
+ With no argument, <tt>notes</tt> will search recursively in the current
19
+ directory. For details, see <tt>notes --help</tt>.
20
+
21
+ Examples:
22
+
23
+ $ notes
24
+ $ notes foo.h src/
25
+ $ notes --tag @@@
26
+ $ notes --no-{todo,fixme,xxx} --tag FOO
27
+
28
+ === Integration with Git
29
+
30
+ A cool thing to do is to add a Git alias to parse every versionned files:
31
+
32
+ $ git config --global alias.n '!git ls-files | xargs notes'
33
+
34
+ Now, running <tt>git n</tt> in any Git repository will search
35
+ notes in every files under version control!
36
+
37
+ === Convention over configuration
38
+
39
+ No custom output.
40
+
41
+ It uses a grep-style display, which makes it easy to fit your
42
+ needs. <tt>cut</tt> is great:
43
+
44
+ $ notes | cut -d: -f3,4-
45
+
46
+ will display this:
47
+
48
+ TODO: /* add a cool feature */
49
+
50
+ instead of the normal output:
51
+
52
+ foo.c:42:TODO: /* add a cool feature */
53
+
54
+ And colors will still be displayed.
55
+
56
+ Notes won't filter.
57
+
58
+ <tt>find</tt>, <tt>xargs</tt> are your friends:
59
+
60
+ $ find . -name '*.rb' | xargs notes
61
+
62
+ Or get the list of tagged files in the current directory with:
63
+
64
+ $ notes | cut -d: -f1 | sort -u
65
+
66
+ == Installation
67
+
68
+ Notes is available on Rubygems.org[http://rubygems.org/gems/notes] and
69
+ can be installed with:
70
+
71
+ $ [sudo] gem install notes
72
+
73
+ Or you can install from the source directory with:
74
+
75
+ $ rake install
76
+
77
+ == The Notes library
78
+
79
+ The Notes module provides convenient methods.
80
+
81
+ require 'notes'
82
+
83
+ Notes.scan_file("foo.c") do |note|
84
+ puts "#{note.tag} found at line #{note.line}!"
85
+ end
86
+
87
+ Notes can also extend an object to add a new method (see Notes#notes),
88
+ or allow you to create your own scanner (see the Notes::Scanner).
89
+
90
+ == License
91
+
92
+ That's free and friendly for sure! See the LICENSE file.
data/bin/notes CHANGED
@@ -1,40 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # ----------------------------------------------------------------------------
4
- # "THE BEER-WARE LICENSE" (Revision 42):
5
- # <vivien@didelot.org> wrote this file. As long as you retain this notice you
6
- # can do whatever you want with this stuff. If we meet some day, and you think
7
- # this stuff is worth it, you can buy me a beer in return Vivien Didelot
8
- # ----------------------------------------------------------------------------
9
-
3
+ require 'rubygems'
10
4
  require 'notes'
11
5
  require 'optparse'
12
6
  require 'paint'
13
7
  require 'find'
14
8
 
15
- # grep-style display
16
- def pretty_print(note, colors)
17
- col = Paint[':', :cyan]
18
- format = Paint['%s', :magenta] + col
19
- format << Paint['%s', :green] + col
20
- format << Paint['%s', colors[note.tag] || colors[:custom], :bold] + col
21
- format << "%s\n"
22
- printf(format,
23
- note.source,
24
- note.line,
25
- note.tag,
26
- note.text.rstrip)
27
- end
28
-
29
- tags = Notes::TAGS.dup
30
- colors = {
31
- "TODO" => 'green',
32
- "FIXME" => 'yellow',
33
- "XXX" => 'red',
34
- :custom => 'cyan'
35
- }
36
-
37
9
  usage = 'Usage: notes [OPTION]... [FILE]...'
10
+ tags = Notes::TAGS.dup
38
11
 
39
12
  ARGV.options do |o|
40
13
  o.version = Notes::VERSION
@@ -42,12 +15,17 @@ ARGV.options do |o|
42
15
  o.on( '--no-todo', 'Do not search TODO tags') { tags -= ['TODO'] }
43
16
  o.on( '--no-fixme', 'Do not search FIXME tags') { tags -= ['FIXME'] }
44
17
  o.on( '--no-xxx', 'Do not search XXX tags') { tags -= ['XXX'] }
45
- o.on('-t', '--tag=TAG', 'Search TAG tags') { |tag| tags |= [tag] }
18
+ o.on('-a', '--tag=TAG', 'Search TAG tags') { |tag| tags |= [tag] }
46
19
  o.on( '--no-color', 'Do not colorize ouput') { Paint.mode = 0 }
47
20
  end
48
21
 
49
22
  begin
50
23
  ARGV.options.parse!
24
+ if ARGV.empty?
25
+ paths = [Dir.pwd]
26
+ else
27
+ paths = ARGV.map { |p| File.exist? p or raise Errno::ENOENT, p ; p }
28
+ end
51
29
  rescue => e
52
30
  STDERR.puts "notes: #{e.message}"
53
31
  STDERR.puts usage
@@ -55,15 +33,23 @@ rescue => e
55
33
  exit 1
56
34
  end
57
35
 
36
+ # grep-style display
37
+ c = Paint[':', :cyan]
38
+ format = Paint['%s', :magenta] + c + Paint['%s', :green] + c + '%s' + c + "%s\n"
39
+ colors = {
40
+ 'TODO' => 'green',
41
+ 'FIXME' => 'yellow',
42
+ 'XXX' => 'red',
43
+ :custom => 'cyan'
44
+ }
45
+
58
46
  scanner = Notes::Scanner.new
59
- scanner.look_for tags
47
+ scanner.tags = tags
60
48
  scanner.on_note do |note|
61
- pretty_print(note, colors)
49
+ tag = Paint[note.tag, colors[note.tag] || colors[:custom], :bold]
50
+ printf(format, note.file, note.line, tag, note.text.rstrip)
62
51
  end
63
52
 
64
- paths = ARGV.dup
65
- paths.empty? and paths << Dir.pwd
66
-
67
53
  Find.find(*paths) do |path|
68
54
  unless paths.include? path
69
55
  Find.prune if File.basename(path).start_with? '.'
@@ -72,6 +58,8 @@ Find.find(*paths) do |path|
72
58
 
73
59
  begin
74
60
  scanner.scan_file(path)
61
+ rescue Errno::ENOENT => e
62
+ STDERR.puts "notes: #{e.message} (broken symlink?)"
75
63
  rescue => e
76
64
  STDERR.puts "notes: #{path}: #{e.message}"
77
65
  end
@@ -1,35 +1,91 @@
1
- # ------------------------------------------------------------------------------
2
- # "THE BEER-WARE LICENSE" (Revision 42):
3
- # <vivien.didelot@gmail.com> wrote this file. As long as you retain this notice
4
- # you can do whatever you want with this stuff. If we meet some day, and you
5
- # think this stuff is worth it, you can buy me a beer in return. Vivien Didelot
6
- # ------------------------------------------------------------------------------
7
-
8
1
  require 'notes/version'
9
2
  require 'notes/scanner'
10
3
 
11
4
  module Notes
12
5
 
13
6
  # Default tags to grep in source code.
7
+ # They are *TODO*, *FIXME*, and *XXX*.
14
8
  TAGS = %w[TODO FIXME XXX]
15
9
 
16
- Note = Struct.new(:tag, :text, :line, :source)
10
+ # The Note class. This is basically an object with accessors to four attributes:
11
+ # * tag: Tag the line is marked with;
12
+ # * text: The line of text containing the tag;
13
+ # * line: The line number;
14
+ # * file: The filename of the input source.
15
+ Note = Struct.new(:tag, :text, :line, :file)
17
16
 
18
- # TODO doc
17
+ # Scan a source string
18
+ #
19
+ # @example
20
+ # Notes.scan("...\nXXX fix this asap!") do |note|
21
+ # puts note.text
22
+ # end
23
+ #
24
+ # @param [String] source
25
+ # input source to scan
26
+ #
27
+ # @params [Array] tags
28
+ # tags to look for
29
+ # if nil, tags will be the defaults (TODO, FIXME, XXX)
30
+ #
31
+ # @params [Proc] block
32
+ # callback to execute when a note is found
33
+ #
34
+ # @return [Enumerator]
35
+ # an enumerator on notes when no block is given
19
36
  def self.scan(source, tags = nil, &block)
20
37
  block.nil? and return enum_for(__method__, source, tags, &block)
21
38
  scanner = Scanner.new(tags, &block)
22
39
  scanner.scan(source)
23
40
  end
24
41
 
25
- # TODO doc
42
+ # Scan a file
43
+ #
44
+ # @example
45
+ # Notes.scan_file("src/foo.c") do |note|
46
+ # puts note.text
47
+ # end
48
+ #
49
+ # Notes.scan_file("bar.hs", ['@@@']) do |note|
50
+ # puts "File to fix: #{note.file}!"
51
+ # end
52
+ #
53
+ # @param [String] filename
54
+ # name of the file to scan
55
+ #
56
+ # @params [Array] tags
57
+ # tags to look for
58
+ # if nil, tags will be the defaults (TODO, FIXME, XXX)
59
+ #
60
+ # @params [Proc] block
61
+ # callback to execute when a note is found
62
+ #
63
+ # @return [Enumerator]
64
+ # an enumerator on notes when no block is given
26
65
  def self.scan_file(file, tags = nil, &block)
27
66
  block.nil? and return enum_for(__method__, file, tags, &block)
28
67
  scanner = Scanner.new(tags, &block)
29
68
  scanner.scan_file(file)
30
69
  end
31
70
 
32
- # TODO doc
71
+ # Add a :notes method to an object
72
+ #
73
+ # @example
74
+ # file = File.new("foo.c")
75
+ # file.extend Notes
76
+ # file.notes do |note|
77
+ # puts note.text
78
+ # end
79
+ #
80
+ # @params [Array] tags
81
+ # tags to look for
82
+ # if nil, tags will be the defaults (TODO, FIXME, XXX)
83
+ #
84
+ # @params [Proc] block
85
+ # callback to execute when a note is found
86
+ #
87
+ # @return [Enumerator]
88
+ # an enumerator on notes when no block is given
33
89
  def notes(tags = nil, &block)
34
90
  block.nil? and return enum_for(__method__, tags, &block)
35
91
  scanner = Scanner.new(tags, &block)
@@ -1,45 +1,84 @@
1
1
  module Notes
2
2
  class Scanner
3
3
 
4
- attr_accessor :tags, :action
4
+ # The array of tags to look for
5
+ #
6
+ # @example
7
+ # scanner.tags << "FOO"
8
+ #
9
+ # @return [Array]
10
+ # the tags list
11
+ attr_accessor :tags
5
12
 
6
- # TODO doc
13
+ # The block to execute when a note is found
14
+ #
15
+ # @example
16
+ # scanner.callback = proc { |note| puts note.file }
17
+ #
18
+ # @see :on_note
19
+ attr_accessor :callback
20
+
21
+ # Create a new scanner
22
+ #
23
+ # @example
24
+ # scan = Notes::Scanner.new(["TODO", "@@@"]) do |note|
25
+ # puts "#{note.file} contains notes!"
26
+ # end
27
+ #
28
+ # class NotesCounter < Notes::Scanner
29
+ # attr_reader :notes
30
+ #
31
+ # def initialize tags = nil
32
+ # super(tags)
33
+ # @notes = []
34
+ # @callback = proc { |note| @notes << note }
35
+ # end
36
+ # end
7
37
  def initialize tags = nil, &block
8
38
  @tags = tags || TAGS.dup
9
- @action = block || proc { |note| tag(note) }
39
+ @callback = block
10
40
  end
11
41
 
12
- # TODO doc
13
- alias look_for tags=
14
-
15
- # TODO doc
42
+ # Define the callback to execute when a note is given
43
+ #
44
+ # @example
45
+ # scanner.on_note do |note|
46
+ # puts note.text
47
+ # end
48
+ #
49
+ # @see :callback=
16
50
  def on_note &block
17
- @action = block
51
+ @callback = block
18
52
  end
19
53
 
20
- # TODO doc
54
+ # Scan a source string
55
+ #
56
+ # @example
57
+ # scanner.scan("...//XXX urgent fix!")
21
58
  def scan source
59
+ return if tags.empty? || callback.nil?
60
+ rxp = regexp
22
61
  source.split("\n").each_with_index do |line, i|
23
- if line =~ regexp
24
- @action.call Note.new($1, line, i + 1)
62
+ if rxp =~ line
63
+ callback.call Note.new($1, line, i + 1)
25
64
  end
26
65
  end
27
66
  end
28
67
 
29
- # TODO doc
68
+ # Scan a file
69
+ #
70
+ # @example
71
+ # scanner.scan_file("foo.c")
30
72
  def scan_file path
31
- file = File.open(path, 'r')
32
- file.each_with_index do |line, i|
33
- if line =~ regexp
34
- @action.call Note.new($1, line, i + 1, path)
73
+ return if tags.empty? || callback.nil?
74
+ rxp = regexp
75
+ File.open(path, 'r') do |file|
76
+ file.each_with_index do |line, i|
77
+ if rxp =~ line
78
+ callback.call Note.new($1, line, i + 1, path)
79
+ end
35
80
  end
36
81
  end
37
- file.close
38
- end
39
-
40
- # TODO doc
41
- def tag note
42
- puts "#{note.type} on line #{note.line}: #{note.text.strip}"
43
82
  end
44
83
 
45
84
  private
@@ -1,4 +1,4 @@
1
1
  module Notes
2
- VERSION = "0.1.0.pre"
2
+ VERSION = "0.1.0"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre
5
- prerelease: 6
4
+ version: 0.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Vivien Didelot
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-09 00:00:00.000000000 Z
12
+ date: 2012-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: paint
16
- requirement: &20331680 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,12 @@ dependencies:
21
21
  version: 0.8.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *20331680
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.4
25
30
  description:
26
31
  email: vivien.didelot@gmail.com
27
32
  executables:
@@ -32,10 +37,11 @@ files:
32
37
  - lib/notes.rb
33
38
  - lib/notes/scanner.rb
34
39
  - lib/notes/version.rb
35
- - README.md
40
+ - README.rdoc
36
41
  - CHANGELOG.rdoc
37
42
  - LICENSE
38
- - bin/notes
43
+ - !binary |-
44
+ YmluL25vdGVz
39
45
  homepage:
40
46
  licenses: []
41
47
  post_install_message:
@@ -51,13 +57,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
51
57
  required_rubygems_version: !ruby/object:Gem::Requirement
52
58
  none: false
53
59
  requirements:
54
- - - ! '>'
60
+ - - ! '>='
55
61
  - !ruby/object:Gem::Version
56
- version: 1.3.1
62
+ version: '0'
57
63
  requirements: []
58
64
  rubyforge_project:
59
- rubygems_version: 1.8.15
65
+ rubygems_version: 1.8.21
60
66
  signing_key:
61
67
  specification_version: 3
62
- summary: A Ruby gem to grep tags in source files.
68
+ summary: Stupidly grep tags in source code.
63
69
  test_files: []
data/README.md DELETED
@@ -1,105 +0,0 @@
1
- # Notes
2
-
3
- grep tags in source files
4
-
5
- This gem provides a command line tool and a Ruby library to find tags in
6
- source code. Defaults tags are *TODO*, *FIXME*, and *XXX*.
7
- Custom tags can be found as well.
8
-
9
- It's kind of a generic version of the `rake notes` command,
10
- which is only available in Ruby on Rails applications.
11
-
12
- ## Command line tool
13
-
14
- Usage:
15
-
16
- $ notes [options] [file...]
17
-
18
- With no argument, `notes` will search recursively in the current
19
- directory. For details, see `notes --help`.
20
-
21
- Examples:
22
-
23
- $ notes
24
- $ notes foo.h src/
25
- $ notes --tag @@@
26
- $ notes --no-{todo,fixme,xxx} --tag FOO
27
-
28
- ### Convention over configuration
29
-
30
- Notes won't filter. `find`, `xargs` are here for you:
31
-
32
- $ find . -name '*.rb' | xargs notes
33
-
34
- No custom output. It uses a grep-style display, which makes it easy to
35
- fit your needs. Try:
36
-
37
- $ notes | cut -d: -f3,4-
38
-
39
- Or get the list of tagged files in the current directory with:
40
-
41
- $ notes | cut -d: -f1 | sort -u
42
-
43
- ## Installation
44
-
45
- Notes is available on [Rubygems.org](http://rubygems.org/gems/notes) and
46
- can be installed with:
47
-
48
- $ [sudo] gem install notes
49
-
50
- ## The Notes library
51
-
52
- Module functions:
53
-
54
- require 'notes'
55
-
56
- Notes.scan_file("foo.c") do |note|
57
- puts "#{note.tag} found at line #{note.line}!"
58
- end
59
-
60
- Notes.scan("...\nXXX: an urgent note!") do |note|
61
- putes note.text
62
- end
63
-
64
- Extending the Notes module:
65
-
66
- require 'notes'
67
-
68
- file = File.new("foo.c")
69
- file.extend Notes
70
- file.notes { |note| puts note.text }
71
-
72
- Using the Notes scanner:
73
-
74
- require 'notes'
75
-
76
- scan = Notes::Scanner.new
77
- scan.tags = Notes::TAGS + "FOO"
78
- scan.on_note do |note|
79
- puts "found!"
80
- end
81
- scan.scan_file("foo.c")
82
- scan.scan_file("bar.c")
83
-
84
- Create your own scanner:
85
-
86
- require 'notes'
87
-
88
- class Foo < Notes::Scanner
89
- attr_reader :notes
90
-
91
- def initialize tags = nil
92
- super(tags)
93
- @notes = []
94
- end
95
-
96
- # Called if no action block set. So override it.
97
- def tag note
98
- @notes << note
99
- end
100
- end
101
-
102
- License
103
- -------
104
-
105
- That's free for sure! See the LICENSE file.