task-list 0.2 → 0.3

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 60d92ec2193240ec457f321e2442d2bd3477b0ea
4
+ data.tar.gz: f6f89aa6e24bed0ab8877644d175fb6cd0627051
5
+ SHA512:
6
+ metadata.gz: 996b8959b3fcce9b2c2ae4920451053fc7a1a128f4401313d7896554e2ef0c8761d41158160c2ac20567adf72bddfca6303db745c860210b91d4a1685cd1254e
7
+ data.tar.gz: afdbff8b9f781a1379192a34f98ec8c5b031f0ab7f23493c4aab363551f2ba21889d810160c38e3f4edabf3c1a3b5f671306174775796f4167641e3bd3471859
data/bin/tl CHANGED
@@ -1,24 +1,28 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require "optparse"
3
4
  require_relative "../lib/task-list"
4
5
 
5
- args = []
6
- if ARGV.empty?
7
- puts "Do you want to list the tasks that are under the current directory?"
8
- print "[Yes|No] "
9
- answer = $stdin.gets.chomp
6
+ options = {}
10
7
 
11
- answer = answer.split(//)
12
- answer = answer.empty? ? [""] : [answer.fetch(0).downcase]
13
- if answer.fetch(0) == "y"
14
- args = ["."]
15
- else
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: tl [<query>] [<option> ...]"
10
+
11
+ opts.on("-t", "--type", "Type of tasks to list") do |o|
12
+ options[:type] = o
13
+ end
14
+
15
+ opts.on("-v", "--version", "Show TaskList's version") do |o|
16
+ puts "tl version #{TaskList::VERSION}"
17
+ exit
18
+ end
19
+
20
+ opts.on("-h", "--help", "Show this help message") do |o|
21
+ puts opts
16
22
  exit
17
23
  end
18
- else
19
- args = ARGV
20
- end
24
+ end.parse!
21
25
 
22
- parser = TaskList::Parser.new(*args)
23
- parser.parse
24
- parser.print
26
+ parser = TaskList::Parser.new(arguments: ARGV, options: options)
27
+ parser.parse!
28
+ parser.print!
data/lib/task-list.rb CHANGED
@@ -1,8 +1,64 @@
1
- require "yaml"
2
-
3
- require_relative "task-list/version"
4
- require_relative "task-list/parser"
1
+ require_relative "./task-list/exceptions"
2
+ require_relative "./task-list/version"
3
+ require_relative "./task-list/parser"
5
4
 
6
5
  module TaskList
7
- # Your code goes here...
6
+ EXCLUDED_EXTENSIONS = [
7
+ ".jpg",
8
+ ".jpeg",
9
+ ".png",
10
+ ".gif",
11
+ ".svg",
12
+ ".sqlite3",
13
+ ".log",
14
+ ".rbc",
15
+ ".sassc",
16
+ ".gem"
17
+ ]
18
+
19
+ EXCLUDED_DIRECTORIES = [
20
+ ".git",
21
+ "coverage",
22
+ "config",
23
+ "tmp",
24
+ "cache",
25
+ "log",
26
+ "logs"
27
+ ]
28
+
29
+ EXCLUDED_GLOBS = [
30
+ "*~",
31
+ ".DS_Store",
32
+ ".AppleDouble",
33
+ ".LSOverride",
34
+ "Icon",
35
+ "._*",
36
+ ".Spotlight-V100",
37
+ ".Trashes",
38
+ "Thumbs.db",
39
+ "ehthumbs.db",
40
+ "Desktop.ini",
41
+ "$RECYCLE.BIN/",
42
+ "*.cab",
43
+ "*.msi",
44
+ "*.msm",
45
+ "*.msp",
46
+ ".svn/",
47
+ "/CVS/*",
48
+ "*/CVS/*",
49
+ ".cvsignore",
50
+ "*/.cvsignore"
51
+ ]
52
+
53
+ VALID_TASKS = [
54
+ "TODO",
55
+ "FIXME",
56
+ "NOTE",
57
+ "BUG",
58
+ "CHANGED",
59
+ "OPTIMIZE",
60
+ "XXX",
61
+ "!!!",
62
+ "???"
63
+ ]
8
64
  end
@@ -0,0 +1,8 @@
1
+ module TaskList
2
+ module Exceptions
3
+ end
4
+ end
5
+
6
+ Dir[File.dirname(__FILE__) + "/exceptions/*.rb"].each do |file|
7
+ require file
8
+ end
@@ -0,0 +1,17 @@
1
+ module TaskList
2
+ module Exceptions
3
+ class InvalidTaskTypeError < NameError
4
+ def initialize(type: "", message: "")
5
+ if message.empty?
6
+ message = "tl: Invalid task type"
7
+
8
+ unless type.empty?
9
+ message << ": #{type}"
10
+ end
11
+ end
12
+
13
+ super message
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,159 +1,194 @@
1
+ require "find"
2
+
1
3
  module TaskList
2
4
  class Parser
3
5
  attr_reader :files, :tasks
4
6
 
5
- def initialize(*args)
6
- validate args
7
-
8
- # Get the list of files
9
- @files = collect args
10
-
11
- # Setup the absolute path to the config folder
12
- @config_folder = File.realpath(File.dirname(__FILE__) + "/../../config")
13
-
14
- # Get the list of valid tasks
15
- @valid_tasks = get_valid_tasks
16
-
17
- # Get excluded folders
18
- @excluded_folders = get_excluded_folders
19
-
20
- # Initialize the tasks hash
21
- @tasks = initialize_tasks_hash
7
+ def initialize(arguments: [], options: {})
8
+ @type = options[:type].upcase if options[:type]
9
+ # @files = fuzzy_find_files queries: arguments unless arguments.empty?
10
+ @files = fuzzy_find_files queries: arguments
11
+ @tasks = {}
12
+ VALID_TASKS.each { |t| @tasks[t.to_sym] = [] }
22
13
  end
23
14
 
24
15
  # Parse all the collected files to find tasks
25
- # and populate the @tasks hash
26
- def parse(type = nil)
27
- unless type.nil? || (type.is_a?(Symbol) && @valid_tasks.has_key?(type))
28
- raise ArgumentError
16
+ # and populate the tasks hash
17
+ def parse!
18
+ unless @type.nil? || VALID_TASKS.include?(@type)
19
+ raise TaskList::Exceptions::InvalidTaskTypeError.new type: @type
29
20
  end
30
21
 
31
- @files.each do |file|
32
- parsef file, type
33
- end
22
+ @files.each { |f| parsef! file: f }
34
23
  end
35
24
 
36
- def print
25
+ def print!
37
26
  @tasks.each do |type, tasks|
38
27
  unless tasks.empty?
39
- puts "\n#{type}:\n#{'-' * (type.length + 1)}\n"
28
+ puts "#{type}:\n#{'-' * (type.length + 1)}\n"
40
29
 
41
30
  tasks.each do |task|
42
31
  puts task[:task]
43
- # CHANGED: Colors are now always enabled.
44
- # Without colors the output is unreadable.
45
32
  puts " \e[30m\e[1mline #{task[:line_number]} in #{task[:file]}\e[0m"
46
33
  end
34
+
35
+ puts
47
36
  end
48
37
  end
49
38
  end
50
39
 
51
40
  private
52
41
 
53
- # Validate the argument passed to the parser's controller.
54
- # The argument must be a String and a valid file/folder path (relative or absolute).
55
- def validate(args)
56
- raise ArgumentError unless args.is_a?(Array) && args.any?
42
+ def fuzzy_find_files(queries: [])
43
+ patterns = regexify queries
57
44
 
58
- args.each do |arg|
59
- unless arg.is_a? String
60
- raise ArgumentError, "The argument passed to the parser's constructor must be a String"
61
- end
45
+ paths = []
46
+ # FIXME: Search in the root of a project if in a git repo
47
+ Find.find('.') do |path|
48
+ paths << path unless FileTest.directory?(path)
49
+ end
62
50
 
63
- unless File.file?(arg) || File.directory?(arg)
64
- raise ArgumentError, "The argument passed to the parse's constructor must be either a file or a folder"
65
- end
51
+ paths.map! { |p| p.gsub /\A\.\//, "" }
52
+
53
+ EXCLUDED_DIRECTORIES.each do |d|
54
+ paths.delete_if { |p| p =~ /\A#{Regexp.escape(d)}/ }
66
55
  end
67
- end
68
56
 
69
- # Take the args, which are files/folders list,
70
- # and create a list of all the files to parse
71
- def collect(args)
72
- files = []
73
- args.each do |arg|
74
- %w[**/* **/*.* **/.*].each do |glob|
75
- files << Dir.glob("#{arg}/#{glob}")
76
- end
57
+ EXCLUDED_EXTENSIONS.each do |e|
58
+ paths.delete_if { |p| File.file?(p) && File.extname(p) =~ /\A#{Regexp.escape(e)}/ }
77
59
  end
78
60
 
79
- files.flatten.uniq.delete_if { |file| File.directory?(file) }
80
- end
61
+ EXCLUDED_GLOBS.each do |g|
62
+ paths.delete_if { |p| p =~ /#{unglobify(g)}/ }
63
+ end
64
+
65
+ if queries.empty?
66
+ paths
67
+ else
68
+ results = []
81
69
 
82
- # Get the valid tasks and their regex
83
- # from the config/valid_tasks.yml YAML file
84
- def get_valid_tasks
85
- tasks = {}
70
+ patterns.each do |pattern|
71
+ paths.each do |path|
72
+ matches = path.match(/#{pattern}/).to_a
86
73
 
87
- shit = YAML::load(File.open(@config_folder + "/valid_tasks.yml"))
88
- shit.each do |crap|
89
- crap.each do |task, regex|
90
- tasks[task] = regex
74
+ results << path unless matches.empty?
75
+ end
91
76
  end
92
- end
93
77
 
94
- tasks
78
+ results
79
+ end
95
80
  end
96
81
 
97
- # Get the list of excluded folders and their regex
98
- # from the config/excluded_folders.yml YAML file
99
- def get_excluded_folders
100
- YAML::load(File.open(@config_folder + "/excluded_folders.yml"))
101
- end
82
+ def regexify(queries)
83
+ patterns = []
84
+
85
+ queries.each do |query|
86
+ if query.include?("/")
87
+ pattern = query.split("/").map { |p| p.split("").join(")[^\/]*?(").prepend("[^\/]*?(") + ")[^\/]*?" }.join("\/")
88
+ pattern << "\/" if query[-1] == "/"
89
+ else
90
+ pattern = query.split("").join(").*?(").prepend(".*?(") + ").*?"
91
+ end
102
92
 
103
- # Initialize the tasks hash
104
- def initialize_tasks_hash
105
- tasks = {}
106
- @valid_tasks.each do |task, regex|
107
- tasks[task] = []
93
+ patterns << pattern
108
94
  end
109
95
 
110
- tasks
96
+ patterns
111
97
  end
112
98
 
113
- # Parse a file to find tasks
114
- def parsef(file, type = nil)
115
- # Don't parse files that are in excluded folders!
116
- @excluded_folders.each do |regex|
117
- return if file =~ /#{regex}/
99
+ # NOTE: This is actually a glob-to-regex method
100
+ def unglobify(glob)
101
+ chars = glob.split("")
102
+
103
+ chars = smoosh(chars)
104
+
105
+ curlies = 0
106
+ escaping = false
107
+ string = chars.map do |char|
108
+ if escaping
109
+ escaping = false
110
+ char
111
+ else
112
+ case char
113
+ when "**"
114
+ "([^/]+/)*"
115
+ when '*'
116
+ ".*"
117
+ when "?"
118
+ "."
119
+ when "."
120
+ "\."
121
+
122
+ when "{"
123
+ curlies += 1
124
+ "("
125
+ when "}"
126
+ if curlies > 0
127
+ curlies -= 1
128
+ ")"
129
+ else
130
+ char
131
+ end
132
+ when ","
133
+ if curlies > 0
134
+ "|"
135
+ else
136
+ char
137
+ end
138
+ when "\\"
139
+ escaping = true
140
+ "\\"
141
+ else
142
+ char
143
+ end
144
+ end
118
145
  end
119
146
 
120
- valid_tasks = (type.nil?) ? @valid_tasks : @valid_tasks.select { |k,v| k == type }
121
-
122
- unless ignore?(file)
123
- File.open(file, "r") do |f|
124
- line_number = 1
125
- while line = f.gets
126
- valid_tasks.each do |type, regex|
127
- begin
128
- result = line.match regex
129
- rescue ArgumentError
130
- # NOTE: Some files like .DS_Store are not filtered by the ignore? method...
131
- return
132
- end
147
+ '(\A|\/)' + string.join + '\Z'
148
+ end
133
149
 
134
- unless result.nil?
135
- task = {
136
- file: file,
137
- line_number: line_number,
138
- task: result.to_a.last
139
- }
150
+ def smoosh(chars)
151
+ out = []
140
152
 
141
- @tasks[type] << task
142
- end
143
- end
153
+ until chars.empty?
154
+ char = chars.shift
144
155
 
145
- line_number += 1
146
- end
156
+ if char == "*" && chars.first == "*"
157
+ chars.shift
158
+ chars.shift if chars.first == "/"
159
+ out.push("**")
160
+ else
161
+ out.push(char)
147
162
  end
148
163
  end
164
+
165
+ out
149
166
  end
150
167
 
151
- # Should a file be ignored?
152
- # Some files, like images or SQLite databases, are not meant to be parsed
153
- def ignore?(file)
154
- # Get the list of file extensions to ignore
155
- extensions = YAML::load(File.open(@config_folder + "/excluded_extensions.yml"))
156
- extensions.include?(File.extname(file))
168
+ # Parse a file to find tasks
169
+ def parsef!(file: "")
170
+ types = @type ? [@type] : VALID_TASKS
171
+
172
+ File.open(file, "r") do |f|
173
+ line_number = 1
174
+ while line = f.gets
175
+ types.each do |type|
176
+ result = line.match /#{Regexp.escape(type)}[\s,:-]+(\S.*)\Z/
177
+
178
+ unless result.nil?
179
+ task = {
180
+ file: file,
181
+ line_number: line_number,
182
+ task: result.to_a.last
183
+ }
184
+
185
+ @tasks[type.to_sym] << task
186
+ end
187
+ end
188
+
189
+ line_number += 1
190
+ end
191
+ end
157
192
  end
158
193
  end
159
194
  end
@@ -1,3 +1,3 @@
1
1
  module TaskList
2
- VERSION = "0.2"
2
+ VERSION = "0.3"
3
3
  end
data/task-list.gemspec CHANGED
@@ -15,9 +15,4 @@ Gem::Specification.new do |s|
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
-
19
- s.add_development_dependency "guard"
20
- s.add_development_dependency "guard-minitest"
21
- s.add_development_dependency "rb-fsevent"
22
- s.add_development_dependency "ruby_gntp"
23
18
  end
metadata CHANGED
@@ -1,60 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: task-list
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
5
- prerelease:
4
+ version: '0.3'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Aziz Light
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-01-14 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: guard
16
- requirement: &70204542044480 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
- prerelease: false
24
- version_requirements: *70204542044480
25
- - !ruby/object:Gem::Dependency
26
- name: guard-minitest
27
- requirement: &70204542043500 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *70204542043500
36
- - !ruby/object:Gem::Dependency
37
- name: rb-fsevent
38
- requirement: &70204542041860 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- type: :development
45
- prerelease: false
46
- version_requirements: *70204542041860
47
- - !ruby/object:Gem::Dependency
48
- name: ruby_gntp
49
- requirement: &70204542041380 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: *70204542041380
11
+ date: 2013-12-28 00:00:00.000000000 Z
12
+ dependencies: []
58
13
  description: TaskList parses source code to find code tags and list them in a terminal.
59
14
  See README.md for more info.
60
15
  email:
@@ -65,47 +20,39 @@ extensions: []
65
20
  extra_rdoc_files: []
66
21
  files:
67
22
  - .gitignore
68
- - .rvmrc
69
23
  - Gemfile
70
24
  - Gemfile.lock
71
- - Guardfile
72
25
  - LICENSE.md
73
26
  - README.md
74
27
  - Rakefile
75
28
  - bin/tl
76
- - config/excluded_extensions.yml
77
- - config/excluded_folders.yml
78
- - config/valid_tasks.yml
79
29
  - lib/task-list.rb
30
+ - lib/task-list/exceptions.rb
31
+ - lib/task-list/exceptions/invalid_task_type.rb
80
32
  - lib/task-list/parser.rb
81
33
  - lib/task-list/version.rb
82
- - spec/parser_spec.rb
83
- - spec/spec_helper.rb
84
34
  - task-list.gemspec
85
35
  homepage: https://github.com/AzizLight/TaskList
86
36
  licenses: []
37
+ metadata: {}
87
38
  post_install_message:
88
39
  rdoc_options: []
89
40
  require_paths:
90
41
  - lib
91
42
  required_ruby_version: !ruby/object:Gem::Requirement
92
- none: false
93
43
  requirements:
94
- - - ! '>='
44
+ - - '>='
95
45
  - !ruby/object:Gem::Version
96
46
  version: '0'
97
47
  required_rubygems_version: !ruby/object:Gem::Requirement
98
- none: false
99
48
  requirements:
100
- - - ! '>='
49
+ - - '>='
101
50
  - !ruby/object:Gem::Version
102
51
  version: '0'
103
52
  requirements: []
104
53
  rubyforge_project:
105
- rubygems_version: 1.8.10
54
+ rubygems_version: 2.0.14
106
55
  signing_key:
107
- specification_version: 3
56
+ specification_version: 4
108
57
  summary: Code tasks parser and lister
109
- test_files:
110
- - spec/parser_spec.rb
111
- - spec/spec_helper.rb
58
+ test_files: []
data/.rvmrc DELETED
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
- # development environment upon cd'ing into the directory
5
-
6
- # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
- environment_id="ruby-1.9.3-p0@task-list"
8
-
9
- #
10
- # Uncomment following line if you want options to be set only for given project.
11
- #
12
- # PROJECT_JRUBY_OPTS=( --1.9 )
13
-
14
- #
15
- # First we attempt to load the desired environment directly from the environment
16
- # file. This is very fast and efficient compared to running through the entire
17
- # CLI and selector. If you want feedback on which environment was used then
18
- # insert the word 'use' after --create as this triggers verbose mode.
19
- #
20
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
21
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
22
- then
23
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
24
-
25
- if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
26
- then
27
- . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
28
- fi
29
- else
30
- # If the environment file has not yet been created, use the RVM CLI to select.
31
- if ! rvm --create "$environment_id"
32
- then
33
- echo "Failed to create RVM environment '${environment_id}'."
34
- exit 1
35
- fi
36
- fi
37
-
38
- #
39
- # If you use an RVM gemset file to install a list of gems (*.gems), you can have
40
- # it be automatically loaded. Uncomment the following and adjust the filename if
41
- # necessary.
42
- #
43
- # filename=".gems"
44
- # if [[ -s "$filename" ]]
45
- # then
46
- # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
47
- # fi
48
-
49
- # If you use bundler, this might be useful to you:
50
- # if command -v bundle && [[ -s Gemfile ]]
51
- # then
52
- # bundle install
53
- # fi
54
-
55
-
data/Guardfile DELETED
@@ -1,6 +0,0 @@
1
- guard 'minitest' do
2
- watch(%r|^spec/(.*)_spec\.rb|)
3
- watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch(%r|^lib/task-list/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
5
- watch(%r|^spec/spec_helper\.rb|) { "spec" }
6
- end
@@ -1,11 +0,0 @@
1
- ---
2
- - '.jpg'
3
- - '.jpeg'
4
- - '.png'
5
- - '.gif'
6
- - '.svg'
7
- - '.sqlite3'
8
- - '.log'
9
- - '.rbc'
10
- - '.sassc'
11
- - '.gem'
@@ -1,6 +0,0 @@
1
- ---
2
- - '\/coverage\/'
3
- - '\/config\/'
4
- - '\/tmp\/'
5
- - '\/cache\/'
6
- - '\/logs?\/'
@@ -1,9 +0,0 @@
1
- ---
2
- - :TODO: 'TODO[\s,:-]+(\S.*)$'
3
- - :FIXME: 'FIX ?ME[\s,:-]+(\S.*)$'
4
- - :NOTE: 'NOTE[\s,:-]+(\S.*)$'
5
- - :BUG: 'BUG[\s,:-]+(\S.*)$'
6
- - :CHANGED: 'CHANGED[\s,:-]+(\S.*)$'
7
- - :OPTIMIZE: 'OPTIMIZE[\s,:-]+(\S.*)$'
8
- - :XXX: 'XXX[\s,:-]+(\S.*)$'
9
- - :!!!: '!!![\s,:-]+(\S.*)$'
data/spec/parser_spec.rb DELETED
@@ -1,17 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Parser" do
4
- it "must work" do
5
- lambda do
6
- TaskList::Parser
7
- end.must_be_silent
8
- end
9
-
10
- describe "arguments" do
11
- it "must require at least one argument" do
12
- lambda do
13
- TaskList::Parser.new
14
- end.must_raise ArgumentError
15
- end
16
- end
17
- end
data/spec/spec_helper.rb DELETED
@@ -1,6 +0,0 @@
1
- require_relative "../lib/task-list"
2
-
3
- require "minitest/spec"
4
- require "minitest/pride"
5
-
6
- MiniTest::Unit.autorun