todo_lint 0.2.3 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cfbc707bf83355d703a91f8d939cb5ff22a9909
4
- data.tar.gz: 9511008b2ac6197a9d310f9f2948a187ef806501
3
+ metadata.gz: 3d925d1749e411f4de9fc8c753060ab43ef53937
4
+ data.tar.gz: b8c5e5db3ca4f210b752ede2a47c43e451e72fab
5
5
  SHA512:
6
- metadata.gz: 50f3de4d47e85788b3b7d179c2834655c04515df9539b0e809ebacd4073e117b85dd86777ae338ae600ee0f57fcb0190763d984fbf88b6a8b7203e36be4f2b61
7
- data.tar.gz: d0bda1517784ce548ee12f3a7c9ef33c61460b40f9be95c78929e3fcd91876422138304d279c476530bd62afdc4d4ffddd834c6070577b33f024cf9c1e656a9e
6
+ metadata.gz: 99c1e602b9ef8577c0cd984b772a1417b4c1b658a026d6183d2420d1bf4f2a3e63b80c625d525f46221cd9ab61a29a853e9af6598a6c9cd7c6e9b3984af087e6
7
+ data.tar.gz: 45caf05a85101b675925986157b573ccf8d2ff7230435b448711d0078ef9141d6fbe90e426aad8fe878ee9070d1cca31e5d9f65bec811802fb6116b5c09465eb
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+
1
4
  Style/StringLiterals:
2
5
  EnforcedStyle: double_quotes
3
6
 
@@ -6,3 +9,12 @@ Style/SignalException:
6
9
 
7
10
  Style/HashSyntax:
8
11
  EnforcedStyle: hash_rockets
12
+
13
+ Metrics/AbcSize:
14
+ Exclude:
15
+ - lib/todo_lint/cli.rb
16
+
17
+ Metrics/MethodLength:
18
+ Exclude:
19
+ - lib/todo_lint/cli.rb
20
+ - lib/todo_lint/options.rb
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
- - 2.2.2
4
+ - 2.2.4
5
+ - 2.3.0
5
6
  before_install: gem install bundler -v 1.10.5
6
7
  script:
7
8
  - bundle exec rake form
data/Gemfile CHANGED
@@ -1,4 +1,11 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ gem "rake", "~> 10.0"
4
+ gem "rspec"
5
+ gem "timecop"
6
+ gem "rubocop"
7
+ gem "yardstick"
8
+ gem "pry"
9
+
3
10
  # Specify your gem's dependencies in todo_lint.gemspec
4
11
  gemspec
data/lib/todo_lint/cli.rb CHANGED
@@ -7,7 +7,7 @@ module TodoLint
7
7
  # @example
8
8
  # Cli.new(["-i", ".rb,.js"])
9
9
  # @api public
10
- def initialize(args) # rubocop:disable Metrics/AbcSize
10
+ def initialize(args) # rubocop:disable
11
11
  @options = Options.new.parse(args)
12
12
  if @options[:config_file]
13
13
  @options.merge!(ConfigFile.new.read_config_file(@options[:config_file]))
@@ -18,12 +18,48 @@ module TodoLint
18
18
  add_default_extensions unless @options.fetch(:files, []).any?
19
19
  end
20
20
 
21
+ # Perform the actions requested based on the options specified
22
+ #
21
23
  # @example
22
24
  # Cli.new(["-i", ".rb"]).run!
23
25
  # @return exit code 0 for success, 1 for failure
24
26
  # @api public
25
- # rubocop:disable Metrics/AbcSize
26
- def run! # rubocop:disable Metrics/MethodLength
27
+ def run!
28
+ if options[:report]
29
+ print_report
30
+ else
31
+ lint_codebase
32
+ end
33
+ end
34
+
35
+ # Loads the files to be read
36
+ # @return [Array<String>]
37
+ # @example cli.load_files(file_finder)
38
+ # @api public
39
+ def load_files(file_finder)
40
+ if file_finder.options.fetch(:files).empty?
41
+ file_finder.list(*options[:extensions])
42
+ else
43
+ file_finder.options.fetch(:files, [])
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Where are we looking for files?
50
+ # @return [String]
51
+ # @api private
52
+ attr_reader :path
53
+
54
+ # Options hash for all configurations
55
+ # @return [Hash]
56
+ # @api private
57
+ attr_reader :options
58
+
59
+ # Check requested files for problematic TODO comments
60
+ # @return exit code 0 for success, 1 for failure
61
+ # @api private
62
+ def lint_codebase
27
63
  finder = FileFinder.new(path, options)
28
64
  files = load_files(finder)
29
65
  files_count = files.count
@@ -52,29 +88,28 @@ module TodoLint
52
88
  end
53
89
  end
54
90
 
55
- # Loads the files to be read
56
- # @return [Array<String>]
57
- # @example cli.load_files(file_finder)
58
- # @api public
59
- def load_files(file_finder)
60
- if file_finder.options.fetch(:files).empty?
61
- file_finder.list(*options[:extensions])
62
- else
63
- file_finder.options.fetch(:files, [])
64
- end
65
- end
66
-
67
- private
68
-
69
- # Where are we looking for files?
70
- # @return [String]
91
+ # Print report of todos in codebase, then exit
92
+ #
93
+ # @return by exiting with 0
71
94
  # @api private
72
- attr_reader :path
95
+ def print_report
96
+ todos = []
97
+ finder = FileFinder.new(path, options)
98
+ files = load_files(finder)
99
+ files.each do |file|
100
+ todos += Todo.within(File.open(file))
101
+ end
102
+ todos.sort.each.with_index do |todo, num|
103
+ due_date = if todo.due_date
104
+ Rainbow(" (due #{todo.due_date.to_date})").blue
105
+ else
106
+ Rainbow(" (missing due date)").red
107
+ end
108
+ puts "#{num + 1}. #{todo.task}#{due_date}"
109
+ end
73
110
 
74
- # Options hash for all configurations
75
- # @return [Hash]
76
- # @api private
77
- attr_reader :options
111
+ exit 0
112
+ end
78
113
 
79
114
  # Pluralize a word based on the count
80
115
  # @return [String]
@@ -9,7 +9,7 @@ module TodoLint
9
9
  # @param args [Array<String>] arguments passed via the command line
10
10
  # @return [Hash] parsed options
11
11
  def parse(args)
12
- @options = {}
12
+ @options = { :report => false }
13
13
 
14
14
  OptionParser.new do |parser|
15
15
  parser.banner = "Usage: todo_lint [options] [files]"
@@ -17,6 +17,7 @@ module TodoLint
17
17
  exclude_file_options parser
18
18
  include_extension_options parser
19
19
  report_version parser
20
+ report_report_options parser
20
21
  end.parse!(args)
21
22
 
22
23
  # Any remaining arguments are assumed to be files
@@ -71,6 +72,15 @@ module TodoLint
71
72
  end
72
73
  end
73
74
 
75
+ # Checks if the user requested a report on the todos in their codebase
76
+ # @api private
77
+ # @return [Hash]
78
+ def report_report_options(parser)
79
+ parser.on("-r", "--report") do
80
+ options[:report] = true
81
+ end
82
+ end
83
+
74
84
  # Options hash for all configurations
75
85
  # @return [Hash]
76
86
  # @api private
@@ -24,7 +24,7 @@ module TodoLint
24
24
  return if judge.charge.nil?
25
25
 
26
26
  "#{todo_location} #{problem}\n" \
27
- "#{todo.line.chomp}\n" \
27
+ "#{todo.line.chomp.lstrip}\n" \
28
28
  "#{spaces}#{carets}"
29
29
  end
30
30
 
@@ -63,14 +63,21 @@ module TodoLint
63
63
  # @return [String]
64
64
  # @api private
65
65
  def spaces
66
- " " * (todo.character_number - 1)
66
+ " " * number_of_spaces
67
+ end
68
+
69
+ # How many spaces before the carets should there be?
70
+ # @return [Fixnum]
71
+ # @api private
72
+ def number_of_spaces
73
+ todo.character_number - 1 - (todo.line.length - todo.line.lstrip.length)
67
74
  end
68
75
 
69
76
  # Generate the ^^^^ characters to point at the flag
70
77
  # @return [String]
71
78
  # @api private
72
79
  def carets
73
- "^" * (todo.flag.length)
80
+ "^" * todo.flag.length
74
81
  end
75
82
  end
76
83
  end
@@ -4,8 +4,9 @@ module TodoLint
4
4
  # The regular expression that identifies todo comments
5
5
  PATTERN = /
6
6
  (?<flag> TODO ){0}
7
- (?<due_date> \(\d{4}-\d{2}-\d{2}\) ){0}
8
- \g<flag>\g<due_date>?
7
+ (?<due_date> \(\d{4}-\d{2}-\d{2}\)){0}
8
+ (?<task>.+){0}
9
+ \g<flag>\g<due_date>?: \g<task>
9
10
  /x
10
11
 
11
12
  # Search a file for all of the todo/fixme/etc comments within it
@@ -66,6 +67,17 @@ module TodoLint
66
67
  !match[:due_date].nil?
67
68
  end
68
69
 
70
+ # What is the actual task associated with this todo?
71
+ #
72
+ # @example
73
+ # todo.task #=> "Wash the car"
74
+ #
75
+ # @return [String]
76
+ # @api public
77
+ def task
78
+ match[:task].lstrip
79
+ end
80
+
69
81
  # When this todo is due
70
82
  # @example
71
83
  # due_todo.line #=> "# TODO(2015-05-24): go to the beach"
@@ -97,6 +109,31 @@ module TodoLint
97
109
  (line =~ PATTERN) + 1
98
110
  end
99
111
 
112
+ # Which todo is due sooner?
113
+ #
114
+ # @example
115
+ # [todo_one, todo_two].sort # this implicitly calls <=>
116
+ #
117
+ # @return [Fixnum]
118
+ # @api public
119
+ def <=>(other)
120
+ due_date_for_sorting <=> other.due_date_for_sorting
121
+ end
122
+
123
+ protected
124
+
125
+ # Helper for sorting todos
126
+ #
127
+ # @example
128
+ # todo.due_date_for_sorting #=> #<Date: 2016-02-06>
129
+ #
130
+ # @return [Date]
131
+ # @api semipublic
132
+ def due_date_for_sorting
133
+ # Date.new is like the beginning of time
134
+ due_date ? due_date.to_date : Date.new
135
+ end
136
+
100
137
  private
101
138
 
102
139
  # Analyze the line to help identify when the todo is due
@@ -2,5 +2,5 @@
2
2
  # it's in its own file so it can be required in the gemspec without requiring
3
3
  # everything else as well
4
4
  module TodoLint
5
- VERSION = "0.2.3"
5
+ VERSION = "0.3.0".freeze
6
6
  end
data/todo_lint.gemspec CHANGED
@@ -26,13 +26,8 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ["lib"]
28
28
 
29
+ spec.add_development_dependency "bundler", "~> 1.10"
30
+
29
31
  spec.add_runtime_dependency "required_arg", "~> 1.0"
30
32
  spec.add_runtime_dependency "rainbow", "~> 2.0.0"
31
- spec.add_development_dependency "bundler", "~> 1.10"
32
- spec.add_development_dependency "rake", "~> 10.0"
33
- spec.add_development_dependency "rspec"
34
- spec.add_development_dependency "timecop"
35
- spec.add_development_dependency "rubocop"
36
- spec.add_development_dependency "yardstick"
37
- spec.add_development_dependency "pry"
38
33
  end
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: todo_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Jacobson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-11 00:00:00.000000000 Z
11
+ date: 2016-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: required_arg
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
- - !ruby/object:Gem::Dependency
28
- name: rainbow
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 2.0.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 2.0.0
41
13
  - !ruby/object:Gem::Dependency
42
14
  name: bundler
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -53,89 +25,33 @@ dependencies:
53
25
  - !ruby/object:Gem::Version
54
26
  version: '1.10'
55
27
  - !ruby/object:Gem::Dependency
56
- name: rake
28
+ name: required_arg
57
29
  requirement: !ruby/object:Gem::Requirement
58
30
  requirements:
59
31
  - - "~>"
60
32
  - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
33
+ version: '1.0'
34
+ type: :runtime
63
35
  prerelease: false
64
36
  version_requirements: !ruby/object:Gem::Requirement
65
37
  requirements:
66
38
  - - "~>"
67
39
  - !ruby/object:Gem::Version
68
- version: '10.0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: timecop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: yardstick
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
40
+ version: '1.0'
125
41
  - !ruby/object:Gem::Dependency
126
- name: pry
42
+ name: rainbow
127
43
  requirement: !ruby/object:Gem::Requirement
128
44
  requirements:
129
- - - ">="
45
+ - - "~>"
130
46
  - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
47
+ version: 2.0.0
48
+ type: :runtime
133
49
  prerelease: false
134
50
  version_requirements: !ruby/object:Gem::Requirement
135
51
  requirements:
136
- - - ">="
52
+ - - "~>"
137
53
  - !ruby/object:Gem::Version
138
- version: '0'
54
+ version: 2.0.0
139
55
  description: todo_lint can be integrated into a continuous integration workflow to
140
56
  keep todo comments from becoming stagnant over time. Just annotate the comment with
141
57
  a date, and if that date has passed, your build will fail, and you'll be reminded
@@ -190,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
106
  version: '0'
191
107
  requirements: []
192
108
  rubyforge_project:
193
- rubygems_version: 2.4.5
109
+ rubygems_version: 2.5.2
194
110
  signing_key:
195
111
  specification_version: 4
196
112
  summary: Linter to help you remember your todos