glyptodont 0.1.0 → 0.2.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
  SHA256:
3
- metadata.gz: 2ad92f48b0fac0e3a90a61d375ccb01f187c79a79070bb801cac3d30f13585e3
4
- data.tar.gz: eec6a97e7ab90f1bbd557f5e8fbfc4e6f5809f7aa21f030a1b1f5eae124f1288
3
+ metadata.gz: 3cfa9e6366161885c86dbe07e79c0c14d57a58bbdf8c7e69d3683b6d96838dfe
4
+ data.tar.gz: d71c6335cd02094e9bbabc72701c21e7cb6001617a2eddbb5884f68d496dff43
5
5
  SHA512:
6
- metadata.gz: b1daa8bc22b0345c15c8c6f19b394f236e9169007f402b934c94a55b5076ac4ce0c21e9b1c5a49300a5276490b2366df4e68ebc731ece3a89d4b1e12f4eb7c2a
7
- data.tar.gz: d1238f2ffbde7b028bc65405ffe0e9b1573f4f8fc86450a2fd1a5cd1ceece15ef4b3bd8e6d7662c0418c7861311d1084c39f0b5dd9931c35b99a3a81b9369e33
6
+ metadata.gz: 994f96b328e5beef3093bb344ec53f362c3fa2255da24338343069b9511fafd0be2999ecd8a5e60a43bb55966e8e155061ef43a1b0dca5acdf180b7f857bffa5
7
+ data.tar.gz: 1e8200f3b8cce054163ba12d9e31a87267f12ea3c0796cb47809c7abf5d66f7603cd0fefb59cc6cfca1e7ffd5b2a533a0e080be15012b9223a081af8517ca2f7
@@ -10,12 +10,15 @@ jobs:
10
10
  ruby: ['2.4', '2.5', '2.6', '2.7', '3.0']
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v2
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
14
16
  - name: Set up Ruby
15
17
  uses: ruby/setup-ruby@v1
16
18
  with:
17
19
  ruby-version: ${{ matrix.ruby }}
18
- - name: Run the default task
20
+
21
+ - name: Run The CI Build
19
22
  run: |
20
23
  gem install bundler
21
24
  sudo apt install cmake
data/.glyptodont.yaml CHANGED
@@ -1,10 +1,14 @@
1
1
  ---
2
+ threshold: 1
3
+ max_age_in_days: 1
2
4
  ignore:
3
- - README.md:10
4
- - README.md:15
5
- - lib/glyptodont/checkers/counter.rb:28
5
+ - README.md:11
6
+ - README.md:16
6
7
  - lib/glyptodont/checkers/counter.rb:30
7
- - lib/glyptodont/todo_researcher.rb:32
8
+ - lib/glyptodont/checkers/counter.rb:32
8
9
  - lib/glyptodont/todo_researcher.rb:33
9
10
  - lib/glyptodont/todo_researcher.rb:34
10
11
  - lib/glyptodont/todo_researcher.rb:35
12
+ - lib/glyptodont/todo_researcher.rb:36
13
+ - spec/checkers/counter_spec.rb:20
14
+ - spec/checkers/counter_spec.rb:28
data/.rubocop.yml CHANGED
@@ -13,3 +13,7 @@ Style/StringLiteralsInInterpolation:
13
13
 
14
14
  Layout/LineLength:
15
15
  Max: 120
16
+
17
+ Metrics/BlockLength:
18
+ Exclude:
19
+ - "spec/**/*.rb"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to
7
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
+
1
9
  ## [Unreleased]
2
10
 
11
+ [Unreleased]: https://github.com/johnsyweb/glyptodont/compare/v0.2.0..main
12
+
13
+ ## [0.2.0] - 2021-03-28
14
+
15
+ ### Added
16
+
17
+ - Configuration settings for `max_age_in_days` and `threshold`, to allow for
18
+ setting these per project. [[#3]]
19
+
20
+ ### Changed
21
+
22
+ - Report all old TODOs, use age of the youngest in message [[#2]]
23
+
24
+ ### Fixed
25
+
26
+ - Handle empty configuration file [[#1]]
27
+
28
+ [#1]: https://github.com/johnsyweb/glyptodont/pull/1
29
+ [#2]: https://github.com/johnsyweb/glyptodont/pull/2
30
+ [#3]: https://github.com/johnsyweb/glyptodont/pull/3
31
+
32
+ [Unreleased]: https://github.com/johnsyweb/glyptodont/compare/v0.1.0..v0.2.0
33
+
3
34
  ## [0.1.0] - 2021-03-13
4
35
 
5
36
  - Initial release
37
+
38
+ [0.1.0]: https://github.com/johnsyweb/glyptodont/releases/tag/v0.1.0
data/Gemfile CHANGED
@@ -8,5 +8,6 @@ gemspec
8
8
  gem "rake", "~> 13.0"
9
9
 
10
10
  gem "rspec", "~> 3.0"
11
+ gem "rspec-its", "~> 1.3.0"
11
12
 
12
13
  gem "rubocop", "~> 1.7"
data/README.md CHANGED
@@ -59,17 +59,29 @@ Usage: glyptodont [options]
59
59
  ## Configuration
60
60
 
61
61
  glyptodont looks for an optional `.glyptodont.yaml` configuration file in the
62
- root of the directory being scanned, which contains an `ignore` list of
63
- `file_name:line_number` pairs to ignore when researching TODOs. This may be
64
- useful if you have, for example, Spanish language text in your project.
62
+ root of the directory being scanned.
63
+
64
+ ### Sections
65
+
66
+ - `threshold`: Maximum number of TODOs to allow. Can be overridden by
67
+ command-line options.
68
+ - `max_age_in_days`: Maximum number of days to allow TODOs to stay. Can be
69
+ overridden by command-line options.
70
+ - `ignore`: List of `file_name:line_number` pairs to ignore when researching
71
+ TODOs. This may be useful if you have, for example, Spanish language text in
72
+ your project or you talk about TODOs a lot :-)
65
73
 
66
74
  ### _Exempli gratiā_
67
75
 
68
76
  ```yaml
69
77
  ---
78
+ threshold: 1
79
+ max_age_in_days: 1
70
80
  ignore:
71
- - lib/glyptodont/checkers/counter.rb:28
72
- - lib/glyptodont/todo_researcher.rb:34
81
+ - README.md:11
82
+ - lib/glyptodont/checkers/counter.rb:30
83
+ - lib/glyptodont/todo_researcher.rb:33
84
+ - spec/checkers/counter_spec.rb:20
73
85
  ```
74
86
 
75
87
  ## Requirements
@@ -95,3 +107,8 @@ The gem is available as open source under the terms of the [MIT License](https:/
95
107
  Everyone interacting in the Glyptodont project's codebases, issue trackers, chat
96
108
  rooms and mailing lists is expected to follow the [code of
97
109
  conduct](https://github.com/johnsyweb/glyptodont/blob/master/CODE_OF_CONDUCT.md).
110
+
111
+ ## See also
112
+
113
+ <https://github.com/johnsyweb/glyptodont-docker> to run this in a container,
114
+ ideal for your CI pipeline.
data/lib/glyptodont.rb CHANGED
@@ -1,38 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "glyptodont/checkers/age"
4
- require_relative "glyptodont/checkers/counter"
5
- require_relative "glyptodont/configuration"
6
- require_relative "glyptodont/formatting"
7
- require_relative "glyptodont/options"
8
- require_relative "glyptodont/todo_researcher"
3
+ require_relative "glyptodont/checker"
9
4
 
10
- require "forwardable"
11
-
12
- # This is where the magic happens
5
+ # Entry point
13
6
  module Glyptodont
14
- class << self
15
- def check
16
- @options = Options.new
17
- @configuration = Configuration.new(directory)
18
-
19
- todos = TodoResearcher.new(directory, ignore).research
20
-
21
- checks = [
22
- Checkers::Counter.new(todos: todos, threshold: threshold),
23
- Checkers::Age.new(todos: todos, threshold: max_age_in_days)
24
- ].freeze
25
-
26
- checks.each { |check| puts check.check }
27
-
28
- checks.all?(&:passed?)
29
- end
30
-
31
- attr_reader :configuration, :options
32
-
33
- extend Forwardable
34
-
35
- def_delegator :@configuration, :ignore
36
- def_delegators :@options, :directory, :threshold, :max_age_in_days
7
+ def self.check
8
+ Checker.new(ARGV).check
37
9
  end
38
10
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "checkers/age"
4
+ require_relative "checkers/counter"
5
+ require_relative "configuration"
6
+ require_relative "formatting"
7
+ require_relative "options"
8
+ require_relative "todo_researcher"
9
+
10
+ require "forwardable"
11
+
12
+ module Glyptodont
13
+ # Main class where all the work happens
14
+ class Checker
15
+ DEFAULT_THRESHOLD = 10
16
+ DEFAULT_MAX_AGE_IN_DAYS = 14
17
+
18
+ def initialize(args)
19
+ @options = Options.new(args)
20
+ @configuration = Configuration.new(directory)
21
+ end
22
+
23
+ def check
24
+ todos = TodoResearcher.new(directory, ignore).research
25
+
26
+ checks = [
27
+ Checkers::Counter.new(todos: todos, threshold: threshold),
28
+ Checkers::Age.new(todos: todos, threshold: max_age_in_days)
29
+ ].freeze
30
+
31
+ checks.each { |check| puts check.check }
32
+
33
+ checks.all?(&:passed?)
34
+ end
35
+
36
+ attr_reader :configuration, :options
37
+
38
+ extend Forwardable
39
+
40
+ def_delegator :@configuration, :ignore
41
+ def_delegators :@options, :directory
42
+
43
+ def threshold
44
+ options.threshold || configuration.threshold || DEFAULT_THRESHOLD
45
+ end
46
+
47
+ def max_age_in_days
48
+ options.max_age_in_days || configuration.max_age_in_days || DEFAULT_MAX_AGE_IN_DAYS
49
+ end
50
+ end
51
+ end
@@ -10,32 +10,40 @@ module Glyptodont
10
10
  end
11
11
 
12
12
  def check
13
- @age, @reportable_todos = oldest_todos
14
13
  message
15
14
  end
16
15
 
17
16
  def passed?
18
- todos.empty? || age <= threshold
17
+ stale_todos.empty?
19
18
  end
20
19
 
21
20
  private
22
21
 
23
- attr_reader :todos, :threshold, :age, :reportable_todos
22
+ attr_reader :todos, :threshold
24
23
 
25
24
  def message
26
25
  if todos.empty?
27
26
  "Nothing left to do"
28
27
  elsif passed?
29
- "At #{Glyptodont.pluralize(age, "day")}, TODOs are fresh enough for now"
28
+ "At #{Glyptodont.pluralize(oldest_age, "day")}, TODOs are fresh enough for now"
30
29
  else
31
- "Some TODOs are too stale at #{Glyptodont.pluralize(age, "day")} old:\n" +
32
- reportable_todos.map { |t| Glyptodont.format_todo(t) }.join("\n")
30
+ "Some TODOs are too stale at more than #{Glyptodont.pluralize(youngest_stale - 1, "day")} old:\n" +
31
+ stale_todos.map { |t| Glyptodont.format_todo(t) }.join("\n")
33
32
  end
34
33
  end
35
34
 
36
- def oldest_todos
37
- todos.group_by { |todo| todo[:age] }
38
- .max_by { |age, _group| age }
35
+ def stale_todos
36
+ @stale_todos ||= todos.select { |todo| todo[:age] > threshold }
37
+ .sort_by { |todo| todo[:age] }
38
+ .reverse
39
+ end
40
+
41
+ def oldest_age
42
+ todos.max_by { |t| t[:age] }[:age]
43
+ end
44
+
45
+ def youngest_stale
46
+ stale_todos.last[:age]
39
47
  end
40
48
  end
41
49
  end
@@ -10,8 +10,6 @@ module Glyptodont
10
10
  end
11
11
 
12
12
  def check
13
- @count = todos.size
14
- @reportable_todos = passed? ? todos : []
15
13
  message
16
14
  end
17
15
 
@@ -21,6 +19,10 @@ module Glyptodont
21
19
 
22
20
  private
23
21
 
22
+ def count
23
+ @count ||= todos.size
24
+ end
25
+
24
26
  def message
25
27
  if count.zero?
26
28
  "All done"
@@ -32,7 +34,7 @@ module Glyptodont
32
34
  end
33
35
  end
34
36
 
35
- attr_reader :todos, :threshold, :count
37
+ attr_reader :todos, :threshold
36
38
  end
37
39
  end
38
40
  end
@@ -7,6 +7,7 @@ module Glyptodont
7
7
  # Allow for configuring the tool
8
8
  class Configuration
9
9
  FILENAME = ".glyptodont.yaml"
10
+
10
11
  def initialize(directory)
11
12
  @config_filename = File.join(directory, FILENAME)
12
13
  end
@@ -15,16 +16,24 @@ module Glyptodont
15
16
  @ignore ||= extract_ignore_set || []
16
17
  end
17
18
 
19
+ def threshold
20
+ @threshold ||= config.fetch("threshold", nil)
21
+ end
22
+
23
+ def max_age_in_days
24
+ @max_age_in_days ||= config.fetch("max_age_in_days", nil)
25
+ end
26
+
18
27
  private
19
28
 
20
29
  attr_reader :config_filename
21
30
 
22
31
  def config
23
- @config ||= begin
24
- YAML.load_file(config_filename)
25
- rescue Errno::ENOENT
26
- {}
27
- end
32
+ @config ||= if File.exist?(config_filename)
33
+ YAML.load_file(config_filename, fallback: {})
34
+ else
35
+ {}
36
+ end
28
37
  end
29
38
 
30
39
  def extract_ignore_set
@@ -9,10 +9,9 @@ module Glyptodont
9
9
  class Options
10
10
  attr_reader :directory, :threshold, :max_age_in_days
11
11
 
12
- def initialize
12
+ def initialize(args)
13
+ @args = args
13
14
  @directory = "."
14
- @threshold = 10
15
- @max_age_in_days = 14
16
15
  parse
17
16
  end
18
17
 
@@ -26,7 +25,7 @@ module Glyptodont
26
25
  threshold_option(opts)
27
26
  max_age_in_days_option(opts)
28
27
  version_option(opts)
29
- end.parse!(ARGV)
28
+ end.parse!(@args)
30
29
  end
31
30
 
32
31
  def directory_option(opts)
@@ -9,6 +9,7 @@ module Glyptodont
9
9
  def initialize(directory, ignore)
10
10
  @directory = directory
11
11
  @ignore = ignore
12
+ @annotator = {}
12
13
  end
13
14
 
14
15
  def research
@@ -65,7 +66,8 @@ module Glyptodont
65
66
  end
66
67
 
67
68
  def line_info(file_path:, line_number:)
68
- Rugged::Blame.new(repository, file_path).for_line(line_number)
69
+ @annotator[file_path] ||= Rugged::Blame.new(repository, file_path)
70
+ @annotator[file_path].for_line(line_number)
69
71
  end
70
72
 
71
73
  def repository
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glyptodont
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/script/test CHANGED
@@ -10,6 +10,9 @@ cd "$(dirname "$0")/.."
10
10
 
11
11
  [ -z "$DEBUG" ] || set -x
12
12
 
13
+ echo "==> Code quality…"
14
+ bundle exec rubocop
15
+
13
16
  echo "==> Running tests…"
14
17
 
15
18
  if [ -n "$1" ]; then
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glyptodont
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Johns
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-16 00:00:00.000000000 Z
11
+ date: 2021-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git
@@ -64,6 +64,7 @@ files:
64
64
  - exe/glyptodont
65
65
  - glyptodont.gemspec
66
66
  - lib/glyptodont.rb
67
+ - lib/glyptodont/checker.rb
67
68
  - lib/glyptodont/checkers/age.rb
68
69
  - lib/glyptodont/checkers/counter.rb
69
70
  - lib/glyptodont/configuration.rb