todo_lint 0.1.0

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: 686068fe84fc3df1f9b68a3232bc4272130a6191
4
+ data.tar.gz: a5c69875e0ff6d09990dee6d1216ab1153ff8a7f
5
+ SHA512:
6
+ metadata.gz: 978754c35cc15b51db3b722619547b38826dae4ab21a053500c3023908b39213bac09449a5fc2b333ba194d31b482cec979617fdaa3e7a8525c036e8dfeecc0d
7
+ data.tar.gz: b3d93d84768d834d8c3ae582c839d013605d01b50cfeac210ff7532fca505bc8cbe7fe4e39e275c4562e3eefbecb8d74e01568078ea3a85f6b9a30771d7d455b
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ Style/StringLiterals:
2
+ EnforcedStyle: double_quotes
3
+
4
+ Style/SignalException:
5
+ EnforcedStyle: only_raise
6
+
7
+ Style/HashSyntax:
8
+ EnforcedStyle: hash_rockets
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.2.2
5
+ before_install: gem install bundler -v 1.10.5
6
+ script:
7
+ - bundle exec rake form
8
+ - bundle exec rake function
9
+ - bundle exec rake clarity
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in todo_lint.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Max Jacobson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # todo_lint
2
+
3
+ [![Build Status](https://travis-ci.org/maxjacobson/todo_lint.svg)][travis]
4
+
5
+ [travis]: https://travis-ci.org/maxjacobson/todo_lint
6
+
7
+ Sometimes TODO comments stagnate over time and you forget about them. It would
8
+ be great if you could snooze them, Mailbox-style, and be reminded about them
9
+ again later.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'todo_lint'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install todo_lint
26
+
27
+ ## Usage
28
+
29
+ Add this to your continuous integration list of commands in your `.travis.yml`
30
+ or `circle.yml`:
31
+
32
+ bundle exec todo_lint .rb .coffee .scss
33
+
34
+ (Put whichever file extensions you want it to check; note the leading dot.)
35
+
36
+ If you have a bunch of TODO comments in your code, your next build will fail.
37
+
38
+ Go through your TODO comments, and change from:
39
+
40
+ ```ruby
41
+ # TODO: refactor into multiple classes
42
+ ```
43
+
44
+ to:
45
+
46
+ ```ruby
47
+ # TODO(2043-11-05): refactor into multiple classes
48
+ ```
49
+
50
+ Now your build will pass. Until November, 2043.
51
+
52
+ ## Development
53
+
54
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
55
+ `rake` to run the tests. You can also run `bin/console` for an interactive
56
+ prompt that will allow you to experiment.
57
+
58
+ To install this gem onto your local machine, run `bundle exec rake install`. To
59
+ release a new version, update the version number in `version.rb`, and then run
60
+ `bundle exec rake release`, which will create a git tag for the version, push
61
+ git commits and tags, and push the `.gem` file to
62
+ [rubygems.org](https://rubygems.org).
63
+
64
+ ## Contributing
65
+
66
+ Bug reports and pull requests are welcome on GitHub at
67
+ https://github.com/maxjacobson/todo_lint. This project is intended to be a
68
+ safe, welcoming space for collaboration, and contributors are expected to
69
+ adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
70
+ conduct.
71
+
72
+
73
+ ## License
74
+
75
+ The gem is available as open source under the terms of the [MIT
76
+ License](http://opensource.org/licenses/MIT).
77
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+ require "yardstick/rake/verify"
5
+
6
+ RSpec::Core::RakeTask.new(:function)
7
+ RuboCop::RakeTask.new(:form)
8
+ Yardstick::Rake::Verify.new(:clarity)
9
+
10
+ task :default => [:function, :form, :clarity]
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "todo_lint"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/todo_lint ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "todo_lint"
4
+
5
+ TodoLint::Cli.new(ARGV).run!
data/lib/todo_lint.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "required_arg"
2
+ require "rainbow"
3
+ require "todo_lint/version"
4
+ require "todo_lint/due_date"
5
+ require "todo_lint/file_finder"
6
+ require "todo_lint/todo"
7
+ require "todo_lint/reporter"
8
+ require "todo_lint/judge"
9
+ require "todo_lint/cli"
10
+
11
+ # here we establish the module which will namespace all of the code for this gem
12
+ module TodoLint
13
+ end
@@ -0,0 +1,67 @@
1
+ module TodoLint
2
+ # Here we bring together all the pieces and see if it comes together
3
+ # TODO: test this class somehow
4
+ class Cli
5
+ # Startup the thing that actually checks the files for todos!
6
+ # @example
7
+ # Cli.new([".rb", ".js"])
8
+ # @api public
9
+ def initialize(extensions = [])
10
+ @path = File.expand_path(".")
11
+ @extensions = extensions
12
+ end
13
+
14
+ # @example
15
+ # Cli.new([".rb"]).run!
16
+ # @return exit code 0 for success, 1 for failure
17
+ # @api public
18
+ # rubocop:disable Metrics/AbcSize
19
+ def run! # rubocop:disable Metrics/MethodLength
20
+ finder = FileFinder.new(File.expand_path("."))
21
+ files = finder.list(*extensions)
22
+ files_count = files.count
23
+ reports = files.map do |file|
24
+ Todo.within(File.open(file)).map do |todo|
25
+ reporter = Reporter.new(todo,
26
+ :path => path,
27
+ :judge => Judge.new(todo))
28
+ reporter.report.tap do |report|
29
+ print Rainbow(".").public_send(report.nil? ? :green : :red)
30
+ end
31
+ end
32
+ end.flatten.compact
33
+ if reports.any?
34
+ reports.each do |report|
35
+ puts report
36
+ end
37
+ puts "\nFound #{pluralize('problematic todo', reports.count)} in " \
38
+ "#{pluralize('file', files_count)}"
39
+ exit 1
40
+ else
41
+ puts "\nGreat job! No overdue todos in " \
42
+ "#{pluralize('file', files_count)}"
43
+ exit 0
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Which file extensions are we checking?
50
+ # @return [Array<String>]
51
+ # @api private
52
+ attr_reader :extensions
53
+
54
+ # Where are we looking for files?
55
+ # @return [String]
56
+ # @api private
57
+ attr_reader :path
58
+
59
+ # Pluralize a word based on the count
60
+ # @return [String]
61
+ # @api private
62
+ def pluralize(word, count)
63
+ s = count == 1 ? "" : "s"
64
+ "#{count} #{word + s}"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,47 @@
1
+ require "date"
2
+
3
+ module TodoLint
4
+ # When is this todo actually due? When ought we be reminded of this one?
5
+ class DueDate
6
+ ANNOTATION_PATTERN = /\((\d{4})-(\d{2})-(\d{2})/
7
+
8
+ # Parse the date from the todo comment's due date annotation
9
+ # @example
10
+ # DueDate.from_annotation("(2015-04-14)")
11
+ # @return [DueDate] if the annotation is formatted properly
12
+ # @raise [ArgumentError] if the annotation is not formatted properly
13
+ # @api public
14
+ def self.from_annotation(annotation)
15
+ if (match = ANNOTATION_PATTERN.match(annotation))
16
+ DueDate.new(Date.new(match[1].to_i, match[2].to_i, match[3].to_i))
17
+ else
18
+ msg = "not a properly formatted annotation: #{annotation.inspect}"
19
+ raise ArgumentError, msg
20
+ end
21
+ end
22
+
23
+ # The actual date object when something is due
24
+ # @example
25
+ # DueDate.new(Date.today).to_date == Date.today #=> true
26
+ # @return [Date]
27
+ # @api public
28
+ attr_reader :to_date
29
+
30
+ # Take a simple date object and imbue it with meaning
31
+ # @example
32
+ # DueDate.new(Date.today)
33
+ # @api public
34
+ def initialize(date)
35
+ @to_date = date
36
+ end
37
+
38
+ # Is this due date in the past?
39
+ # @example
40
+ # due_date.overdue? #=> true
41
+ # @return [Boolean]
42
+ # @api public
43
+ def overdue?
44
+ Date.today > to_date
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ require "pathname"
2
+
3
+ module TodoLint
4
+ # Which files are we going to inspect?
5
+ class FileFinder
6
+ # Instantiate a FileFinder with the path to a folder
7
+ # @example
8
+ # FileFinder.new("/Users/max/src/layabout")
9
+ # @api public
10
+ def initialize(path)
11
+ @path = path
12
+ @all_files = Dir.glob(Pathname.new(path).join("**", "*"))
13
+ end
14
+
15
+ # Absolute paths to all the files with the provided extensions
16
+ # @example
17
+ # FileFinder.new("/Users/max/src/layabout").list(".rb", ".coffee")
18
+ # @api public
19
+ # @return [Array<String>]
20
+ def list(*extensions)
21
+ all_files.keep_if do |filename|
22
+ extensions.include?(Pathname.new(filename).extname)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # Which folder to look within for files
29
+ # @return [String]
30
+ # @api private
31
+ attr_reader :path
32
+
33
+ # Absolute paths to all the files which exist within the provided folder
34
+ # @return [Array<String>]
35
+ # @api private
36
+ attr_reader :all_files
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ module TodoLint
2
+ # Is this todo worth bothering the user about? Judge the todo, and charge it
3
+ # with a crime if necessary
4
+ class Judge
5
+ # The problem, if any, with this todo
6
+ # @example
7
+ # judge.charge #=> "The todo is overly dramatic"
8
+ # @return [String] if the todo has something going on with it
9
+ # @return [NilClass] if the todo is fine
10
+ # @api public
11
+ attr_reader :charge
12
+
13
+ # Accept and judge a todo
14
+ # @example
15
+ # Judge.new(todo)
16
+ # @api public
17
+ def initialize(todo)
18
+ if todo.annotated?
19
+ @charge = "Overdue due date" if todo.due_date.overdue?
20
+ else
21
+ @charge = "Missing due date annotation"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,76 @@
1
+ module TodoLint
2
+ # We want to be able to report to users about the todos in their code, and
3
+ # the Reporter is responsible for passing judgment and generating output
4
+ class Reporter
5
+ # Accept a todo and a path to check for problems
6
+ # @example
7
+ # Reporter.new(todo,
8
+ # path: "/Users/max/src/required_arg/README.md",
9
+ # judge: Judge.new(todo))
10
+ # @api public
11
+ def initialize(todo, path: RequiredArg.new, judge: RequiredArg.new)
12
+ @todo = todo
13
+ @path = path
14
+ @judge = judge
15
+ end
16
+
17
+ # Generate the output to show the user about their todo
18
+ # @example
19
+ # reporter.report
20
+ # @return [String] if the todo is problematic
21
+ # @return [NilClass] if the todo is fine
22
+ # @api public
23
+ def report
24
+ return if judge.charge.nil?
25
+
26
+ "#{todo_location} #{problem}\n" \
27
+ "#{todo.line}\n" \
28
+ "#{spaces}#{carets}"
29
+ end
30
+
31
+ private
32
+
33
+ # The todo being reported on
34
+ # @return [Todo]
35
+ # @api private
36
+ attr_reader :todo
37
+
38
+ # The path to the file containing the todo
39
+ # @return [String]
40
+ # @api private
41
+ attr_reader :path
42
+
43
+ # The object responsible for charging the todo with a crime, or not
44
+ # @return [Judge]
45
+ # @api private
46
+ attr_reader :judge
47
+
48
+ # Which file, line, and character can the todo be found at?
49
+ # @return [String]
50
+ # @api private
51
+ def todo_location
52
+ Rainbow(path).green + ":#{todo.line_number}:#{todo.character_number}"
53
+ end
54
+
55
+ # The reason we are reporting on this todo
56
+ # @return [String]
57
+ # @api private
58
+ def problem
59
+ Rainbow(judge.charge).red
60
+ end
61
+
62
+ # Generate the indentation before the carets
63
+ # @return [String]
64
+ # @api private
65
+ def spaces
66
+ " " * (todo.character_number - 1)
67
+ end
68
+
69
+ # Generate the ^^^^ characters to point at the flag
70
+ # @return [String]
71
+ # @api private
72
+ def carets
73
+ "^" * (todo.flag.length)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,116 @@
1
+ module TodoLint
2
+ # Todo represents a todo/fixme/etc comment within your source code
3
+ class Todo
4
+ # The regular expression that identifies todo comments
5
+ PATTERN = /
6
+ (?<flag> TODO ){0}
7
+ (?<due_date> \(\d{4}-\d{2}-\d{2}\) ){0}
8
+ \g<flag>\g<due_date>?
9
+ /x
10
+
11
+ # Search a file for all of the todo/fixme/etc comments within it
12
+ # @example
13
+ # Todo.within(File.open("app.rb"))
14
+ # @api public
15
+ # @return [Array<Todo>]
16
+ def self.within(file)
17
+ file.each_line.with_index.map do |line, line_number|
18
+ new(line, :line_number => line_number + 1) if present_in?(line)
19
+ end.compact
20
+ end
21
+
22
+ # Does this line contain a todo?
23
+ # @example
24
+ # Todo.present_in?("hello") #=> false
25
+ # Todo.present_in?("TODO") #=> true
26
+ # @return [Boolean]
27
+ # @api public
28
+ def self.present_in?(line)
29
+ line =~ PATTERN
30
+ end
31
+
32
+ # The content of the line of source code containing the todo comment
33
+ # @example
34
+ # todo.line #=> "# TODO: refactor me"
35
+ # @api public
36
+ # @return [String]
37
+ attr_reader :line
38
+
39
+ # The 1-indexed line on which the todo was discovered
40
+ # @example
41
+ # todo.line_number #=> 4
42
+ # @api public
43
+ # @return [Fixnum]
44
+ attr_reader :line_number
45
+
46
+ # A new Todo must know a few things
47
+ # @example
48
+ # Todo.new("#TODO: get a boat", line_number: 4)
49
+ # @api public
50
+ def initialize(line, line_number: RequiredArg.new(:line_number))
51
+ absent_todo!(line) unless self.class.present_in?(line)
52
+ @line = line
53
+ @line_number = line_number
54
+ end
55
+
56
+ # Was this todo annotated with a due date?
57
+ # @example
58
+ # annotated_todo.line #=> "# TODO(2013-05-24): learn to fly"
59
+ # annotated_todo.annotated? #=> true
60
+ #
61
+ # not_annotated_todo.line #=> "# TODO: read a poem"
62
+ # not_annotated_todo.annotated? #=> false"
63
+ # @return [Boolean]
64
+ # @api public
65
+ def annotated?
66
+ !match[:due_date].nil?
67
+ end
68
+
69
+ # When this todo is due
70
+ # @example
71
+ # due_todo.line #=> "# TODO(2015-05-24): go to the beach"
72
+ # due__todo.due_date.to_date #=> #<Date: 2015-05-24>
73
+ # not_due_todo.line #=> "# TODO: become a fish"
74
+ # not_due_todo.due_date #=> nil
75
+ # @return [DueDate] if there is a due date
76
+ # @return [NilClass] if there is no due date
77
+ # @api public
78
+ def due_date
79
+ DueDate.from_annotation(match[:due_date]) if annotated?
80
+ end
81
+
82
+ # What did the developer write to get our attention?
83
+ # @example
84
+ # todo.flag #=> "TODO"
85
+ # @return [String]
86
+ # @api public
87
+ def flag
88
+ match[:flag]
89
+ end
90
+
91
+ # The 1-indexed character at which the todo comment is found
92
+ # @example
93
+ # todo.character_number #=> 4
94
+ # @return [Fixnum]
95
+ # @api public
96
+ def character_number
97
+ (line =~ PATTERN) + 1
98
+ end
99
+
100
+ private
101
+
102
+ # Analyze the line to help identify when the todo is due
103
+ # @return [MatchData]
104
+ # @api private
105
+ def match
106
+ @match ||= PATTERN.match(line)
107
+ end
108
+
109
+ # complain that this line isn't even a todo, so nothing will work anyway
110
+ # @return Does not return
111
+ # @api private
112
+ def absent_todo!(line)
113
+ raise ArgumentError, "Not even a todo: #{line.inspect}"
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,6 @@
1
+ # this file's sole responsibility is noting the latest version for the gem,
2
+ # it's in its own file so it can be required in the gemspec without requiring
3
+ # everything else as well
4
+ module TodoLint
5
+ VERSION = "0.1.0"
6
+ end
data/todo_lint.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "todo_lint/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "todo_lint"
8
+ spec.version = TodoLint::VERSION
9
+ spec.authors = ["Max Jacobson"]
10
+ spec.email = ["max@hardscrabble.net"]
11
+
12
+ spec.summary = "Linter to help you remember your todos"
13
+ spec.description = "todo_lint can be integrated into a continuous " \
14
+ "integration workflow to keep todo comments from " \
15
+ "becoming stagnant over time. Just annotate the " \
16
+ "comment with a date, and if that date has passed, " \
17
+ "your build will fail, and you'll be reminded to " \
18
+ "snooze the todo a little later, or finally address it."
19
+ spec.homepage = "https://github.com/maxjacobson/todo_lint"
20
+ spec.license = "MIT"
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_runtime_dependency "required_arg", "~> 1.0"
30
+ 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
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: todo_lint
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Max Jacobson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-06-29 00:00:00.000000000 Z
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
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !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'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: todo_lint can be integrated into a continuous integration workflow to
140
+ keep todo comments from becoming stagnant over time. Just annotate the comment with
141
+ a date, and if that date has passed, your build will fail, and you'll be reminded
142
+ to snooze the todo a little later, or finally address it.
143
+ email:
144
+ - max@hardscrabble.net
145
+ executables:
146
+ - todo_lint
147
+ extensions: []
148
+ extra_rdoc_files: []
149
+ files:
150
+ - ".gitignore"
151
+ - ".rspec"
152
+ - ".rubocop.yml"
153
+ - ".travis.yml"
154
+ - CODE_OF_CONDUCT.md
155
+ - Gemfile
156
+ - LICENSE.txt
157
+ - README.md
158
+ - Rakefile
159
+ - bin/console
160
+ - bin/setup
161
+ - exe/todo_lint
162
+ - lib/todo_lint.rb
163
+ - lib/todo_lint/cli.rb
164
+ - lib/todo_lint/due_date.rb
165
+ - lib/todo_lint/file_finder.rb
166
+ - lib/todo_lint/judge.rb
167
+ - lib/todo_lint/reporter.rb
168
+ - lib/todo_lint/todo.rb
169
+ - lib/todo_lint/version.rb
170
+ - todo_lint.gemspec
171
+ homepage: https://github.com/maxjacobson/todo_lint
172
+ licenses:
173
+ - MIT
174
+ metadata: {}
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubyforge_project:
191
+ rubygems_version: 2.4.5
192
+ signing_key:
193
+ specification_version: 4
194
+ summary: Linter to help you remember your todos
195
+ test_files: []
196
+ has_rdoc: