task-list 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
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