watnow 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +93 -0
- data/Rakefile +2 -0
- data/bin/watnow +7 -0
- data/lib/watnow/annotation/annotation.rb +41 -0
- data/lib/watnow/annotation/annotation_line.rb +54 -0
- data/lib/watnow/config.rb +51 -0
- data/lib/watnow/option_parser.rb +53 -0
- data/lib/watnow/version.rb +3 -0
- data/lib/watnow.rb +171 -0
- data/watnow.gemspec +20 -0
- metadata +75 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Etienne Lemay
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Watnow
|
2
|
+
|
3
|
+
<b>Watnow</b> finds and lists your project TODOs and FIXMEs.<br>
|
4
|
+
It basically does what the Rails’ `rake notes` does, but in a more generic way.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
```sh
|
8
|
+
$ gem install watnow
|
9
|
+
```
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
```sh
|
14
|
+
$ watnow
|
15
|
+
```
|
16
|
+
|
17
|
+
### Help
|
18
|
+
```sh
|
19
|
+
$ watnow --help
|
20
|
+
|
21
|
+
Usage: watnow [options]
|
22
|
+
|
23
|
+
-h, --help show this message
|
24
|
+
-v, --version display version
|
25
|
+
-d, --directory DIR directory DIR to scan (defaults: ./)
|
26
|
+
|
27
|
+
watnow commands:
|
28
|
+
open <ID> open annotation ID in your editor
|
29
|
+
remove <ID> remove annotation ID
|
30
|
+
```
|
31
|
+
|
32
|
+
## Commands
|
33
|
+
### open
|
34
|
+
Opens an annotation in your $EDITOR focused on the annotation line.
|
35
|
+
```sh
|
36
|
+
$ watnow open 13
|
37
|
+
```
|
38
|
+
|
39
|
+
### remove
|
40
|
+
Removes the annotation line from its file.<br>
|
41
|
+
(Make sure there is nothing else on that line)
|
42
|
+
```sh
|
43
|
+
$ watnow remove 13
|
44
|
+
```
|
45
|
+
|
46
|
+
## Features
|
47
|
+
### Mentions
|
48
|
+
```rb
|
49
|
+
# TODO @rafBM: Update user form
|
50
|
+
# TODO Update user controller @rafBM
|
51
|
+
```
|
52
|
+
```sh
|
53
|
+
[ 2 ] TODO: Update user form [ @rafBM ]
|
54
|
+
[ 1 ] TODO: Update user controller [ @rafBM ]
|
55
|
+
```
|
56
|
+
|
57
|
+
### Priority
|
58
|
+
Exclamation mark (!) preceded by a whitespace. (`/\s(!+)\s?/`)
|
59
|
+
|
60
|
+
```rb
|
61
|
+
# TODO !!!: This is level 3 urgent
|
62
|
+
# TODO @rafBM: Just do it !
|
63
|
+
# TODO: This is not a priority!!
|
64
|
+
# TODO !!!!!!!!!!!!! @EtienneLem: This is a nicolas-cage-level urgent task
|
65
|
+
```
|
66
|
+
```sh
|
67
|
+
[ 3 ] TODO: This is not a priority!!
|
68
|
+
[ 2 ] TODO: Just do it [ @rafBM - ! ]
|
69
|
+
[ 1 ] TODO: This is level 3 urgent [ !!! ]
|
70
|
+
[ 4 ] TODO: This is a nicolas-cage-level urgent task [ @EtienneLem - !!!!!!!!!!!!! ]
|
71
|
+
```
|
72
|
+
|
73
|
+
### Super color-friendly
|
74
|
+
(Seriously, I’m open to color suggestions…)
|
75
|
+

|
76
|
+
|
77
|
+
## Watnow config
|
78
|
+
Override defaults in `~/.watnowconfig`. Supported options are:
|
79
|
+
```
|
80
|
+
username (String) | A username so that you can be mentioned in TODOs | Default: ''
|
81
|
+
color (Boolean) | Enable/disable colored output | Default: true
|
82
|
+
patterns (Array) | An array of string/regex that you want to monitor | Default: []
|
83
|
+
```
|
84
|
+
|
85
|
+
Use YAML syntax:
|
86
|
+
```
|
87
|
+
username: EtienneLem
|
88
|
+
color: false
|
89
|
+
patterns: [potato, ba(na)+]
|
90
|
+
```
|
91
|
+
|
92
|
+
## Contribution
|
93
|
+
My Ruby skills are far from exemplary, please teach me.
|
data/Rakefile
ADDED
data/bin/watnow
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Watnow
|
2
|
+
# An Annotation is basically a group of AnnotationLine
|
3
|
+
class Annotation
|
4
|
+
|
5
|
+
@@id = 0
|
6
|
+
@@instances = []
|
7
|
+
|
8
|
+
attr_accessor :id, :file, :lines, :priority
|
9
|
+
|
10
|
+
# An ORM-like method that returns all Annotation instances
|
11
|
+
def self.all
|
12
|
+
@@instances
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(opts)
|
16
|
+
@priority = 0
|
17
|
+
@file = opts[:file]
|
18
|
+
@lines = set_lines(opts[:lines])
|
19
|
+
|
20
|
+
# Auto increment instances id
|
21
|
+
# Push instance into a class array
|
22
|
+
@id = @@id += 1
|
23
|
+
@@instances << self
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Loop through lines data and create AnnotationLine instance
|
29
|
+
# Send self so that an AnnotationLine knows its Annotation and vice versa
|
30
|
+
def set_lines(lines)
|
31
|
+
results = []
|
32
|
+
|
33
|
+
lines.each do |line|
|
34
|
+
results << AnnotationLine.new(line, self)
|
35
|
+
end
|
36
|
+
|
37
|
+
results
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Watnow
|
2
|
+
class AnnotationLine
|
3
|
+
|
4
|
+
@@id = 0
|
5
|
+
@@instances = []
|
6
|
+
@@tag_length = 0
|
7
|
+
|
8
|
+
attr_accessor :id, :lineno, :tag, :priority, :mention, :message, :annotation
|
9
|
+
|
10
|
+
# An ORM-like find method that returns an AnnotationLine instance
|
11
|
+
def self.find(id)
|
12
|
+
@@instances.each do |instance|
|
13
|
+
return instance if instance.id == id
|
14
|
+
end
|
15
|
+
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns longest tag length
|
20
|
+
# Used to format output
|
21
|
+
def self.tag_length
|
22
|
+
@@tag_length
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(opts, annotation)
|
26
|
+
@lineno = opts[:lineno]
|
27
|
+
@tag = opts[:tag]
|
28
|
+
@priority = opts[:priority] || 0
|
29
|
+
@mention = opts[:mention] || ''
|
30
|
+
@message = opts[:message]
|
31
|
+
@annotation = annotation
|
32
|
+
|
33
|
+
@annotation.priority = @priority if @priority > @annotation.priority
|
34
|
+
|
35
|
+
# Auto increment instances id
|
36
|
+
# Push instance into a class array
|
37
|
+
@id = @@id += 1
|
38
|
+
@@instances << self
|
39
|
+
|
40
|
+
# Update class’ tag_length to the longest tag
|
41
|
+
@@tag_length = @tag.length if @tag.length > @@tag_length
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an array of "meta data"
|
45
|
+
# Namely: The AnnotationLine mention and priority
|
46
|
+
def meta_data
|
47
|
+
data = []
|
48
|
+
data << "@#{@mention}" unless @mention.empty?
|
49
|
+
data << Array.new(@priority + 1).join('!') if @priority > 0
|
50
|
+
data
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Watnow::Config
|
4
|
+
|
5
|
+
# Default constants
|
6
|
+
FOLDER_IGNORE = %w(tmp node_modules db public log)
|
7
|
+
FILE_EXTENSION_IGNORE = %w(tmproj markdown md txt)
|
8
|
+
PATTERNS = %w(TODO FIXME)
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
defaults = {
|
12
|
+
'color' => true,
|
13
|
+
'folder_ignore' => [],
|
14
|
+
'file_extension_ignore' => [],
|
15
|
+
'patterns' => [],
|
16
|
+
'username' => ''
|
17
|
+
}
|
18
|
+
|
19
|
+
# Parse YAML config file (~/.watnowconfig)
|
20
|
+
parser = YamlParser.new
|
21
|
+
custom_options = parser.parse
|
22
|
+
|
23
|
+
# Merge defaults with custom options
|
24
|
+
# Add default constants
|
25
|
+
options = defaults.merge(custom_options)
|
26
|
+
options['folder_ignore'].concat(FOLDER_IGNORE)
|
27
|
+
options['file_extension_ignore'].concat(FILE_EXTENSION_IGNORE)
|
28
|
+
options['patterns'].concat(PATTERNS)
|
29
|
+
|
30
|
+
# Generate singleton methods with options keys for quick access
|
31
|
+
# i.e. self.color, self.patterns, self.username, etc
|
32
|
+
options.each do |option|
|
33
|
+
define_singleton_method option[0] do
|
34
|
+
option[1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Simple YAML parser
|
40
|
+
# Returns empty object if no file found
|
41
|
+
class YamlParser
|
42
|
+
def parse
|
43
|
+
begin
|
44
|
+
YAML.load_file("#{ENV['HOME']}/.watnowconfig")
|
45
|
+
rescue
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Watnow
|
4
|
+
# Home made Option parser built on top of Ruby’s optparse
|
5
|
+
class OptParser
|
6
|
+
|
7
|
+
def self.parse(args)
|
8
|
+
# Defaults
|
9
|
+
options = {}
|
10
|
+
options[:directory] = '.'
|
11
|
+
|
12
|
+
opts = OptionParser.new('', 24, ' ') do |opts|
|
13
|
+
opts.separator ' Usage: watnow [options]'
|
14
|
+
opts.separator ''
|
15
|
+
|
16
|
+
# Help
|
17
|
+
opts.on('-h', '--help', 'show this message') do
|
18
|
+
puts opts
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
# Version
|
23
|
+
opts.on('-v', '--version', 'display version') do
|
24
|
+
puts VERSION
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
# Directory
|
29
|
+
opts.on('-d', '--directory DIR', 'directory DIR to scan (defaults: ./)') do |d|
|
30
|
+
options[:directory] = d
|
31
|
+
end
|
32
|
+
|
33
|
+
# Commands
|
34
|
+
opts.separator ''
|
35
|
+
opts.separator ' watnow commands:'
|
36
|
+
opts.separator ' open <ID> open annotation ID in your editor'
|
37
|
+
opts.separator ' remove <ID> remove annotation ID'
|
38
|
+
|
39
|
+
options[:open] = get_option_value('open', args)
|
40
|
+
options[:remove] = get_option_value('remove', args)
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.parse!(args)
|
45
|
+
options
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.get_option_value(option, args)
|
49
|
+
args.include?(option) ? args[args.index(option) + 1] : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/watnow.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'watnow/version'
|
2
|
+
require 'watnow/config'
|
3
|
+
require 'watnow/option_parser'
|
4
|
+
require 'watnow/annotation/annotation'
|
5
|
+
require 'watnow/annotation/annotation_line'
|
6
|
+
require 'colored'
|
7
|
+
|
8
|
+
module Watnow
|
9
|
+
class Extractor
|
10
|
+
include Watnow::Config
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
# Parse options and scan given directory
|
14
|
+
options = OptParser.parse(ARGV)
|
15
|
+
scan(options[:directory])
|
16
|
+
|
17
|
+
# If open command is parsed (`watnow open 13`)
|
18
|
+
if options[:open]
|
19
|
+
id = Integer(options[:open])
|
20
|
+
annotation_line = AnnotationLine.find(id)
|
21
|
+
open_file_at_line(annotation_line.annotation.file, annotation_line.lineno)
|
22
|
+
|
23
|
+
# If remove command is parsed (`watnow remove 13`)
|
24
|
+
elsif options[:remove]
|
25
|
+
id = Integer(options[:remove])
|
26
|
+
annotation_line = AnnotationLine.find(id)
|
27
|
+
remove_line_of_file(annotation_line.annotation.file, annotation_line.lineno)
|
28
|
+
|
29
|
+
# No specific command parsed. Output the annotations list
|
30
|
+
else
|
31
|
+
output(Annotation.all)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Recursively scan given directory
|
38
|
+
# Ignore folders and files from Config
|
39
|
+
# Create a new Annotation when data si found
|
40
|
+
def scan(dir, annotations=[])
|
41
|
+
Dir.glob("#{dir}/*") do |path|
|
42
|
+
next if File.basename(path) =~ /(#{Config.folder_ignore.join('|')})$/
|
43
|
+
|
44
|
+
if File.directory? path
|
45
|
+
scan(path, annotations)
|
46
|
+
else
|
47
|
+
begin
|
48
|
+
next if File.extname(path) =~ /(#{Config.file_extension_ignore.join('|')})$/
|
49
|
+
content = read_file(path, /(#{Config.patterns.join('|')})/i)
|
50
|
+
Annotation.new(content) if content
|
51
|
+
rescue
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Read a file line by line and look for given patterns
|
59
|
+
def read_file(file, patterns)
|
60
|
+
lineno = 0
|
61
|
+
|
62
|
+
result = File.readlines(file).inject([]) do |list, line|
|
63
|
+
lineno += 1
|
64
|
+
next list unless line =~ patterns
|
65
|
+
|
66
|
+
# Pattern is found, save the tag
|
67
|
+
tag = line.slice!($1)
|
68
|
+
|
69
|
+
# Look for priority
|
70
|
+
# Exclamation mark (!) preceded by a whitespace
|
71
|
+
priority = line.slice!(/\s(!+)\s?/)
|
72
|
+
priority = $1 ? $1.length : 0
|
73
|
+
|
74
|
+
# Look for mention
|
75
|
+
# Any word character preceded by @
|
76
|
+
mention = line.slice!(/\s@(\w+)\s*/)
|
77
|
+
mention = $1
|
78
|
+
|
79
|
+
# We assume the message starts with any word character
|
80
|
+
message = line.slice!(/(\w.*)/)
|
81
|
+
message = $1
|
82
|
+
|
83
|
+
# Push data into result
|
84
|
+
# Remove closing comment characters that we didn’t extract from regexs
|
85
|
+
list << {
|
86
|
+
:lineno => lineno,
|
87
|
+
:tag => tag,
|
88
|
+
:priority => priority,
|
89
|
+
:mention => mention,
|
90
|
+
:message => message.gsub(/\s*(\*\/|-->|%>)$/, '')
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns content that is sent to Annotation
|
95
|
+
result.empty? ? nil : { :file => file, :lines => result }
|
96
|
+
end
|
97
|
+
|
98
|
+
# Open a file with the user’s $EDITOR
|
99
|
+
# Automatically focus the annotation line number
|
100
|
+
# Supported editors are TextMate, Vim & Sublime Text
|
101
|
+
def open_file_at_line(filename, line)
|
102
|
+
command = filename
|
103
|
+
|
104
|
+
if ENV['EDITOR'] =~ /mate/
|
105
|
+
command = "#{filename} --line #{line}"
|
106
|
+
elsif ENV['EDITOR'] =~ /vi|vim/
|
107
|
+
command = "+#{line} #{filename}"
|
108
|
+
elsif ENV['EDITOR'] =~ /subl/
|
109
|
+
command = "#{filename}:#{line}"
|
110
|
+
end
|
111
|
+
|
112
|
+
Kernel.system("$EDITOR #{command}")
|
113
|
+
end
|
114
|
+
|
115
|
+
# Remove line from given file
|
116
|
+
def remove_line_of_file(filename, line)
|
117
|
+
file = File.readlines(filename)
|
118
|
+
file.delete_at(line - 1)
|
119
|
+
File.open(filename, 'w+') {|f| f.write file.join() }
|
120
|
+
end
|
121
|
+
|
122
|
+
def output(annotations)
|
123
|
+
# Sort annotations (file) by priority then by id
|
124
|
+
annotations.sort_by! { |a| [a.priority, -a.id] }
|
125
|
+
|
126
|
+
annotations.each do |annotation|
|
127
|
+
# Remove './' prefix in filenames
|
128
|
+
filename = annotation.file.gsub(/^\.\//, '')
|
129
|
+
|
130
|
+
# Display the filename
|
131
|
+
display_line "\n#{filename}", 'magenta'
|
132
|
+
|
133
|
+
# Sort annotation lines by priority DESC
|
134
|
+
# Higher priority is lower in the list
|
135
|
+
annotation.lines.sort! { |a,b| a.priority <=> b.priority }
|
136
|
+
annotation.lines.each do |annotation_line|
|
137
|
+
# Make sure all tags use the same (white)space
|
138
|
+
tag_spaces_count = AnnotationLine.tag_length - annotation_line.tag.length
|
139
|
+
tag_spaces = Array.new(tag_spaces_count + 1).join(' ')
|
140
|
+
|
141
|
+
# Boolean. True if current user is being mentioned in the annotation line
|
142
|
+
is_mentioned = (annotation_line.mention.downcase == Config.username.downcase)
|
143
|
+
|
144
|
+
# The actual outputting
|
145
|
+
display_text '[ ', 'green', is_mentioned
|
146
|
+
display_text annotation_line.id, 'cyan'
|
147
|
+
display_text " ] #{' ' if annotation_line.id < 10}", 'green', is_mentioned
|
148
|
+
display_text "#{annotation_line.tag}: #{tag_spaces}#{annotation_line.message}", 'green', is_mentioned
|
149
|
+
if annotation_line.meta_data.size > 0
|
150
|
+
display_text ' [ ', 'green', is_mentioned
|
151
|
+
display_text annotation_line.meta_data.join(' - '), 'cyan'
|
152
|
+
display_text ' ]', 'green', is_mentioned
|
153
|
+
end
|
154
|
+
display_line ""
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# display_text followed by a newline
|
160
|
+
def display_line(msg, color=nil, color_condition=true)
|
161
|
+
display_text "#{msg}\n", color, color_condition
|
162
|
+
end
|
163
|
+
|
164
|
+
# Output helper. Print text in color if color_condition is truthy
|
165
|
+
def display_text(msg, color=nil, color_condition=true)
|
166
|
+
output = color && color_condition && Config.color ? "#{msg}".send(color) : msg
|
167
|
+
STDOUT.write "#{output}"
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
data/watnow.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/watnow/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Etienne Lemay"]
|
6
|
+
gem.email = ["etienne@heliom.ca"]
|
7
|
+
gem.homepage = "https://github.com/etiennelem/watnow"
|
8
|
+
|
9
|
+
gem.description = "Watnow finds and lists your project todo and fixme"
|
10
|
+
gem.summary = gem.description
|
11
|
+
gem.version = Watnow::VERSION
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split($\)
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.name = "watnow"
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.add_dependency("colored", "~> 1.2")
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: watnow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Etienne Lemay
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: colored
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.2'
|
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: '1.2'
|
30
|
+
description: Watnow finds and lists your project todo and fixme
|
31
|
+
email:
|
32
|
+
- etienne@heliom.ca
|
33
|
+
executables:
|
34
|
+
- watnow
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- Gemfile
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- bin/watnow
|
44
|
+
- lib/watnow.rb
|
45
|
+
- lib/watnow/annotation/annotation.rb
|
46
|
+
- lib/watnow/annotation/annotation_line.rb
|
47
|
+
- lib/watnow/config.rb
|
48
|
+
- lib/watnow/option_parser.rb
|
49
|
+
- lib/watnow/version.rb
|
50
|
+
- watnow.gemspec
|
51
|
+
homepage: https://github.com/etiennelem/watnow
|
52
|
+
licenses: []
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.8.23
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Watnow finds and lists your project todo and fixme
|
75
|
+
test_files: []
|